diff --git a/include/osgPresentation/SlideEventHandler b/include/osgPresentation/SlideEventHandler index 802b0dd13..c46bfee5c 100644 --- a/include/osgPresentation/SlideEventHandler +++ b/include/osgPresentation/SlideEventHandler @@ -197,6 +197,7 @@ struct ObjectOperator : public osg::Referenced virtual void* ptr() const = 0; virtual void enter(SlideEventHandler*) = 0; + virtual void frame(SlideEventHandler*) {} ; virtual void maintain(SlideEventHandler*) = 0; virtual void leave(SlideEventHandler*) = 0; virtual void setPause(SlideEventHandler*, bool pause) = 0; @@ -215,6 +216,8 @@ public: void process(SlideEventHandler* seh); + void frame(SlideEventHandler*); + void setPause(SlideEventHandler* seh, bool pause); bool getPause() const { return _pause; } @@ -319,6 +322,8 @@ public: void setRequestReload(bool flag); bool getRequestReload() const { return _requestReload; } + double getReferenceTime() const { return _referenceTime; } + protected: ~SlideEventHandler() {} @@ -344,6 +349,7 @@ protected: int _activeLayer; bool _firstTraversal; + double _referenceTime; double _previousTime; double _timePerSlide; bool _autoSteppingActive; diff --git a/src/osgPresentation/SlideEventHandler.cpp b/src/osgPresentation/SlideEventHandler.cpp index 66a0d3c5b..3912d8cda 100644 --- a/src/osgPresentation/SlideEventHandler.cpp +++ b/src/osgPresentation/SlideEventHandler.cpp @@ -170,10 +170,22 @@ struct InteractiveImageSequenceOperator : public ObjectOperator struct ImageStreamOperator : public ObjectOperator { ImageStreamOperator(osg::ImageStream* imageStream): - _imageStream(imageStream) {} + _imageStream(imageStream), + _delayTime(0.0), + _startTime(0.0), + _stopTime(-1.0), + _timeOfLastReset(0.0), + _started(false), + _stopped(false) + { + _imageStream->getUserValue("delay",_delayTime); + _imageStream->getUserValue("start",_startTime); + _imageStream->getUserValue("stop",_stopTime); + } virtual void* ptr() const { return _imageStream.get(); } + virtual void enter(SlideEventHandler* seh) { OSG_NOTICE<<"enter() : _imageStream->rewind() + play"<getReferenceTime()-_timeOfLastReset; + if (timeSinceLastRest>_delayTime) + { + OSG_NOTICE<<"ImageStreamOperator::frame("<getReferenceTime()<<") calling start"<0.0 && _started && !_stopped) + { + double timeSinceLastReset = seh->getReferenceTime()-_timeOfLastReset; + double timeSinceStart = (timeSinceLastReset-_delayTime); + if ((timeSinceStart+_startTime)>_stopTime) + { + OSG_NOTICE<<"ImageStreamOperator::frame("<getReferenceTime()<<") calling stop"<setPause("<pause(); - else _imageStream->play(); + if (_started) + { + if (pause) _imageStream->pause(); + else _imageStream->play(); + } } - virtual void reset(SlideEventHandler*) + virtual void reset(SlideEventHandler* seh) { OSG_NOTICE<<"ImageStreamOperator::reset()"<getStatus(); + _timeOfLastReset = seh->getReferenceTime(); + _stopped = false; + + if (_delayTime==0.0) + { + start(seh); + } + } - double startTime; - if (_imageStream->getUserValue("start",startTime)) - { - _imageStream->seek(startTime); - } - else - { - _imageStream->rewind(); - } + void start(SlideEventHandler*) + { + if (_started) return; + + _started = true; + _stopped = false; + + if (_startTime!=0.0) _imageStream->seek(_startTime); + else _imageStream->rewind(); //_imageStream->setVolume(previousVolume); - if(previousStatus==osg::ImageStream::PLAYING) - { - _imageStream->play(); - } + _imageStream->play(); // add a delay so that movie thread has a chance to do the rewind float microSecondsToDelay = SlideEventHandler::instance()->getTimeDelayOnNewSlideWithMovies() * 1000000.0f; OpenThreads::Thread::microSleep(static_cast(microSecondsToDelay)); } + void stop(SlideEventHandler* seh) + { + if (!_started) return; + + _started = false; + _stopped = true; + + _imageStream->pause(); + } + osg::ref_ptr _imageStream; + double _delayTime; + double _startTime; + double _stopTime; + double _timeOfLastReset; + bool _started; + bool _stopped; }; struct CallbackOperator : public ObjectOperator @@ -538,6 +596,16 @@ void ActiveOperators::collect(osg::Node* incommingNode, osg::NodeVisitor::Traver } } +void ActiveOperators::frame(SlideEventHandler* seh) +{ + for(OperatorList::iterator itr = _current.begin(); + itr != _current.end(); + ++itr) + { + (*itr)->frame(seh); + } +} + void ActiveOperators::setPause(SlideEventHandler* seh, bool pause) { _pause = pause; @@ -785,7 +853,8 @@ SlideEventHandler::SlideEventHandler(osgViewer::Viewer* viewer): _slideSwitch(0), _activeLayer(0), _firstTraversal(true), - _previousTime(-1.0f), + _referenceTime(-1.0), + _previousTime(-1.0), _timePerSlide(1.0), _autoSteppingActive(false), _loopPresentation(false), @@ -929,6 +998,8 @@ bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction if (ea.getHandled()) return false; + _referenceTime = ea.getTime(); + switch(ea.getEventType()) { case(osgGA::GUIEventAdapter::FRAME): @@ -962,6 +1033,8 @@ bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction } } } + _activeOperators.frame(this); + return false; }