diff --git a/include/osgPresentation/SlideEventHandler b/include/osgPresentation/SlideEventHandler index f220165a0..bf53e5400 100644 --- a/include/osgPresentation/SlideEventHandler +++ b/include/osgPresentation/SlideEventHandler @@ -142,17 +142,20 @@ struct dereference_less } }; +// forward declare +class SlideEventHandler; + struct ObjectOperator : public osg::Referenced { inline bool operator < (const ObjectOperator& rhs) const { return ptr() < rhs.ptr(); } virtual void* ptr() const = 0; - virtual void enter() = 0; - virtual void maintain() = 0; - virtual void leave() = 0; - virtual void setPause(bool pause) = 0; - virtual void reset() = 0; + virtual void enter(SlideEventHandler*) = 0; + virtual void maintain(SlideEventHandler*) = 0; + virtual void leave(SlideEventHandler*) = 0; + virtual void setPause(SlideEventHandler*, bool pause) = 0; + virtual void reset(SlideEventHandler*) = 0; virtual ~ObjectOperator() {} }; @@ -165,21 +168,21 @@ public: void collect(osg::Node* incommingNode, osg::NodeVisitor::TraversalMode tm = osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN); - void process(); + void process(SlideEventHandler* seh); - void setPause(bool pause); + void setPause(SlideEventHandler* seh, bool pause); bool getPause() const { return _pause; } - void reset(); + void reset(SlideEventHandler* seh); typedef std::set< osg::ref_ptr, dereference_less > OperatorList; protected: - void processOutgoing(); - void processIncomming(); - void processMaintained(); - + void processOutgoing(SlideEventHandler* seh); + void processIncomming(SlideEventHandler* seh); + void processMaintained(SlideEventHandler* seh); + bool _pause; OperatorList _previous; @@ -266,6 +269,8 @@ public: void setRequestReload(bool flag); bool getRequestReload() const { return _requestReload; } + void setNormalizedMousePosition(const osg::Vec2& pos) { _normalizedMousePosition = pos; } + const osg::Vec2& getNormalizedMousePosition() const { return _normalizedMousePosition; } protected: @@ -277,6 +282,8 @@ protected: void updateAlpha(bool, bool, float x, float y); void updateLight(float x, float y); + void updateOperators(); + osg::observer_ptr _viewer; @@ -320,8 +327,7 @@ protected: bool _requestReload; - void updateOperators(); - + osg::Vec2 _normalizedMousePosition; }; } diff --git a/include/osgPresentation/SlideShowConstructor b/include/osgPresentation/SlideShowConstructor index 506524afe..6e27443c4 100644 --- a/include/osgPresentation/SlideShowConstructor +++ b/include/osgPresentation/SlideShowConstructor @@ -242,7 +242,9 @@ public: backgroundColor(1.0f,1.0f,1.0f,1.0f), fps(30.0), duration(-1.0), - imageSequencePagingMode(osg::ImageSequence::PAGE_AND_DISCARD_USED_IMAGES) + imageSequence(false), + imageSequencePagingMode(osg::ImageSequence::PAGE_AND_DISCARD_USED_IMAGES), + imageSequenceInteractionMode(PLAY_AUTOMATICALLY_LIKE_MOVIE) {} std::string options; @@ -256,7 +258,17 @@ public: osg::Vec4 backgroundColor; double fps; double duration; + + bool imageSequence; osg::ImageSequence::Mode imageSequencePagingMode; + + enum ImageSequenceInteractionMode + { + PLAY_AUTOMATICALLY_LIKE_MOVIE, + USE_MOUSE_X_POSITION + }; + ImageSequenceInteractionMode imageSequenceInteractionMode; + }; struct VolumeData diff --git a/src/osg/ImageSequence.cpp b/src/osg/ImageSequence.cpp index 7506a11ef..c981ca2ba 100644 --- a/src/osg/ImageSequence.cpp +++ b/src/osg/ImageSequence.cpp @@ -306,7 +306,7 @@ void ImageSequence::update(osg::NodeVisitor* nv) } else { - OSG_NOTICE<<"ImageSequence::update(..) Same index."<children.begin(); itr != cur->children.end(); ++itr) @@ -1110,12 +1123,25 @@ void ReaderWriterP3DXML::parseStereoPair(osgPresentation::SlideShowConstructor& getProperties(child,imageDataLeft); filenameLeft = child->getTrimmedContents(); } - if (child->name == "image_right") + else if (child->name == "imagesequence_left") + { + imageDataLeft.imageSequence = true; + getProperties(child,imageDataLeft); + filenameLeft = child->getTrimmedContents(); + } + else if (child->name == "image_right") { getProperties(child,imageDataRight); filenameRight = child->getTrimmedContents(); + getProperties(cur,imageDataRight); } + else if (child->name == "imagesequence_right") + { + imageDataRight.imageSequence = true; + getProperties(child,imageDataRight); + filenameRight = child->getTrimmedContents(); + } } OSG_INFO<<" filenameLeft="<name == "imagesequence") + { + osgPresentation::SlideShowConstructor::PositionData positionData = constructor.getImagePositionData(); + bool positionRead = getProperties(cur,positionData); + + osgPresentation::SlideShowConstructor::ImageData imageData;// = constructor.getImageData(); + imageData.imageSequence = true; + getProperties(cur,imageData); + + constructor.addImage(cur->getTrimmedContents(), + positionRead ? positionData : constructor.getImagePositionData(), + imageData); + } else if (cur->name == "graph") { osgPresentation::SlideShowConstructor::PositionData positionData = constructor.getImagePositionData(); diff --git a/src/osgPresentation/SlideEventHandler.cpp b/src/osgPresentation/SlideEventHandler.cpp index 1b1b17d35..aca323866 100644 --- a/src/osgPresentation/SlideEventHandler.cpp +++ b/src/osgPresentation/SlideEventHandler.cpp @@ -58,6 +58,47 @@ void LayerAttributes::callLeaveCallbacks(osg::Node* node) } +struct InteractiveImageSequenceOperator : public ObjectOperator +{ + InteractiveImageSequenceOperator(osg::ImageSequence* imageSequence): + _imageSequence(imageSequence) {} + + virtual void* ptr() const { return _imageSequence.get(); } + + virtual void enter(SlideEventHandler* seh) + { + set(seh); + // need to pause till the load has been completed. + } + + virtual void maintain(SlideEventHandler* seh) + { + } + + virtual void leave(SlideEventHandler* seh) + { + } + + virtual void setPause(SlideEventHandler* seh, bool pause) + { + } + + virtual void reset(SlideEventHandler* seh) + { + set(seh); + } + + void set(SlideEventHandler* seh) + { + OSG_NOTICE<<"Mouse x position is : "<getNormalizedMousePosition().x()<(seh->getNormalizedMousePosition().x())+1.0)*0.5*_imageSequence->getLength(); + + _imageSequence->seek(position); + } + + osg::ref_ptr _imageSequence; +}; + struct ImageStreamOperator : public ObjectOperator { ImageStreamOperator(osg::ImageStream* imageStream): @@ -65,25 +106,25 @@ struct ImageStreamOperator : public ObjectOperator virtual void* ptr() const { return _imageStream.get(); } - virtual void enter() + virtual void enter(SlideEventHandler* seh) { OSG_INFO<<"enter() : _imageStream->rewind() + play"<pause()"<pause(); } - virtual void setPause(bool pause) + virtual void setPause(SlideEventHandler*, bool pause) { OSG_INFO<<"_imageStream->setPause("<play(); } - virtual void reset() + virtual void reset(SlideEventHandler*) { osg::ImageStream::StreamStatus previousStatus = _imageStream->getStatus(); @@ -121,20 +162,20 @@ struct CallbackOperator : public ObjectOperator virtual void* ptr() const { return _callback.get(); } - virtual void enter() + virtual void enter(SlideEventHandler* seh) { - reset(); + reset(seh); } - virtual void maintain() + virtual void maintain(SlideEventHandler*) { } - virtual void leave() + virtual void leave(SlideEventHandler*) { } - virtual void setPause(bool pause) + virtual void setPause(SlideEventHandler*, bool pause) { osg::AnimationPathCallback* apc = dynamic_cast(_callback.get()); osgUtil::TransformCallback* tc = dynamic_cast(_callback.get()); @@ -156,7 +197,7 @@ struct CallbackOperator : public ObjectOperator } } - virtual void reset() + virtual void reset(SlideEventHandler*) { osg::AnimationPathCallback* apc = dynamic_cast(_callback.get()); osgUtil::TransformCallback* tc = dynamic_cast(_callback.get()); @@ -191,7 +232,7 @@ struct LayerAttributesOperator : public ObjectOperator virtual void* ptr() const { return _layerAttribute.get(); } - virtual void enter() + virtual void enter(SlideEventHandler*) { _layerAttribute->callEnterCallbacks(_node.get()); @@ -235,22 +276,22 @@ struct LayerAttributesOperator : public ObjectOperator } - virtual void maintain() + virtual void maintain(SlideEventHandler*) { } - virtual void leave() + virtual void leave(SlideEventHandler*) { OSG_INFO<<"LayerAttribute leave"<callLeaveCallbacks(_node.get()); } - virtual void setPause(bool pause) + virtual void setPause(SlideEventHandler*, bool pause) { } - virtual void reset() + virtual void reset(SlideEventHandler*) { } @@ -279,7 +320,15 @@ public: LayerAttributes* la = dynamic_cast(node.getUserData()); if (la) { - _operatorList.insert(new LayerAttributesOperator(&node, la)); + if ((_objectsHandled[la]++)==0) + { + OSG_NOTICE<<"LayerAttributeOperator for "<(ss->getTextureAttribute(i,osg::StateAttribute::TEXTURE)); osg::Image* image = texture ? texture->getImage(0) : 0; - osg::ImageStream* imageStream = image ? dynamic_cast(image) : 0; - if (imageStream) + osg::ImageSequence* imageSequence = dynamic_cast(image); + osg::ImageStream* imageStream = dynamic_cast(image); + if (imageSequence && imageSequence->getName()=="USE_MOUSE_X_POSITION") { - _operatorList.insert(new ImageStreamOperator(imageStream)); + if ((_objectsHandled[image]++)==0) + { + OSG_INFO<<"ImageSequenceOperator for"< ObjectsHandled; + ObjectsHandled _objectsHandled; + ActiveOperators::OperatorList& _operatorList; }; @@ -357,66 +430,66 @@ void ActiveOperators::collect(osg::Node* incommingNode, osg::NodeVisitor::Traver } } -void ActiveOperators::setPause(bool pause) +void ActiveOperators::setPause(SlideEventHandler* seh, bool pause) { _pause = pause; for(OperatorList::iterator itr = _current.begin(); itr != _current.end(); ++itr) { - (*itr)->setPause(_pause); + (*itr)->setPause(seh, _pause); } } -void ActiveOperators::reset() +void ActiveOperators::reset(SlideEventHandler* seh) { for(OperatorList::iterator itr = _current.begin(); itr != _current.end(); ++itr) { - (*itr)->reset(); + (*itr)->reset(seh); } } -void ActiveOperators::process() +void ActiveOperators::process(SlideEventHandler* seh) { - processOutgoing(); - processMaintained(); - processIncomming(); + processOutgoing(seh); + processMaintained(seh); + processIncomming(seh); } -void ActiveOperators::processOutgoing() +void ActiveOperators::processOutgoing(SlideEventHandler* seh) { OSG_INFO<<" outgoing.size()="<<_outgoing.size()<leave(); + (*itr)->leave(seh); } } -void ActiveOperators::processMaintained() +void ActiveOperators::processMaintained(SlideEventHandler* seh) { OSG_INFO<<" maintained.size()="<<_maintained.size()<maintain(); + (*itr)->maintain(seh); } } -void ActiveOperators::processIncomming() +void ActiveOperators::processIncomming(SlideEventHandler* seh) { OSG_INFO<<" incomming.size()="<<_incomming.size()<enter(); - (*itr)->setPause(_pause); + (*itr)->enter(seh); + (*itr)->setPause(seh, _pause); } } @@ -621,7 +694,8 @@ SlideEventHandler::SlideEventHandler(osgViewer::Viewer* viewer): _timeDelayOnNewSlideWithMovies(0.25f), _minimumTimeBetweenKeyPresses(0.25), _timeLastKeyPresses(-1.0), - _requestReload(false) + _requestReload(false), + _normalizedMousePosition(0.0f,0.0f) { s_seh = this; } @@ -647,7 +721,7 @@ void SlideEventHandler::set(osg::Node* model) ActiveOperators operators; operators.collect(model, osg::NodeVisitor::TRAVERSE_ALL_CHILDREN); - operators.setPause(true); + operators.setPause(this, true); FindNamedSwitchVisitor findPresentation("Presentation"); model->accept(findPresentation); @@ -747,6 +821,7 @@ bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction } //else OSG_NOTICE<<"SlideEventHandler::handle() "<setLength(double(maxNum)*(1.0/imageData.fps)); } + if (imageData.imageSequenceInteractionMode==ImageData::USE_MOUSE_X_POSITION) + { + imageSequence->setName("USE_MOUSE_X_POSITION"); + } + imageSequence->play(); image = imageSequence; @@ -1289,7 +1308,6 @@ void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft, c subgraph = animation_transform; } - // attached any animation osg::AnimationPathCallback* animation = getAnimationPathCallback(positionData); if (animation)