Intial work towards support an interaction <imagesequence> tag in Present3D.

This commit is contained in:
Robert Osfield
2012-10-29 15:58:02 +00:00
parent ce623c697e
commit d879cd7715
6 changed files with 249 additions and 99 deletions

View File

@@ -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<ObjectOperator>, 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<osgViewer::Viewer> _viewer;
@@ -320,8 +327,7 @@ protected:
bool _requestReload;
void updateOperators();
osg::Vec2 _normalizedMousePosition;
};
}

View File

@@ -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

View File

@@ -306,7 +306,7 @@ void ImageSequence::update(osg::NodeVisitor* nv)
}
else
{
OSG_NOTICE<<"ImageSequence::update(..) Same index."<<std::endl;
// OSG_NOTICE<<"ImageSequence::update(..) Same index."<<std::endl;
}
}

View File

@@ -889,6 +889,16 @@ bool ReaderWriterP3DXML::getProperties(osgDB::XmlNode*cur, osgPresentation::Slid
OSG_NOTIFY(_notifyLevel)<<"read imageSequencePagingMode \""<<value.imageSequencePagingMode<<"\""<<std::endl;
}
if (getProperty(cur, "interaction_mode", str))
{
propertiesRead = true;
if (str=="PLAY_AUTOMATICALLY_LIKE_MOVIE") value.imageSequenceInteractionMode = osgPresentation::SlideShowConstructor::ImageData::PLAY_AUTOMATICALLY_LIKE_MOVIE;
else if (str=="USE_MOUSE_X_POSITION") value.imageSequenceInteractionMode = osgPresentation::SlideShowConstructor::ImageData::USE_MOUSE_X_POSITION;
OSG_NOTIFY(_notifyLevel)<<"read imageSequencePagingMode \""<<value.imageSequenceInteractionMode<<"\""<<std::endl;
}
/*
if (getProperty(cur, "texcoord_offset", value.texcoord_offset))
{
@@ -1099,6 +1109,9 @@ void ReaderWriterP3DXML::parseStereoPair(osgPresentation::SlideShowConstructor&
osgPresentation::SlideShowConstructor::ImageData imageDataLeft;// = constructor.getImageData();
osgPresentation::SlideShowConstructor::ImageData imageDataRight;// = constructor.getImageData();
getProperties(cur,imageDataLeft);
getProperties(cur,imageDataRight);
for(osgDB::XmlNode::Children::iterator itr = cur->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="<<filenameLeft<<std::endl;
@@ -1326,6 +1352,19 @@ void ReaderWriterP3DXML::parseLayer(osgPresentation::SlideShowConstructor& const
positionRead ? positionData : constructor.getImagePositionData(),
imageData);
}
else if (cur->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();

View File

@@ -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 : "<<seh->getNormalizedMousePosition().x()<<std::endl;
double position = (static_cast<double>(seh->getNormalizedMousePosition().x())+1.0)*0.5*_imageSequence->getLength();
_imageSequence->seek(position);
}
osg::ref_ptr<osg::ImageSequence> _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"<<std::endl;
reset();
reset(seh);
}
virtual void maintain()
virtual void maintain(SlideEventHandler*)
{
}
virtual void leave()
virtual void leave(SlideEventHandler*)
{
OSG_INFO<<"leave() : _imageStream->pause()"<<std::endl;
_imageStream->pause();
}
virtual void setPause(bool pause)
virtual void setPause(SlideEventHandler*, bool pause)
{
OSG_INFO<<"_imageStream->setPause("<<pause<<")"<<std::endl;
@@ -91,7 +132,7 @@ struct ImageStreamOperator : public ObjectOperator
else _imageStream->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<osg::AnimationPathCallback*>(_callback.get());
osgUtil::TransformCallback* tc = dynamic_cast<osgUtil::TransformCallback*>(_callback.get());
@@ -156,7 +197,7 @@ struct CallbackOperator : public ObjectOperator
}
}
virtual void reset()
virtual void reset(SlideEventHandler*)
{
osg::AnimationPathCallback* apc = dynamic_cast<osg::AnimationPathCallback*>(_callback.get());
osgUtil::TransformCallback* tc = dynamic_cast<osgUtil::TransformCallback*>(_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"<<std::endl;
_layerAttribute->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<LayerAttributes*>(node.getUserData());
if (la)
{
_operatorList.insert(new LayerAttributesOperator(&node, la));
if ((_objectsHandled[la]++)==0)
{
OSG_NOTICE<<"LayerAttributeOperator for "<<la<<" required, assigning one."<<std::endl;
_operatorList.insert(new LayerAttributesOperator(&node, la));
}
else
{
OSG_NOTICE<<"LayerAttributeOperator for "<<la<<" not required, as one already assigned."<<std::endl;
}
}
traverse(node);
@@ -301,14 +350,38 @@ public:
{
osg::Texture* texture = dynamic_cast<osg::Texture*>(ss->getTextureAttribute(i,osg::StateAttribute::TEXTURE));
osg::Image* image = texture ? texture->getImage(0) : 0;
osg::ImageStream* imageStream = image ? dynamic_cast<osg::ImageStream*>(image) : 0;
if (imageStream)
osg::ImageSequence* imageSequence = dynamic_cast<osg::ImageSequence*>(image);
osg::ImageStream* imageStream = dynamic_cast<osg::ImageStream*>(image);
if (imageSequence && imageSequence->getName()=="USE_MOUSE_X_POSITION")
{
_operatorList.insert(new ImageStreamOperator(imageStream));
if ((_objectsHandled[image]++)==0)
{
OSG_INFO<<"ImageSequenceOperator for"<<imageSequence<<" required, assigning one, name = '"<<image->getName()<<"'"<<std::endl;
_operatorList.insert(new InteractiveImageSequenceOperator(imageSequence));
}
else
{
OSG_INFO<<"ImageSequenceOperator for"<<imageSequence<<" not required, as one already assigned"<<std::endl;
}
}
else if (imageStream)
{
if ((_objectsHandled[image]++)==0)
{
OSG_INFO<<"ImageStreamOperator for"<<imageStream<<" required, assigning one"<<std::endl;
_operatorList.insert(new ImageStreamOperator(imageStream));
}
else
{
OSG_INFO<<"ImageStreamOperator for"<<imageStream<<" not required, as one already assigned"<<std::endl;
}
}
}
}
typedef std::map<osg::Referenced*,unsigned int> 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()<<std::endl;
for(OperatorList::iterator itr = _outgoing.begin();
itr != _outgoing.end();
++itr)
{
(*itr)->leave();
(*itr)->leave(seh);
}
}
void ActiveOperators::processMaintained()
void ActiveOperators::processMaintained(SlideEventHandler* seh)
{
OSG_INFO<<" maintained.size()="<<_maintained.size()<<std::endl;
for(OperatorList::iterator itr = _maintained.begin();
itr != _maintained.end();
++itr)
{
(*itr)->maintain();
(*itr)->maintain(seh);
}
}
void ActiveOperators::processIncomming()
void ActiveOperators::processIncomming(SlideEventHandler* seh)
{
OSG_INFO<<" incomming.size()="<<_incomming.size()<<std::endl;
for(OperatorList::iterator itr = _incomming.begin();
itr != _incomming.end();
++itr)
{
(*itr)->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() "<<ea.getTime()<<std::endl;
_normalizedMousePosition.set(ea.getXnormalized(), ea.getYnormalized());
if (ea.getHandled()) return false;
@@ -890,7 +965,7 @@ bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction
#if 0
resetUpdateCallbackActivity(ALL_OBJECTS);
#endif
_activeOperators.setPause(_pause);
_activeOperators.setPause(this, _pause);
}
return true;
@@ -904,7 +979,7 @@ bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction
#if 0
resetUpdateCallbackActivity(ALL_OBJECTS);
#endif
_activeOperators.setPause(_pause);
_activeOperators.setPause(this, _pause);
}
return true;
@@ -919,7 +994,7 @@ bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction
#if 0
resetUpdateCallbacks(ALL_OBJECTS);
#endif
_activeOperators.reset();
_activeOperators.reset(this);
return true;
}
/*
@@ -1221,7 +1296,7 @@ bool SlideEventHandler::previousLayer()
void SlideEventHandler::updateOperators()
{
_activeOperators.collect(_slideSwitch.get());
_activeOperators.process();
_activeOperators.process(this);
if (_viewer.valid())
{

View File

@@ -879,11 +879,58 @@ osg::Image* SlideShowConstructor::readImage(const std::string& filename, const I
std::string foundFile = filename;
// check for wild cards
if (filename.find('*')!=std::string::npos)
if (imageData.imageSequence)
{
OSG_INFO<<"Expanding wildcard "<<std::endl;
filenames = osgDB::expandWildcardsInFilename(filename);
// check for wild cards
if (filename.find('*')!=std::string::npos)
{
OSG_INFO<<"Expanding wildcard "<<std::endl;
filenames = osgDB::expandWildcardsInFilename(filename);
}
else
{
std::string foundFile = filename;
osgDB::FileType fileType = osgDB::fileType(foundFile);
if (fileType == osgDB::FILE_NOT_FOUND)
{
foundFile = findFileAndRecordPath(foundFile);
fileType = osgDB::fileType(foundFile);
}
if (fileType == osgDB::DIRECTORY)
{
OSG_INFO<<"Reading directory "<<foundFile<<std::endl;
filenames = osgDB::getDirectoryContents(foundFile);
// need to insert the directory path in front of the filenames so it's relative to the appropriate directory.
for(osgDB::DirectoryContents::iterator itr = filenames.begin();
itr != filenames.end();
++itr)
{
*itr = foundFile + osgDB::getNativePathSeparator() + *itr;
}
// prune any directory entries from the list.
for(osgDB::DirectoryContents::iterator itr = filenames.begin();
itr != filenames.end();
)
{
if (osgDB::fileType(*itr)!=osgDB::REGULAR_FILE)
{
itr = filenames.erase(itr);
}
else
{
++itr;
}
}
}
else
{
filenames.push_back(foundFile);
}
}
}
else
{
@@ -894,42 +941,9 @@ osg::Image* SlideShowConstructor::readImage(const std::string& filename, const I
foundFile = findFileAndRecordPath(foundFile);
fileType = osgDB::fileType(foundFile);
}
if (fileType == osgDB::DIRECTORY)
{
OSG_INFO<<"Reading directory "<<foundFile<<std::endl;
filenames = osgDB::getDirectoryContents(foundFile);
// need to insert the directory path in front of the filenames so it's relative to the appropriate directory.
for(osgDB::DirectoryContents::iterator itr = filenames.begin();
itr != filenames.end();
++itr)
{
*itr = foundFile + osgDB::getNativePathSeparator() + *itr;
}
// prune any directory entries from the list.
for(osgDB::DirectoryContents::iterator itr = filenames.begin();
itr != filenames.end();
)
{
if (osgDB::fileType(*itr)!=osgDB::REGULAR_FILE)
{
itr = filenames.erase(itr);
}
else
{
++itr;
}
}
}
else
{
filenames.push_back(foundFile);
}
filenames.push_back(foundFile);
}
if (filenames.empty()) return 0;
if (filenames.size()==1)
@@ -990,6 +1004,11 @@ osg::Image* SlideShowConstructor::readImage(const std::string& filename, const I
imageSequence->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)