Implement presentation update feature that reloads the presentation on pressing 'u'.

This commit is contained in:
Robert Osfield
2011-11-04 12:50:05 +00:00
parent e8bae33143
commit 693d79c638
4 changed files with 123 additions and 195 deletions

View File

@@ -251,8 +251,12 @@ osg::ref_ptr<osg::Node> p3d::readShowFiles(osg::ArgumentParser& arguments,const
if(node)
{
if (node->getName().empty()) node->setName( arguments[pos] );
nodeList.push_back(node);
// make sure that this presentation isn't cached
osgDB::Registry::instance()->removeFromObjectCache( arguments[pos] );
}
}
}

View File

@@ -129,59 +129,6 @@ void setViewer(osgViewer::Viewer& viewer, float width, float height, float dista
viewer.getCamera()->setProjectionMatrixAsPerspective( vfov, width/height, 0.1, 1000.0);
}
#if 1
class RayFollowsMouseCallback : public osg::Drawable::EventCallback
{
RayFollowsMouseCallback() {}
/** do customized Event code. */
virtual void event(osg::NodeVisitor* nv, osg::Drawable* drawable)
{
osg::Geometry* geometry = drawable->asGeometry();
osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(nv);
if (!ev || !geometry) return;
osgGA::GUIActionAdapter* aa = ev->getActionAdapter();
osgViewer::View* view = dynamic_cast<osgViewer::View*>(aa);
if (!view) return;
osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
if (!vertices) return;
osg::Camera* camera = view->getCamera();
osg::Matrix VP = camera->getViewMatrix() * camera->getProjectionMatrix();
osg::Matrix inverse_VP;
inverse_VP.invert(VP);
osgGA::EventQueue::Events& events = ev->getEvents();
for(osgGA::EventQueue::Events::iterator itr = events.begin();
itr != events.end();
++itr)
{
handle(inverse_VP, *(*itr), vertices);
}
}
void handle(const osg::Matrix& inverse_VP, osgGA::GUIEventAdapter& ea, osg::Vec3Array* vertices)
{
osg::Vec3d start_eye(ea.getXnormalized(), ea.getYnormalized(), 0.0);
osg::Vec3d end_eye(ea.getXnormalized(), ea.getYnormalized(), 1.0);
osg::Vec3d start_world = start_eye * inverse_VP;
osg::Vec3d end_world = start_eye * inverse_VP;
osg::notify(osg::NOTICE)<<"start_world="<<start_world<<std::endl;
osg::notify(osg::NOTICE)<<"end_world="<<end_world<<std::endl;
(*vertices)[0] = start_world;
(*vertices)[1] = end_world;
}
};
class FollowMouseCallback: public osgGA::GUIEventHandler
{
public:
@@ -199,17 +146,16 @@ class FollowMouseCallback: public osgGA::GUIEventHandler
{
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
transform->setNodeMask(0x0);
osg::notify(osg::NOTICE)<<std::endl<<"ea.getGraphicsContext()="<<ea.getGraphicsContext()<<std::endl;
osg::notify(osg::NOTICE)<<"ea.getWindowWidth()="<<ea.getWindowWidth()<<std::endl;
osg::notify(osg::NOTICE)<<"ea.getWindowHeight()="<<ea.getWindowHeight()<<std::endl;
osg::notify(osg::NOTICE)<<"ea.getX()="<<ea.getX()<<std::endl;
osg::notify(osg::NOTICE)<<"ea.getXin()="<<ea.getXmin()<<std::endl;
osg::notify(osg::NOTICE)<<"ea.getXmax()="<<ea.getXmax()<<std::endl;
osg::notify(osg::NOTICE)<<"ea.getY()="<<ea.getY()<<std::endl;
osg::notify(osg::NOTICE)<<"ea.getYin()="<<ea.getYmin()<<std::endl;
osg::notify(osg::NOTICE)<<"ea.getYmax()="<<ea.getYmax()<<std::endl;
osg::NotifySeverity level = osg::INFO;
osg::notify(level)<<std::endl<<"ea.getGraphicsContext()="<<ea.getGraphicsContext()<<std::endl;
osg::notify(level)<<"ea.getWindowWidth()="<<ea.getWindowWidth()<<std::endl;
osg::notify(level)<<"ea.getWindowHeight()="<<ea.getWindowHeight()<<std::endl;
osg::notify(level)<<"ea.getX()="<<ea.getX()<<std::endl;
osg::notify(level)<<"ea.getXin()="<<ea.getXmin()<<std::endl;
osg::notify(level)<<"ea.getXmax()="<<ea.getXmax()<<std::endl;
osg::notify(level)<<"ea.getY()="<<ea.getY()<<std::endl;
osg::notify(level)<<"ea.getYin()="<<ea.getYmin()<<std::endl;
osg::notify(level)<<"ea.getYmax()="<<ea.getYmax()<<std::endl;
osg::Camera* camera = view->getCamera();
osg::Matrix VP = camera->getViewMatrix() * camera->getProjectionMatrix();
@@ -223,12 +169,14 @@ class FollowMouseCallback: public osgGA::GUIEventHandler
osg::Vec3d start_world = start_eye * inverse_VP;
osg::Vec3d end_world = start_eye * inverse_VP;
osg::notify(osg::NOTICE)<<"start_world="<<start_world<<std::endl;
osg::notify(osg::NOTICE)<<"end_world="<<end_world<<std::endl;
osg::notify(level)<<"start_world="<<start_world<<std::endl;
osg::notify(level)<<"end_world="<<end_world<<std::endl;
transform->setPosition(end_world);
transform->setNodeMask(0xffffffff);
if (end_world.valid()) transform->setPosition(end_world);
else
{
OSG_NOTICE<<"Ignoring invalid end_world position"<<std::endl;
}
break;
}
@@ -267,6 +215,7 @@ osg::Node* createCursorSubgraph(const std::string& filename, float size)
size = 20.0f;
osg::Geometry* geom = osg::createTexturedQuadGeometry(osg::Vec3(-size*0.5f,-size*0.5f,0.0f),osg::Vec3(size,0.0f,0.0f),osg::Vec3(0.0f,size,0.0f));
geom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
osg::Image* image = osgDB::readImageFile(osgDB::findDataFile(filename));
if (image)
@@ -291,101 +240,6 @@ osg::Node* createCursorSubgraph(const std::string& filename, float size)
return transform;
}
#else
class FollowMouseCallback: public osgGA::GUIEventHandler
{
public:
virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&, osg::Object* object, osg::NodeVisitor*)
{
switch(ea.getEventType())
{
case(osgGA::GUIEventAdapter::MOVE):
case(osgGA::GUIEventAdapter::DRAG):
{
osg::Camera* camera = dynamic_cast<osg::Camera*>(object);
if (camera)
{
double x = ea.getXnormalized();
double y = ea.getYnormalized();
camera->setViewMatrix(osg::Matrixd::translate(x,y,0.0));
}
break;
}
case(osgGA::GUIEventAdapter::KEYDOWN):
{
if (ea.getKey()=='c')
{
osg::Camera* camera = dynamic_cast<osg::Camera*>(object);
if (camera)
{
for(unsigned int i=0; i< camera->getNumChildren(); ++i)
{
osg::Node* node = camera->getChild(i);
node->setNodeMask(
node->getNodeMask()!=0 ?
0 :
0xffffff);
}
}
}
break;
}
default:
break;
}
return false;
}
virtual void accept(osgGA::GUIEventHandlerVisitor& v)
{
v.visit(*this);
}
};
osg::Node* createCursorSubgraph(const std::string& filename, float size)
{
osg::Geode* geode = new osg::Geode;
osg::Geometry* geom = osg::createTexturedQuadGeometry(osg::Vec3(-size*0.5f,-size*0.5f,0.0f),osg::Vec3(size,0.0f,0.0f),osg::Vec3(0.0f,size,0.0f));
osg::Image* image = osgDB::readImageFile(osgDB::findDataFile(filename));
if (image)
{
osg::StateSet* stateset = geom->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(0, new osg::Texture2D(image),osg::StateAttribute::ON);
stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
stateset->setRenderBinDetails(1000, "DepthSortedBin");
}
geode->addDrawable(geom);
osg::Camera* camera = new osg::Camera;
// set the projection matrix
camera->setProjectionMatrix(osg::Matrix::ortho2D(-1,1,-1,1));
// set the view matrix
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setViewMatrix(osg::Matrix::identity());
// only clear the depth buffer
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
// draw subgraph after main camera view.
camera->setRenderOrder(osg::CameraNode::NESTED_RENDER);
camera->addChild(geode);
camera->setEventCallback(new FollowMouseCallback());
return camera;
}
#endif
enum P3DApplicationType
@@ -396,6 +250,29 @@ enum P3DApplicationType
};
void processLoadedModel(osg::ref_ptr<osg::Node>& loadedModel, int optimizer_options, const std::string& cursorFileName)
{
if (!loadedModel) return;
#if !defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GL3_AVAILABLE)
// add back in enabling of the GL_ALPHA_TEST to get around the core OSG no longer setting it by default for opaque bins.
// the alpha test is required for the volume rendering alpha clipping to work.
loadedModel->getOrCreateStateSet()->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
#endif
// optimize the scene graph, remove rendundent nodes and state etc.
osgUtil::Optimizer optimizer;
optimizer.optimize(loadedModel.get(), optimizer_options);
if (!cursorFileName.empty())
{
osg::ref_ptr<osg::Group> group = new osg::Group;
group->addChild(loadedModel.get());
group->addChild(createCursorSubgraph(cursorFileName, 0.05f));
loadedModel = group;
}
}
int main( int argc, char **argv )
{
@@ -606,8 +483,8 @@ int main( int argc, char **argv )
// register the slide event handler - which moves the presentation from slide to slide, layer to layer.
osgPresentation::SlideEventHandler* seh = new osgPresentation::SlideEventHandler(&viewer);
viewer.addEventHandler(seh);
osg::ref_ptr<osgPresentation::SlideEventHandler> seh = new osgPresentation::SlideEventHandler(&viewer);
viewer.addEventHandler(seh.get());
seh->setAutoSteppingActive(autoSteppingActive);
seh->setTimeDelayBetweenSlides(timeDelayBetweenSlides);
@@ -643,8 +520,8 @@ int main( int argc, char **argv )
// osgDB::Registry::instance()->getOrCreateDatabasePager()->setExpiryDelay(1.0f);
// register the handler for modifying the point size
PointsEventHandler* peh = new PointsEventHandler;
viewer.addEventHandler(peh);
osg::ref_ptr<PointsEventHandler> peh = new PointsEventHandler;
viewer.addEventHandler(peh.get());
// add the screen capture handler
std::string screenCaptureFilename = "screen_short.jpg";
@@ -815,26 +692,7 @@ int main( int argc, char **argv )
}
#if !defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GL3_AVAILABLE)
// add back in enabling of the GL_ALPHA_TEST to get around the core OSG no longer setting it by default for opaque bins.
// the alpha test is required for the volume rendering alpha clipping to work.
loadedModel->getOrCreateStateSet()->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
#endif
// optimize the scene graph, remove rendundent nodes and state etc.
osgUtil::Optimizer optimizer;
optimizer.optimize(loadedModel.get(), optimizer_options);
if (!cursorFileName.empty())
{
osg::ref_ptr<osg::Group> group = new osg::Group;
group->addChild(loadedModel.get());
group->addChild(createCursorSubgraph(cursorFileName, 0.05f));
loadedModel = group.get();
}
processLoadedModel(loadedModel, optimizer_options, cursorFileName);
// set the scene to render
viewer.setSceneData(loadedModel.get());
@@ -853,6 +711,9 @@ int main( int argc, char **argv )
viewerInitialized = true;
}
// pass the model to the slide event handler so it knows which to manipulate.
seh->set(loadedModel.get());
seh->selectSlide(0);
@@ -971,6 +832,31 @@ int main( int argc, char **argv )
// call all node update callbacks and animations.
viewer.eventTraversal();
if (seh->getRequestReload())
{
OSG_INFO<<"Reload requested"<<std::endl;
seh->setRequestReload(false);
int previous_ActiveSlide = seh->getActiveSlide();
int previous_ActiveLayer = seh->getActiveLayer();
// reset time so any event key generate
loadedModel = p3d::readShowFiles(arguments,cacheAllOption.get());
processLoadedModel(loadedModel, optimizer_options, cursorFileName);
if (!loadedModel)
{
return 0;
}
viewer.setSceneData(loadedModel.get());
seh->set(loadedModel.get());
seh->selectSlide(previous_ActiveSlide, previous_ActiveLayer);
continue;
}
// update the scene by traversing it with the the update visitor which will
// call all node update callbacks and animations.
viewer.updateTraversal();
@@ -992,7 +878,7 @@ int main( int argc, char **argv )
{
ExportHTML::write(seh, viewer, exportName);
}
return 0;
}

View File

@@ -263,6 +263,10 @@ public:
void dispatchEvent(const KeyPosition& keyPosition);
void setRequestReload(bool flag);
bool getRequestReload() const { return _requestReload; }
protected:
~SlideEventHandler() {}
@@ -314,6 +318,8 @@ protected:
osg::ref_ptr<CompileSlideCallback> _compileSlideCallback;
bool _requestReload;
void updateOperators();
};

View File

@@ -620,7 +620,8 @@ SlideEventHandler::SlideEventHandler(osgViewer::Viewer* viewer):
_tickAtLastSlideOrLayerChange(0),
_timeDelayOnNewSlideWithMovies(0.25f),
_minimumTimeBetweenKeyPresses(0.25),
_timeLastKeyPresses(-1.0)
_timeLastKeyPresses(-1.0),
_requestReload(false)
{
s_seh = this;
}
@@ -639,6 +640,10 @@ void SlideEventHandler::set(osg::Node* model)
aucv.setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
model->accept(aucv);
#endif
_firstSlideOrLayerChange = true;
_tickAtFirstSlideOrLayerChange = 0;
_tickAtLastSlideOrLayerChange = 0;
_timeLastKeyPresses = -1;
ActiveOperators operators;
operators.collect(model, osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
@@ -740,7 +745,7 @@ bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction
home();
OSG_NOTICE<<"Assigned viewer. to SlideEventHandler"<<std::endl;
}
// else OSG_NOTICE<<"SlideEventHandler::handle()"<<std::endl;
//else OSG_NOTICE<<"SlideEventHandler::handle() "<<ea.getTime()<<std::endl;
if (ea.getHandled()) return false;
@@ -957,6 +962,11 @@ bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction
_hold = false;
return true;
}
else if (ea.getKey()=='u')
{
setRequestReload(true);
return true;
}
return false;
}
default:
@@ -985,6 +995,11 @@ bool SlideEventHandler::selectSlide(int slideNum,int layerNum)
OSG_INFO<<"selectSlide("<<slideNum<<","<<layerNum<<")"<<std::endl;
if (slideNum>=static_cast<int>(_presentationSwitch->getNumChildren()))
{
slideNum = LAST_POSITION;
}
if (slideNum==LAST_POSITION && _presentationSwitch->getNumChildren()>0)
{
slideNum = _presentationSwitch->getNumChildren()-1;
@@ -1072,6 +1087,11 @@ bool SlideEventHandler::selectLayer(int layerNum)
{
if (!_slideSwitch) return false;
if (layerNum>=static_cast<int>(_slideSwitch->getNumChildren()))
{
layerNum = LAST_POSITION;
}
if (layerNum==LAST_POSITION && _slideSwitch->getNumChildren()>0)
{
layerNum = _slideSwitch->getNumChildren()-1;
@@ -1091,18 +1111,21 @@ bool SlideEventHandler::selectLayer(int layerNum)
bool SlideEventHandler::nextLayerOrSlide()
{
OSG_INFO<<"nextLayerOrSlide()"<<std::endl;
if (nextLayer()) return true;
else return nextSlide();
}
bool SlideEventHandler::previousLayerOrSlide()
{
OSG_INFO<<"previousLayerOrSlide()"<<std::endl;
if (previousLayer()) return true;
else return previousSlide();
}
bool SlideEventHandler::nextSlide()
{
OSG_INFO<<"nextSlide()"<<std::endl;
LayerAttributes* la = _slideSwitch.valid() ? dynamic_cast<LayerAttributes*>(_slideSwitch->getUserData()) : 0;
if (la && la->requiresJump())
{
@@ -1132,6 +1155,7 @@ bool SlideEventHandler::nextSlide()
bool SlideEventHandler::previousSlide()
{
OSG_INFO<<"previousSlide()"<<std::endl;
#if 1
// start position when doing previous slide set to top of slide
if (_activeSlide>0) return selectSlide(_activeSlide-1);
@@ -1147,6 +1171,8 @@ bool SlideEventHandler::previousSlide()
bool SlideEventHandler::nextLayer()
{
OSG_INFO<<"nextLayer()"<<std::endl;
LayerAttributes* la = (_slideSwitch.valid() && _activeLayer<static_cast<int>(_slideSwitch->getNumChildren())) ? dynamic_cast<LayerAttributes*>(_slideSwitch->getChild(_activeLayer)->getUserData()) : 0;
if (la)
{
@@ -1179,6 +1205,7 @@ bool SlideEventHandler::nextLayer()
bool SlideEventHandler::previousLayer()
{
OSG_INFO<<"previousLayer()"<<std::endl;
if (_activeLayer>0) return selectLayer(_activeLayer-1);
else return false;
}
@@ -1294,11 +1321,9 @@ void SlideEventHandler::releaseSlide(unsigned int slideNum)
void SlideEventHandler::dispatchEvent(const KeyPosition& keyPosition)
{
OSG_INFO<<" keyPosition._key "<<keyPosition._key<<" "<<keyPosition._x<<" "<<keyPosition._y<<std::endl;
osgGA::EventQueue* eq = _viewer->getEventQueue();
// reset the time of the last key press to ensure thatthe event is disgarded as a key repeat.
// reset the time of the last key press to ensure that the event is disgarded as a key repeat.
_timeLastKeyPresses = -1.0;
if (keyPosition._x!=FLT_MAX)
@@ -1309,7 +1334,10 @@ void SlideEventHandler::dispatchEvent(const KeyPosition& keyPosition)
if (keyPosition._y!=FLT_MAX)
{
float yRescaled = eq->getCurrentEventState()->getYmin() + (keyPosition._y+1.0f)*0.5f*(eq->getCurrentEventState()->getXmax()-eq->getCurrentEventState()->getYmin());
float y = (eq->getCurrentEventState()->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS) ?
keyPosition._y : -keyPosition._y;
float yRescaled = eq->getCurrentEventState()->getYmin() + (y+1.0f)*0.5f*(eq->getCurrentEventState()->getYmax()-eq->getCurrentEventState()->getYmin());
eq->getCurrentEventState()->setY(yRescaled);
}
@@ -1318,4 +1346,8 @@ void SlideEventHandler::dispatchEvent(const KeyPosition& keyPosition)
}
void SlideEventHandler::setRequestReload(bool flag)
{
_requestReload = flag;
}