diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 9a84b2e9e..c8290b1e2 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -46,6 +46,7 @@ IF(DYNAMIC_OPENSCENEGRAPH) ADD_SUBDIRECTORY(osgfont) ADD_SUBDIRECTORY(osgforest) ADD_SUBDIRECTORY(osgfxbrowser) + ADD_SUBDIRECTORY(osgframerenderer) ADD_SUBDIRECTORY(osgoutline) ADD_SUBDIRECTORY(osggameoflife) ADD_SUBDIRECTORY(osggeodemo) diff --git a/examples/osgframerenderer/CMakeLists.txt b/examples/osgframerenderer/CMakeLists.txt new file mode 100644 index 000000000..6200cbba0 --- /dev/null +++ b/examples/osgframerenderer/CMakeLists.txt @@ -0,0 +1,10 @@ +SET(TARGET_SRC + CameraPathProperty.cpp + CaptureSettings.cpp + EventProperty.cpp + gscframerenderer.cpp + UpdateProperty.cpp +) + +#### end var setup ### +SETUP_EXAMPLE(osgframerenderer) diff --git a/examples/osgframerenderer/CameraPathProperty.cpp b/examples/osgframerenderer/CameraPathProperty.cpp new file mode 100644 index 000000000..7a10dbcdc --- /dev/null +++ b/examples/osgframerenderer/CameraPathProperty.cpp @@ -0,0 +1,88 @@ +#include "CameraPathProperty.h" + +using namespace gsc; + +void CameraPathProperty::update(osgViewer::View* view) +{ + osg::Camera* camera = view->getCamera(); + osg::FrameStamp* fs = view->getFrameStamp(); + + if (_animationPath.valid()) + { + osg::AnimationPath::ControlPoint cp; + _animationPath->getInterpolatedControlPoint( fs->getSimulationTime(), cp ); + + OSG_NOTICE<<"CameraPathProperty "<getFrameNumber()<<" "<getSimulationTime()<setViewMatrix( osg::Matrix::inverse(matrix) ); + } +} + +void CameraPathProperty::loadAnimationPath() +{ + _animationPath = new osg::AnimationPath;; + //_animationPath->setLoopMode(osg::AnimationPath::LOOP); + + osgDB::ifstream in(_filename.c_str()); + if (!in) + { + OSG_WARN << "CameraPathProperty: Cannot open animation path file \"" << _filename << "\".\n"; + return; + } + + _animationPath->read(in); +} + +bool CameraPathProperty::getTimeRange(double& startTime, double& endTime) const +{ + if (!_animationPath) return false; + + const osg::AnimationPath::TimeControlPointMap& tcpm = _animationPath->getTimeControlPointMap(); + if (tcpm.empty()) return false; + + startTime = tcpm.begin()->first; + endTime = tcpm.rbegin()->first; + + return true; +} + +void CameraPathProperty::resetTimeRange(double startTime, double endTime) +{ + if (!_animationPath) return; + + osg::AnimationPath::TimeControlPointMap& tcpm = _animationPath->getTimeControlPointMap(); + if (tcpm.empty()) return; + + osg::AnimationPath::TimeControlPointMap copy_tcpm = tcpm; + + double offset = tcpm.begin()->first; + double originalLength = tcpm.rbegin()->first - tcpm.begin()->first ; + double scale = originalLength>0.0 ? (endTime-startTime)/originalLength : 1.0; + + tcpm.clear(); + + for(osg::AnimationPath::TimeControlPointMap::iterator itr = copy_tcpm.begin(); + itr != copy_tcpm.end(); + ++itr) + { + tcpm[startTime + (itr->first-offset)*scale] = itr->second; + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// +// Serialization support +// +REGISTER_OBJECT_WRAPPER( gsc_CameraPathProperty, + new gsc::CameraPathProperty, + gsc::CameraPathProperty, + "osg::Object gsc::CameraPathProperty" ) +{ + ADD_STRING_SERIALIZER( AnimationPathFileName, "" ); +} + + + + diff --git a/examples/osgframerenderer/CameraPathProperty.h b/examples/osgframerenderer/CameraPathProperty.h new file mode 100644 index 000000000..8d28c7fac --- /dev/null +++ b/examples/osgframerenderer/CameraPathProperty.h @@ -0,0 +1,46 @@ +#ifndef CAMERAPATHPROPERTY_H +#define CAMERAPATHPROPERTY_H + +#include + +#include "UpdateProperty.h" + +namespace gsc +{ + +class CameraPathProperty : public gsc::UpdateProperty +{ +public: + + CameraPathProperty() {} + CameraPathProperty(const std::string& filename) { setAnimationPathFileName(filename); } + CameraPathProperty(const CameraPathProperty& cpp, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) {} + + META_Object(gsc, CameraPathProperty); + + void setAnimationPathFileName(const std::string& filename) { _filename = filename; loadAnimationPath(); } + const std::string& getAnimationPathFileName() const { return _filename; } + + void setAnimationPath(osg::AnimationPath* ap) { _animationPath = ap; } + osg::AnimationPath* getAnimationPath() { return _animationPath.get(); } + const osg::AnimationPath* getAnimationPath() const { return _animationPath.get(); } + + bool getTimeRange(double& startTime, double& endTime) const; + + void resetTimeRange(double startTime, double endTime); + + virtual void update(osgViewer::View* view); + +protected: + + virtual ~CameraPathProperty() {} + + void loadAnimationPath(); + + std::string _filename; + osg::ref_ptr _animationPath; +}; + +} + +#endif \ No newline at end of file diff --git a/examples/osgframerenderer/CaptureSettings.cpp b/examples/osgframerenderer/CaptureSettings.cpp new file mode 100644 index 000000000..0e6d263ed --- /dev/null +++ b/examples/osgframerenderer/CaptureSettings.cpp @@ -0,0 +1,144 @@ +#include "CaptureSettings.h" + +using namespace gsc; + +CaptureSettings::CaptureSettings() +{ + _offscreen = false; + _width = 1024; + _height = 524; + _samples = 0; + _sampleBuffers = 0; + _stereo = false; + _frameRate = 60.0; + _numberOfFrames = 0; +} + +void CaptureSettings::setOutputFileName(const std::string& filename) +{ + _outputFileName = filename; + + _outputDirectoryName = osgDB::getFilePath(filename); + if (!_outputDirectoryName.empty()) _outputDirectoryName += osgDB::getNativePathSeparator(); + + _outputBaseFileName = osgDB::getStrippedName(filename); + + _outputExtension = osgDB::getFileExtensionIncludingDot(filename); +} + +const std::string& CaptureSettings::getOutputFileName() const +{ + return _outputFileName; +} + +std::string CaptureSettings::getOutputFileName(unsigned int frameNumber) const +{ + std::stringstream str; + str<<_outputDirectoryName<<_outputBaseFileName<<"_"<0 && !_outputBaseFileName.empty() && !_outputExtension.empty() && !_inputFileName.empty(); +} + + +///////////////////////////////////////////////////////////////////////////////////////// +// +// Serialization support +// +static bool checkEventHandlers( const gsc::CaptureSettings& cs ) +{ + return !cs.getEventHandlers().empty(); +} + +static bool readEventHandlers( osgDB::InputStream& is, gsc::CaptureSettings& cs ) +{ + unsigned int size = 0; is >> size >> is.BEGIN_BRACKET; + for ( unsigned int i=0; i obj = is.readObject(); + gsc::UpdateProperty* up = dynamic_cast( obj.get() ); + if ( up ) cs.addUpdateProperty( up ); + } + is >> is.END_BRACKET; + return true; +} + +static bool writeEventHandlers( osgDB::OutputStream& os, const gsc::CaptureSettings& cs ) +{ + const gsc::CaptureSettings::EventHandlers& pl = cs.getEventHandlers(); + unsigned int size = pl.size(); + os << size << os.BEGIN_BRACKET << std::endl; + for ( unsigned int i=0; i> size >> is.BEGIN_BRACKET; + for ( unsigned int i=0; i obj = is.readObject(); + gsc::UpdateProperty* up = dynamic_cast( obj.get() ); + if ( up ) cs.addUpdateProperty( up ); + } + is >> is.END_BRACKET; + return true; +} + +static bool writeProperties( osgDB::OutputStream& os, const gsc::CaptureSettings& cs ) +{ + const gsc::CaptureSettings::Properties& pl = cs.getProperties(); + unsigned int size = pl.size(); + os << size << os.BEGIN_BRACKET << std::endl; + for ( unsigned int i=0; i +#include +#include +#include +#include + +#include "UpdateProperty.h" + +namespace gsc +{ + +class CaptureSettings : public osg::Object +{ +public: + CaptureSettings(); + CaptureSettings(const CaptureSettings& cs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) {} + + META_Object(gsc, CaptureSettings); + + void setInputFileName(const std::string& filename) { _inputFileName = filename; } + const std::string& getInputFileName() const { return _inputFileName; } + + void setOutputFileName(const std::string& filename); + const std::string& getOutputFileName() const; + + std::string getOutputFileName(unsigned int frameNumber) const; + std::string getOutputFileName(unsigned int cameraNumber, unsigned int frameNumber) const; + + void setOffscreen(bool o) { _offscreen = o; } + bool getOffscreen() const { return _offscreen; } + + void setWidth(unsigned int width) { _width = width; } + unsigned int getWidth() const { return _width; } + + void setHeight(unsigned int height) { _height = height; } + unsigned int getHeight() const { return _height; } + + void setSamples(unsigned int s) { _samples = s; } + unsigned int getSamples() const { return _samples; } + + void setSampleBuffers(unsigned int s) { _sampleBuffers = s; } + unsigned int getSampleBuffers() const { return _sampleBuffers; } + + void setStereo(bool on) { _stereo = on; } + bool getStereo() const { return _stereo; } + + void setFrameRate(double fr) { _frameRate = fr; } + double getFrameRate() const { return _frameRate; } + + void setNumberOfFrames(unsigned int nf) { _numberOfFrames = nf; } + unsigned int getNumberOfFrames() const { return _numberOfFrames; } + + typedef std::vector< osg::ref_ptr > EventHandlers; + void setEventHandlers(const EventHandlers& eh); + EventHandlers& getEventHandlers() { return _eventHandlers; } + const EventHandlers& getEventHandlers() const { return _eventHandlers; } + + typedef std::vector< osg::ref_ptr > Properties; + + void addUpdateProperty(UpdateProperty* up) { _properties.push_back(up); } + + void setProperties(const Properties& pl) { _properties = pl; } + Properties& getProperties() { return _properties; } + const Properties& getProperties() const { return _properties; } + + bool valid() const; + +protected: + virtual ~CaptureSettings() {} + + std::string _inputFileName; + + std::string _outputFileName; + std::string _outputDirectoryName; + std::string _outputBaseFileName; + std::string _outputExtension; + + bool _offscreen; + + unsigned int _width; + unsigned int _height; + unsigned int _samples; + unsigned int _sampleBuffers; + + bool _stereo; + + double _frameRate; + unsigned int _numberOfFrames; + + EventHandlers _eventHandlers; + Properties _properties; + +}; + +} + +#endif diff --git a/examples/osgframerenderer/EventProperty.cpp b/examples/osgframerenderer/EventProperty.cpp new file mode 100644 index 000000000..5300d4a57 --- /dev/null +++ b/examples/osgframerenderer/EventProperty.cpp @@ -0,0 +1,41 @@ +#include "EventProperty.h" + +namespace gsc +{ + +void EventProperty::update(osgViewer::View* view) +{ + if (view && view->getEventQueue() && _event.valid()) + { + view->getEventQueue()->addEvent(_event); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// +// Serialization support +// +REGISTER_OBJECT_WRAPPER( gsc_EventProperty, + new gsc::EventProperty, + gsc::EventProperty, + "osg::Object gsc::EventProperty" ) +{ + ADD_OBJECT_SERIALIZER( Event, osgGA::GUIEventAdapter, NULL ); +} + + +} + +namespace osgGA +{ + + + + +namespace B +{ + + +} + +} \ No newline at end of file diff --git a/examples/osgframerenderer/EventProperty.h b/examples/osgframerenderer/EventProperty.h new file mode 100644 index 000000000..36c51bfce --- /dev/null +++ b/examples/osgframerenderer/EventProperty.h @@ -0,0 +1,38 @@ +#ifndef EVENTPROPERTY_H +#define EVENTPROPERTY_H + +#include +#include "UpdateProperty.h" + +namespace gsc +{ + +class EventProperty : public gsc::UpdateProperty +{ +public: + + EventProperty() {} + EventProperty(osgGA::GUIEventAdapter* event):_event(event) {} + EventProperty(const EventProperty& cpp, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) {} + + META_Object(gsc, EventProperty); + + void setEvent(osgGA::GUIEventAdapter* ea) { _event = ea; } + osgGA::GUIEventAdapter* getEvent() { return _event.get(); } + const osgGA::GUIEventAdapter* getEvent() const { return _event.get(); } + + virtual void update(osgViewer::View* view); + +protected: + + virtual ~EventProperty() {} + + double _previousFrameTime; + osg::ref_ptr _event; +}; + + + +} + +#endif \ No newline at end of file diff --git a/examples/osgframerenderer/UpdateProperty.cpp b/examples/osgframerenderer/UpdateProperty.cpp new file mode 100644 index 000000000..1f86d120c --- /dev/null +++ b/examples/osgframerenderer/UpdateProperty.cpp @@ -0,0 +1,4 @@ +#include "UpdateProperty.h" + +using namespace gsc; + diff --git a/examples/osgframerenderer/UpdateProperty.h b/examples/osgframerenderer/UpdateProperty.h new file mode 100644 index 000000000..caaf385e1 --- /dev/null +++ b/examples/osgframerenderer/UpdateProperty.h @@ -0,0 +1,32 @@ +#ifndef UPDATEPROPERTY_H +#define UPDATEPROPERTY_H + +#include +#include +#include +#include +#include + +namespace gsc +{ + +class UpdateProperty : public osg::Object +{ +public: + + UpdateProperty() {} + UpdateProperty(const UpdateProperty& up, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) {} + + META_Object(gsc, UpdateProperty); + + virtual void update(osgViewer::View* view) {} + +protected: + + virtual ~UpdateProperty() {} +}; + + +} + +#endif \ No newline at end of file diff --git a/examples/osgframerenderer/gscframerenderer.cpp b/examples/osgframerenderer/gscframerenderer.cpp new file mode 100644 index 000000000..4a03e2b73 --- /dev/null +++ b/examples/osgframerenderer/gscframerenderer.cpp @@ -0,0 +1,382 @@ +#include +#include +#include +#include +#include + +#include "UpdateProperty.h" +#include "CameraPathProperty.h" +#include "EventProperty.h" + +#include "CaptureSettings.h" + +#include + + +struct ScreenShot : public osg::Camera::DrawCallback +{ + ScreenShot() {} + + virtual void operator () (osg::RenderInfo& renderInfo) const + { + if (!_frameCapture) + { + OSG_NOTICE<<"No FrameCamera assigned"<getFrameStamp()->getFrameNumber(); + + CameraNumMap::const_iterator itr = _cameraNumMap.find(renderInfo.getCurrentCamera()); + std::string outputFileName = (itr!=_cameraNumMap.end()) ? + _frameCapture->getOutputFileName(itr->second, frameNumber) : + _frameCapture->getOutputFileName(frameNumber); + + OSG_NOTICE<<"outputFileName="<getViewport() : 0; + if (viewport) + { + OSG_NOTICE<<"Doing read of ="<x()<<", "<y()<<", "<width()<<", "<height()<getDrawBuffer()); + osg::ref_ptr image = new osg::Image; + + image->readPixels(viewport->x(),viewport->y(),viewport->width(),viewport->height(), + GL_RGB, GL_UNSIGNED_BYTE, 1); + + osgDB::writeImageFile(*image, outputFileName); + } + + } + + typedef std::map CameraNumMap; + + osg::ref_ptr _frameCapture; + CameraNumMap _cameraNumMap; +}; + +int main( int argc, char **argv ) +{ + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of 3D textures."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + + osgViewer::Viewer viewer; + + typedef std::list< osg::ref_ptr > CaptureSettingsList; + CaptureSettingsList frameCaptureList; + + osg::ref_ptr fc = new gsc::CaptureSettings; + + double duration = 0.0; + double fps = 0.0f; + unsigned int nframes = 0; + + std::string filename; + if (arguments.read("--cs",filename)) + { + osg::ref_ptr object = osgDB::readObjectFile(filename); + gsc::CaptureSettings* input_cs = dynamic_cast(object.get()); + if (input_cs) fc = input_cs; + else OSG_NOTICE<<"Unable to read CaptureSettings from file: "<setInputFileName(filename); + if (arguments.read("-o",filename)) fc->setOutputFileName(filename); + if (arguments.read("-p",filename)) + { + osg::ref_ptr cpp = new gsc::CameraPathProperty; + cpp->setAnimationPathFileName(filename); + + double startTime = 0, endTime = 1.0f; + if (cpp->getTimeRange(startTime, endTime)) + { + OSG_NOTICE<<"Camera path time range "<resetTimeRange(0.0, endTime-startTime); + if (cpp->getTimeRange(startTime, endTime)) + { + OSG_NOTICE<<" new time range "<addUpdateProperty(cpp.get()); + } + + if (arguments.read("--offscreen")) fc->setOffscreen(true); + + unsigned int width = 1024; + if (arguments.read("-w",width)) fc->setWidth(width); + + unsigned int height = 512; + if (arguments.read("-h",height)) fc->setHeight(height); + + unsigned int samples = 0; + if (arguments.read("--samples",samples)) fc->setSamples(samples); + + unsigned int sampleBuffers = 0; + if (arguments.read("--sampleBuffers",sampleBuffers)) fc->setSampleBuffers(sampleBuffers); + + unsigned int ms = 0; + if (arguments.read("--ms",ms)) + { + fc->setSamples(ms); + fc->setSampleBuffers(1); + } + + if (arguments.read("--stereo")) + { + OSG_NOTICE<<"Enabling stereo"<setStereo(true); + } + + if (arguments.read("-f",fps)) fc->setFrameRate(fps); + + if (arguments.read("-n",nframes)) fc->setNumberOfFrames(nframes); + + + std::string key; + double time; + while(arguments.read("--key-down",time, key) && key.size()>=1) + { + OSG_NOTICE<<"keydown "< event = new osgGA::GUIEventAdapter; + event->setTime(time); + event->setEventType(osgGA::GUIEventAdapter::KEYDOWN); + event->setKey(key[0]); + fc->addUpdateProperty(new gsc::EventProperty(event.get())); + } + + while(arguments.read("--key-up",time, key) && key.size()>=1) + { + OSG_NOTICE<<"keyup "< event = new osgGA::GUIEventAdapter; + event->setTime(time); + event->setEventType(osgGA::GUIEventAdapter::KEYUP); + event->setKey(key[0]); + fc->addUpdateProperty(new gsc::EventProperty(event.get())); + } + + double mouse_x, mouse_y; + while(arguments.read("--mouse-move",time, mouse_x, mouse_y)) + { + OSG_NOTICE<<"mouse move "< event = new osgGA::GUIEventAdapter; + event->setTime(time); + event->setEventType(osgGA::GUIEventAdapter::MOVE); + event->setX(mouse_x); + event->setY(mouse_y); + fc->addUpdateProperty(new gsc::EventProperty(event.get())); + } + + while(arguments.read("--mouse-drag",time, mouse_x, mouse_y)) + { + OSG_NOTICE<<"mouse drag "< event = new osgGA::GUIEventAdapter; + event->setTime(time); + event->setEventType(osgGA::GUIEventAdapter::DRAG); + event->setX(mouse_x); + event->setY(mouse_y); + fc->addUpdateProperty(new gsc::EventProperty(event.get())); + } + + + if (duration!=0.0) + { + if (fps!=0.0) nframes = static_cast(ceil(duration*fps)); + else if (nframes!=0) fps = duration/static_cast(nframes); + else + { + fps = 60.0; + nframes = static_cast(ceil(duration/fps)); + } + } + else // duration == 0.0 + { + if (fps==0.0) fps=60.0; + if (nframes==0) nframes=1; + + duration = static_cast(nframes)/fps; + } + + fc->setNumberOfFrames(nframes); + fc->setFrameRate(fps); + + OSG_NOTICE<<"Duration="< ds = new osg::DisplaySettings; + + ds->setStereoMode(osg::DisplaySettings::HORIZONTAL_SPLIT); + ds->setStereo(fc->getStereo()); + + osg::ref_ptr traits = new osg::GraphicsContext::Traits(ds.get()); + + traits->readDISPLAY(); + if (traits->displayNum<0) traits->displayNum = 0; + + traits->x = 0; + traits->y = 0; + traits->width = fc->getWidth(); + traits->height = fc->getHeight(); + traits->samples = fc->getSamples(); + traits->sampleBuffers = fc->getSampleBuffers(); + traits->windowDecoration = !(fc->getOffscreen()); + traits->doubleBuffer = true; + traits->sharedContext = 0; + traits->pbuffer = fc->getOffscreen(); + + osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits.get()); + if (!gc) + { + OSG_NOTICE<<"Failed to created requested graphics context"<setGraphicsContext(gc.get()); + viewer.getCamera()->setDisplaySettings(ds); + + osgViewer::GraphicsWindow* gw = dynamic_cast(gc.get()); + if (gw) + { + OSG_INFO<<"GraphicsWindow has been created successfully."<getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, fc->getWidth(), fc->getHeight()); + } + else + { + OSG_NOTICE<<"PixelBuffer has been created succseffully "<width<<", "<height<getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar); + + double newAspectRatio = double(traits->width) / double(traits->height); + double aspectRatioChange = newAspectRatio / aspectRatio; + if (aspectRatioChange != 1.0) + { + viewer.getCamera()->getProjectionMatrix() *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0); + } + + viewer.getCamera()->setViewport(new osg::Viewport(0, 0, traits->width, traits->height)); + + GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + + viewer.getCamera()->setDrawBuffer(buffer); + viewer.getCamera()->setReadBuffer(buffer); + } + + viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); + viewer.realize(); + + // set up screen shot + osg::ref_ptr screenShot = new ScreenShot; + { + + osgViewer::Viewer::Cameras cameras; + viewer.getCameras(cameras); + if (cameras.size()>1) + { + unsigned int cameraNum = 0; + for(osgViewer::Viewer::Cameras::iterator itr = cameras.begin(); + itr != cameras.end(); + ++itr, ++cameraNum) + { + osg::Camera* camera = *itr; + camera->setFinalDrawCallback(screenShot); + screenShot->_cameraNumMap[camera] = cameraNum; + } + } + else if (cameras.size()==1) + { + osg::Camera* camera = cameras.front(); + camera->setFinalDrawCallback(screenShot); + } + else + { + OSG_NOTICE<<"No usable Cameras created."<get(); + screenShot->_frameCapture = fc; + + osg::ref_ptr model = osgDB::readNodeFile(fc->getInputFileName()); + if (!model) break; + + viewer.setSceneData(model.get()); + + double simulationTime = 0.0; + + for(unsigned int i=0; igetNumberOfFrames(); ++i) + { + OSG_NOTICE<<"fc.getOutputFileName("<getOutputFileName(i)<getProperties(); + for(gsc::CaptureSettings::Properties::iterator plitr = pl.begin(); + plitr != pl.end(); + ++plitr) + { + (*plitr)->update(&viewer); + } + + viewer.eventTraversal(); + viewer.updateTraversal(); + viewer.renderingTraversals(); + + // advance simulationTime and number of frames rendered + simulationTime += 1.0/fc->getFrameRate(); + } + } + + osg::ref_ptr object = new osgGA::StateSetManipulator; + osg::ref_ptr ss = dynamic_cast(object.get()); + + return 0; +} \ No newline at end of file