]> git.mxchange.org Git - simgear.git/commitdiff
Don't modify OSG Registry with file path
authortimoore <timoore>
Tue, 4 Dec 2007 22:38:40 +0000 (22:38 +0000)
committertimoore <timoore>
Tue, 4 Dec 2007 22:38:40 +0000 (22:38 +0000)
To set a path when loading model files, use an osg ReaderWriter::Options object.

Put locks in ModelRegistry::readNode and ModelRegistry::readImage to avoid
conflicts when files are loaded from both the pager and the main thread.

15 files changed:
projects/VC7.1/SimGear.vcproj
simgear/misc/Makefile.am
simgear/misc/PathOptions.cxx [new file with mode: 0644]
simgear/misc/PathOptions.hxx [new file with mode: 0644]
simgear/scene/material/mat.cxx
simgear/scene/model/ModelRegistry.cxx
simgear/scene/model/ModelRegistry.hxx
simgear/scene/model/animation.cxx
simgear/scene/model/animation.hxx
simgear/scene/model/model.cxx
simgear/scene/model/model.hxx
simgear/scene/model/shadanim.cxx
simgear/scene/sky/cloud.cxx
simgear/scene/sky/moon.cxx
simgear/scene/sky/oursun.cxx

index 69799c1e0fff07c271c7f19c57bd8fe9bbcc07e9..596e6476afdbbef73159a59e1cd65aeb71aef48b 100755 (executable)
                        <File
                                RelativePath="..\..\simgear\misc\zfstream.hxx">
                        </File>
+                       <File
+                               RelativePath="..\..\simgear\misc\PathOptions.cxx">
+                       </File>
+                       <File
+                               RelativePath="..\..\simgear\misc\PathOptions.hxx">
+                       </File>
                </Filter>
                <Filter
                        Name="Lib_sgroute"
index 980e032164ce1b5310b9df485e8659fe79ec0d14..db9181ba88d648d93e96af14a1207c0a42505160 100644 (file)
@@ -11,7 +11,8 @@ include_HEADERS = \
        texcoord.hxx \
        zfstream.hxx \
        interpolator.hxx \
-       stdint.hxx
+       stdint.hxx \
+       PathOptions.hxx
 
 libsgmisc_a_SOURCES = \
        sg_path.cxx \
@@ -20,7 +21,8 @@ libsgmisc_a_SOURCES = \
        tabbed_values.cxx \
        texcoord.cxx \
        zfstream.cxx \
-       interpolator.cxx
+       interpolator.cxx \
+       PathOptions.cxx
 
 noinst_PROGRAMS = tabbed_value_test swap_test
 
diff --git a/simgear/misc/PathOptions.cxx b/simgear/misc/PathOptions.cxx
new file mode 100644 (file)
index 0000000..a74ae94
--- /dev/null
@@ -0,0 +1,33 @@
+// PathOptions.cxx -- make an osgDB Options object from a path
+// Copyright (C) 2007  Tim Moore timoore@redhat.com
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+// $Id$
+
+#include <osgDB/Registry>
+
+#include <PathOptions.hxx>
+
+using namespace simgear;
+
+osgDB::ReaderWriter::Options* simgear::makeOptionsFromPath(const SGPath& path)
+{
+    using namespace osgDB;
+    ReaderWriter::Options *options
+        = new ReaderWriter::Options(*(Registry::instance()->getOptions()));
+    options->setDatabasePath(path.str());
+    return options;
+}
diff --git a/simgear/misc/PathOptions.hxx b/simgear/misc/PathOptions.hxx
new file mode 100644 (file)
index 0000000..9b14d6e
--- /dev/null
@@ -0,0 +1,30 @@
+// PathOptions.hxx -- make an osgDB Options object from a path
+// Copyright (C) 2007  Tim Moore timoore@redhat.com
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+// $Id$
+
+#ifndef PATHOPTIONSHXX
+#define PATHOPTIONSHXX 1
+
+#include <osgDB/ReaderWriter>
+#include <simgear/misc/sg_path.hxx>
+
+namespace simgear
+{
+osgDB::ReaderWriter::Options* makeOptionsFromPath(const SGPath&);
+}
+#endif
index fdccd51175eac48b8adeffd56b2c9217f9792e23..94da1b5cdb1d013dd02fae073bd91c6871b798c8 100644 (file)
@@ -324,7 +324,7 @@ void SGMaterial::assignTexture( osg::StateSet *state, const std::string &fname,
    _tex_cache_iter = _tex_cache.find(fname);
    if (_tex_cache_iter == _tex_cache.end())
    {
-      osg::Texture2D* texture = SGLoadTexture2D(fname, _wrapu, _wrapv,
+     osg::Texture2D* texture = SGLoadTexture2D(fname, 0, _wrapu, _wrapv,
                                                 mipmap ? -1 : 0);
          texture->setMaxAnisotropy( SGGetTextureFilter());
       state->setTextureAttributeAndModes(0, texture);
index ab9e03ac80e4da0f39669688aacbfd6f3ccd7ff2..b2dfa1b611d978d3e6e28967fa40a31c1fceba83 100644 (file)
@@ -18,6 +18,8 @@
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include "ModelRegistry.hxx"
 
+#include <OpenThreads/ScopedLock>
+
 #include <osg/observer_ptr>
 #include <osg/ref_ptr>
 #include <osg/Group>
@@ -202,11 +204,12 @@ ReaderWriter::ReadResult
 ModelRegistry::readImage(const string& fileName,
                          const ReaderWriter::Options* opt)
 {
+    OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(readerMutex);
     CallbackMap::iterator iter
         = imageCallbackMap.find(getFileExtension(fileName));
     if (iter != imageCallbackMap.end() && iter->second.valid())
         return iter->second->readImage(fileName, opt);
-    string absFileName = findDataFile(fileName);
+    string absFileName = findDataFile(fileName, opt);
     if (!fileExists(absFileName)) {
         SG_LOG(SG_IO, SG_ALERT, "Cannot find image file \""
                << fileName << "\"");
@@ -309,7 +312,7 @@ osg::Node* DefaultCopyPolicy::copy(osg::Node* model, const string& fileName,
     res->addObserver(databaseReference);
 
     // Update liveries
-    SGTextureUpdateVisitor liveryUpdate(getDataFilePathList());
+    SGTextureUpdateVisitor liveryUpdate(opt->getDatabasePathList());
     res->accept(liveryUpdate);
     return res;
 }
@@ -319,7 +322,7 @@ string OSGSubstitutePolicy::substitute(const string& name,
 {
     string fileSansExtension = getNameLessExtension(name);
     string osgFileName = fileSansExtension + ".osg";
-    string absFileName = findDataFile(osgFileName);
+    string absFileName = findDataFile(osgFileName, opt);
     return absFileName;
 }
 
@@ -356,6 +359,7 @@ ReaderWriter::ReadResult
 ModelRegistry::readNode(const string& fileName,
                         const ReaderWriter::Options* opt)
 {
+    OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(readerMutex);
     Registry* registry = Registry::instance();
     ReaderWriter::ReadResult res;
     Node* cached = 0;
@@ -437,18 +441,3 @@ namespace
 {
 ModelRegistryCallbackProxy<ACCallback> g_acRegister("ac");
 }   
-
-
-ReaderWriter::ReadResult
-OSGFileCallback::readImage(const string& fileName,
-                           const ReaderWriter::Options* opt)
-{
-    return Registry::instance()->readImageImplementation(fileName, opt);
-}
-
-ReaderWriter::ReadResult
-OSGFileCallback::readNode(const string& fileName,
-                          const ReaderWriter::Options* opt)
-{
-    return Registry::instance()->readNodeImplementation(fileName, opt);
-}
index 2c0102976c2815096a09a880ceecd99bc4137e39..e14292680f9d4808c58eaf9db4b8a183874d5994 100644 (file)
@@ -19,6 +19,8 @@
 #ifndef _SG_MODELREGISTRY_HXX
 #define _SG_MODELREGISTRY_HXX 1
 
+#include <OpenThreads/ReentrantMutex>
+
 #include <osg/ref_ptr>
 #include <osg/Node>
 #include <osgDB/FileUtils>
@@ -225,6 +227,9 @@ protected:
     CallbackMap imageCallbackMap;
     CallbackMap nodeCallbackMap;
     osg::ref_ptr<DefaultCallback> _defaultCallback;
+    // Protect against simultaneous calls from main thread (MP models)
+    // and pager thread.
+    OpenThreads::ReentrantMutex readerMutex;
 };
 
 // Callback that only loads the file without any caching or
@@ -245,19 +250,5 @@ public:
             ->addNodeCallbackForExtension(extension, new T(extension));
     }
 };
-
-// Callback for file extensions that load files using the default OSG
-// implementation.
-
-class OSGFileCallback : public osgDB::Registry::ReadFileCallback {
-public:
-    virtual osgDB::ReaderWriter::ReadResult
-    readImage(const std::string& fileName,
-              const osgDB::ReaderWriter::Options* opt);
-    virtual osgDB::ReaderWriter::ReadResult
-    readNode(const std::string& fileName,
-             const osgDB::ReaderWriter::Options* opt);
-};
-
 }
 #endif // _SG_MODELREGISTRY_HXX
index ba4bb75e27fab5e266f2895ecb91e4d5bba46d8e..d32308c2c13f53ac4832696e266cfd6490fc52e6 100644 (file)
@@ -501,7 +501,8 @@ SGAnimation::~SGAnimation()
 
 bool
 SGAnimation::animate(osg::Node* node, const SGPropertyNode* configNode,
-                     SGPropertyNode* modelRoot)
+                     SGPropertyNode* modelRoot,
+                     const osgDB::ReaderWriter::Options* options)
 {
   std::string type = configNode->getStringValue("type", "none");
   if (type == "alpha-test") {
@@ -541,7 +542,7 @@ SGAnimation::animate(osg::Node* node, const SGPropertyNode* configNode,
     SGSelectAnimation animInst(configNode, modelRoot);
     animInst.apply(node);
   } else if (type == "shader") {
-    SGShaderAnimation animInst(configNode, modelRoot);
+    SGShaderAnimation animInst(configNode, modelRoot, options);
     animInst.apply(node);
   } else if (type == "textranslate" || type == "texrotate" ||
              type == "texmultiple") {
index 4f3007df65470fa385053d12cba4f550ac52abd8..61901e9bcfc0b5496c5358f6968861b1f546656b 100644 (file)
@@ -28,6 +28,7 @@
 #include <osg/Texture2D>
 #include <osg/TexMat>
 
+#include <osgDB/ReaderWriter>
 #include <simgear/props/props.hxx>
 #include <simgear/misc/sg_path.hxx>
 
@@ -74,7 +75,8 @@ public:
   virtual ~SGAnimation();
 
   static bool animate(osg::Node* node, const SGPropertyNode* configNode,
-                      SGPropertyNode* modelRoot);
+                      SGPropertyNode* modelRoot,
+                      const osgDB::ReaderWriter::Options* options);
 
 protected:
   void apply(osg::Node* node);
@@ -352,7 +354,8 @@ private:
 class SGShaderAnimation : public SGAnimation {
 public:
   SGShaderAnimation(const SGPropertyNode* configNode,
-                    SGPropertyNode* modelRoot);
+                    SGPropertyNode* modelRoot,
+                    const osgDB::ReaderWriter::Options* options);
   virtual osg::Group* createAnimationGroup(osg::Group& parent);
 private:
   class UpdateCallback;
index 4c49fd359ef81d4003256e21fa0a3d336461524b..76d5a90fdf61553a806725950f56e2c945044ca5 100644 (file)
 SG_USING_STD(vector);
 
 osg::Texture2D*
-SGLoadTexture2D(const std::string& path, bool wrapu, bool wrapv, int)
+SGLoadTexture2D(const std::string& path,
+                const osgDB::ReaderWriter::Options* options,
+                bool wrapu, bool wrapv, int)
 {
-  osg::Image* image = osgDB::readImageFile(path);
+  osg::Image* image;
+  if (options)
+    image = osgDB::readImageFile(path, options);
+  else
+    image = osgDB::readImageFile(path);
   osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
   texture->setImage(image);
   texture->setDataVariance(osg::Object::STATIC);
@@ -148,25 +154,26 @@ sgLoad3DModel( const string &fg_root, const string &path,
     }
   }
 
-  osgDB::FilePathList pathList = osgDB::getDataFilePathList();
-  osgDB::Registry::instance()->initFilePathLists();
+  osg::ref_ptr<osgDB::ReaderWriter::Options> options
+      = new osgDB::ReaderWriter::Options(*osgDB::Registry::instance()
+                                         ->getOptions());
 
   // Assume that textures are in
   // the same location as the XML file.
   if (!model) {
-    if (texturepath.extension() != "")
+      if (texturepath.extension() != "")
           texturepath = texturepath.dir();
 
-    osgDB::Registry::instance()->getDataFilePathList().push_front(texturepath.str());
+      options->setDatabasePath(texturepath.str());
+      if (!externalTexturePath.str().empty())
+          options->getDatabasePathList().push_back(externalTexturePath.str());
 
-    model = osgDB::readNodeFile(modelpath.str());
-    if (model == 0)
-      throw sg_io_exception("Failed to load 3D model", 
-                            sg_location(modelpath.str()));
+      model = osgDB::readNodeFile(modelpath.str(), options.get());
+      if (model == 0)
+          throw sg_io_exception("Failed to load 3D model", 
+                                sg_location(modelpath.str()));
   }
 
-  osgDB::Registry::instance()->getDataFilePathList().push_front(externalTexturePath.str());
-
   // Set up the alignment node
   osg::ref_ptr<osg::MatrixTransform> alignmainmodel = new osg::MatrixTransform;
   alignmainmodel->addChild(model.get());
@@ -251,10 +258,8 @@ sgLoad3DModel( const string &fg_root, const string &path,
   animation_nodes = props.getChildren("animation");
   for (unsigned i = 0; i < animation_nodes.size(); ++i)
     /// OSGFIXME: duh, why not only model?????
-    SGAnimation::animate(alignmainmodel.get(), animation_nodes[i], prop_root);
-
-  // restore old path list
-  osgDB::setDataFilePathList(pathList);
+    SGAnimation::animate(alignmainmodel.get(), animation_nodes[i], prop_root,
+                         options.get());
 
   if (props.hasChild("debug-outfile")) {
     std::string outputfile = props.getStringValue("debug-outfile",
index 29306f0501378a52714ef474303e010ff0c11927..2f2b01af058ecbb05f4e2e190543062d16dd209c 100644 (file)
@@ -20,6 +20,7 @@ SG_USING_STD(set);
 
 #include <osg/Node>
 #include <osg/Texture2D>
+#include <osgDB/ReaderWriter>
 
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/props/props.hxx>
@@ -82,14 +83,17 @@ sgMakeAnimation( osg::Node* model,
 
 
 osg::Texture2D*
-SGLoadTexture2D(const std::string& path, bool wrapu = true,
-                bool wrapv = true, int mipmaplevels = -1);
+SGLoadTexture2D(const std::string& path,
+                const osgDB::ReaderWriter::Options* options = 0,
+                bool wrapu = true, bool wrapv = true, int mipmaplevels = -1);
 
 inline osg::Texture2D*
-SGLoadTexture2D(const SGPath& path, bool wrapu = true, bool wrapv = true,
+SGLoadTexture2D(const SGPath& path,
+                const osgDB::ReaderWriter::Options* options = 0,
+                bool wrapu = true, bool wrapv = true,
                 int mipmaplevels = -1)
 {
-  return SGLoadTexture2D(path.str(), wrapu, wrapv, mipmaplevels);
+    return SGLoadTexture2D(path.str(), options, wrapu, wrapv, mipmaplevels);
 }
 
 #endif // __MODEL_HXX
index ec1403b178b6fc9498f0875ca6fd2db6b5b0cc6a..f9b747e1795483bd9ff0ce02d63901cb9e0216b7 100644 (file)
@@ -178,12 +178,14 @@ static void create_specular_highlights(osg::Node *node)
 
 
 SGShaderAnimation::SGShaderAnimation(const SGPropertyNode* configNode,
-                                     SGPropertyNode* modelRoot) :
+                                     SGPropertyNode* modelRoot,
+                                     const osgDB::ReaderWriter::Options*
+                                     options) :
   SGAnimation(configNode, modelRoot)
 {
   const SGPropertyNode* node = configNode->getChild("texture");
   if (node)
-    _effect_texture = SGLoadTexture2D(node->getStringValue());
+    _effect_texture = SGLoadTexture2D(node->getStringValue(), options);
 }
 
 namespace {
index 5ff1b0891ebdbbe671e60a6ee6f31e766783deba..34361cd9294435706f44ec745afc383405cec88b 100644 (file)
@@ -42,6 +42,7 @@
 #include <osg/TexMat>
 
 #include <simgear/math/sg_random.h>
+#include <simgear/misc/PathOptions.hxx>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/scene/model/model.hxx>
 #include <simgear/math/polar3d.hxx>
@@ -50,6 +51,7 @@
 #include "cloudfield.hxx"
 #include "cloud.hxx"
 
+using namespace simgear;
 // #if defined(__MINGW32__)
 // #define isnan(x) _isnan(x)
 // #endif
@@ -81,9 +83,10 @@ SGMakeState(const SGPath &path, const char* colorTexture,
 {
     osg::StateSet *stateSet = new osg::StateSet;
 
-    SGPath colorPath(path);
-    colorPath.append(colorTexture);
-    stateSet->setTextureAttribute(0, SGLoadTexture2D(colorPath));
+    osg::ref_ptr<osgDB::ReaderWriter::Options> options
+        = makeOptionsFromPath(path);
+    stateSet->setTextureAttribute(0, SGLoadTexture2D(colorTexture,
+                                                     options.get()));
     stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
 
     osg::TexEnv* texEnv = new osg::TexEnv;
index 464b5a0f4dcdaae80cad203d728ab98516bd2c9c..211d96ca3107a5b5d5f7ffd780a8d7ac8bb023c1 100644 (file)
 #include <simgear/constants.h>
 #include <simgear/screen/colors.hxx>
 #include <simgear/scene/model/model.hxx>
+#include <simgear/misc/PathOptions.hxx>
 
 #include "sphere.hxx"
 #include "moon.hxx"
 
+using namespace simgear;
+
 // Constructor
 SGMoon::SGMoon( void ) :
     prev_moon_angle(-1)
@@ -71,9 +74,10 @@ SGMoon::build( SGPath path, double moon_size ) {
     stateSet->setRenderBinDetails(-5, "RenderBin");
 
     // set up the orb state
-    path.append( "moon.rgba" );
+    osg::ref_ptr<osgDB::ReaderWriter::Options> options
+        = makeOptionsFromPath(path);
 
-    osg::Texture2D* texture = SGLoadTexture2D(path);
+    osg::Texture2D* texture = SGLoadTexture2D("moon.rgba", options.get());
     stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
     osg::TexEnv* texEnv = new osg::TexEnv;
     texEnv->setMode(osg::TexEnv::MODULATE);
index e2b5a59dbee60658305c05f0c27adad57c9076da..8a2cd6bd135bad11e166696cf881c9eb77104542 100644 (file)
 #include <osg/Texture2D>
 #include <osgDB/ReadFile>
 
+#include <simgear/misc/PathOptions.hxx>
 #include <simgear/screen/colors.hxx>
 #include <simgear/scene/model/model.hxx>
 #include "oursun.hxx"
 
+using namespace simgear;
+
 // Constructor
 SGSun::SGSun( void ) {
     prev_sun_angle = -9999.0;
@@ -63,8 +66,8 @@ SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node )
 
     env_node = property_tree_Node;
 
-    SGPath ihalopath = path, ohalopath = path;
-
+    osg::ref_ptr<osgDB::ReaderWriter::Options> options
+        = makeOptionsFromPath(path);
     // build the ssg scene graph sub tree for the sky and connected
     // into the provide scene graph branch
     sun_transform = new osg::MatrixTransform;
@@ -100,15 +103,13 @@ SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node )
     stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
     stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
 
-
     osg::Geode* geode = new osg::Geode;
     stateSet = geode->getOrCreateStateSet();
 
     stateSet->setRenderBinDetails(-6, "RenderBin");
 
     // set up the sun-state
-    path.append( "sun.rgba" );
-    osg::Texture2D* texture = SGLoadTexture2D(path);
+    osg::Texture2D* texture = SGLoadTexture2D("sun.rgba", options.get());
     stateSet->setTextureAttributeAndModes(0, texture);
 
     // Build scenegraph
@@ -139,14 +140,12 @@ SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node )
 
     sun_transform->addChild( geode );
 
-
     // set up the inner-halo state
     geode = new osg::Geode;
     stateSet = geode->getOrCreateStateSet();
     stateSet->setRenderBinDetails(-7, "RenderBin");
     
-    ihalopath.append( "inner_halo.rgba" );
-    texture = SGLoadTexture2D(ihalopath);
+    texture = SGLoadTexture2D("inner_halo.rgba", options.get());
     stateSet->setTextureAttributeAndModes(0, texture);
 
     // Build ssg structure
@@ -177,7 +176,6 @@ SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node )
     geode->addDrawable(geometry);
 
     sun_transform->addChild( geode );
-
     
     // set up the outer halo state
     
@@ -185,8 +183,7 @@ SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node )
     stateSet = geode->getOrCreateStateSet();
     stateSet->setRenderBinDetails(-8, "RenderBin");
 
-    ohalopath.append( "outer_halo.rgba" );
-    texture = SGLoadTexture2D(ohalopath);
+    texture = SGLoadTexture2D("outer_halo.rgba", options.get());
     stateSet->setTextureAttributeAndModes(0, texture);
 
     // Build ssg structure