void Timeout::traverse(osg::NodeVisitor& nv) { if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR) { osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv); if (_displayTimeout && 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; bool needToAction = false; if (deltaFrameNumber>1) { needToRecordEventTime = true; } bool previous_displayTimeout = _displayTimeout; bool needToDismiss = false; osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(&nv); osgViewer::Viewer* viewer = ev ? dynamic_cast<osgViewer::Viewer*>(ev->getActionAdapter()) : 0; 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(); bool keyEvent = event->getEventType()==osgGA::GUIEventAdapter::KEYDOWN || event->getEventType()==osgGA::GUIEventAdapter::KEYUP; if (keyEvent && event->getKey()==_keyStartsTimoutDisplay) { OSG_NOTICE<<"_keyStartsTimoutDisplay pressed"<<std::endl; _displayTimeout = true; } else if (keyEvent && event->getKey()==_keyDismissTimoutDisplay) { OSG_NOTICE<<"_keyDismissTimoutDisplay pressed"<<std::endl; needToRecordEventTime = true; needToDismiss = _displayTimeout; _displayTimeout = false; } else if (keyEvent && event->getKey()==_keyRunTimeoutAction) { OSG_NOTICE<<"_keyRunTimeoutAction pressed"<<std::endl; _displayTimeout = false; needToRecordEventTime = true; needToAction = true; } else if (event->getEventType()!=osgGA::GUIEventAdapter::FRAME) { needToRecordEventTime = true; needToDismiss = _displayTimeout; _displayTimeout = false; } } } if (needToRecordEventTime) { _timeOfLastEvent = nv.getFrameStamp()->getReferenceTime(); } double timeSinceLastEvent = nv.getFrameStamp() ? nv.getFrameStamp()->getReferenceTime()-_timeOfLastEvent : 0.0; if (timeSinceLastEvent>_idleDurationBeforeTimeoutDisplay) { _displayTimeout = true; } if (timeSinceLastEvent>_idleDurationBeforeTimeoutAction) { _displayTimeout = false; needToAction = true; needToDismiss = false; } if (!previous_displayTimeout && _displayTimeout) { if (viewer && (_displayBroadcastKeyPos._key!=0 || _displayBroadcastKeyPos._x!=FLT_MAX || _displayBroadcastKeyPos._y!=FLT_MAX)) { OSG_NOTICE<<"Doing display broadcast key event"<<_displayBroadcastKeyPos._key<<std::endl; broadcastEvent(viewer, _displayBroadcastKeyPos); } OperationVisitor leave(OperationVisitor::ENTER); accept(leave); if (leave.sleepTime()!=0.0) { OSG_NOTICE<<"Pausing for "<<leave.sleepTime()<<std::endl; OpenThreads::Thread::microSleep(static_cast<unsigned int>(1000000.0*leave.sleepTime())); OSG_NOTICE<<"Finished Pause "<<std::endl; } } if (needToDismiss) { if (viewer && (_dismissBroadcastKeyPos._key!=0 || _dismissBroadcastKeyPos._x!=FLT_MAX || _dismissBroadcastKeyPos._y!=FLT_MAX)) { OSG_NOTICE<<"Doing dismiss broadcast key event"<<_dismissBroadcastKeyPos._key<<std::endl; broadcastEvent(viewer, _dismissBroadcastKeyPos); } OperationVisitor leave(OperationVisitor::LEAVE); accept(leave); } Transform::traverse(nv); if (needToAction) { OSG_NOTICE<<"Do timeout action"<<std::endl; _previousFrameNumber = -1; _timeOfLastEvent = nv.getFrameStamp()->getReferenceTime(); if (_actionJumpData.requiresJump()) { OSG_NOTICE<<"Doing timeout jump"<<std::endl; _actionJumpData.jump(SlideEventHandler::instance()); } if (_actionKeyPos._key!=0 || _actionKeyPos._x!=FLT_MAX || _actionKeyPos._y!=FLT_MAX) { OSG_NOTICE<<"Doing timeout key event"<<_actionKeyPos._key<<std::endl; if (SlideEventHandler::instance()) SlideEventHandler::instance()->dispatchEvent(_actionKeyPos); } if (viewer && (_actionBroadcastKeyPos._key!=0 || _actionBroadcastKeyPos._x!=FLT_MAX || _actionBroadcastKeyPos._y!=FLT_MAX)) { OSG_NOTICE<<"Doing timeout broadcast key event"<<_actionBroadcastKeyPos._key<<std::endl; broadcastEvent(viewer, _actionBroadcastKeyPos); } } } else if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR) { if (_displayTimeout) Transform::traverse(nv); } else { if (strcmp(nv.className(),"FindOperatorsVisitor")==0) { OSG_NOTICE<<"Timout::traverse() "<<nv.className()<<", ignoring traversal"<<std::endl; } else { Transform::traverse(nv); } } }