Extended scenery/STG suffix handling

This commit is contained in:
James Turner 2016-11-19 13:20:03 +00:00
parent 4dc66a385e
commit e266e44f63
2 changed files with 65 additions and 41 deletions

View File

@ -87,14 +87,14 @@ static SGBucket bucketIndexFromFileName(const std::string& fileName)
struct ReaderWriterSTG::_ModelBin { struct ReaderWriterSTG::_ModelBin {
struct _Object { struct _Object {
std::string _errorLocation; SGPath _errorLocation;
std::string _token; std::string _token;
std::string _name; std::string _name;
osg::ref_ptr<SGReaderWriterOptions> _options; osg::ref_ptr<SGReaderWriterOptions> _options;
}; };
struct _ObjectStatic { struct _ObjectStatic {
_ObjectStatic() : _agl(false), _proxy(false), _lon(0), _lat(0), _elev(0), _hdg(0), _pitch(0), _roll(0), _range(SG_OBJECT_RANGE_ROUGH) { } _ObjectStatic() : _agl(false), _proxy(false), _lon(0), _lat(0), _elev(0), _hdg(0), _pitch(0), _roll(0), _range(SG_OBJECT_RANGE_ROUGH) { }
std::string _errorLocation; SGPath _errorLocation;
std::string _token; std::string _token;
std::string _name; std::string _name;
bool _agl; bool _agl;
@ -106,7 +106,7 @@ struct ReaderWriterSTG::_ModelBin {
}; };
struct _Sign { struct _Sign {
_Sign() : _agl(false), _lon(0), _lat(0), _elev(0), _hdg(0), _size(-1) { } _Sign() : _agl(false), _lon(0), _lat(0), _elev(0), _hdg(0), _size(-1) { }
std::string _errorLocation; SGPath _errorLocation;
std::string _token; std::string _token;
std::string _name; std::string _name;
bool _agl; bool _agl;
@ -284,29 +284,32 @@ struct ReaderWriterSTG::_ModelBin {
return SGGeod::fromCart(cart).getElevationM(); return SGGeod::fromCart(cart).getElevationM();
} }
bool read(const std::string& absoluteFileName, const osgDB::Options* options) bool read(const SGPath& absoluteFileName, const osgDB::Options* options)
{ {
// Determine object ranges. Mesh size of 2000mx2000m needs to be accounted for. if (!absoluteFileName.exists()) {
_object_range_bare = 1414.0f + atof(options->getPluginStringData("SimGear::LOD_RANGE_BARE").c_str());
_object_range_rough = 1414.0f + atof(options->getPluginStringData("SimGear::LOD_RANGE_ROUGH").c_str());
_object_range_detailed = 1414.0f + atof(options->getPluginStringData("SimGear::LOD_RANGE_DETAILED").c_str());
_building_mesh_enabled = (options->getPluginStringData("SimGear::RENDER_BUILDING_MESH") == "true");
if (absoluteFileName.empty())
return false; return false;
}
sg_gzifstream stream(absoluteFileName); sg_gzifstream stream(absoluteFileName);
if (!stream.is_open()) if (!stream.is_open()) {
return false; return false;
}
// Determine object ranges. Mesh size of 2000mx2000m needs to be accounted for.
_object_range_bare = 1414.0f + atof(options->getPluginStringData("SimGear::LOD_RANGE_BARE").c_str());
_object_range_rough = 1414.0f + atof(options->getPluginStringData("SimGear::LOD_RANGE_ROUGH").c_str());
_object_range_detailed = 1414.0f + atof(options->getPluginStringData("SimGear::LOD_RANGE_DETAILED").c_str());
_building_mesh_enabled = (options->getPluginStringData("SimGear::RENDER_BUILDING_MESH") == "true");
SG_LOG(SG_TERRAIN, SG_INFO, "Loading stg file " << absoluteFileName); SG_LOG(SG_TERRAIN, SG_INFO, "Loading stg file " << absoluteFileName);
std::string filePath = osgDB::getFilePath(absoluteFileName); std::string filePath = osgDB::getFilePath(absoluteFileName.local8BitStr());
// Bucket provides a consistent seed // Bucket provides a consistent seed
// so we have consistent set of pseudo-random numbers for each STG file // so we have consistent set of pseudo-random numbers for each STG file
mt seed; mt seed;
int bucket = atoi(SGPath(absoluteFileName).file_base().c_str()); int bucket = atoi(absoluteFileName.file_base().c_str());
mt_init(&seed, bucket); mt_init(&seed, bucket);
// do only load airport btg files. // do only load airport btg files.
@ -467,12 +470,12 @@ struct ReaderWriterSTG::_ModelBin {
terrainGroup->setName("terrain"); terrainGroup->setName("terrain");
if (_foundBase) { if (_foundBase) {
for (std::list<_Object>::iterator i = _objectList.begin(); i != _objectList.end(); ++i) { for (auto stgObject : _objectList) {
osg::ref_ptr<osg::Node> node; osg::ref_ptr<osg::Node> node;
node = osgDB::readRefNodeFile(i->_name, i->_options.get()); node = osgDB::readRefNodeFile(stgObject._name, stgObject._options.get());
if (!node.valid()) { if (!node.valid()) {
SG_LOG(SG_TERRAIN, SG_ALERT, i->_errorLocation << ": Failed to load " SG_LOG(SG_TERRAIN, SG_ALERT, stgObject._errorLocation << ": Failed to load "
<< i->_token << " '" << i->_name << "'"); << stgObject._token << " '" << stgObject._name << "'");
continue; continue;
} }
terrainGroup->addChild(node.get()); terrainGroup->addChild(node.get());
@ -571,31 +574,44 @@ ReaderWriterSTG::readNode(const std::string& fileName, const osgDB::Options* opt
if (osgDB::getSimpleFileName(fileName) != fileName) { if (osgDB::getSimpleFileName(fileName) != fileName) {
if (!modelBin.read(fileName, options)) if (!modelBin.read(fileName, options))
return ReadResult::FILE_NOT_FOUND; return ReadResult::FILE_NOT_FOUND;
} else { }
// For stg meta files, we need options for the search path.
if (!options)
return ReadResult::FILE_NOT_FOUND;
SG_LOG(SG_TERRAIN, SG_INFO, "Loading tile " << fileName); // For stg meta files, we need options for the search path.
if (!options) {
return ReadResult::FILE_NOT_FOUND;
}
std::string basePath = bucket.gen_base_path(); osg::ref_ptr<SGReaderWriterOptions> sgOpts(SGReaderWriterOptions::copyOrCreate(options));
if (sgOpts->getSceneryPathSuffixes().empty()) {
SG_LOG(SG_TERRAIN, SG_ALERT, "Loading tile " << fileName << ", no scenery path suffixes were configured so giving up");
return ReadResult::FILE_NOT_FOUND;
// Stop scanning once an object base is found }
// This is considered a meta file, so apply the scenery path search
const osgDB::FilePathList& filePathList = options->getDatabasePathList();
for (osgDB::FilePathList::const_iterator i = filePathList.begin();
i != filePathList.end() && !modelBin._foundBase; ++i) {
SGPath objects(*i);
objects.append("Objects");
objects.append(basePath);
objects.append(fileName);
modelBin.read(objects.local8BitStr(), options);
SGPath terrain(*i); SG_LOG(SG_TERRAIN, SG_INFO, "Loading tile " << fileName);
terrain.append("Terrain");
terrain.append(basePath); std::string basePath = bucket.gen_base_path();
terrain.append(fileName);
modelBin.read(terrain.local8BitStr(), options); // Stop scanning paths once an object base is found
// But do load all STGs at the same level (i.e from the same scenery path)
const osgDB::FilePathList& filePathList = options->getDatabasePathList();
for (auto path : filePathList) {
if (modelBin._foundBase) {
break;
}
SGPath base(path);
// check for non-suffixed file, and warn.
SGPath pathWithoutSuffix = base / basePath / fileName;
if (pathWithoutSuffix.exists()) {
SG_LOG(SG_TERRAIN, SG_ALERT, "Found scenery file " << pathWithoutSuffix << " in scenery path " << path
<< ".\nScenery paths without type subdirectories are no longer supported, please move thse files\n"
<< "into a an appropriate subdirectory, for example:" << base / "Objects" / basePath / fileName);
}
for (auto suffix : sgOpts->getSceneryPathSuffixes()) {
SGPath p = base / suffix / basePath / fileName;
modelBin.read(p, options);
} }
} }

View File

@ -27,7 +27,7 @@
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
class SGPropertyNode; class SGPropertyNode;
typedef std::vector < std::string > string_list;
namespace simgear namespace simgear
{ {
@ -62,7 +62,8 @@ public:
_materialLib(options._materialLib), _materialLib(options._materialLib),
_load_panel(options._load_panel), _load_panel(options._load_panel),
_model_data(options._model_data), _model_data(options._model_data),
_instantiateEffects(options._instantiateEffects) _instantiateEffects(options._instantiateEffects),
_sceneryPathSuffixes(options._sceneryPathSuffixes)
{ } { }
META_Object(simgear, SGReaderWriterOptions); META_Object(simgear, SGReaderWriterOptions);
@ -94,6 +95,12 @@ public:
void setInstantiateEffects(bool instantiateEffects) void setInstantiateEffects(bool instantiateEffects)
{ _instantiateEffects = instantiateEffects; } { _instantiateEffects = instantiateEffects; }
const string_list& getSceneryPathSuffixes() const
{ return _sceneryPathSuffixes; }
void setSceneryPathSuffixes(const string_list& suffixes)
{ _sceneryPathSuffixes = suffixes; }
static SGReaderWriterOptions* copyOrCreate(const osgDB::Options* options); static SGReaderWriterOptions* copyOrCreate(const osgDB::Options* options);
static SGReaderWriterOptions* fromPath(const std::string& path); static SGReaderWriterOptions* fromPath(const std::string& path);
@ -106,6 +113,7 @@ private:
osg::Node *(*_load_panel)(SGPropertyNode *); osg::Node *(*_load_panel)(SGPropertyNode *);
osg::ref_ptr<SGModelData> _model_data; osg::ref_ptr<SGModelData> _model_data;
bool _instantiateEffects; bool _instantiateEffects;
string_list _sceneryPathSuffixes;
}; };
} }