From 68c7a47388ff91b553a2419278e86458f4e6c538 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 5 Oct 2004 09:53:36 +0000 Subject: [PATCH] Added support to osgProducer::Viewer for forcing an early exit form applications and recording an image on exit. --- include/osgProducer/Viewer | 56 +++++++++++++++++ include/osgProducer/ViewerEventHandler | 16 +++-- src/osgProducer/Viewer.cpp | 87 +++++++++++++++++++++++++- src/osgProducer/ViewerEventHandler.cpp | 69 +++++++++++++------- 4 files changed, 200 insertions(+), 28 deletions(-) diff --git a/include/osgProducer/Viewer b/include/osgProducer/Viewer index a945bf4f0..b46057703 100644 --- a/include/osgProducer/Viewer +++ b/include/osgProducer/Viewer @@ -75,13 +75,61 @@ class OSGPRODUCER_EXPORT Viewer : public OsgCameraGroup, public osgGA::GUIAction void setUpViewer(unsigned int options=STANDARD_SETTINGS); + /** Set the viewer so it sets done to true once the refrence time equals or exceeds specified elapsed time. + * Automatically does a setDoneAtElapsedTimeEnabled(true). */ + void setDoneAtElapsedTime(double elapsedTime) { _setDoneAtElapsedTimeEnabled = true; _setDoneAtElapsedTime = elapsedTime; } + + /** Get the elapsed time that will cause done to be set to be true.*/ + double getDoneAtElapsedTime() const { return _setDoneAtElapsedTime; } + + /** Set whether to use a elapsed time to limit the run of the viewer.*/ + void setDoneAtElapsedTimeEnabled(bool enabled) { _setDoneAtElapsedTimeEnabled = enabled; } + + /** Get whether to use a elapsed time to limit the run of the viewer.*/ + bool getDoneAtElapsedTimeEnabled() const { return _setDoneAtElapsedTimeEnabled; } + + + + /** Set the viewer so it sets done to true once the frame number equals or exceeds specified frame number. + * Automatically does a setDoneAtFrameNumberEnabled(true). */ + void setDoneAtFrameNumber(unsigned int frameNumber) { _setDoneAtFrameNumberEnabled = true; _setDoneAtFrameNumber = frameNumber; } + + /** Get the frame number that will cause done to be set to be true.*/ + unsigned int getDoneAtFrameNumber() const { return _setDoneAtFrameNumber; } + + /** Set whether to use a frame number to limit the run of the viewer.*/ + void setDoneAtFrameNumberEnabled(bool enabled) { _setDoneAtFrameNumberEnabled = enabled; } + + /** Get whether to use a frame number to limit the run of the viewer.*/ + bool getDoneAtFrameNumberEnabled() const { return _setDoneAtFrameNumberEnabled; } + + + + /** Set the done flag signalling that the viewer exit.*/ void setDone(bool done) { _done = done; } + /** Get the done flag which signals that the viewer exit.*/ bool getDone() const { return _done; } /** return true if the application is done and should exit.*/ virtual bool done() const; + + /** Set the viewer to take an image snapshot on the last frame() when done is enabled.*/ + void setWriteImageWhenDone(bool enabled) { _writeImageWhenDone = enabled; } + + /** Set the viewer to take an image snapshot on the last frame() when done is enabled.*/ + bool getWriteImageWhenDone() const { return _writeImageWhenDone; } + + + /** Set the filename to write to when the viewer takes an image snapshot on the last frame() when done is enabled.*/ + void setWriteImageFileName(const std::string& filename); + + /** Set the filename to write to when the viewer takes an image snapshot on the last frame() when done is enabled.*/ + const std::string& getWriteImageFileName() const; + + + /** Override the Producer::CameraGroup::setViewByMatrix to catch all changes to view.*/ virtual void setViewByMatrix( const Producer::Matrix & pm); @@ -180,8 +228,16 @@ class OSGPRODUCER_EXPORT Viewer : public OsgCameraGroup, public osgGA::GUIAction protected : + bool _setDoneAtElapsedTimeEnabled; + double _setDoneAtElapsedTime; + + bool _setDoneAtFrameNumberEnabled; + unsigned int _setDoneAtFrameNumber; + bool _done; + bool _writeImageWhenDone; + std::string _writeImageFileName; osg::ref_ptr _kbm; diff --git a/include/osgProducer/ViewerEventHandler b/include/osgProducer/ViewerEventHandler index 7abef6e66..29dc181cf 100644 --- a/include/osgProducer/ViewerEventHandler +++ b/include/osgProducer/ViewerEventHandler @@ -55,23 +55,29 @@ class OSGPRODUCER_EXPORT ViewerEventHandler : public osgGA::GUIEventHandler void setFrameStatsMode(FrameStatsMode mode) { _frameStatsMode = mode; } FrameStatsMode getFrameStatsMode() { return _frameStatsMode; } + void setWriteImageOnNextFrame(bool writeImageOnNextFrame); + + void setWriteImageFileName(const std::string& filename); + const std::string& getWriteImageFileName() const { return _writeImageFileName; } + protected: osgProducer::OsgCameraGroup* _cg; - std::string _writeNodeFileName; + std::string _writeNodeFileName; - bool _displayHelp; - FrameStatsMode _frameStatsMode; + bool _displayHelp; + FrameStatsMode _frameStatsMode; - bool _firstTimeTogglingFullScreen; + bool _firstTimeTogglingFullScreen; class StatsAndHelpDrawCallback; StatsAndHelpDrawCallback* _statsAndHelpDrawCallback; class SnapImageDrawCallback; typedef std::vector SnapImageDrawCallbackList; - SnapImageDrawCallbackList _snapImageDrawCallbackList; + SnapImageDrawCallbackList _snapImageDrawCallbackList; + std::string _writeImageFileName; }; diff --git a/src/osgProducer/Viewer.cpp b/src/osgProducer/Viewer.cpp index 0c0d5b275..ba6a3fc41 100644 --- a/src/osgProducer/Viewer.cpp +++ b/src/osgProducer/Viewer.cpp @@ -225,7 +225,13 @@ protected: // osgProducer::Viewer implemention // Viewer::Viewer(): + _setDoneAtElapsedTimeEnabled(false), + _setDoneAtElapsedTime(0.0), + _setDoneAtFrameNumberEnabled(false), + _setDoneAtFrameNumber(0), _done(false), + _writeImageWhenDone(false), + _writeImageFileName("saved_image.jpg"), _recordingAnimationPath(false), _recordingStartTime(0.0) { @@ -237,7 +243,13 @@ Viewer::Viewer(): Viewer::Viewer(Producer::CameraConfig *cfg): OsgCameraGroup(cfg), + _setDoneAtElapsedTimeEnabled(false), + _setDoneAtElapsedTime(0.0), + _setDoneAtFrameNumberEnabled(false), + _setDoneAtFrameNumber(0), _done(false), + _writeImageWhenDone(false), + _writeImageFileName("saved_image.jpg"), _recordingAnimationPath(false), _recordingStartTime(0.0) { @@ -250,7 +262,13 @@ Viewer::Viewer(Producer::CameraConfig *cfg): Viewer::Viewer(const std::string& configFile): OsgCameraGroup(configFile), + _setDoneAtElapsedTimeEnabled(false), + _setDoneAtElapsedTime(0.0), + _setDoneAtFrameNumberEnabled(false), + _setDoneAtFrameNumber(0), _done(false), + _writeImageWhenDone(false), + _writeImageFileName("saved_image.jpg"), _recordingAnimationPath(false), _recordingStartTime(0.0) { @@ -262,7 +280,13 @@ Viewer::Viewer(const std::string& configFile): Viewer::Viewer(osg::ArgumentParser& arguments): OsgCameraGroup(arguments), + _setDoneAtElapsedTimeEnabled(false), + _setDoneAtElapsedTime(0.0), + _setDoneAtFrameNumberEnabled(false), + _setDoneAtFrameNumber(0), _done(false), + _writeImageWhenDone(false), + _writeImageFileName("saved_image.jpg"), _recordingAnimationPath(false), _recordingStartTime(0.0) { @@ -275,6 +299,8 @@ Viewer::Viewer(osg::ArgumentParser& arguments): if (arguments.getApplicationUsage()) { arguments.getApplicationUsage()->addCommandLineOption("-p ","Specify camera path file to animate the camera through the loaded scene"); + arguments.getApplicationUsage()->addCommandLineOption("--run-till-frame-number ","Specify the number of frame to run"); + arguments.getApplicationUsage()->addCommandLineOption("--run-till-elapsed-time","Specify the about of time to run"); } osg::DisplaySettings::instance()->readCommandLine(arguments); @@ -290,12 +316,52 @@ Viewer::Viewer(osg::ArgumentParser& arguments): selectCameraManipulator(num); } } + + unsigned int frameNumber; + while (arguments.read("--run-till-frame-number",frameNumber)) + { + setDoneAtFrameNumber(frameNumber); + } + + double elapsedTime; + while (arguments.read("--run-till-elapsed-time",elapsedTime)) + { + setDoneAtElapsedTime(elapsedTime); + } + + std::string filename; + while (arguments.read("--write-image-when-done",filename)) + { + setWriteImageWhenDone(true); + setWriteImageFileName(filename); + } } Viewer::~Viewer() { } +void Viewer::setWriteImageFileName(const std::string& filename) +{ + _writeImageFileName = filename; + for(EventHandlerList::iterator itr = getEventHandlerList().begin(); + itr != getEventHandlerList().end(); + ++itr) + { + ViewerEventHandler* viewerEventHandler = dynamic_cast(itr->get()); + if (viewerEventHandler) + { + viewerEventHandler->setWriteImageFileName(filename); + } + } +} + +const std::string& Viewer::getWriteImageFileName() const +{ + return _writeImageFileName; +} + + void Viewer::setCoordindateSystemNodePath(const osg::NodePath& nodePath) { _coordinateSystemNodePath.clear(); @@ -454,7 +520,10 @@ unsigned int Viewer::addCameraManipulator(osgGA::MatrixManipulator* cm) bool Viewer::done() const { - return _done || !validForRendering(); + return _done || + !validForRendering() || + (_setDoneAtElapsedTimeEnabled && _setDoneAtElapsedTime<=getFrameStamp()->getReferenceTime()) || + (_setDoneAtFrameNumberEnabled && _setDoneAtFrameNumber<=_frameNumber); } void Viewer::setViewByMatrix( const Producer::Matrix & pm) @@ -641,6 +710,22 @@ void Viewer::frame() getAnimationPath()->insert(_frameStamp->getReferenceTime()-_recordingStartTime,osg::AnimationPath::ControlPoint(osg::Vec3(_position[0],_position[1],_position[2]),_orientation)); } + + if (done() && getWriteImageWhenDone()) + { + for(EventHandlerList::iterator itr = getEventHandlerList().begin(); + itr != getEventHandlerList().end(); + ++itr) + { + ViewerEventHandler* viewerEventHandler = dynamic_cast(itr->get()); + if (viewerEventHandler) + { + osg::notify(osg::NOTICE)<<"Need to write image"<setWriteImageOnNextFrame(true); + } + } + + } OsgCameraGroup::frame(); diff --git a/src/osgProducer/ViewerEventHandler.cpp b/src/osgProducer/ViewerEventHandler.cpp index 00cdf91d8..f2fe9afd4 100644 --- a/src/osgProducer/ViewerEventHandler.cpp +++ b/src/osgProducer/ViewerEventHandler.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -14,12 +15,14 @@ class ViewerEventHandler::SnapImageDrawCallback : public Producer::Camera::Callb { public: - SnapImageDrawCallback(const std::string& filename): - _filename(filename), + SnapImageDrawCallback(): _snapImageOnNextFrame(false) { } + void setFileName(const std::string& filename) { _filename = filename; } + const std::string& getFileName() const { return _filename; } + void setSnapImageOnNextFrame(bool flag) { _snapImageOnNextFrame = flag; } bool getSnapImageOnNextFrame() const { return _snapImageOnNextFrame; } @@ -716,28 +719,56 @@ ViewerEventHandler::ViewerEventHandler(OsgCameraGroup* cg): _statsAndHelpDrawCallback = new StatsAndHelpDrawCallback(this,0); cam->addPostDrawCallback(_statsAndHelpDrawCallback); - std::string basename("saved_image"); - std::string ext(".jpg"); - if (cfg->getNumberOfCameras()==1) + for(unsigned int i=0;igetNumberOfCameras();++i) { - SnapImageDrawCallback* snapImageDrawCallback = new SnapImageDrawCallback(basename+ext); - cam->addPostDrawCallback(snapImageDrawCallback); + SnapImageDrawCallback* snapImageDrawCallback = new SnapImageDrawCallback(); + cfg->getCamera(i)->addPostDrawCallback(snapImageDrawCallback); _snapImageDrawCallbackList.push_back(snapImageDrawCallback); } - else + + + Viewer* viewer = dynamic_cast(cg); + if (viewer) setWriteImageFileName(viewer->getWriteImageFileName()); + else setWriteImageFileName("saved_image.jpg"); + +} + +void ViewerEventHandler::setWriteImageOnNextFrame(bool writeImageOnNextFrame) +{ + for(SnapImageDrawCallbackList::iterator itr=_snapImageDrawCallbackList.begin(); + itr!=_snapImageDrawCallbackList.end(); + ++itr) { - for(unsigned int i=0;igetNumberOfCameras();++i) + (*itr)->setSnapImageOnNextFrame(writeImageOnNextFrame); + } +} + +void ViewerEventHandler::setWriteImageFileName(const std::string& filename) +{ + std::string basename = osgDB::getNameLessExtension(filename); + std::string ext = osgDB::getFileExtension(filename); + + unsigned int cameraNum = 0; + for(SnapImageDrawCallbackList::iterator itr=_snapImageDrawCallbackList.begin(); + itr!=_snapImageDrawCallbackList.end(); + ++itr, ++cameraNum) + { + if (cameraNum==0) { - std::string filename(basename+"_"); - filename += ('0'+i); - filename += ext; - SnapImageDrawCallback* snapImageDrawCallback = new SnapImageDrawCallback(filename); - cfg->getCamera(i)->addPostDrawCallback(snapImageDrawCallback); - _snapImageDrawCallbackList.push_back(snapImageDrawCallback); + (*itr)->setFileName(filename); + } + else + { + std::string name(basename+"_"); + name += ('0'+cameraNum); + name += '.'; + name += ext; + (*itr)->setFileName(name); } } } + bool ViewerEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa) { if(!_cg) return false; @@ -832,13 +863,7 @@ bool ViewerEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActio case osgGA::GUIEventAdapter::KEY_Print : case 'O' : { - for(SnapImageDrawCallbackList::iterator itr=_snapImageDrawCallbackList.begin(); - itr!=_snapImageDrawCallbackList.end(); - ++itr) - { - (*itr)->setSnapImageOnNextFrame(true); - } - + setWriteImageOnNextFrame(true); return true; } case '+' :