]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/model/ModelRegistry.cxx
Build boundingvolumes in the model loading phase.
[simgear.git] / simgear / scene / model / ModelRegistry.cxx
index d20ce3ed61b302314559877dbff385cc1af83c56..7c2afff648f3e10ab7aabf85770f3d22a02cf367 100644 (file)
@@ -50,6 +50,8 @@
 #include <simgear/props/props_io.hxx>
 #include <simgear/props/condition.hxx>
 
+#include "BoundingVolumeBuildVisitor.hxx"
+
 using namespace std;
 using namespace osg;
 using namespace osgUtil;
@@ -280,39 +282,6 @@ public:
   }
 };
 
-// Work around an OSG bug - the file loaders don't use the file path
-// in options while the file is being loaded.
-
-struct OptionsPusher {
-    FilePathList localPathList;
-    bool validOptions;
-    OptionsPusher(const ReaderWriter::Options* options):
-        validOptions(false)
-    {
-        if (!options)
-            return;
-        Registry* registry = Registry::instance();
-        localPathList = registry->getDataFilePathList();
-        const FilePathList& regPathList = registry->getDataFilePathList();
-        const FilePathList& optionsPathList = options->getDatabasePathList();
-        for (FilePathList::const_iterator iter = optionsPathList.begin();
-             iter != optionsPathList.end();
-             ++iter) {
-            if (find(regPathList.begin(), regPathList.end(), *iter)
-                == regPathList.end())
-                localPathList.push_back(*iter);
-        }
-        // Save the current Registry path list and install the augmented one.
-        localPathList.swap(registry->getDataFilePathList());
-        validOptions = true;
-    }
-    ~OptionsPusher()
-    {
-        // Restore the old path list
-        if (validOptions)
-            localPathList.swap(Registry::instance()->getDataFilePathList());
-    }
-};
 } // namespace
 
 Node* DefaultProcessPolicy::process(Node* node, const string& filename,
@@ -332,10 +301,9 @@ ModelRegistry::readImage(const string& fileName,
         = imageCallbackMap.find(getFileExtension(fileName));
     // XXX Workaround for OSG plugin bug
     {
-        OptionsPusher pusher(opt);
         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 << "\"");
@@ -345,6 +313,11 @@ ModelRegistry::readImage(const string& fileName,
         Registry* registry = Registry::instance();
         ReaderWriter::ReadResult res;
         res = registry->readImageImplementation(absFileName, opt);
+        if (!res.success()) {
+          SG_LOG(SG_IO, SG_WARN, "Image loading failed:" << res.message());
+          return res;
+        }
+        
         if (res.loadedFromCache())
             SG_LOG(SG_IO, SG_INFO, "Returning cached image \""
                    << res.getImage()->getFileName() << "\"");
@@ -455,7 +428,8 @@ string OSGSubstitutePolicy::substitute(const string& name,
 }
 
 ModelRegistry::ModelRegistry() :
-    _defaultCallback(new DefaultCallback(""))
+    _defaultCallback(new DefaultCallback("")),
+    _nestingLevel(0)
 {
 }
 
@@ -478,16 +452,29 @@ ModelRegistry::readNode(const string& fileName,
                         const ReaderWriter::Options* opt)
 {
     ScopedLock<ReentrantMutex> lock(readerMutex);
+    ++_nestingLevel;
+
     // XXX Workaround for OSG plugin bug.
-    OptionsPusher pusher(opt);
     Registry* registry = Registry::instance();
     ReaderWriter::ReadResult res;
-    Node* cached = 0;
     CallbackMap::iterator iter
         = nodeCallbackMap.find(getFileExtension(fileName));
+    ReaderWriter::ReadResult result;
     if (iter != nodeCallbackMap.end() && iter->second.valid())
-        return iter->second->readNode(fileName, opt);
-    return _defaultCallback->readNode(fileName, opt);
+        result = iter->second->readNode(fileName, opt);
+    else
+        result = _defaultCallback->readNode(fileName, opt);
+
+    if (0 == --_nestingLevel) {
+        SG_LOG(SG_IO, SG_INFO, "Building boundingvolume tree for \""
+               << fileName << "\".");
+        BoundingVolumeBuildVisitor bvBuilder;
+        result.getNode()->accept(bvBuilder);
+    } else {
+        SG_LOG(SG_IO, SG_INFO, "Defering boundingvolume tree built for \""
+               << fileName << "\" to parent.");
+    }
+    return result;
 }
 
 class SGReadCallbackInstaller {
@@ -524,13 +511,14 @@ struct ACOptimizePolicy : public OptimizeModelPolicy {
     {
         ref_ptr<Node> optimized
             = OptimizeModelPolicy::optimize(node, fileName, opt);
+        Group* group = dynamic_cast<Group*>(optimized.get());
         MatrixTransform* transform
             = dynamic_cast<MatrixTransform*>(optimized.get());
-        if (transform && transform->getMatrix().isIdentity()
-            && transform->getName().empty()
-            && transform->getNumChildren() == 1) {
-            optimized = static_cast<Node*>(transform->getChild(0));
-            Group* group = dynamic_cast<Group*>(optimized.get());
+        if (((transform && transform->getMatrix().isIdentity()) || group)
+            && group->getName().empty()
+            && group->getNumChildren() == 1) {
+            optimized = static_cast<Node*>(group->getChild(0));
+            group = dynamic_cast<Group*>(optimized.get());
             if (group && group->getName().empty()
                 && group->getNumChildren() == 1)
                 optimized = static_cast<Node*>(group->getChild(0));