diff --git a/projects/VC7.1/SimGear.vcproj b/projects/VC7.1/SimGear.vcproj
index 69799c1e..596e6476 100755
--- a/projects/VC7.1/SimGear.vcproj
+++ b/projects/VC7.1/SimGear.vcproj
@@ -386,6 +386,12 @@
+
+
+
+
+
+#include
+
+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
index 00000000..9b14d6e8
--- /dev/null
+++ b/simgear/misc/PathOptions.hxx
@@ -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
+#include
+
+namespace simgear
+{
+osgDB::ReaderWriter::Options* makeOptionsFromPath(const SGPath&);
+}
+#endif
diff --git a/simgear/scene/material/mat.cxx b/simgear/scene/material/mat.cxx
index fdccd511..94da1b5c 100644
--- a/simgear/scene/material/mat.cxx
+++ b/simgear/scene/material/mat.cxx
@@ -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);
diff --git a/simgear/scene/model/ModelRegistry.cxx b/simgear/scene/model/ModelRegistry.cxx
index ab9e03ac..b2dfa1b6 100644
--- a/simgear/scene/model/ModelRegistry.cxx
+++ b/simgear/scene/model/ModelRegistry.cxx
@@ -18,6 +18,8 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "ModelRegistry.hxx"
+#include
+
#include
#include
#include
@@ -202,11 +204,12 @@ ReaderWriter::ReadResult
ModelRegistry::readImage(const string& fileName,
const ReaderWriter::Options* opt)
{
+ OpenThreads::ScopedLock 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 lock(readerMutex);
Registry* registry = Registry::instance();
ReaderWriter::ReadResult res;
Node* cached = 0;
@@ -437,18 +441,3 @@ namespace
{
ModelRegistryCallbackProxy 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);
-}
diff --git a/simgear/scene/model/ModelRegistry.hxx b/simgear/scene/model/ModelRegistry.hxx
index 2c010297..e1429268 100644
--- a/simgear/scene/model/ModelRegistry.hxx
+++ b/simgear/scene/model/ModelRegistry.hxx
@@ -19,6 +19,8 @@
#ifndef _SG_MODELREGISTRY_HXX
#define _SG_MODELREGISTRY_HXX 1
+#include
+
#include
#include
#include
@@ -225,6 +227,9 @@ protected:
CallbackMap imageCallbackMap;
CallbackMap nodeCallbackMap;
osg::ref_ptr _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
diff --git a/simgear/scene/model/animation.cxx b/simgear/scene/model/animation.cxx
index ba4bb75e..d32308c2 100644
--- a/simgear/scene/model/animation.cxx
+++ b/simgear/scene/model/animation.cxx
@@ -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") {
diff --git a/simgear/scene/model/animation.hxx b/simgear/scene/model/animation.hxx
index 4f3007df..61901e9b 100644
--- a/simgear/scene/model/animation.hxx
+++ b/simgear/scene/model/animation.hxx
@@ -28,6 +28,7 @@
#include
#include
+#include
#include
#include
@@ -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;
diff --git a/simgear/scene/model/model.cxx b/simgear/scene/model/model.cxx
index 4c49fd35..76d5a90f 100644
--- a/simgear/scene/model/model.cxx
+++ b/simgear/scene/model/model.cxx
@@ -37,9 +37,15 @@
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 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 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 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",
diff --git a/simgear/scene/model/model.hxx b/simgear/scene/model/model.hxx
index 29306f05..2f2b01af 100644
--- a/simgear/scene/model/model.hxx
+++ b/simgear/scene/model/model.hxx
@@ -20,6 +20,7 @@ SG_USING_STD(set);
#include
#include
+#include
#include
#include
@@ -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
diff --git a/simgear/scene/model/shadanim.cxx b/simgear/scene/model/shadanim.cxx
index ec1403b1..f9b747e1 100644
--- a/simgear/scene/model/shadanim.cxx
+++ b/simgear/scene/model/shadanim.cxx
@@ -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 {
diff --git a/simgear/scene/sky/cloud.cxx b/simgear/scene/sky/cloud.cxx
index 5ff1b089..34361cd9 100644
--- a/simgear/scene/sky/cloud.cxx
+++ b/simgear/scene/sky/cloud.cxx
@@ -42,6 +42,7 @@
#include
#include
+#include
#include
#include
#include
@@ -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 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;
diff --git a/simgear/scene/sky/moon.cxx b/simgear/scene/sky/moon.cxx
index 464b5a0f..211d96ca 100644
--- a/simgear/scene/sky/moon.cxx
+++ b/simgear/scene/sky/moon.cxx
@@ -46,10 +46,13 @@
#include
#include
#include
+#include
#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 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);
diff --git a/simgear/scene/sky/oursun.cxx b/simgear/scene/sky/oursun.cxx
index e2b5a59d..8a2cd6bd 100644
--- a/simgear/scene/sky/oursun.cxx
+++ b/simgear/scene/sky/oursun.cxx
@@ -41,10 +41,13 @@
#include
#include
+#include
#include
#include
#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 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