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.
This commit is contained in:
James Turner 2022-09-18 11:51:01 +02:00
parent 3ef521b53f
commit 836ee9a3f0
2 changed files with 55 additions and 11 deletions

View File

@ -774,9 +774,12 @@ ModelRegistry::readNode(const string& fileName,
// try this AC reader; if it succeeds, we can use that. // try this AC reader; if it succeeds, we can use that.
auto iter = nodeCallbackMap.find("ac"); auto iter = nodeCallbackMap.find("ac");
result = iter->second->readNode(fileName, opt); result = iter->second->readNode(plainModelFileName, opt);
if (result.validNode()) { 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; return result;
} }
} }

View File

@ -16,11 +16,10 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// //
#ifdef HAVE_CONFIG_H #include <simgear_config.h>
# include <simgear_config.h>
#endif
#include <algorithm> #include <algorithm>
#include <optional>
//yuck //yuck
#include <cstring> #include <cstring>
#include <cassert> #include <cassert>
@ -39,6 +38,7 @@
#include <simgear/props/condition.hxx> #include <simgear/props/condition.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/scene/util/SGNodeMasks.hxx> #include <simgear/scene/util/SGNodeMasks.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx> #include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include <simgear/structure/exception.hxx> #include <simgear/structure/exception.hxx>
@ -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); SG_LOG(SG_INPUT, SG_DEBUG, "auto-tooltips: num_new_animations=" << num_new_animations);
} }
static std::optional<SGPath> 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<std::string>{
"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<int, osg::Node *> static std::tuple<int, osg::Node *>
sgLoad3DModel_internal(const SGPath& path, sgLoad3DModel_internal(const SGPath& path,
const osgDB::Options* dbOptions, const osgDB::Options* dbOptions,
SGPropertyNode *overlay) SGPropertyNode *overlay)
{ {
SGPath modelpath(path);
SGPath texturepath(path);
if (!path.exists()) { if (!path.exists()) {
simgear::reportFailure(simgear::LoadFailure::NotFound, simgear::ErrorCode::XMLModelLoad, // tolerate .xml paths where we removed the wrapper XML
"Failed to load model XML: not found", path); // becuase this is a resolved path, only works when the bare model
SG_LOG(SG_IO, SG_DEV_ALERT, "Failed to load file: \"" << path << "\""); // is in the same location.
return std::make_tuple(0, (osg::Node*)NULL);
// 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<SGReaderWriterOptions> options; osg::ref_ptr<SGReaderWriterOptions> options;
options = SGReaderWriterOptions::copyOrCreate(dbOptions); options = SGReaderWriterOptions::copyOrCreate(dbOptions);
SGPath modelpath(path);
SGPath texturepath(path);
SGPath modelDir(modelpath.dir()); SGPath modelDir(modelpath.dir());
int animationcount = 0; int animationcount = 0;