From d23491646aed26f4b31bf01132479085fbcd866e Mon Sep 17 00:00:00 2001 From: James Turner Date: Thu, 29 Jul 2010 01:04:10 +0100 Subject: [PATCH] Use a custom 'findDataFile' method in key places, and hook this into a callback set on SGModelLib. --- simgear/scene/material/makeEffect.cxx | 2 +- simgear/scene/model/ModelRegistry.cxx | 4 +- simgear/scene/model/SGReaderWriterXML.cxx | 15 ++++--- simgear/scene/model/modellib.cxx | 52 +++++++++++++++++------ simgear/scene/model/modellib.hxx | 37 +++++++++------- 5 files changed, 71 insertions(+), 39 deletions(-) diff --git a/simgear/scene/material/makeEffect.cxx b/simgear/scene/material/makeEffect.cxx index dfb7fe97..02ac244f 100644 --- a/simgear/scene/material/makeEffect.cxx +++ b/simgear/scene/material/makeEffect.cxx @@ -128,7 +128,7 @@ Effect* makeEffect(const string& name, string effectFileName(name); effectFileName += ".eff"; string absFileName - = osgDB::findDataFile(effectFileName, options); + = SGModelLib::findDataFile(effectFileName, options); if (absFileName.empty()) { SG_LOG(SG_INPUT, SG_ALERT, "can't find \"" << effectFileName << "\""); return 0; diff --git a/simgear/scene/model/ModelRegistry.cxx b/simgear/scene/model/ModelRegistry.cxx index 2bf8c878..82f1a1c7 100644 --- a/simgear/scene/model/ModelRegistry.cxx +++ b/simgear/scene/model/ModelRegistry.cxx @@ -207,7 +207,7 @@ ModelRegistry::readImage(const string& fileName, { if (iter != imageCallbackMap.end() && iter->second.valid()) return iter->second->readImage(fileName, opt); - string absFileName = findDataFile(fileName, opt); + string absFileName = SGModelLib::findDataFile(fileName, opt); if (!fileExists(absFileName)) { SG_LOG(SG_IO, SG_ALERT, "Cannot find image file \"" << fileName << "\""); @@ -297,7 +297,7 @@ string OSGSubstitutePolicy::substitute(const string& name, { string fileSansExtension = getNameLessExtension(name); string osgFileName = fileSansExtension + ".osg"; - string absFileName = findDataFile(osgFileName, opt); + string absFileName = SGModelLib::findDataFile(osgFileName, opt); return absFileName; } diff --git a/simgear/scene/model/SGReaderWriterXML.cxx b/simgear/scene/model/SGReaderWriterXML.cxx index 3efc0ded..7eed6dac 100644 --- a/simgear/scene/model/SGReaderWriterXML.cxx +++ b/simgear/scene/model/SGReaderWriterXML.cxx @@ -202,21 +202,21 @@ sgLoad3DModel_internal(const string &path, SGSharedPtr prop_root; osg::Node *(*load_panel)(SGPropertyNode *)=0; osg::ref_ptr data; - + SGPath modelpath; + if (xmlOptions) { prop_root = xmlOptions->getPropRoot(); load_panel = xmlOptions->getLoadPanel(); data = xmlOptions->getModelData(); } + + + modelpath = SGModelLib::findDataFile(path); + if (!prop_root) { prop_root = new SGPropertyNode; } - osgDB::FilePathList filePathList; - filePathList = osgDB::Registry::instance()->getDataFilePathList(); - filePathList.push_front(std::string()); - - SGPath modelpath = osgDB::findFileInPath(path, filePathList); if (modelpath.str().empty()) { SG_LOG(SG_INPUT, SG_ALERT, "Failed to load file: \"" << path << "\""); return 0; @@ -262,7 +262,7 @@ sgLoad3DModel_internal(const string &path, = new SGReaderWriterXMLOptions(*options_); options->setPropRoot(prop_root); options->setLoadPanel(load_panel); - + // Assume that textures are in // the same location as the XML file. if (!model) { @@ -345,6 +345,7 @@ sgLoad3DModel_internal(const string &path, options = new SGReaderWriterXMLOptions(*options_); options->setPropRoot(prop_root); options->setLoadPanel(load_panel); + try { submodel = sgLoad3DModel_internal(submodelpath.str(), options.get(), sub_props->getNode("overlay")); diff --git a/simgear/scene/model/modellib.cxx b/simgear/scene/model/modellib.cxx index 4b457f5e..b965ff3e 100644 --- a/simgear/scene/model/modellib.cxx +++ b/simgear/scene/model/modellib.cxx @@ -45,7 +45,10 @@ using namespace simgear; osgDB::RegisterReaderWriterProxy g_readerWriter_XML_Proxy; ModelRegistryCallbackProxy g_xmlCallbackProxy("xml"); - + SGPropertyNode_ptr SGModelLib::static_propRoot; +SGModelLib::panel_func SGModelLib::static_panelFunc = NULL; +SGModelLib::resolve_func SGModelLib::static_resolver = NULL; + //////////////////////////////////////////////////////////////////////// // Implementation of SGModelLib. //////////////////////////////////////////////////////////////////////// @@ -54,6 +57,34 @@ void SGModelLib::init(const string &root_dir) osgDB::Registry::instance()->getDataFilePathList().push_front(root_dir); } +void SGModelLib::setPropRoot(SGPropertyNode* root) +{ + static_propRoot = root; +} + +void SGModelLib::setPanelFunc(panel_func pf) +{ + static_panelFunc = pf; +} + +void SGModelLib::setResolveFunc(resolve_func rf) +{ + static_resolver = rf; +} + +std::string SGModelLib::findDataFile(const std::string& file, + const osgDB::ReaderWriter::Options* opts) +{ + if (static_resolver) { + SGPath p = static_resolver(file); + if (p.exists()) { + return p.str(); + } + } + + return osgDB::findDataFile(file, opts); +} + SGModelLib::SGModelLib() { } @@ -87,8 +118,10 @@ SGModelLib::loadModel(const string &path, SGModelData *data) { osg::ref_ptr opt = new SGReaderWriterXMLOptions(*(osgDB::Registry::instance()->getOptions())); - opt->setPropRoot(prop_root); + opt->setPropRoot(prop_root ? prop_root: static_propRoot.get()); opt->setModelData(data); + opt->setLoadPanel(static_panelFunc); + osg::Node *n = loadFile(path, opt.get()); if (n && n->getName().empty()) n->setName("Direct loaded model \"" + path + "\""); @@ -96,17 +129,6 @@ SGModelLib::loadModel(const string &path, } -osg::Node* -SGModelLib::loadModel(const string &path, - SGPropertyNode *prop_root, - panel_func pf) -{ - osg::ref_ptr opt = new SGReaderWriterXMLOptions(*(osgDB::Registry::instance()->getOptions())); - opt->setPropRoot(prop_root); - opt->setLoadPanel(pf); - return loadFile(path, opt.get()); -} - osg::Node* SGModelLib::loadPagedModel(const string &path, SGPropertyNode *prop_root, @@ -118,8 +140,10 @@ SGModelLib::loadPagedModel(const string &path, plod->setRange(0, 0.0, 50.0*SG_NM_TO_METER); osg::ref_ptr opt = new SGReaderWriterXMLOptions(*(osgDB::Registry::instance()->getOptions())); - opt->setPropRoot(prop_root); + opt->setPropRoot(prop_root ? prop_root: static_propRoot.get()); opt->setModelData(data); + opt->setLoadPanel(static_panelFunc); + plod->setReaderWriterOptions(opt.get()); return plod; } diff --git a/simgear/scene/model/modellib.hxx b/simgear/scene/model/modellib.hxx index 7c38b10a..7e093db3 100644 --- a/simgear/scene/model/modellib.hxx +++ b/simgear/scene/model/modellib.hxx @@ -27,11 +27,10 @@ #include #include +#include #include - -using std::map; -using std::string; +#include namespace simgear { @@ -45,33 +44,41 @@ class SGModelLib public: typedef osg::Node *(*panel_func)(SGPropertyNode *); - static void init(const string &root_dir); + typedef SGPath (*resolve_func)(const std::string& path); + + static void init(const std::string &root_dir); + + static void setPropRoot(SGPropertyNode* root); + + static void setPanelFunc(panel_func pf); + + static void setResolveFunc(resolve_func rf); // Load a 3D model (any format) // data->modelLoaded() will be called after the model is loaded - static osg::Node* loadModel(const string &path, - SGPropertyNode *prop_root, + static osg::Node* loadModel(const std::string &path, + SGPropertyNode *prop_root = NULL, SGModelData *data=0); - // Load a 3D model (any format) - // with a panel_func to load a panel - static osg::Node* loadModel(const string &path, - SGPropertyNode *prop_root, - panel_func pf); - // Load a 3D model (any format) through the DatabasePager. // Most models should be loaded using this function! // This function will initially return an SGPagedLOD node. // data->modelLoaded() will be called after the model is loaded and // connected to the scene graph. See AIModelData on how to use this. // NOTE: AIModelData uses observer_ptr to avoid circular references. - static osg::Node* loadPagedModel(const string &path, - SGPropertyNode *prop_root, + static osg::Node* loadPagedModel(const std::string &path, + SGPropertyNode *prop_root = NULL, SGModelData *data=0); + static std::string findDataFile(const std::string& file, const osgDB::ReaderWriter::Options* opts = NULL); protected: SGModelLib(); ~SGModelLib (); + +private: + static SGPropertyNode_ptr static_propRoot; + static panel_func static_panelFunc; + static resolve_func static_resolver; }; @@ -83,7 +90,7 @@ protected: class SGModelData : public osg::Referenced { public: virtual ~SGModelData() {} - virtual void modelLoaded(const string& path, SGPropertyNode *prop, + virtual void modelLoaded(const std::string& path, SGPropertyNode *prop, osg::Node* branch) = 0; }; -- 2.39.5