From 7366daca911140d486d9e94915e4b4d8f98f1e8c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 10 Aug 2007 10:52:35 +0000 Subject: [PATCH] Refactored the way the Scene is used in Viewer and CompositeViewer to ensure that only on Scene exists per scene graph. --- include/osg/GraphicsThread | 14 ++++ include/osgViewer/CompositeViewer | 5 ++ include/osgViewer/Scene | 28 +------ include/osgViewer/View | 43 ++++------ include/osgViewer/Viewer | 50 ++++++------ src/osg/GraphicsThread.cpp | 15 ++++ src/osgViewer/CompositeViewer.cpp | 45 +++++++--- src/osgViewer/Renderer.cpp | 15 ++-- src/osgViewer/Scene.cpp | 76 +++++++---------- src/osgViewer/View.cpp | 131 +++++++++++++++--------------- src/osgViewer/Viewer.cpp | 57 ++++++------- 11 files changed, 234 insertions(+), 245 deletions(-) diff --git a/include/osg/GraphicsThread b/include/osg/GraphicsThread index c11a7e30f..f1c95e902 100644 --- a/include/osg/GraphicsThread +++ b/include/osg/GraphicsThread @@ -15,6 +15,7 @@ #define OSG_GRAPHICSTHREAD 1 #include +#include namespace osg { @@ -117,6 +118,19 @@ public: }; +class OSG_EXPORT EndOfDynamicDrawBlock : public OpenThreads::BlockCount, public osg::State::DynamicObjectRenderingCompletedCallback +{ + public: + + EndOfDynamicDrawBlock(unsigned int); + + void completed(osg::State* state); + + protected: + + ~EndOfDynamicDrawBlock() {} +}; + } #endif diff --git a/include/osgViewer/CompositeViewer b/include/osgViewer/CompositeViewer index 3ab689a1f..a5b93fa66 100644 --- a/include/osgViewer/CompositeViewer +++ b/include/osgViewer/CompositeViewer @@ -15,6 +15,7 @@ #define OSGVIEWER_CompositeViewer 1 #include +#include #include #include @@ -196,6 +197,10 @@ class OSGVIEWER_EXPORT CompositeViewer : public osg::Referenced osg::ref_ptr _eventQueue; osg::ref_ptr _eventVisitor; + osg::ref_ptr _updateOperations; + osg::ref_ptr _updateVisitor; + + osg::ref_ptr _realizeOperation; }; diff --git a/include/osgViewer/Scene b/include/osgViewer/Scene index 063c8dd76..e4b6d79f0 100644 --- a/include/osgViewer/Scene +++ b/include/osgViewer/Scene @@ -14,7 +14,6 @@ #ifndef OSGVIEWER_SCENE #define OSGVIEWER_SCENE 1 -#include #include #include #include @@ -26,7 +25,7 @@ namespace osgViewer{ /** Scene holds the highe level reference to a single scene graph.*/ -class OSGVIEWER_EXPORT Scene : public virtual osg::Referenced +class OSGVIEWER_EXPORT Scene : public osg::Referenced { public: @@ -37,38 +36,19 @@ class OSGVIEWER_EXPORT Scene : public virtual osg::Referenced osg::Node* getSceneData(); const osg::Node* getSceneData() const; - void setFrameStamp(osg::FrameStamp* frameStamp); - osg::FrameStamp* getFrameStamp() { return _frameStamp.get(); } - const osg::FrameStamp* getFrameStamp() const { return _frameStamp.get(); } - void setDatabasePager(osgDB::DatabasePager* dp); osgDB::DatabasePager* getDatabasePager() { return _databasePager.get(); } const osgDB::DatabasePager* getDatabasePager() const { return _databasePager.get(); } - void setUpdateVisitor(osgUtil::UpdateVisitor* uv) { _updateVisitor = uv; } - osgUtil::UpdateVisitor* getUpdateVisitor() { return _updateVisitor.get(); } - const osgUtil::UpdateVisitor* getUpdateVisitor() const { return _updateVisitor.get(); } + /** Get the Scene object that has the specified node assigned to it. + * return 0 if no Scene has yet been assigned the specified node.*/ + static Scene* getScene(osg::Node* node); - virtual void advance(); - - virtual void updateTraversal(); - - - - public: - - void init(); - protected: - bool _firstFrame; - osg::ref_ptr _frameStamp; - osg::ref_ptr _sceneData; - osg::ref_ptr _updateVisitor; - osg::ref_ptr _databasePager; }; diff --git a/include/osgViewer/View b/include/osgViewer/View index 9a2cdf96a..055e9aba3 100644 --- a/include/osgViewer/View +++ b/include/osgViewer/View @@ -25,33 +25,6 @@ namespace osgViewer { -class OSGVIEWER_EXPORT EndOfDynamicDrawBlock : public osg::State::DynamicObjectRenderingCompletedCallback -{ - public: - - EndOfDynamicDrawBlock(unsigned int); - - void completed(osg::State* state); - - void block(); - - void reset(); - - void release(); - - void setNumOfBlocks(unsigned int blockCount); - - protected: - - ~EndOfDynamicDrawBlock(); - - OpenThreads::Mutex _mut; - OpenThreads::Condition _cond; - unsigned int _numberOfBlocks; - unsigned int _blockCount; -}; - - /** View holds a single view on a scene, this view may be composed of one or more slave cameras.*/ class OSGVIEWER_EXPORT View : public osg::View, public osgGA::GUIActionAdapter { @@ -63,6 +36,13 @@ class OSGVIEWER_EXPORT View : public osg::View, public osgGA::GUIActionAdapter META_Object(osgViewer,View); + virtual void setStartTick(osg::Timer_t tick); + osg::Timer_t getStartTick() const { return _startTick; } + + void setFrameStamp(osg::FrameStamp* fs) { _frameStamp = fs; } + osg::FrameStamp* getFrameStamp() { return _frameStamp.get(); } + const osg::FrameStamp* getFrameStamp() const { return _frameStamp.get(); } + Scene* getScene() { return _scene.get(); } const Scene* getScene() const { return _scene.get(); } @@ -75,6 +55,12 @@ class OSGVIEWER_EXPORT View : public osg::View, public osgGA::GUIActionAdapter /** Get the const View's scene graph.*/ const osg::Node* getSceneData() const { return _scene.valid() ? _scene->getSceneData() : 0; } + /** Get the View's database pager.*/ + osgDB::DatabasePager* getDatabasePager(); + + /** Get the const View's database pager.*/ + const osgDB::DatabasePager* getDatabasePager() const; + /* Set the EventQueue that View uses to intregrate external non window related events.*/ void setEventQueue(osgGA::EventQueue* eventQueue) { _eventQueue = eventQueue; } @@ -188,6 +174,9 @@ class OSGVIEWER_EXPORT View : public osg::View, public osgGA::GUIActionAdapter virtual osg::GraphicsOperation* createRenderer(osg::Camera* camera); + osg::Timer_t _startTick; + osg::ref_ptr _frameStamp; + osg::ref_ptr _scene; osg::ref_ptr _eventQueue; osg::ref_ptr _cameraManipulator; diff --git a/include/osgViewer/Viewer b/include/osgViewer/Viewer index defa2bc16..11cb6fc58 100644 --- a/include/osgViewer/Viewer +++ b/include/osgViewer/Viewer @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -43,15 +44,10 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View bool done() const { return _done; } - void setStartTick(osg::Timer_t tick); - osg::Timer_t getStartTick() const { return _startTick; } + virtual void setStartTick(osg::Timer_t tick); void setReferenceTime(double time=0.0); - osg::FrameStamp* getFrameStamp() { return _frameStamp.get(); } - const osg::FrameStamp* getFrameStamp() const { return _frameStamp.get(); } - - /** Set the sene graph data that viewer with view.*/ virtual void setSceneData(osg::Node* node); @@ -200,34 +196,34 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View } - bool _firstFrame; + bool _firstFrame; - bool _done; - int _keyEventSetsDone; - bool _quitEventSetsDone; + bool _done; + int _keyEventSetsDone; + bool _quitEventSetsDone; - ThreadingModel _threadingModel; - bool _threadsRunning; + ThreadingModel _threadingModel; + bool _threadsRunning; - bool _useMainThreadForRenderingTraversal; - BarrierPosition _endBarrierPosition; + bool _useMainThreadForRenderingTraversal; + BarrierPosition _endBarrierPosition; - osg::ref_ptr _startRenderingBarrier; - osg::ref_ptr _endRenderingDispatchBarrier; - osg::ref_ptr _endDynamicDrawBlock; + osg::ref_ptr _startRenderingBarrier; + osg::ref_ptr _endRenderingDispatchBarrier; + osg::ref_ptr _endDynamicDrawBlock; - unsigned int _numWindowsOpenAtLastSetUpThreading; + unsigned int _numWindowsOpenAtLastSetUpThreading; - osg::Timer_t _startTick; - osg::ref_ptr _frameStamp; + osg::observer_ptr _cameraWithFocus; + + osg::ref_ptr _eventVisitor; + + osg::ref_ptr _updateOperations; + osg::ref_ptr _updateVisitor; + + osg::ref_ptr _realizeOperation; - osg::observer_ptr _cameraWithFocus; - - osg::ref_ptr _eventVisitor; - - osg::ref_ptr _realizeOperation; - - osg::observer_ptr _currentContext; + osg::observer_ptr _currentContext; }; diff --git a/src/osg/GraphicsThread.cpp b/src/osg/GraphicsThread.cpp index 02dad51ae..b68475947 100644 --- a/src/osg/GraphicsThread.cpp +++ b/src/osg/GraphicsThread.cpp @@ -133,3 +133,18 @@ void RunOperations::operator () (osg::GraphicsContext* context) { context->runOperations(); } + + +///////////////////////////////////////////////////////////////////////////// +// +// EndOfDynamicDrawBlock +// +EndOfDynamicDrawBlock::EndOfDynamicDrawBlock(unsigned int numberOfBlocks): + BlockCount(numberOfBlocks) +{ +} + +void EndOfDynamicDrawBlock::completed(osg::State* /*state*/) +{ + BlockCount::completed(); +} diff --git a/src/osgViewer/CompositeViewer.cpp b/src/osgViewer/CompositeViewer.cpp index 37b143b9c..dabaf7633 100644 --- a/src/osgViewer/CompositeViewer.cpp +++ b/src/osgViewer/CompositeViewer.cpp @@ -61,6 +61,11 @@ void CompositeViewer::constructorInit() setEventQueue(new osgGA::EventQueue); _eventVisitor = new osgGA::EventVisitor; + _eventVisitor->setFrameStamp(_frameStamp.get()); + + _updateVisitor = new osgUtil::UpdateVisitor; + _updateVisitor->setFrameStamp(_frameStamp.get()); + } CompositeViewer::~CompositeViewer() @@ -106,6 +111,8 @@ void CompositeViewer::addView(osgViewer::View* view) _views.push_back(view); + view->setFrameStamp(_frameStamp.get()); + if (threadsWereRuinning) startThreading(); } @@ -177,6 +184,13 @@ void CompositeViewer::setStartTick(osg::Timer_t tick) { _startTick = tick; + for(Views::iterator vitr = _views.begin(); + vitr != _views.end(); + ++vitr) + { + (*vitr)->setStartTick(tick); + } + Contexts contexts; getContexts(contexts,false); @@ -970,16 +984,24 @@ void CompositeViewer::updateTraversal() Scenes scenes; getScenes(scenes); - for(Scenes::iterator sitr = scenes.begin(); sitr != scenes.end(); ++sitr) { - (*sitr)->setFrameStamp(_frameStamp.get()); - (*sitr)->updateTraversal(); + Scene* scene = *sitr; + if (scene->getSceneData()) + { + scene->getSceneData()->accept(*_updateVisitor); + } + + if (scene->getDatabasePager()) + { + // syncronize changes required by the DatabasePager thread to the scene graph + scene->getDatabasePager()->updateSceneGraph(_frameStamp->getReferenceTime()); + } + } - - + for(Views::iterator vitr = _views.begin(); vitr != _views.end(); ++vitr) @@ -987,23 +1009,22 @@ void CompositeViewer::updateTraversal() View* view = vitr->get(); Scene* scene = view->getScene(); - osgUtil::UpdateVisitor* uv = scene ? scene->getUpdateVisitor() : 0; - if (uv) + { // 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 = uv->getTraversalMode(); - uv->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE); + osg::NodeVisitor::TraversalMode tm = _updateVisitor->getTraversalMode(); + _updateVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE); - if (view->getCamera() && view->getCamera()->getUpdateCallback()) view->getCamera()->accept(*uv); + if (view->getCamera() && view->getCamera()->getUpdateCallback()) view->getCamera()->accept(*_updateVisitor); for(unsigned int i=0; igetNumSlaves(); ++i) { osg::Camera* camera = view->getSlave(i)._camera.get(); - if (camera && camera->getUpdateCallback()) camera->accept(*uv); + if (camera && camera->getUpdateCallback()) camera->accept(*_updateVisitor); } - uv->setTraversalMode(tm); + _updateVisitor->setTraversalMode(tm); } diff --git a/src/osgViewer/Renderer.cpp b/src/osgViewer/Renderer.cpp index 5169fdb04..839f86899 100644 --- a/src/osgViewer/Renderer.cpp +++ b/src/osgViewer/Renderer.cpp @@ -20,7 +20,6 @@ #include #include -#include #include @@ -232,12 +231,10 @@ void Renderer::updateSceneView(osgUtil::SceneView* sceneView) } osgViewer::View* view = dynamic_cast(_camera->getView()); - osgViewer::Viewer* viewer = dynamic_cast(view); - Scene* scene = view ? view->getScene() : 0; - osgDB::DatabasePager* databasePager = scene ? scene->getDatabasePager() : 0; + osgDB::DatabasePager* databasePager = view ? view->getDatabasePager() : 0; sceneView->getCullVisitor()->setDatabaseRequestHandler(databasePager); - sceneView->setFrameStamp(scene ? scene->getFrameStamp() : state->getFrameStamp()); + sceneView->setFrameStamp(view ? view->getFrameStamp() : state->getFrameStamp()); if (databasePager) databasePager->setCompileGLObjectsForContextID(state->getContextID(), true); @@ -246,7 +243,7 @@ void Renderer::updateSceneView(osgUtil::SceneView* sceneView) sceneView->setDisplaySettings(ds); - if (viewer) _startTick = viewer->getStartTick(); + if (view) _startTick = view->getStartTick(); } @@ -330,8 +327,7 @@ void Renderer::draw() OpenThreads::ScopedLock lock(_mutex[_currentDraw]); osgViewer::View* view = dynamic_cast(_camera->getView()); - Scene* scene = view ? view->getScene() : 0; - osgDB::DatabasePager* databasePager = scene ? scene->getDatabasePager() : 0; + osgDB::DatabasePager* databasePager = view ? view->getDatabasePager() : 0; // osg::notify(osg::NOTICE)<<"Drawing buffer "<<_currentDraw<(_camera->getView()); - Scene* scene = view ? view->getScene() : 0; - osgDB::DatabasePager* databasePager = scene ? scene->getDatabasePager() : 0; + osgDB::DatabasePager* databasePager = view ? view->getDatabasePager() : 0; osg::GraphicsContext* compileContext = osg::GraphicsContext::getCompileContext(sceneView->getState()->getContextID()); osg::GraphicsThread* compileThread = compileContext ? compileContext->getGraphicsThread() : 0; diff --git a/src/osgViewer/Scene.cpp b/src/osgViewer/Scene.cpp index 289bc78a4..40de79636 100644 --- a/src/osgViewer/Scene.cpp +++ b/src/osgViewer/Scene.cpp @@ -16,35 +16,35 @@ using namespace osgViewer; -Scene::Scene(): - _firstFrame(true) -{ - _frameStamp = new osg::FrameStamp; - _frameStamp->setFrameNumber(0); - _frameStamp->setReferenceTime(0); +typedef std::vector< osg::observer_ptr > SceneCache; +static OpenThreads::Mutex s_sceneCacheMutex; +static SceneCache s_sceneCache; - _updateVisitor = new osgUtil::UpdateVisitor; - _updateVisitor->setFrameStamp(_frameStamp.get()); - +Scene::Scene(): + osg::Referenced(true) +{ setDatabasePager(osgDB::DatabasePager::create()); + + OpenThreads::ScopedLock lock(s_sceneCacheMutex); + s_sceneCache.push_back(this); } Scene::~Scene() { + OpenThreads::ScopedLock lock(s_sceneCacheMutex); + for(SceneCache::iterator itr = s_sceneCache.begin(); + itr != s_sceneCache.end(); + ++itr) + { + Scene* scene = itr->get(); + if (scene==this) + { + s_sceneCache.erase(itr); + break; + } + } } -void Scene::setFrameStamp(osg::FrameStamp* frameStamp) -{ - _frameStamp = frameStamp; - _updateVisitor->setFrameStamp(_frameStamp.get()); -} - -void Scene::init() -{ - osg::notify(osg::NOTICE)<<"Scene::init() not implementated yet."<getReferenceTime(); - - _frameStamp->setReferenceTime(osg::Timer::instance()->time_s()); - _frameStamp->setFrameNumber(_frameStamp->getFrameNumber()+1); - - // osg::notify(osg::NOTICE)<<"Frame rate = "<<1.0/(_frameStamp->getReferenceTime()-previousTime)<setTraversalNumber(_frameStamp->getFrameNumber()); - - if (!getSceneData()) return; - - getSceneData()->accept(*_updateVisitor); - - if (_databasePager.valid()) - { - // syncronize changes required by the DatabasePager thread to the scene graph - _databasePager->updateSceneGraph(_frameStamp->getReferenceTime()); + OpenThreads::ScopedLock lock(s_sceneCacheMutex); + for(SceneCache::iterator itr = s_sceneCache.begin(); + itr != s_sceneCache.end(); + ++itr) + { + Scene* scene = itr->get(); + if (scene && scene->getSceneData()==node) return scene; } + return 0; } - - - diff --git a/src/osgViewer/View.cpp b/src/osgViewer/View.cpp index 83197a6f7..9a680eddd 100644 --- a/src/osgViewer/View.cpp +++ b/src/osgViewer/View.cpp @@ -17,6 +17,7 @@ #include +#include #include using namespace osgViewer; @@ -125,6 +126,15 @@ View::View(): { // osg::notify(osg::NOTICE)<<"Constructing osgViewer::View"<setFrameNumber(0); + _frameStamp->setReferenceTime(0); + _frameStamp->setSimulationTime(0); + + _scene = new Scene; + // make sure View is safe to reference multi-threaded. setThreadSafeRefUnref(true); @@ -141,6 +151,12 @@ View::View(const osgViewer::View& view, const osg::CopyOp& copyop): _fusionDistanceMode(view._fusionDistanceMode), _fusionDistanceValue(view._fusionDistanceValue) { + _scene = new Scene; + + // need to attach a Renderer to the maaster camera which has been default constructed + getCamera()->setRenderer(createRenderer(getCamera())); + + setEventQueue(new osgGA::EventQueue); } View::~View() @@ -148,6 +164,7 @@ View::~View() // osg::notify(osg::NOTICE)<<"Destructing osgViewer::View"<setSceneData(node); + if (_scene->getSceneData()==node) return; + + Scene* scene = Scene::getScene(node); + + if (scene) + { + osg::notify(osg::INFO)<<"View::setSceneData() Sharing scene "<referenceCount()!=1) + { + // we are not the only reference to the Scene so we cannot reuse it. + _scene = new Scene; + osg::notify(osg::INFO)<<"View::setSceneData() Allocating new scene"<<_scene.get()<setSceneData(node); + } + + if (getSceneData()) + { + // now make sure the scene graph is set up with the correct DataVariance to protect the dyamic elements of + // the scene graph from being run in parallel. + osgUtil::Optimizer::StaticObjectDetectionVisitor sodv; + getSceneData()->accept(sodv); + } computeActiveCoordinateSystemNodePath(); assignSceneDataToCameras(); } +osgDB::DatabasePager* View::getDatabasePager() +{ + return _scene.valid() ? _scene->getDatabasePager() : 0; +} + +const osgDB::DatabasePager* View::getDatabasePager() const +{ + return _scene.valid() ? _scene->getDatabasePager() : 0; +} + + void View::setCameraManipulator(osgGA::MatrixManipulator* manipulator) { _cameraManipulator = manipulator; @@ -829,67 +892,3 @@ bool View::computeIntersections(float x,float y, osg::NodePath& nodePath, osgUti return false; } } - - -///////////////////////////////////////////////////////////////////////////// -// -// EndOfDynamicDrawBlock -// -EndOfDynamicDrawBlock::EndOfDynamicDrawBlock(unsigned int numberOfBlocks): - _numberOfBlocks(numberOfBlocks), - _blockCount(0) -{ -} - -void EndOfDynamicDrawBlock::completed(osg::State* /*state*/) -{ - OpenThreads::ScopedLock mutlock(_mut); - if (_blockCount>0) - { - --_blockCount; - - if (_blockCount==0) - { - // osg::notify(osg::NOTICE)<<"Released"< mutlock(_mut); - if (_blockCount) - _cond.wait(&_mut); -} - -void EndOfDynamicDrawBlock::release() -{ - OpenThreads::ScopedLock mutlock(_mut); - if (_blockCount) - { - _blockCount = 0; - _cond.broadcast(); - } -} - -void EndOfDynamicDrawBlock::reset() -{ - OpenThreads::ScopedLock mutlock(_mut); - if (_numberOfBlocks!=_blockCount) - { - if (_numberOfBlocks==0) _cond.broadcast(); - _blockCount = _numberOfBlocks; - } -} - -void EndOfDynamicDrawBlock::setNumOfBlocks(unsigned int blockCount) -{ - _numberOfBlocks = blockCount; -} - -EndOfDynamicDrawBlock::~EndOfDynamicDrawBlock() -{ - _blockCount = 0; - release(); -} diff --git a/src/osgViewer/Viewer.cpp b/src/osgViewer/Viewer.cpp index 793c6f305..2ec9f6ec9 100644 --- a/src/osgViewer/Viewer.cpp +++ b/src/osgViewer/Viewer.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -86,16 +85,14 @@ void Viewer::constructorInit() _useMainThreadForRenderingTraversal = true; _endBarrierPosition = AfterSwapBuffers; _numWindowsOpenAtLastSetUpThreading = 0; - _startTick = 0; - - _frameStamp = new osg::FrameStamp; - _frameStamp->setFrameNumber(0); - _frameStamp->setReferenceTime(0); - _frameStamp->setSimulationTime(0); _eventVisitor = new osgGA::EventVisitor; _eventVisitor->setActionAdapter(this); + _eventVisitor->setFrameStamp(_frameStamp.get()); + _updateVisitor = new osgUtil::UpdateVisitor; + _updateVisitor->setFrameStamp(_frameStamp.get()); + setStats(new osg::Stats("Viewer")); } @@ -205,7 +202,7 @@ int Viewer::run() void Viewer::setStartTick(osg::Timer_t tick) { - _startTick = tick; + View::setStartTick(tick); Contexts contexts; getContexts(contexts,false); @@ -239,23 +236,9 @@ void Viewer::setReferenceTime(double time) void Viewer::setSceneData(osg::Node* node) { - _scene = new osgViewer::Scene; - _scene->setSceneData(node); - _scene->setFrameStamp(_frameStamp.get()); - - if (getSceneData()) - { - // now make sure the scene graph is set up with the correct DataVariance to protect the dyamic elements of - // the scene graph from being run in parallel. - osgUtil::Optimizer::StaticObjectDetectionVisitor sodv; - getSceneData()->accept(sodv); - } - - computeActiveCoordinateSystemNodePath(); - setReferenceTime(0.0); - - assignSceneDataToCameras(); + + View::setSceneData(node); } GraphicsWindowEmbedded* Viewer::setUpViewerAsEmbeddedInWindow(int x, int y, int width, int height) @@ -543,7 +526,7 @@ void Viewer::startThreading() { _startRenderingBarrier = 0; _endRenderingDispatchBarrier = 0; - _endDynamicDrawBlock = new EndOfDynamicDrawBlock(numViewerDoubleBufferedRenderingOperation); + _endDynamicDrawBlock = new osg::EndOfDynamicDrawBlock(numViewerDoubleBufferedRenderingOperation); if (!osg::Referenced::getDeleteHandler()) osg::Referenced::setDeleteHandler(new osg::DeleteHandler(2)); else osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(2); @@ -1349,26 +1332,32 @@ void Viewer::updateTraversal() double beginUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick()); - // do the update traversal of the scene. - if (_scene.valid()) _scene->updateTraversal(); + if (getSceneData()) + { + getSceneData()->accept(*_updateVisitor); + } + + if (_scene->getDatabasePager()) + { + // syncronize changes required by the DatabasePager thread to the scene graph + _scene->getDatabasePager()->updateSceneGraph(_frameStamp->getReferenceTime()); + } - osgUtil::UpdateVisitor* uv = _scene.valid() ? _scene->getUpdateVisitor() : 0; - if (uv) { // 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 = uv->getTraversalMode(); - uv->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE); + osg::NodeVisitor::TraversalMode tm = _updateVisitor->getTraversalMode(); + _updateVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE); - if (_camera.valid() && _camera->getUpdateCallback()) _camera->accept(*uv); + if (_camera.valid() && _camera->getUpdateCallback()) _camera->accept(*_updateVisitor); for(unsigned int i=0; igetUpdateCallback()) camera->accept(*uv); + if (camera && camera->getUpdateCallback()) camera->accept(*_updateVisitor); } - uv->setTraversalMode(tm); + _updateVisitor->setTraversalMode(tm); } if (_cameraManipulator.valid())