Implemented basic Timeout display and timing codes

This commit is contained in:
Robert Osfield 2013-01-16 16:13:30 +00:00
parent 81008c24df
commit b8b8365c06
5 changed files with 248 additions and 63 deletions

View File

@ -34,28 +34,11 @@
#include <osgPresentation/AnimationMaterial>
#include <osgPresentation/SlideEventHandler>
#include <osgPresentation/PropertyManager>
#include <osgPresentation/Timeout>
namespace osgPresentation
{
class OSGPRESENTATION_EXPORT HUDSettings : public osg::Referenced
{
public:
HUDSettings(double slideDistance, float eyeOffset, unsigned int leftMask, unsigned int rightMask);
virtual bool getModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const;
virtual bool getInverseModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const;
double _slideDistance;
double _eyeOffset;
unsigned int _leftMask;
unsigned int _rightMask;
protected:
virtual ~HUDSettings();
};
class OSGPRESENTATION_EXPORT HUDTransform : public osg::Transform
@ -398,6 +381,7 @@ public:
void setSlideDuration(double duration);
void addTimeout();
void addLayer(bool inheritPreviousLayers=true, bool defineAsBaseLayer=false);
@ -483,6 +467,9 @@ public:
osg::Switch* getCurrentSlide() { return _slide.get(); }
void pushCurrentLayer();
void popCurrentLayer();
osg::Group* getCurrentLayer() { return _currentLayer.get(); }
void setLoopPresentation(bool loop) { _loopPresentation = loop; }
@ -580,6 +567,8 @@ protected:
osg::ref_ptr<osg::Group> _previousLayer;
osg::ref_ptr<osg::Group> _currentLayer;
typedef std::vector< osg::ref_ptr<osg::Group> > LayerStack;
LayerStack _layerStack;
osg::ref_ptr<FilePathData> _filePathData;

View File

@ -14,28 +14,63 @@
#ifndef OSGPRESENTATION_TIMOUTOUT
#define OSGPRESENTATION_TIMOUTOUT 1
#include <osg/Group>
#include <osg/Transform>
#include <osgPresentation/Export>
namespace osgPresentation {
class OSGPRESENTATION_EXPORT Timeout : public osg::Group
class OSGPRESENTATION_EXPORT HUDSettings : public osg::Referenced
{
public:
HUDSettings(double slideDistance, float eyeOffset, unsigned int leftMask, unsigned int rightMask);
virtual bool getModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const;
virtual bool getInverseModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const;
double _slideDistance;
double _eyeOffset;
unsigned int _leftMask;
unsigned int _rightMask;
protected:
virtual ~HUDSettings();
};
class OSGPRESENTATION_EXPORT Timeout : public osg::Transform
{
public:
Timeout();
Timeout(HUDSettings* hudSettings=0);
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
Timeout(const Timeout&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
Timeout(const Timeout& timeout,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
META_Node(osgPresentation, Timeout);
void setIdleDurationBeforeTimeoutDisplay(double t) { _idleDurationBeforeTimeoutDisplay = t; }
double getIdleDurationBeforeTimeoutDisplay() const { return _idleDurationBeforeTimeoutDisplay; }
void setIdleDurationBeforeTimeoutAction(double t) { _idleDurationBeforeTimeoutAction = t; }
double getIdleDurationBeforeTimeoutAction() const { return _idleDurationBeforeTimeoutAction; }
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const;
virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor*) const;
virtual void traverse(osg::NodeVisitor& nv);
protected:
virtual ~Timeout();
osg::ref_ptr<HUDSettings> _hudSettings;
int _previousFrameNumber;
double _timeOfLastEvent;
double _idleDurationBeforeTimeoutDisplay;
double _idleDurationBeforeTimeoutAction;
};
}

View File

@ -132,6 +132,8 @@ public:
void parseStereoPair(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode*cur) const;
void parseTimeout(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode*cur) const;
void parseLayer(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode*cur) const;
void parseBullets(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode*cur, bool inheritPreviousLayers, bool defineAsBaseLayer) const;
@ -1441,6 +1443,17 @@ bool ReaderWriterP3DXML::getKeyPositionInner(osgDB::XmlNode*cur, osgPresentation
}
void ReaderWriterP3DXML::parseTimeout(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode*cur) const
{
// to allow the timeout to be nested with a Layer but still behave like a Layer itself we push the timeout as a Layer, saving the original Layer
constructor.pushCurrentLayer();
constructor.addTimeout();
parseLayer(constructor, cur);
constructor.popCurrentLayer(); // return the
}
void ReaderWriterP3DXML::parseLayer(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode* root) const
@ -1711,6 +1724,10 @@ void ReaderWriterP3DXML::parseLayer(osgPresentation::SlideShowConstructor& const
{
parseVolume(constructor, cur);
}
else if (cur->name == "timeout")
{
parseTimeout(constructor, cur);
}
else if (cur->name == "duration")
{
constructor.setLayerDuration(osg::asciiToDouble(cur->contents.c_str()));

View File

@ -99,42 +99,6 @@ public:
};
HUDSettings::HUDSettings(double slideDistance, float eyeOffset, unsigned int leftMask, unsigned int rightMask):
_slideDistance(slideDistance),
_eyeOffset(eyeOffset),
_leftMask(leftMask),
_rightMask(rightMask)
{
}
HUDSettings::~HUDSettings()
{
}
bool HUDSettings::getModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
{
matrix.makeLookAt(osg::Vec3d(0.0,0.0,0.0),osg::Vec3d(0.0,_slideDistance,0.0),osg::Vec3d(0.0,0.0,1.0));
if (nv->getTraversalMask()==_leftMask)
{
matrix.postMultTranslate(osg::Vec3(_eyeOffset,0.0,0.0));
}
else if (nv->getTraversalMask()==_rightMask)
{
matrix.postMultTranslate(osg::Vec3(-_eyeOffset,0.0,0.0));
}
return true;
}
bool HUDSettings::getInverseModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
{
osg::Matrix modelView;
getModelViewMatrix(modelView,nv);
matrix.invert(modelView);
return true;
}
HUDTransform::HUDTransform(HUDSettings* hudSettings):
_hudSettings(hudSettings)
{
@ -392,6 +356,28 @@ void SlideShowConstructor::setSlideDuration(double duration)
}
}
void SlideShowConstructor::addTimeout()
{
osg::ref_ptr<osgPresentation::Timeout> timeout = new osgPresentation::Timeout(_hudSettings.get());
if (_currentLayer.valid()) _currentLayer->addChild(timeout.get());
_currentLayer = timeout.get();
}
void SlideShowConstructor::pushCurrentLayer()
{
_layerStack.push_back(_currentLayer.get());
}
void SlideShowConstructor::popCurrentLayer()
{
if (!_layerStack.empty())
{
_currentLayer = _layerStack.back();
_layerStack.pop_back();
}
}
void SlideShowConstructor::addLayer(bool inheritPreviousLayers, bool defineAsBaseLayer)
{
if (!_slide) addSlide();

View File

@ -12,26 +12,184 @@
*/
#include <osgPresentation/Timeout>
#include <osgUtil/CullVisitor>
#include <osgGA/EventVisitor>
using namespace osgPresentation;
Timeout::Timeout()
HUDSettings::HUDSettings(double slideDistance, float eyeOffset, unsigned int leftMask, unsigned int rightMask):
_slideDistance(slideDistance),
_eyeOffset(eyeOffset),
_leftMask(leftMask),
_rightMask(rightMask)
{
}
HUDSettings::~HUDSettings()
{
}
bool HUDSettings::getModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
{
matrix.makeLookAt(osg::Vec3d(0.0,0.0,0.0),osg::Vec3d(0.0,_slideDistance,0.0),osg::Vec3d(0.0,0.0,1.0));
if (nv)
{
if (nv->getTraversalMask()==_leftMask)
{
matrix.postMultTranslate(osg::Vec3(_eyeOffset,0.0,0.0));
}
else if (nv->getTraversalMask()==_rightMask)
{
matrix.postMultTranslate(osg::Vec3(-_eyeOffset,0.0,0.0));
}
}
return true;
}
bool HUDSettings::getInverseModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
{
osg::Matrix modelView;
getModelViewMatrix(modelView,nv);
matrix.invert(modelView);
return true;
}
Timeout::Timeout(HUDSettings* hudSettings):
_previousFrameNumber(-1),
_timeOfLastEvent(0.0),
_idleDurationBeforeTimeoutDisplay(5.0),
_idleDurationBeforeTimeoutAction(6.0)
{
_hudSettings = hudSettings;
setCullingActive(false);
setNumChildrenRequiringEventTraversal(1);
}
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
Timeout::Timeout(const Timeout& timeout,const osg::CopyOp& copyop):
osg::Group(timeout, copyop)
osg::Transform(timeout, copyop),
_hudSettings(timeout._hudSettings)
{
setDataVariance(osg::Object::DYNAMIC);
setReferenceFrame(osg::Transform::ABSOLUTE_RF);
}
Timeout::~Timeout()
{
}
bool Timeout::computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
{
if (_hudSettings.valid()) return _hudSettings->getModelViewMatrix(matrix,nv);
else return false;
}
bool Timeout::computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
{
if (_hudSettings.valid()) return _hudSettings->getInverseModelViewMatrix(matrix,nv);
else return false;
}
void Timeout::traverse(osg::NodeVisitor& nv)
{
OSG_NOTICE<<"Timeout::traverse"<<std::endl;
Group::traverse(nv);
if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR)
{
double timeSinceLastEvent = nv.getFrameStamp() ? nv.getFrameStamp()->getReferenceTime()-_timeOfLastEvent : 0.0;
bool needToDisplay = (timeSinceLastEvent>_idleDurationBeforeTimeoutDisplay);
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
if (needToDisplay && cv)
{
osgUtil::RenderStage* previous_stage = cv->getCurrentRenderBin()->getStage();
osg::ref_ptr<osgUtil::RenderStage> rs = new osgUtil::RenderStage;
osg::ColorMask* colorMask = previous_stage->getColorMask();
rs->setColorMask(colorMask);
// set up the viewport.
osg::Viewport* viewport = previous_stage->getViewport();
rs->setViewport( viewport );
rs->setClearMask(GL_DEPTH_BUFFER_BIT);
// record the render bin, to be restored after creation
// of the render to text
osgUtil::RenderBin* previousRenderBin = cv->getCurrentRenderBin();
// set the current renderbin to be the newly created stage.
cv->setCurrentRenderBin(rs.get());
// traverse the subgraph
{
Transform::traverse(nv);
}
// restore the previous renderbin.
cv->setCurrentRenderBin(previousRenderBin);
// and the render to texture stage to the current stages
// dependancy list.
cv->getCurrentRenderBin()->getStage()->addPostRenderStage(rs.get(),0);
}
}
else if (nv.getVisitorType()==osg::NodeVisitor::EVENT_VISITOR)
{
int deltaFrameNumber = (nv.getFrameStamp()->getFrameNumber()-_previousFrameNumber);
_previousFrameNumber = nv.getFrameStamp()->getFrameNumber();
bool needToRecordEventTime = false;
if (deltaFrameNumber>1)
{
needToRecordEventTime = true;
}
else
{
osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(&nv);
if (ev)
{
osgGA::EventQueue::Events& events = ev->getEvents();
for(osgGA::EventQueue::Events::iterator itr = events.begin();
itr != events.end();
++itr)
{
osgGA::GUIEventAdapter* event = itr->get();
if (event->getEventType()!=osgGA::GUIEventAdapter::FRAME)
{
needToRecordEventTime = true;
}
}
}
}
if (needToRecordEventTime)
{
_timeOfLastEvent = nv.getFrameStamp()->getReferenceTime();
}
Transform::traverse(nv);
double timeSinceLastEvent = nv.getFrameStamp() ? nv.getFrameStamp()->getReferenceTime()-_timeOfLastEvent : 0.0;
bool needToAction = (timeSinceLastEvent>_idleDurationBeforeTimeoutAction);
if (needToAction)
{
OSG_NOTICE<<"Do action"<<std::endl;
_previousFrameNumber = -1;
_timeOfLastEvent = nv.getFrameStamp()->getReferenceTime();
}
}
else
{
Transform::traverse(nv);
}
}