Use a custom 'findDataFile' method in key places, and hook this into a callback set on SGModelLib.

This commit is contained in:
James Turner
2010-07-29 01:04:10 +01:00
parent 1d740a63bd
commit d23491646a
5 changed files with 71 additions and 39 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -202,21 +202,21 @@ sgLoad3DModel_internal(const string &path,
SGSharedPtr<SGPropertyNode> prop_root;
osg::Node *(*load_panel)(SGPropertyNode *)=0;
osg::ref_ptr<SGModelData> 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"));

View File

@@ -45,7 +45,10 @@ using namespace simgear;
osgDB::RegisterReaderWriterProxy<SGReaderWriterXML> g_readerWriter_XML_Proxy;
ModelRegistryCallbackProxy<LoadOnlyCallback> 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<SGReaderWriterXMLOptions> 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<SGReaderWriterXMLOptions> 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<SGReaderWriterXMLOptions> 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;
}

View File

@@ -27,11 +27,10 @@
#include <string>
#include <osg/Node>
#include <osgDB/ReaderWriter>
#include <simgear/props/props.hxx>
using std::map;
using std::string;
#include <simgear/misc/sg_path.hxx>
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;
};