1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 2 * 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 5 * (at your option) any later version. The full license is in LICENSE file 6 * included with this distribution, and on the openscenegraph.org website. 7 * 8 * This library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * OpenSceneGraph Public License for more details. 12 */ 13 14 #include <osgViewer/Scene> 15 #include <osgGA/EventVisitor> 16 17 using namespace osgViewer; 18 19 20 namespace osgViewer 21 { 22 23 24 struct SceneSingleton 25 { SceneSingletonosgViewer::SceneSingleton26 SceneSingleton() {} 27 addosgViewer::SceneSingleton28 inline void add(Scene* scene) 29 { 30 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 31 _cache.push_back(scene); 32 } 33 removeosgViewer::SceneSingleton34 inline void remove(Scene* scene) 35 { 36 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 37 for(SceneCache::iterator itr = _cache.begin(); 38 itr != _cache.end(); 39 ++itr) 40 { 41 if (scene==itr->get()) 42 { 43 _cache.erase(itr); 44 break; 45 } 46 } 47 } 48 getSceneosgViewer::SceneSingleton49 inline Scene* getScene(osg::Node* node) 50 { 51 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 52 for(SceneCache::iterator itr = _cache.begin(); 53 itr != _cache.end(); 54 ++itr) 55 { 56 Scene* scene = itr->get(); 57 if (scene && scene->getSceneData()==node) return scene; 58 } 59 return 0; 60 } 61 62 typedef std::vector< osg::observer_ptr<Scene> > SceneCache; 63 SceneCache _cache; 64 OpenThreads::Mutex _mutex; 65 }; 66 getSceneSingleton()67static SceneSingleton& getSceneSingleton() 68 { 69 static SceneSingleton s_sceneSingleton; 70 return s_sceneSingleton; 71 } 72 73 // Use a proxy to force the initialization of the SceneSingleton during static initialization 74 OSG_INIT_SINGLETON_PROXY(SceneSingletonProxy, getSceneSingleton()) 75 76 } 77 Scene()78Scene::Scene(): 79 osg::Referenced(true) 80 { 81 setDatabasePager(osgDB::DatabasePager::create()); 82 setImagePager(new osgDB::ImagePager); 83 getSceneSingleton().add(this); 84 } 85 ~Scene()86Scene::~Scene() 87 { 88 getSceneSingleton().remove(this); 89 } 90 setSceneData(osg::Node * node)91void Scene::setSceneData(osg::Node* node) 92 { 93 _sceneData = node; 94 } 95 getSceneData()96osg::Node* Scene::getSceneData() 97 { 98 return _sceneData.get(); 99 } 100 getSceneData() const101const osg::Node* Scene::getSceneData() const 102 { 103 return _sceneData.get(); 104 } 105 setDatabasePager(osgDB::DatabasePager * dp)106void Scene::setDatabasePager(osgDB::DatabasePager* dp) 107 { 108 _databasePager = dp; 109 } 110 setImagePager(osgDB::ImagePager * ip)111void Scene::setImagePager(osgDB::ImagePager* ip) 112 { 113 _imagePager = ip; 114 } 115 updateSceneGraph(osg::NodeVisitor & updateVisitor)116void Scene::updateSceneGraph(osg::NodeVisitor& updateVisitor) 117 { 118 if (!_sceneData) return; 119 120 if (getDatabasePager()) 121 { 122 // synchronize changes required by the DatabasePager thread to the scene graph 123 getDatabasePager()->updateSceneGraph((*updateVisitor.getFrameStamp())); 124 } 125 126 if (getImagePager()) 127 { 128 // synchronize changes required by the DatabasePager thread to the scene graph 129 getImagePager()->updateSceneGraph(*(updateVisitor.getFrameStamp())); 130 } 131 132 if (getSceneData()) 133 { 134 updateVisitor.setImageRequestHandler(getImagePager()); 135 getSceneData()->accept(updateVisitor); 136 } 137 } 138 139 getScene(osg::Node * node)140Scene* Scene::getScene(osg::Node* node) 141 { 142 return getSceneSingleton().getScene(node); 143 return 0; 144 } 145 getOrCreateScene(osg::Node * node)146Scene* Scene::getOrCreateScene(osg::Node* node) 147 { 148 if (!node) return 0; 149 150 osgViewer::Scene* scene = getScene(node); 151 if (!scene) 152 { 153 scene = new Scene; 154 scene->setSceneData(node); 155 } 156 157 return scene; 158 } 159