scene: Reorganize stg loading.
This is in preparation loading the non btg objects in a seperate page node. Reorganize this code again.
This commit is contained in:
@@ -77,9 +77,11 @@ const char* SGReaderWriterXML::className() const
|
||||
}
|
||||
|
||||
osgDB::ReaderWriter::ReadResult
|
||||
SGReaderWriterXML::readNode(const std::string& fileName,
|
||||
SGReaderWriterXML::readNode(const std::string& name,
|
||||
const osgDB::Options* options) const
|
||||
{
|
||||
std::string fileName = osgDB::findDataFile(name, options);
|
||||
|
||||
osg::Node *result=0;
|
||||
try {
|
||||
SGPath p = SGModelLib::findDataFile(fileName);
|
||||
|
||||
@@ -40,14 +40,12 @@
|
||||
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
|
||||
#include <simgear/scene/util/RenderConstants.hxx>
|
||||
#include <simgear/scene/util/OsgMath.hxx>
|
||||
#include <simgear/scene/material/mat.hxx>
|
||||
#include <simgear/scene/material/matlib.hxx>
|
||||
#include <simgear/scene/tgdb/apt_signs.hxx>
|
||||
#include <simgear/scene/tgdb/obj.hxx>
|
||||
|
||||
#include "SGOceanTile.hxx"
|
||||
|
||||
using namespace simgear;
|
||||
namespace simgear {
|
||||
|
||||
/// Ok, this is a hack - we do not exactly know if it's an airport or not.
|
||||
/// This feature might also vanish again later. This is currently to
|
||||
@@ -79,18 +77,265 @@ static SGBucket bucketIndexFromFileName(const std::string& fileName)
|
||||
return SGBucket(index);
|
||||
}
|
||||
|
||||
static bool hasOptionalValue(sg_gzifstream &in)
|
||||
{
|
||||
while ( (in.peek() != '\n') && (in.peek() != '\r')
|
||||
&& isspace(in.peek()) ) {
|
||||
in.get();
|
||||
struct ReaderWriterSTG::_ModelBin {
|
||||
struct _Object {
|
||||
std::string _errorLocation;
|
||||
std::string _token;
|
||||
std::string _name;
|
||||
osg::ref_ptr<SGReaderWriterOptions> _options;
|
||||
};
|
||||
struct _ObjectStatic {
|
||||
_ObjectStatic() : _proxy(false), _lon(0), _lat(0), _elev(0), _hdg(0), _pitch(0), _roll(0) { }
|
||||
std::string _errorLocation;
|
||||
std::string _token;
|
||||
std::string _name;
|
||||
bool _proxy;
|
||||
double _lon, _lat, _elev;
|
||||
double _hdg, _pitch, _roll;
|
||||
osg::ref_ptr<SGReaderWriterOptions> _options;
|
||||
};
|
||||
struct _Sign {
|
||||
_Sign() : _lon(0), _lat(0), _elev(0), _hdg(0), _size(-1) { }
|
||||
std::string _errorLocation;
|
||||
std::string _token;
|
||||
std::string _name;
|
||||
double _lon, _lat, _elev;
|
||||
double _hdg;
|
||||
int _size;
|
||||
};
|
||||
|
||||
_ModelBin() :
|
||||
_foundBase(false)
|
||||
{ }
|
||||
|
||||
SGReaderWriterOptions* sharedOptions(const std::string& filePath, const osgDB::Options* options)
|
||||
{
|
||||
osg::ref_ptr<SGReaderWriterOptions> sharedOptions;
|
||||
sharedOptions = SGReaderWriterOptions::copyOrCreate(options);
|
||||
sharedOptions->getDatabasePathList().clear();
|
||||
|
||||
SGPath path = filePath;
|
||||
path.append(".."); path.append(".."); path.append("..");
|
||||
sharedOptions->getDatabasePathList().push_back(path.str());
|
||||
std::string fg_root = options->getPluginStringData("SimGear::FG_ROOT");
|
||||
sharedOptions->getDatabasePathList().push_back(fg_root);
|
||||
|
||||
return sharedOptions.release();
|
||||
}
|
||||
if ( isdigit(in.peek()) || (in.peek() == '-') ){
|
||||
SGReaderWriterOptions* staticOptions(const std::string& filePath, const osgDB::Options* options)
|
||||
{
|
||||
osg::ref_ptr<SGReaderWriterOptions> staticOptions;
|
||||
staticOptions = SGReaderWriterOptions::copyOrCreate(options);
|
||||
staticOptions->getDatabasePathList().clear();
|
||||
|
||||
staticOptions->getDatabasePathList().push_back(filePath);
|
||||
staticOptions->setObjectCacheHint(osgDB::Options::CACHE_NONE);
|
||||
|
||||
return staticOptions.release();
|
||||
}
|
||||
|
||||
bool read(const std::string& absoluteFileName, const osgDB::Options* options)
|
||||
{
|
||||
if (absoluteFileName.empty())
|
||||
return false;
|
||||
|
||||
sg_gzifstream stream(absoluteFileName);
|
||||
if (!stream.is_open())
|
||||
return false;
|
||||
|
||||
SG_LOG(SG_TERRAIN, SG_INFO, "Loading stg file " << absoluteFileName);
|
||||
|
||||
std::string filePath = osgDB::getFilePath(absoluteFileName);
|
||||
|
||||
// do only load airport btg files.
|
||||
bool onlyAirports = options->getPluginStringData("SimGear::FG_ONLY_AIRPORTS") == "ON";
|
||||
// do only load terrain btg files
|
||||
bool onlyTerrain = options->getPluginStringData("SimGear::FG_ONLY_TERRAIN") == "ON";
|
||||
|
||||
while (!stream.eof()) {
|
||||
// read a line
|
||||
std::string line;
|
||||
std::getline(stream, line);
|
||||
|
||||
// strip comments
|
||||
std::string::size_type hash_pos = line.find('#');
|
||||
if (hash_pos != std::string::npos)
|
||||
line.resize(hash_pos);
|
||||
|
||||
// and process further
|
||||
std::stringstream in(line);
|
||||
|
||||
std::string token;
|
||||
in >> token;
|
||||
|
||||
// No comment
|
||||
if (token.empty())
|
||||
continue;
|
||||
|
||||
// Then there is always a name
|
||||
std::string name;
|
||||
in >> name;
|
||||
|
||||
SGPath path = filePath;
|
||||
path.append(name);
|
||||
|
||||
if (token == "OBJECT_BASE") {
|
||||
// Load only once (first found)
|
||||
SG_LOG( SG_TERRAIN, SG_BULK, " " << token << " " << name );
|
||||
_foundBase = true;
|
||||
if (!onlyAirports || isAirportBtg(name)) {
|
||||
_Object obj;
|
||||
obj._errorLocation = absoluteFileName;
|
||||
obj._token = token;
|
||||
obj._name = path.str();
|
||||
obj._options = staticOptions(filePath, options);
|
||||
_objectList.push_back(obj);
|
||||
}
|
||||
|
||||
} else if (token == "OBJECT") {
|
||||
if (!onlyAirports || isAirportBtg(name)) {
|
||||
_Object obj;
|
||||
obj._errorLocation = absoluteFileName;
|
||||
obj._token = token;
|
||||
obj._name = path.str();
|
||||
obj._options = staticOptions(filePath, options);
|
||||
_objectList.push_back(obj);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Always OK to load
|
||||
if (token == "OBJECT_STATIC") {
|
||||
if (!onlyTerrain) {
|
||||
osg::ref_ptr<SGReaderWriterOptions> opt;
|
||||
opt = staticOptions(filePath, options);
|
||||
if (SGPath(name).lower_extension() == "ac")
|
||||
opt->setInstantiateEffects(true);
|
||||
else
|
||||
opt->setInstantiateEffects(false);
|
||||
_ObjectStatic obj;
|
||||
obj._errorLocation = absoluteFileName;
|
||||
obj._token = token;
|
||||
obj._name = name;
|
||||
obj._proxy = true;
|
||||
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
|
||||
obj._options = opt;
|
||||
_objectStaticList.push_back(obj);
|
||||
}
|
||||
|
||||
} else if (token == "OBJECT_SHARED") {
|
||||
if (!onlyTerrain) {
|
||||
osg::ref_ptr<SGReaderWriterOptions> opt;
|
||||
opt = staticOptions(filePath, options);
|
||||
if (SGPath(name).lower_extension() == "ac")
|
||||
opt->setInstantiateEffects(true);
|
||||
else
|
||||
opt->setInstantiateEffects(false);
|
||||
_ObjectStatic obj;
|
||||
obj._errorLocation = absoluteFileName;
|
||||
obj._token = token;
|
||||
obj._name = name;
|
||||
obj._proxy = false;
|
||||
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
|
||||
obj._options = opt;
|
||||
_objectStaticList.push_back(obj);
|
||||
}
|
||||
|
||||
} else if (token == "OBJECT_SIGN") {
|
||||
if (!onlyTerrain) {
|
||||
_Sign sign;
|
||||
sign._token = token;
|
||||
sign._name = name;
|
||||
in >> sign._lon >> sign._lat >> sign._elev >> sign._hdg >> sign._size;
|
||||
_signList.push_back(sign);
|
||||
}
|
||||
|
||||
} else {
|
||||
SG_LOG( SG_TERRAIN, SG_ALERT, absoluteFileName
|
||||
<< ": Unknown token '" << token << "'" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
osg::Node* load(const SGBucket& bucket, const osgDB::Options* opt)
|
||||
{
|
||||
osg::ref_ptr<SGReaderWriterOptions> options;
|
||||
options = SGReaderWriterOptions::copyOrCreate(opt);
|
||||
|
||||
osg::ref_ptr<osg::Group> group = new osg::Group;
|
||||
group->setDataVariance(osg::Object::STATIC);
|
||||
|
||||
if (_foundBase) {
|
||||
for (std::list<_Object>::iterator i = _objectList.begin(); i != _objectList.end(); ++i) {
|
||||
osg::ref_ptr<osg::Node> node;
|
||||
node = osgDB::readRefNodeFile(i->_name, i->_options.get());
|
||||
if (!node.valid()) {
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, i->_errorLocation << ": Failed to load "
|
||||
<< i->_token << " '" << i->_name << "'");
|
||||
continue;
|
||||
}
|
||||
group->addChild(node.get());
|
||||
}
|
||||
} else {
|
||||
SG_LOG(SG_TERRAIN, SG_INFO, " Generating ocean tile");
|
||||
|
||||
osg::Node* node = SGOceanTile(bucket, options->getMaterialLib());
|
||||
if (node) {
|
||||
group->addChild(node);
|
||||
} else {
|
||||
SG_LOG( SG_TERRAIN, SG_ALERT,
|
||||
"Warning: failed to generate ocean tile!" );
|
||||
}
|
||||
}
|
||||
|
||||
for (std::list<_ObjectStatic>::iterator i = _objectStaticList.begin(); i != _objectStaticList.end(); ++i) {
|
||||
osg::ref_ptr<osg::Node> node;
|
||||
if (i->_proxy) {
|
||||
osg::ref_ptr<osg::ProxyNode> proxy = new osg::ProxyNode;
|
||||
proxy->setLoadingExternalReferenceMode(osg::ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER);
|
||||
proxy->setFileName(0, i->_name);
|
||||
proxy->setDatabaseOptions(i->_options.get());
|
||||
node = proxy;
|
||||
} else {
|
||||
node = osgDB::readRefNodeFile(i->_name, i->_options.get());
|
||||
if (!node.valid()) {
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, i->_errorLocation << ": Failed to load "
|
||||
<< i->_token << " '" << i->_name << "'");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (SGPath(i->_name).lower_extension() == "ac")
|
||||
node->setNodeMask(~simgear::MODELLIGHT_BIT);
|
||||
|
||||
osg::Matrix matrix;
|
||||
matrix = makeZUpFrame(SGGeod::fromDegM(i->_lon, i->_lat, i->_elev));
|
||||
matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(i->_hdg), osg::Vec3(0, 0, 1)));
|
||||
matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(i->_pitch), osg::Vec3(0, 1, 0)));
|
||||
matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(i->_roll), osg::Vec3(1, 0, 0)));
|
||||
|
||||
osg::MatrixTransform* matrixTransform;
|
||||
matrixTransform = new osg::MatrixTransform(matrix);
|
||||
matrixTransform->setDataVariance(osg::Object::STATIC);
|
||||
matrixTransform->addChild(node.get());
|
||||
group->addChild(matrixTransform);
|
||||
}
|
||||
|
||||
simgear::AirportSignBuilder signBuilder(options->getMaterialLib(), bucket.get_center());
|
||||
for (std::list<_Sign>::iterator i = _signList.begin(); i != _signList.end(); ++i)
|
||||
signBuilder.addSign(SGGeod::fromDegM(i->_lon, i->_lat, i->_elev), i->_hdg, i->_name, i->_size);
|
||||
if (signBuilder.getSignsGroup())
|
||||
group->addChild(signBuilder.getSignsGroup());
|
||||
|
||||
return group.release();
|
||||
}
|
||||
|
||||
bool _foundBase;
|
||||
std::list<_Object> _objectList;
|
||||
std::list<_ObjectStatic> _objectStaticList;
|
||||
std::list<_Sign> _signList;
|
||||
};
|
||||
|
||||
ReaderWriterSTG::ReaderWriterSTG()
|
||||
{
|
||||
@@ -109,262 +354,46 @@ const char* ReaderWriterSTG::className() const
|
||||
osgDB::ReaderWriter::ReadResult
|
||||
ReaderWriterSTG::readNode(const std::string& fileName, const osgDB::Options* options) const
|
||||
{
|
||||
_ModelBin modelBin;
|
||||
SGBucket bucket(bucketIndexFromFileName(fileName));
|
||||
|
||||
// We treat 123.stg different than ./123.stg.
|
||||
// The difference is that ./123.stg as well as any absolute path
|
||||
// really loads the given stg file and only this.
|
||||
// In contrast 123.stg uses the search paths to load a set of stg
|
||||
// files spread across the scenery directories.
|
||||
if (osgDB::getSimpleFileName(fileName) != fileName)
|
||||
return readStgFile(fileName, options);
|
||||
|
||||
// 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);
|
||||
|
||||
SGBucket bucket(bucketIndexFromFileName(fileName));
|
||||
std::string basePath = bucket.gen_base_path();
|
||||
|
||||
osg::ref_ptr<osg::Group> group = new osg::Group;
|
||||
|
||||
// Stop scanning once an object base is found
|
||||
bool foundBase = false;
|
||||
// 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() && !foundBase; ++i) {
|
||||
SGPath objects(*i);
|
||||
objects.append("Objects");
|
||||
objects.append(basePath);
|
||||
objects.append(fileName);
|
||||
if (readStgFile(objects.str(), bucket, *group, options))
|
||||
foundBase = true;
|
||||
if (osgDB::getSimpleFileName(fileName) != fileName) {
|
||||
if (!modelBin.read(fileName, options))
|
||||
return ReadResult::FILE_NOT_FOUND;
|
||||
} else {
|
||||
// For stg meta files, we need options for the search path.
|
||||
if (!options)
|
||||
return ReadResult::FILE_NOT_FOUND;
|
||||
|
||||
SGPath terrain(*i);
|
||||
terrain.append("Terrain");
|
||||
terrain.append(basePath);
|
||||
terrain.append(fileName);
|
||||
if (readStgFile(terrain.str(), bucket, *group, options))
|
||||
foundBase = true;
|
||||
}
|
||||
|
||||
// ... or generate an ocean tile on the fly
|
||||
if (!foundBase) {
|
||||
SG_LOG(SG_TERRAIN, SG_INFO, " Generating ocean tile");
|
||||
SG_LOG(SG_TERRAIN, SG_INFO, "Loading tile " << fileName);
|
||||
|
||||
osg::ref_ptr<SGReaderWriterOptions> opt;
|
||||
opt = SGReaderWriterOptions::copyOrCreate(options);
|
||||
osg::Node* node = SGOceanTile(bucket, opt->getMaterialLib());
|
||||
if ( node ) {
|
||||
group->addChild(node);
|
||||
} else {
|
||||
SG_LOG( SG_TERRAIN, SG_ALERT,
|
||||
"Warning: failed to generate ocean tile!" );
|
||||
std::string basePath = bucket.gen_base_path();
|
||||
|
||||
// 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.str(), options);
|
||||
|
||||
SGPath terrain(*i);
|
||||
terrain.append("Terrain");
|
||||
terrain.append(basePath);
|
||||
terrain.append(fileName);
|
||||
modelBin.read(terrain.str(), options);
|
||||
}
|
||||
}
|
||||
|
||||
return group.get();
|
||||
return modelBin.load(bucket, options);
|
||||
}
|
||||
|
||||
osgDB::ReaderWriter::ReadResult
|
||||
ReaderWriterSTG::readStgFile(const std::string& fileName, const osgDB::Options* options) const
|
||||
{
|
||||
// This is considered a real existing file.
|
||||
// We still apply the search path algorithms for relative files.
|
||||
osg::ref_ptr<osg::Group> group = new osg::Group;
|
||||
std::string path = osgDB::findDataFile(fileName, options);
|
||||
readStgFile(path, bucketIndexFromFileName(path), *group, options);
|
||||
|
||||
return group.get();
|
||||
}
|
||||
|
||||
bool
|
||||
ReaderWriterSTG::readStgFile(const std::string& absoluteFileName,
|
||||
const SGBucket& bucket,
|
||||
osg::Group& group, const osgDB::Options* options) const
|
||||
{
|
||||
if (absoluteFileName.empty())
|
||||
return false;
|
||||
|
||||
sg_gzifstream in( absoluteFileName );
|
||||
if ( !in.is_open() )
|
||||
return false;
|
||||
|
||||
SG_LOG(SG_TERRAIN, SG_INFO, "Loading stg file " << absoluteFileName);
|
||||
|
||||
std::string filePath = osgDB::getFilePath(absoluteFileName);
|
||||
|
||||
osg::ref_ptr<SGReaderWriterOptions> staticOptions;
|
||||
staticOptions = SGReaderWriterOptions::copyOrCreate(options);
|
||||
staticOptions->getDatabasePathList().clear();
|
||||
staticOptions->getDatabasePathList().push_back(filePath);
|
||||
staticOptions->setObjectCacheHint(osgDB::Options::CACHE_NONE);
|
||||
|
||||
osg::ref_ptr<SGReaderWriterOptions> sharedOptions;
|
||||
sharedOptions = SGReaderWriterOptions::copyOrCreate(options);
|
||||
sharedOptions->getDatabasePathList().clear();
|
||||
|
||||
SGPath path = filePath;
|
||||
path.append(".."); path.append(".."); path.append("..");
|
||||
sharedOptions->getDatabasePathList().push_back(path.str());
|
||||
std::string fg_root = options->getPluginStringData("SimGear::FG_ROOT");
|
||||
sharedOptions->getDatabasePathList().push_back(fg_root);
|
||||
|
||||
// do only load airport btg files.
|
||||
bool onlyAirports = options->getPluginStringData("SimGear::FG_ONLY_AIRPORTS") == "ON";
|
||||
// do only load terrain btg files
|
||||
bool onlyTerrain = options->getPluginStringData("SimGear::FG_ONLY_TERRAIN") == "ON";
|
||||
|
||||
simgear::AirportSignBuilder signBuilder(staticOptions->getMaterialLib(), bucket.get_center());
|
||||
|
||||
bool has_base = false;
|
||||
while ( ! in.eof() ) {
|
||||
std::string token;
|
||||
in >> token;
|
||||
|
||||
// No comment
|
||||
if ( token.empty() || token[0] == '#' ) {
|
||||
in >> ::skipeol;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Then there is always a name
|
||||
std::string name;
|
||||
in >> name;
|
||||
|
||||
SGPath path = filePath;
|
||||
path.append(name);
|
||||
|
||||
osg::ref_ptr<osg::Node> node;
|
||||
if ( token == "OBJECT_BASE" ) {
|
||||
// Load only once (first found)
|
||||
SG_LOG( SG_TERRAIN, SG_BULK, " " << token << " " << name );
|
||||
|
||||
has_base = true;
|
||||
|
||||
if (!onlyAirports || isAirportBtg(name)) {
|
||||
node = osgDB::readRefNodeFile(path.str(),
|
||||
staticOptions.get());
|
||||
|
||||
if (!node.valid()) {
|
||||
SG_LOG( SG_TERRAIN, SG_ALERT, absoluteFileName
|
||||
<< ": Failed to load OBJECT_BASE '"
|
||||
<< name << "'" );
|
||||
}
|
||||
}
|
||||
|
||||
} else if ( token == "OBJECT" ) {
|
||||
if (!onlyAirports || isAirportBtg(name)) {
|
||||
node = osgDB::readRefNodeFile(path.str(),
|
||||
staticOptions.get());
|
||||
|
||||
if (!node.valid()) {
|
||||
SG_LOG( SG_TERRAIN, SG_ALERT, absoluteFileName
|
||||
<< ": Failed to load OBJECT '"
|
||||
<< name << "'" );
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
double lon, lat, elev, hdg;
|
||||
in >> lon >> lat >> elev >> hdg;
|
||||
|
||||
// Always OK to load
|
||||
if ( token == "OBJECT_STATIC" ) {
|
||||
if (!onlyTerrain) {
|
||||
osg::ref_ptr<SGReaderWriterOptions> opt;
|
||||
opt = new SGReaderWriterOptions(*staticOptions);
|
||||
osg::ProxyNode* proxyNode = new osg::ProxyNode;
|
||||
proxyNode->setLoadingExternalReferenceMode(osg::ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER);
|
||||
/// Hmm, the findDataFile should happen downstream
|
||||
std::string absName = osgDB::findDataFile(name, opt.get());
|
||||
proxyNode->setFileName(0, absName);
|
||||
if (SGPath(absName).lower_extension() == "ac")
|
||||
{
|
||||
proxyNode->setNodeMask( ~simgear::MODELLIGHT_BIT );
|
||||
opt->setInstantiateEffects(true);
|
||||
}
|
||||
else
|
||||
opt->setInstantiateEffects(false);
|
||||
proxyNode->setDatabaseOptions(opt.get());
|
||||
node = proxyNode;
|
||||
|
||||
if (!node.valid()) {
|
||||
SG_LOG( SG_TERRAIN, SG_ALERT, absoluteFileName
|
||||
<< ": Failed to load OBJECT_STATIC '"
|
||||
<< name << "'" );
|
||||
}
|
||||
}
|
||||
|
||||
} else if ( token == "OBJECT_SHARED" ) {
|
||||
if (!onlyTerrain) {
|
||||
osg::ref_ptr<SGReaderWriterOptions> opt;
|
||||
opt = new SGReaderWriterOptions(*sharedOptions);
|
||||
/// Hmm, the findDataFile should happen in the downstream readers
|
||||
std::string absName = osgDB::findDataFile(name, opt.get());
|
||||
if (SGPath(absName).lower_extension() == "ac")
|
||||
opt->setInstantiateEffects(true);
|
||||
else
|
||||
opt->setInstantiateEffects(false);
|
||||
node = osgDB::readRefNodeFile(absName, opt.get());
|
||||
if (SGPath(absName).lower_extension() == "ac")
|
||||
node->setNodeMask( ~simgear::MODELLIGHT_BIT );
|
||||
|
||||
if (!node.valid()) {
|
||||
SG_LOG( SG_TERRAIN, SG_ALERT, absoluteFileName
|
||||
<< ": Failed to load OBJECT_SHARED '"
|
||||
<< name << "'" );
|
||||
}
|
||||
}
|
||||
|
||||
} else if ( token == "OBJECT_SIGN" ) {
|
||||
int size(-1);
|
||||
|
||||
if ( hasOptionalValue(in) ){
|
||||
in >> size;
|
||||
}
|
||||
if (!onlyTerrain)
|
||||
signBuilder.addSign(SGGeod::fromDegM(lon, lat, elev), hdg, name, size);
|
||||
} else {
|
||||
SG_LOG( SG_TERRAIN, SG_ALERT, absoluteFileName
|
||||
<< ": Unknown token '" << token << "'" );
|
||||
}
|
||||
|
||||
if (node.valid()) {
|
||||
osg::Matrix matrix;
|
||||
matrix = makeZUpFrame(SGGeod::fromDegM(lon, lat, elev));
|
||||
matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(hdg),
|
||||
osg::Vec3(0, 0, 1)));
|
||||
|
||||
if ( hasOptionalValue(in) ){
|
||||
double pitch(0.0), roll(0.0);
|
||||
in >> pitch >> roll;
|
||||
|
||||
matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(pitch),
|
||||
osg::Vec3(0, 1, 0)));
|
||||
matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(roll),
|
||||
osg::Vec3(1, 0, 0)));
|
||||
}
|
||||
|
||||
osg::MatrixTransform* matrixTransform;
|
||||
matrixTransform = new osg::MatrixTransform(matrix);
|
||||
matrixTransform->setDataVariance(osg::Object::STATIC);
|
||||
matrixTransform->addChild(node.get());
|
||||
node = matrixTransform;
|
||||
}
|
||||
}
|
||||
|
||||
if (node.valid())
|
||||
group.addChild(node.get());
|
||||
|
||||
in >> ::skipeol;
|
||||
}
|
||||
|
||||
if (signBuilder.getSignsGroup())
|
||||
group.addChild(signBuilder.getSignsGroup());
|
||||
|
||||
return has_base;
|
||||
}
|
||||
|
||||
@@ -39,14 +39,7 @@ public:
|
||||
readNode(const std::string&, const osgDB::Options*) const;
|
||||
|
||||
private:
|
||||
/// Read an real existing stg file that exists on disk.
|
||||
ReadResult
|
||||
readStgFile(const std::string& fileName, const osgDB::Options* options) const;
|
||||
|
||||
/// Read an real existing stg file that exists on disk and return true
|
||||
/// if a BASE_OBJECT is found.
|
||||
bool
|
||||
readStgFile(const std::string&, const SGBucket& bucket, osg::Group&, const osgDB::Options*) const;
|
||||
struct _ModelBin;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user