X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fscene%2Fmodel%2FSGReaderWriterXML.cxx;h=1a83f2043aebf3edae8c68ab5899acc841a64186;hb=5a96b283f63cfacd3a3a90a82246defb038242d3;hp=3efc0ded6f1609d287fcd26dbb6580bd79c9e63c;hpb=ad667be0d7100670ecc0a274ae8c567749ef0add;p=simgear.git diff --git a/simgear/scene/model/SGReaderWriterXML.cxx b/simgear/scene/model/SGReaderWriterXML.cxx index 3efc0ded..1a83f204 100644 --- a/simgear/scene/model/SGReaderWriterXML.cxx +++ b/simgear/scene/model/SGReaderWriterXML.cxx @@ -23,11 +23,13 @@ #include //yuck #include +#include #include #include #include +#include #include #include #include @@ -39,11 +41,10 @@ #include #include #include +#include #include "modellib.hxx" -#include "SGPagedLOD.hxx" #include "SGReaderWriterXML.hxx" -#include "SGReaderWriterXMLOptions.hxx" #include "animation.hxx" #include "particles.hxx" @@ -56,8 +57,8 @@ using namespace simgear; using namespace osg; static osg::Node * -sgLoad3DModel_internal(const std::string& path, - const osgDB::ReaderWriter::Options* options, +sgLoad3DModel_internal(const SGPath& path, + const osgDB::Options* options, SGPropertyNode *overlay = 0); @@ -77,13 +78,19 @@ const char* SGReaderWriterXML::className() const osgDB::ReaderWriter::ReadResult SGReaderWriterXML::readNode(const std::string& fileName, - const osgDB::ReaderWriter::Options* options) const + const osgDB::Options* options) const { osg::Node *result=0; try { - result=sgLoad3DModel_internal(fileName, options); - } catch (const sg_throwable &t) { - SG_LOG(SG_INPUT, SG_ALERT, "Failed to load model: " << t.getFormattedMessage()); + SGPath p = SGModelLib::findDataFile(fileName); + if (!p.exists()) { + return ReadResult::FILE_NOT_FOUND; + } + + result=sgLoad3DModel_internal(p, options); + } catch (const sg_exception &t) { + SG_LOG(SG_INPUT, SG_ALERT, "Failed to load model: " << t.getFormattedMessage() + << "\n\tfrom:" << fileName); result=new osg::Node; } if (result) @@ -192,37 +199,27 @@ void makeEffectAnimations(PropertyList& animation_nodes, } static osg::Node * -sgLoad3DModel_internal(const string &path, - const osgDB::ReaderWriter::Options* options_, +sgLoad3DModel_internal(const SGPath& path, + const osgDB::Options* dbOptions, SGPropertyNode *overlay) { - const SGReaderWriterXMLOptions* xmlOptions; - xmlOptions = dynamic_cast(options_); - - SGSharedPtr prop_root; - osg::Node *(*load_panel)(SGPropertyNode *)=0; - osg::ref_ptr data; - - if (xmlOptions) { - prop_root = xmlOptions->getPropRoot(); - load_panel = xmlOptions->getLoadPanel(); - data = xmlOptions->getModelData(); - } - if (!prop_root) { - prop_root = new SGPropertyNode; + if (!path.exists()) { + SG_LOG(SG_INPUT, SG_ALERT, "Failed to load file: \"" << path.str() << "\""); + return NULL; } - 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; - } - SGPath texturepath = modelpath; - + osg::ref_ptr options; + options = SGReaderWriterOptions::copyOrCreate(dbOptions); + + SGPath modelpath(path); + SGPath texturepath(path); + SGPath modelDir(modelpath.dir()); + + SGSharedPtr prop_root = options->getPropertyNode(); + if (!prop_root.valid()) + prop_root = new SGPropertyNode; + osg::ref_ptr data = options->getModelData(); + osg::ref_ptr model; osg::ref_ptr group; SGPropertyNode_ptr props = new SGPropertyNode; @@ -231,7 +228,7 @@ sgLoad3DModel_internal(const string &path, if (modelpath.extension() == "xml") { try { readProperties(modelpath.str(), props); - } catch (const sg_throwable &t) { + } catch (const sg_exception &t) { SG_LOG(SG_INPUT, SG_ALERT, "Failed to load xml: " << t.getFormattedMessage()); throw; @@ -240,11 +237,18 @@ sgLoad3DModel_internal(const string &path, copyProperties(overlay, props); if (props->hasValue("/path")) { - modelpath = modelpath.dir(); - modelpath.append(props->getStringValue("/path")); + string modelPathStr = props->getStringValue("/path"); + modelpath = SGModelLib::findDataFile(modelPathStr, NULL, modelDir); + if (modelpath.isNull()) + throw sg_io_exception("Model file not found: '" + modelPathStr + "'", + path.str()); + if (props->hasValue("/texture-path")) { - texturepath = texturepath.dir(); - texturepath.append(props->getStringValue("/texture-path")); + string texturePathStr = props->getStringValue("/texture-path"); + texturepath = SGModelLib::findDataFile(texturePathStr, NULL, modelDir); + if (texturepath.isNull()) + throw sg_io_exception("Texture file not found: '" + texturePathStr + "'", + path.str()); } } else { model = new osg::Node; @@ -254,15 +258,11 @@ sgLoad3DModel_internal(const string &path, if (mp && prop_root && prop_root->getParent()) copyProperties(mp, prop_root); } else { - SG_LOG(SG_INPUT, SG_DEBUG, "model without wrapper: " - << modelpath.str()); + // model without wrapper } - osg::ref_ptr options - = new SGReaderWriterXMLOptions(*options_); - options->setPropRoot(prop_root); - options->setLoadPanel(load_panel); - + options->setPropertyNode(prop_root); + // Assume that textures are in // the same location as the XML file. if (!model) { @@ -270,12 +270,11 @@ sgLoad3DModel_internal(const string &path, texturepath = texturepath.dir(); options->setDatabasePath(texturepath.str()); - osgDB::ReaderWriter::ReadResult modelResult - = osgDB::Registry::instance()->readNode(modelpath.str(), - options.get()); + osgDB::ReaderWriter::ReadResult modelResult; + modelResult = osgDB::readNodeFile(modelpath.str(), options.get()); if (!modelResult.validNode()) - throw sg_io_exception("Failed to load 3D model", - sg_location(modelpath.str())); + throw sg_io_exception("Failed to load 3D model:" + modelResult.message(), + modelpath.str()); model = copyModel(modelResult.getNode()); // Add an extra reference to the model stored in the database. // That is to avoid expiring the object from the cache even if @@ -333,24 +332,23 @@ sgLoad3DModel_internal(const string &path, SGPath submodelpath; osg::ref_ptr submodel; - string submodelFileName = sub_props->getStringValue("path"); - if (submodelFileName.size() > 2 - && !submodelFileName.compare(0, 2, "./" )) { - submodelpath = modelpath.dir(); - submodelpath.append( submodelFileName.substr( 2 ) ); - } else { - submodelpath = submodelFileName; + + string subPathStr = sub_props->getStringValue("path"); + SGPath submodelPath = SGModelLib::findDataFile(subPathStr, + NULL, modelDir); + + if (submodelPath.isNull()) { + SG_LOG(SG_INPUT, SG_ALERT, "Failed to load file: \"" << subPathStr << "\""); + continue; } - osg::ref_ptr options; - options = new SGReaderWriterXMLOptions(*options_); - options->setPropRoot(prop_root); - options->setLoadPanel(load_panel); + try { - submodel = sgLoad3DModel_internal(submodelpath.str(), options.get(), + submodel = sgLoad3DModel_internal(submodelPath, options.get(), sub_props->getNode("overlay")); - } catch (const sg_throwable &t) { - SG_LOG(SG_INPUT, SG_ALERT, "Failed to load submodel: " << t.getFormattedMessage()); - throw; + } catch (const sg_exception &t) { + SG_LOG(SG_INPUT, SG_ALERT, "Failed to load submodel: " << t.getFormattedMessage() + << "\n\tfrom:" << t.getOrigin()); + continue; } osg::ref_ptr submodel_final = submodel; @@ -391,6 +389,7 @@ sgLoad3DModel_internal(const string &path, } } // end of submodel loading + osg::Node *(*load_panel)(SGPropertyNode *) = options->getLoadPanel(); if ( load_panel ) { // Load panels vector panel_nodes = props->getChildren("panel"); @@ -406,15 +405,17 @@ sgLoad3DModel_internal(const string &path, std::vector particle_nodes; particle_nodes = props->getChildren("particlesystem"); for (unsigned i = 0; i < particle_nodes.size(); ++i) { + osg::ref_ptr options2; + options2 = new SGReaderWriterOptions(*options); if (i==0) { if (!texturepath.extension().empty()) texturepath = texturepath.dir(); - options->setDatabasePath(texturepath.str()); + options2->setDatabasePath(texturepath.str()); } group->addChild(Particles::appendParticles(particle_nodes[i], prop_root, - options.get())); + options2.get())); } std::vector text_nodes; @@ -426,6 +427,7 @@ sgLoad3DModel_internal(const string &path, } PropertyList effect_nodes = props->getChildren("effect"); PropertyList animation_nodes = props->getChildren("animation"); + PropertyList light_nodes = props->getChildren("light"); // Some material animations (eventually all) are actually effects. makeEffectAnimations(animation_nodes, effect_nodes); {