void CompositeViewer::frameStart( const uint32_t frameNumber, const FrameData& frameData ) { //LBINFO << "-----> Viewer::frameStart(" << frameNumber << ")" << std::endl; advance( frameNumber, frameData ); eventTraversal( ); updateTraversal( ); Scenes scenes; getScenes( scenes ); for( Scenes::iterator sitr = scenes.begin( ); sitr != scenes.end( ); ++sitr) { osgViewer::Scene* scene = *sitr; osg::ref_ptr< osgDB::DatabasePager > dp = scene ? scene->getDatabasePager( ) : 0; if( dp.valid( )) dp->signalBeginFrame( getViewerFrameStamp( )); osg::ref_ptr< osg::Node > sceneData = scene ? scene->getSceneData( ) : 0; if( sceneData.valid( )) sceneData->getBound( ); } //LBINFO << "<----- Viewer::frameStart(" << frameNumber << ")" << std::endl; }
CompositeViewer::~CompositeViewer() { OSG_INFO<<"CompositeViewer::~CompositeViewer()"<<std::endl; stopThreading(); Scenes scenes; getScenes(scenes); for(Scenes::iterator sitr = scenes.begin(); sitr != scenes.end(); ++sitr) { Scene* scene = *sitr; if (scene->getDatabasePager()) { scene->getDatabasePager()->cancel(); scene->setDatabasePager(0); } } Contexts contexts; getContexts(contexts); // clear out all the previously assigned operations for(Contexts::iterator citr = contexts.begin(); citr != contexts.end(); ++citr) { (*citr)->close(); } OSG_INFO<<"finished CompositeViewer::~CompositeViewer()"<<std::endl; }
void ViewerBase::setIncrementalCompileOperation(osgUtil::IncrementalCompileOperation* ico) { if (_incrementalCompileOperation == ico) return; Contexts contexts; getContexts(contexts, false); if (_incrementalCompileOperation.valid()) _incrementalCompileOperation->removeContexts(contexts); // assign new operation _incrementalCompileOperation = ico; Scenes scenes; getScenes(scenes,false); for(Scenes::iterator itr = scenes.begin(); itr != scenes.end(); ++itr) { osgDB::DatabasePager* dp = (*itr)->getDatabasePager(); dp->setIncrementalCompileOperation(ico); } if (_incrementalCompileOperation) _incrementalCompileOperation->assignContexts(contexts); }
void CompositeViewer::getAllThreads(Threads& threads, bool onlyActive) { OperationThreads operationThreads; getOperationThreads(operationThreads); for(OperationThreads::iterator itr = operationThreads.begin(); itr != operationThreads.end(); ++itr) { threads.push_back(*itr); } Scenes scenes; getScenes(scenes); for(Scenes::iterator sitr = scenes.begin(); sitr != scenes.end(); ++sitr) { Scene* scene = *sitr; osgDB::DatabasePager* dp = scene->getDatabasePager(); if (dp) { for(unsigned int i=0; i<dp->getNumDatabaseThreads(); ++i) { osgDB::DatabasePager::DatabaseThread* dt = dp->getDatabaseThread(i); if (!onlyActive || dt->isRunning()) { threads.push_back(dt); } } } } }
Hit intersect(const Hit &hit, const Ray &ray) const { Hit hit2=hit; double l = bound.ray_sphere(ray); if (l >= hit.first) return hit; for (Scenes::const_iterator it=child.begin(); it!=child.end(); ++it) hit2 = (*it)->intersect(hit2, ray); return hit2; }
void ViewerBase::setUpThreading() { Contexts contexts; getContexts(contexts); if (_threadingModel==SingleThreaded) { if (_threadsRunning) stopThreading(); else { // we'll set processor affinity here to help single threaded apps // with multiple processor cores, and using the database pager. int numProcessors = OpenThreads::GetNumberOfProcessors(); bool affinity = numProcessors>1; if (affinity) { OpenThreads::SetProcessorAffinityOfCurrentThread(0); Scenes scenes; getScenes(scenes); for(Scenes::iterator scitr = scenes.begin(); scitr != scenes.end(); ++scitr) { if ((*scitr)->getSceneData()) { // update the scene graph so that it has enough GL object buffer memory for the graphics contexts that will be using it. (*scitr)->getSceneData()->resizeGLObjectBuffers(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts()); } } } } } else { if (!_threadsRunning) startThreading(); } }
void CompositeViewer::frameDrawFinish( ) { //LBINFO << "-----> Viewer::frameDrawFinish( )" << std::endl; Scenes scenes; getScenes( scenes ); for( Scenes::iterator sitr = scenes.begin( ); sitr != scenes.end( ); ++sitr ) { osgViewer::Scene* scene = *sitr; osg::ref_ptr< osgDB::DatabasePager > dp = scene ? scene->getDatabasePager( ) : 0; if( dp.valid( )) dp->signalEndFrame( ); } _requestRedraw = false; //LBINFO << "<----- Viewer::frameDrawFinish( )" << std::endl; }
void CompositeViewer::updateTraversal() { if (_done) return; double beginUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick()); _updateVisitor->reset(); _updateVisitor->setFrameStamp(getFrameStamp()); _updateVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber()); Scenes scenes; getScenes(scenes); for(Scenes::iterator sitr = scenes.begin(); sitr != scenes.end(); ++sitr) { Scene* scene = *sitr; scene->updateSceneGraph(*_updateVisitor); } // if we have a shared state manager prune any unused entries if (osgDB::Registry::instance()->getSharedStateManager()) osgDB::Registry::instance()->getSharedStateManager()->prune(); // update the Registry object cache. osgDB::Registry::instance()->updateTimeStampOfObjectsInCacheWithExternalReferences(*getFrameStamp()); osgDB::Registry::instance()->removeExpiredObjectsInCache(*getFrameStamp()); if (_incrementalCompileOperation.valid()) { // merge subgraphs that have been compiled by the incremental compiler operation. _incrementalCompileOperation->mergeCompiledSubgraphs(getFrameStamp()); } if (_updateOperations.valid()) { _updateOperations->runOperations(this); } for(RefViews::iterator vitr = _views.begin(); vitr != _views.end(); ++vitr) { View* view = vitr->get(); { // Do UpdateTraversal for slaves with their own subgraph for(unsigned int i=0; i<view->getNumSlaves(); ++i) { osg::View::Slave& slave = view->getSlave(i); osg::Camera* camera = slave._camera.get(); if(camera && !slave._useMastersSceneData) { camera->accept(*_updateVisitor); } } // call any camera update callbacks, but only traverse that callback, don't traverse its subgraph // leave that to the scene update traversal. osg::NodeVisitor::TraversalMode tm = _updateVisitor->getTraversalMode(); _updateVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE); if (view->getCamera() && view->getCamera()->getUpdateCallback()) view->getCamera()->accept(*_updateVisitor); for(unsigned int i=0; i<view->getNumSlaves(); ++i) { osg::View::Slave& slave = view->getSlave(i); osg::Camera* camera = slave._camera.get(); if (camera && slave._useMastersSceneData && camera->getUpdateCallback()) { camera->accept(*_updateVisitor); } } _updateVisitor->setTraversalMode(tm); } if (view->getCameraManipulator()) { view->setFusionDistance( view->getCameraManipulator()->getFusionDistanceMode(), view->getCameraManipulator()->getFusionDistanceValue() ); view->getCameraManipulator()->updateCamera(*(view->getCamera())); } view->updateSlaves(); } if (getViewerStats() && getViewerStats()->collectStats("update")) { double endUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick()); // update current frames stats getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal begin time", beginUpdateTraversal); getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal end time", endUpdateTraversal); getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal time taken", endUpdateTraversal-beginUpdateTraversal); } }
~Group() { for (Scenes::const_iterator it=child.begin(); it!=child.end(); ++it) delete *it; }
void ViewerBase::renderingTraversals() { bool _outputMasterCameraLocation = false; if (_outputMasterCameraLocation) { Views views; getViews(views); for(Views::iterator itr = views.begin(); itr != views.end(); ++itr) { osgViewer::View* view = *itr; if (view) { const osg::Matrixd& m = view->getCamera()->getInverseViewMatrix(); OSG_NOTICE<<"View "<<view<<", Master Camera position("<<m.getTrans()<<"), rotation("<<m.getRotate()<<")"<<std::endl; } } } Contexts contexts; getContexts(contexts); // check to see if windows are still valid checkWindowStatus(contexts); if (_done) return; double beginRenderingTraversals = elapsedTime(); osg::FrameStamp* frameStamp = getViewerFrameStamp(); if (getViewerStats() && getViewerStats()->collectStats("scene")) { unsigned int frameNumber = frameStamp ? frameStamp->getFrameNumber() : 0; Views views; getViews(views); for(Views::iterator vitr = views.begin(); vitr != views.end(); ++vitr) { View* view = *vitr; osg::Stats* stats = view->getStats(); osg::Node* sceneRoot = view->getSceneData(); if (sceneRoot && stats) { osgUtil::StatsVisitor statsVisitor; sceneRoot->accept(statsVisitor); statsVisitor.totalUpStats(); unsigned int unique_primitives = 0; osgUtil::Statistics::PrimitiveCountMap::iterator pcmitr; for(pcmitr = statsVisitor._uniqueStats.GetPrimitivesBegin(); pcmitr != statsVisitor._uniqueStats.GetPrimitivesEnd(); ++pcmitr) { unique_primitives += pcmitr->second; } stats->setAttribute(frameNumber, "Number of unique StateSet", static_cast<double>(statsVisitor._statesetSet.size())); stats->setAttribute(frameNumber, "Number of unique Group", static_cast<double>(statsVisitor._groupSet.size())); stats->setAttribute(frameNumber, "Number of unique Transform", static_cast<double>(statsVisitor._transformSet.size())); stats->setAttribute(frameNumber, "Number of unique LOD", static_cast<double>(statsVisitor._lodSet.size())); stats->setAttribute(frameNumber, "Number of unique Switch", static_cast<double>(statsVisitor._switchSet.size())); stats->setAttribute(frameNumber, "Number of unique Geode", static_cast<double>(statsVisitor._geodeSet.size())); stats->setAttribute(frameNumber, "Number of unique Drawable", static_cast<double>(statsVisitor._drawableSet.size())); stats->setAttribute(frameNumber, "Number of unique Geometry", static_cast<double>(statsVisitor._geometrySet.size())); stats->setAttribute(frameNumber, "Number of unique Vertices", static_cast<double>(statsVisitor._uniqueStats._vertexCount)); stats->setAttribute(frameNumber, "Number of unique Primitives", static_cast<double>(unique_primitives)); unsigned int instanced_primitives = 0; for(pcmitr = statsVisitor._instancedStats.GetPrimitivesBegin(); pcmitr != statsVisitor._instancedStats.GetPrimitivesEnd(); ++pcmitr) { instanced_primitives += pcmitr->second; } stats->setAttribute(frameNumber, "Number of instanced Stateset", static_cast<double>(statsVisitor._numInstancedStateSet)); stats->setAttribute(frameNumber, "Number of instanced Group", static_cast<double>(statsVisitor._numInstancedGroup)); stats->setAttribute(frameNumber, "Number of instanced Transform", static_cast<double>(statsVisitor._numInstancedTransform)); stats->setAttribute(frameNumber, "Number of instanced LOD", static_cast<double>(statsVisitor._numInstancedLOD)); stats->setAttribute(frameNumber, "Number of instanced Switch", static_cast<double>(statsVisitor._numInstancedSwitch)); stats->setAttribute(frameNumber, "Number of instanced Geode", static_cast<double>(statsVisitor._numInstancedGeode)); stats->setAttribute(frameNumber, "Number of instanced Drawable", static_cast<double>(statsVisitor._numInstancedDrawable)); stats->setAttribute(frameNumber, "Number of instanced Geometry", static_cast<double>(statsVisitor._numInstancedGeometry)); stats->setAttribute(frameNumber, "Number of instanced Vertices", static_cast<double>(statsVisitor._instancedStats._vertexCount)); stats->setAttribute(frameNumber, "Number of instanced Primitives", static_cast<double>(instanced_primitives)); } } } Scenes scenes; getScenes(scenes); for(Scenes::iterator sitr = scenes.begin(); sitr != scenes.end(); ++sitr) { Scene* scene = *sitr; osgDB::DatabasePager* dp = scene ? scene->getDatabasePager() : 0; if (dp) dp->signalBeginFrame(frameStamp); osgDB::ImagePager* ip = scene ? scene->getImagePager() : 0; if (ip) ip->signalBeginFrame(frameStamp); if (scene->getSceneData()) { // fire off a build of the bounding volumes while we // are still running single threaded. scene->getSceneData()->getBound(); } } // OSG_NOTICE<<std::endl<<"Start frame"<<std::endl; Cameras cameras; getCameras(cameras); Contexts::iterator itr; bool doneMakeCurrentInThisThread = false; if (_endDynamicDrawBlock.valid()) { _endDynamicDrawBlock->reset(); } // dispatch the rendering threads if (_startRenderingBarrier.valid()) _startRenderingBarrier->block(); // reset any double buffer graphics objects for(Cameras::iterator camItr = cameras.begin(); camItr != cameras.end(); ++camItr) { osg::Camera* camera = *camItr; Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer()); if (renderer) { if (!renderer->getGraphicsThreadDoesCull() && !(camera->getCameraThread())) { renderer->cull(); } } } for(itr = contexts.begin(); itr != contexts.end() && !_done; ++itr) { if (!((*itr)->getGraphicsThread()) && (*itr)->valid()) { doneMakeCurrentInThisThread = true; makeCurrent(*itr); (*itr)->runOperations(); } } // OSG_NOTICE<<"Joing _endRenderingDispatchBarrier block "<<_endRenderingDispatchBarrier.get()<<std::endl; // wait till the rendering dispatch is done. if (_endRenderingDispatchBarrier.valid()) _endRenderingDispatchBarrier->block(); for(itr = contexts.begin(); itr != contexts.end() && !_done; ++itr) { if (!((*itr)->getGraphicsThread()) && (*itr)->valid()) { doneMakeCurrentInThisThread = true; makeCurrent(*itr); (*itr)->swapBuffers(); } } for(Scenes::iterator sitr = scenes.begin(); sitr != scenes.end(); ++sitr) { Scene* scene = *sitr; osgDB::DatabasePager* dp = scene ? scene->getDatabasePager() : 0; if (dp) dp->signalEndFrame(); osgDB::ImagePager* ip = scene ? scene->getImagePager() : 0; if (ip) ip->signalEndFrame(); } // wait till the dynamic draw is complete. if (_endDynamicDrawBlock.valid()) { // osg::Timer_t startTick = osg::Timer::instance()->tick(); _endDynamicDrawBlock->block(); // OSG_NOTICE<<"Time waiting "<<osg::Timer::instance()->delta_m(startTick, osg::Timer::instance()->tick())<<std::endl;; } if (_releaseContextAtEndOfFrameHint && doneMakeCurrentInThisThread) { //OSG_NOTICE<<"Doing release context"<<std::endl; releaseContext(); } if (getViewerStats() && getViewerStats()->collectStats("update")) { double endRenderingTraversals = elapsedTime(); // update current frames stats getViewerStats()->setAttribute(frameStamp->getFrameNumber(), "Rendering traversals begin time ", beginRenderingTraversals); getViewerStats()->setAttribute(frameStamp->getFrameNumber(), "Rendering traversals end time ", endRenderingTraversals); getViewerStats()->setAttribute(frameStamp->getFrameNumber(), "Rendering traversals time taken", endRenderingTraversals-beginRenderingTraversals); } _requestRedraw = false; }
void ViewerBase::startThreading() { if (_threadsRunning) return; OSG_INFO<<"Viewer::startThreading() - starting threading"<<std::endl; // release any context held by the main thread. releaseContext(); _threadingModel = _threadingModel==AutomaticSelection ? suggestBestThreadingModel() : _threadingModel; Contexts contexts; getContexts(contexts); OSG_INFO<<"Viewer::startThreading() - contexts.size()="<<contexts.size()<<std::endl; Cameras cameras; getCameras(cameras); unsigned int numThreadsOnStartBarrier = 0; unsigned int numThreadsOnEndBarrier = 0; switch(_threadingModel) { case(SingleThreaded): numThreadsOnStartBarrier = 1; numThreadsOnEndBarrier = 1; return; case(CullDrawThreadPerContext): numThreadsOnStartBarrier = contexts.size()+1; numThreadsOnEndBarrier = contexts.size()+1; break; case(DrawThreadPerContext): numThreadsOnStartBarrier = 1; numThreadsOnEndBarrier = 1; break; case(CullThreadPerCameraDrawThreadPerContext): numThreadsOnStartBarrier = cameras.size()+1; numThreadsOnEndBarrier = 1; break; default: OSG_NOTICE<<"Error: Threading model not selected"<<std::endl; return; } // using multi-threading so make sure that new objects are allocated with thread safe ref/unref osg::Referenced::setThreadSafeReferenceCounting(true); Scenes scenes; getScenes(scenes); for(Scenes::iterator scitr = scenes.begin(); scitr != scenes.end(); ++scitr) { if ((*scitr)->getSceneData()) { OSG_INFO<<"Making scene thread safe"<<std::endl; // make sure that existing scene graph objects are allocated with thread safe ref/unref (*scitr)->getSceneData()->setThreadSafeRefUnref(true); // update the scene graph so that it has enough GL object buffer memory for the graphics contexts that will be using it. (*scitr)->getSceneData()->resizeGLObjectBuffers(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts()); } } int numProcessors = OpenThreads::GetNumberOfProcessors(); bool affinity = numProcessors>1; Contexts::iterator citr; unsigned int numViewerDoubleBufferedRenderingOperation = 0; bool graphicsThreadsDoesCull = _threadingModel == CullDrawThreadPerContext || _threadingModel==SingleThreaded; for(Cameras::iterator camItr = cameras.begin(); camItr != cameras.end(); ++camItr) { osg::Camera* camera = *camItr; Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer()); if (renderer) { renderer->setGraphicsThreadDoesCull(graphicsThreadsDoesCull); renderer->setDone(false); renderer->reset(); ++numViewerDoubleBufferedRenderingOperation; } } if (_threadingModel==CullDrawThreadPerContext) { _startRenderingBarrier = 0; _endRenderingDispatchBarrier = 0; _endDynamicDrawBlock = 0; } else if (_threadingModel==DrawThreadPerContext || _threadingModel==CullThreadPerCameraDrawThreadPerContext) { _startRenderingBarrier = 0; _endRenderingDispatchBarrier = 0; _endDynamicDrawBlock = new osg::EndOfDynamicDrawBlock(numViewerDoubleBufferedRenderingOperation); #ifndef OSGUTIL_RENDERBACKEND_USE_REF_PTR if (!osg::Referenced::getDeleteHandler()) osg::Referenced::setDeleteHandler(new osg::DeleteHandler(2)); else osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(2); #endif } if (numThreadsOnStartBarrier>1) { _startRenderingBarrier = new osg::BarrierOperation(numThreadsOnStartBarrier, osg::BarrierOperation::NO_OPERATION); } if (numThreadsOnEndBarrier>1) { _endRenderingDispatchBarrier = new osg::BarrierOperation(numThreadsOnEndBarrier, _endBarrierOperation); } osg::ref_ptr<osg::BarrierOperation> swapReadyBarrier = contexts.empty() ? 0 : new osg::BarrierOperation(contexts.size(), osg::BarrierOperation::NO_OPERATION); osg::ref_ptr<osg::SwapBuffersOperation> swapOp = new osg::SwapBuffersOperation(); typedef std::map<OpenThreads::Thread*, int> ThreadAffinityMap; ThreadAffinityMap threadAffinityMap; unsigned int processNum = 1; for(citr = contexts.begin(); citr != contexts.end(); ++citr, ++processNum) { osg::GraphicsContext* gc = (*citr); if (!gc->isRealized()) { OSG_INFO<<"ViewerBase::startThreading() : Realizng window "<<gc<<std::endl; gc->realize(); } gc->getState()->setDynamicObjectRenderingCompletedCallback(_endDynamicDrawBlock.get()); // create the a graphics thread for this context gc->createGraphicsThread(); if (affinity) gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors); threadAffinityMap[gc->getGraphicsThread()] = processNum % numProcessors; // add the startRenderingBarrier if (_threadingModel==CullDrawThreadPerContext && _startRenderingBarrier.valid()) gc->getGraphicsThread()->add(_startRenderingBarrier.get()); // add the rendering operation itself. gc->getGraphicsThread()->add(new osg::RunOperations()); if (_threadingModel==CullDrawThreadPerContext && _endBarrierPosition==BeforeSwapBuffers && _endRenderingDispatchBarrier.valid()) { // add the endRenderingDispatchBarrier gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get()); } if (swapReadyBarrier.valid()) gc->getGraphicsThread()->add(swapReadyBarrier.get()); // add the swap buffers gc->getGraphicsThread()->add(swapOp.get()); if (_threadingModel==CullDrawThreadPerContext && _endBarrierPosition==AfterSwapBuffers && _endRenderingDispatchBarrier.valid()) { // add the endRenderingDispatchBarrier gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get()); } } if (_threadingModel==CullThreadPerCameraDrawThreadPerContext && numThreadsOnStartBarrier>1) { Cameras::iterator camItr; for(camItr = cameras.begin(); camItr != cameras.end(); ++camItr, ++processNum) { osg::Camera* camera = *camItr; camera->createCameraThread(); if (affinity) camera->getCameraThread()->setProcessorAffinity(processNum % numProcessors); threadAffinityMap[camera->getCameraThread()] = processNum % numProcessors; osg::GraphicsContext* gc = camera->getGraphicsContext(); // add the startRenderingBarrier if (_startRenderingBarrier.valid()) camera->getCameraThread()->add(_startRenderingBarrier.get()); Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer()); renderer->setGraphicsThreadDoesCull(false); camera->getCameraThread()->add(renderer); if (_endRenderingDispatchBarrier.valid()) { // add the endRenderingDispatchBarrier gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get()); } } for(camItr = cameras.begin(); camItr != cameras.end(); ++camItr) { osg::Camera* camera = *camItr; if (camera->getCameraThread() && !camera->getCameraThread()->isRunning()) { OSG_INFO<<" camera->getCameraThread()-> "<<camera->getCameraThread()<<std::endl; camera->getCameraThread()->startThread(); } } } #if 0 if (affinity) { OpenThreads::SetProcessorAffinityOfCurrentThread(0); if (_scene.valid() && _scene->getDatabasePager()) { #if 0 _scene->getDatabasePager()->setProcessorAffinity(1); #else _scene->getDatabasePager()->setProcessorAffinity(0); #endif } } #endif #if 0 if (affinity) { for(ThreadAffinityMap::iterator titr = threadAffinityMap.begin(); titr != threadAffinityMap.end(); ++titr) { titr->first->setProcessorAffinity(titr->second); } } #endif for(citr = contexts.begin(); citr != contexts.end(); ++citr) { osg::GraphicsContext* gc = (*citr); if (gc->getGraphicsThread() && !gc->getGraphicsThread()->isRunning()) { OSG_INFO<<" gc->getGraphicsThread()->startThread() "<<gc->getGraphicsThread()<<std::endl; gc->getGraphicsThread()->startThread(); // OpenThreads::Thread::YieldCurrentThread(); } } _threadsRunning = true; OSG_INFO<<"Set up threading"<<std::endl; }
void CompositeViewer::updateTraversal() { if (_done) return; double beginUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick()); _updateVisitor->reset(); _updateVisitor->setFrameStamp(getFrameStamp()); _updateVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber()); Scenes scenes; getScenes(scenes); for(Scenes::iterator sitr = scenes.begin(); sitr != scenes.end(); ++sitr) { Scene* scene = *sitr; if (scene->getSceneData()) { _updateVisitor->setImageRequestHandler(scene->getImagePager()); scene->getSceneData()->accept(*_updateVisitor); } if (scene->getDatabasePager()) { // synchronize changes required by the DatabasePager thread to the scene graph scene->getDatabasePager()->updateSceneGraph(*_frameStamp); } if (scene->getImagePager()) { // synchronize changes required by the DatabasePager thread to the scene graph scene->getImagePager()->updateSceneGraph(*_frameStamp); } } if (_updateOperations.valid()) { _updateOperations->runOperations(this); } for(RefViews::iterator vitr = _views.begin(); vitr != _views.end(); ++vitr) { View* view = vitr->get(); Scene* scene = view->getScene(); { // call any camera update callbacks, but only traverse that callback, don't traverse its subgraph // leave that to the scene update traversal. osg::NodeVisitor::TraversalMode tm = _updateVisitor->getTraversalMode(); _updateVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE); if (view->getCamera() && view->getCamera()->getUpdateCallback()) view->getCamera()->accept(*_updateVisitor); for(unsigned int i=0; i<view->getNumSlaves(); ++i) { osg::Camera* camera = view->getSlave(i)._camera.get(); if (camera && camera->getUpdateCallback()) camera->accept(*_updateVisitor); } _updateVisitor->setTraversalMode(tm); } if (view->getCameraManipulator()) { view->setFusionDistance( view->getCameraManipulator()->getFusionDistanceMode(), view->getCameraManipulator()->getFusionDistanceValue() ); view->getCamera()->setViewMatrix( view->getCameraManipulator()->getInverseMatrix()); } view->updateSlaves(); } if (getStats() && getStats()->collectStats("update")) { double endUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick()); // update current frames stats getStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal begin time", beginUpdateTraversal); getStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal end time", endUpdateTraversal); getStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal time taken", endUpdateTraversal-beginUpdateTraversal); } }