From 693d79c63800f291464b3477fc661b110fe1d55c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 4 Nov 2011 12:50:05 +0000 Subject: [PATCH] Implement presentation update feature that reloads the presentation on pressing 'u'. --- applications/present3D/ReadShowFile.cpp | 4 + applications/present3D/present3D.cpp | 264 ++++++---------------- include/osgPresentation/SlideEventHandler | 6 + src/osgPresentation/SlideEventHandler.cpp | 44 +++- 4 files changed, 123 insertions(+), 195 deletions(-) diff --git a/applications/present3D/ReadShowFile.cpp b/applications/present3D/ReadShowFile.cpp index 7582b8b3e..b8820cb2c 100644 --- a/applications/present3D/ReadShowFile.cpp +++ b/applications/present3D/ReadShowFile.cpp @@ -251,8 +251,12 @@ osg::ref_ptr 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] ); } } } diff --git a/applications/present3D/present3D.cpp b/applications/present3D/present3D.cpp index 742590564..a1fd7cf1e 100644 --- a/applications/present3D/present3D.cpp +++ b/applications/present3D/present3D.cpp @@ -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(nv); - - if (!ev || !geometry) return; - - osgGA::GUIActionAdapter* aa = ev->getActionAdapter(); - osgViewer::View* view = dynamic_cast(aa); - if (!view) return; - - osg::Vec3Array* vertices = dynamic_cast(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="<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(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(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& 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 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 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 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 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"<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; } diff --git a/include/osgPresentation/SlideEventHandler b/include/osgPresentation/SlideEventHandler index ac0a5778d..0f45af319 100644 --- a/include/osgPresentation/SlideEventHandler +++ b/include/osgPresentation/SlideEventHandler @@ -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; + bool _requestReload; + void updateOperators(); }; diff --git a/src/osgPresentation/SlideEventHandler.cpp b/src/osgPresentation/SlideEventHandler.cpp index e7064c391..77359493b 100644 --- a/src/osgPresentation/SlideEventHandler.cpp +++ b/src/osgPresentation/SlideEventHandler.cpp @@ -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"<=static_cast(_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(_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()"<(_slideSwitch->getUserData()) : 0; if (la && la->requiresJump()) { @@ -1132,6 +1155,7 @@ bool SlideEventHandler::nextSlide() bool SlideEventHandler::previousSlide() { + OSG_INFO<<"previousSlide()"<0) return selectSlide(_activeSlide-1); @@ -1147,6 +1171,8 @@ bool SlideEventHandler::previousSlide() bool SlideEventHandler::nextLayer() { + OSG_INFO<<"nextLayer()"<(_slideSwitch->getNumChildren())) ? dynamic_cast(_slideSwitch->getChild(_activeLayer)->getUserData()) : 0; if (la) { @@ -1179,6 +1205,7 @@ bool SlideEventHandler::nextLayer() bool SlideEventHandler::previousLayer() { + OSG_INFO<<"previousLayer()"<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 "<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; +}