From 836ee9a3f073db6427c03aafa6823ab5ca4e5676 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 18 Sep 2022 11:51:01 +0200 Subject: [PATCH] Accept old XML model paths for some models Update my work-around for this from last year, and handle another case (where models are loaded directly rather using the delayed callback via the osgDB::Pager) Where we replaced the XMl-wrapper with an AC model in FGData or TerraSync, accept the old path ending in .xml, to avoid many errors loading custom scenery. --- simgear/scene/model/ModelRegistry.cxx | 7 ++- simgear/scene/model/SGReaderWriterXML.cxx | 59 +++++++++++++++++++---- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/simgear/scene/model/ModelRegistry.cxx b/simgear/scene/model/ModelRegistry.cxx index f1717690..cc217e91 100644 --- a/simgear/scene/model/ModelRegistry.cxx +++ b/simgear/scene/model/ModelRegistry.cxx @@ -774,9 +774,12 @@ ModelRegistry::readNode(const string& fileName, // try this AC reader; if it succeeds, we can use that. auto iter = nodeCallbackMap.find("ac"); - result = iter->second->readNode(fileName, opt); + result = iter->second->readNode(plainModelFileName, opt); if (result.validNode()) { - SG_LOG(SG_IO, SG_DEV_WARN, "Couldn't find XML model, found via .AC instead:" << fileName); + // TODO: allow extracting keys from the error-context; + // would need an additional callback added with a return value + // const auto stgName = ec.get("terrain-stg"); + SG_LOG(SG_IO, SG_DEV_WARN, "Couldn't find XML model, found via .AC instead:" << plainModelFileName); return result; } } diff --git a/simgear/scene/model/SGReaderWriterXML.cxx b/simgear/scene/model/SGReaderWriterXML.cxx index 5cc5f663..6d5f6f38 100644 --- a/simgear/scene/model/SGReaderWriterXML.cxx +++ b/simgear/scene/model/SGReaderWriterXML.cxx @@ -16,11 +16,10 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // -#ifdef HAVE_CONFIG_H -# include -#endif +#include #include +#include //yuck #include #include @@ -39,6 +38,7 @@ #include #include #include + #include #include #include @@ -496,23 +496,64 @@ void addTooltipAnimations(const SGPath& path, SGPropertyNode_ptr props, osg::ref SG_LOG(SG_INPUT, SG_DEBUG, "auto-tooltips: num_new_animations=" << num_new_animations); } +static std::optional isModelWithRemovedXMLWrapper(const SGPath& model) +{ + if (model.extension() != "xml") { + return {}; + } + + const auto grandparentDirPath = model.dirPath().dirPath(); + if (grandparentDirPath.file() != "Models") { + return {}; + } + + const auto names = std::vector{ + "marker", + "ndb", + }; + + const auto it = std::find(names.begin(), names.end(), model.file_base()); + if (it != names.end()) { + return SGPath{model.dirPath() / (*it + ".ac")}; + } + + return {}; +} + static std::tuple sgLoad3DModel_internal(const SGPath& path, const osgDB::Options* dbOptions, SGPropertyNode *overlay) { + SGPath modelpath(path); + SGPath texturepath(path); + if (!path.exists()) { - simgear::reportFailure(simgear::LoadFailure::NotFound, simgear::ErrorCode::XMLModelLoad, - "Failed to load model XML: not found", path); - SG_LOG(SG_IO, SG_DEV_ALERT, "Failed to load file: \"" << path << "\""); - return std::make_tuple(0, (osg::Node*)NULL); + // tolerate .xml paths where we removed the wrapper XML + // becuase this is a resolved path, only works when the bare model + // is in the same location. + + // NOTE: there is seperate logic to handle this situation, in the ModelRegistry, + // for the DelayedModelLoadCallback case. (See fileNameIsFGDataModelXML)] + // Would be nice to share the implementation but inside an OSG RegistryCallback, + // it's tricky to work with SGPaths as our code here does. + auto b = isModelWithRemovedXMLWrapper(path); + if (b) { + modelpath = b.value_or(SGPath{}); + texturepath = b.value_or(SGPath{}); + SG_LOG(SG_IO, SG_DEV_WARN, "Requested model which previously used an XML wrapper:" << path + << " mapped to " << modelpath); + } else { + simgear::reportFailure(simgear::LoadFailure::NotFound, simgear::ErrorCode::XMLModelLoad, + "Failed to load model XML: not found", path); + return std::make_tuple(0, (osg::Node*) nullptr); + } } osg::ref_ptr options; options = SGReaderWriterOptions::copyOrCreate(dbOptions); - SGPath modelpath(path); - SGPath texturepath(path); + SGPath modelDir(modelpath.dir()); int animationcount = 0;