Add a range noun to STG verbs
Previously the PagedLoD range for OBJECT_STATIC etc. was purely measured from the object reference point. For large meshes from osm2city this was problematic, particular at DETAILED LOD ranges, where the range of (say) 1500m would result in the mesh being rendered at 500m distance from the edge. We fudged this by adding 1400m to the DETAILED LOD range. Now, such meshes can specify their radius in the STG file, ensuring they are loaded at the correct distance.
This commit is contained in:
parent
02b20462e1
commit
158ac28e60
@ -112,7 +112,7 @@ struct ReaderWriterSTG::_ModelBin {
|
|||||||
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(0) { }
|
||||||
SGPath _errorLocation;
|
SGPath _errorLocation;
|
||||||
std::string _token;
|
std::string _token;
|
||||||
std::string _name;
|
std::string _name;
|
||||||
@ -375,8 +375,7 @@ struct ReaderWriterSTG::_ModelBin {
|
|||||||
double bareRangeDelta = atof(options->getPluginStringData("SimGear::LOD_RANGE_BARE").c_str());
|
double bareRangeDelta = atof(options->getPluginStringData("SimGear::LOD_RANGE_BARE").c_str());
|
||||||
double roughRangeDelta = atof(options->getPluginStringData("SimGear::LOD_RANGE_ROUGH").c_str());
|
double roughRangeDelta = atof(options->getPluginStringData("SimGear::LOD_RANGE_ROUGH").c_str());
|
||||||
|
|
||||||
// Determine object ranges. Mesh size of 2000mx2000m needs to be accounted for.
|
_object_range_detailed = detailedRange;
|
||||||
_object_range_detailed = 1414.0f + detailedRange;
|
|
||||||
_object_range_bare = _object_range_detailed + bareRangeDelta;
|
_object_range_bare = _object_range_detailed + bareRangeDelta;
|
||||||
_object_range_rough = _object_range_detailed + roughRangeDelta;
|
_object_range_rough = _object_range_detailed + roughRangeDelta;
|
||||||
|
|
||||||
@ -450,56 +449,56 @@ struct ReaderWriterSTG::_ModelBin {
|
|||||||
} else if (!onlyTerrain) {
|
} else if (!onlyTerrain) {
|
||||||
// Load non-terrain objects
|
// Load non-terrain objects
|
||||||
|
|
||||||
// Determine an appropriate range for the object, which has some randomness
|
// Determine an appropriate range for the object, which has some randomness
|
||||||
double range = _object_range_rough;
|
double range = _object_range_rough;
|
||||||
double lrand = mt_rand(&seed);
|
double lrand = mt_rand(&seed);
|
||||||
if (lrand < 0.1) range = range * 2.0;
|
if (lrand < 0.1) range = range * 2.0;
|
||||||
else if (lrand < 0.4) range = range * 1.5;
|
else if (lrand < 0.4) range = range * 1.5;
|
||||||
|
|
||||||
if (token == "OBJECT_STATIC" || token == "OBJECT_STATIC_AGL") {
|
if (token == "OBJECT_STATIC" || token == "OBJECT_STATIC_AGL") {
|
||||||
osg::ref_ptr<SGReaderWriterOptions> opt;
|
osg::ref_ptr<SGReaderWriterOptions> opt;
|
||||||
opt = staticOptions(filePath, options);
|
opt = staticOptions(filePath, options);
|
||||||
if (SGPath(name).lower_extension() == "ac")
|
if (SGPath(name).lower_extension() == "ac")
|
||||||
opt->setInstantiateEffects(true);
|
opt->setInstantiateEffects(true);
|
||||||
else
|
else
|
||||||
opt->setInstantiateEffects(false);
|
opt->setInstantiateEffects(false);
|
||||||
_ObjectStatic obj;
|
_ObjectStatic obj;
|
||||||
|
|
||||||
obj._errorLocation = absoluteFileName;
|
obj._errorLocation = absoluteFileName;
|
||||||
obj._token = token;
|
obj._token = token;
|
||||||
obj._name = name;
|
obj._name = name;
|
||||||
obj._agl = (token == "OBJECT_STATIC_AGL");
|
obj._agl = (token == "OBJECT_STATIC_AGL");
|
||||||
obj._proxy = true;
|
obj._proxy = true;
|
||||||
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
|
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll >> obj._range;
|
||||||
obj._range = range;
|
obj._range += range;
|
||||||
obj._options = opt;
|
obj._options = opt;
|
||||||
checkInsideBucket(absoluteFileName, obj._lon, obj._lat);
|
checkInsideBucket(absoluteFileName, obj._lon, obj._lat);
|
||||||
_objectStaticList.push_back(obj);
|
_objectStaticList.push_back(obj);
|
||||||
} else if (token == "OBJECT_SHARED" || token == "OBJECT_SHARED_AGL") {
|
} else if (token == "OBJECT_SHARED" || token == "OBJECT_SHARED_AGL") {
|
||||||
osg::ref_ptr<SGReaderWriterOptions> opt;
|
osg::ref_ptr<SGReaderWriterOptions> opt;
|
||||||
opt = sharedOptions(filePath, options);
|
opt = sharedOptions(filePath, options);
|
||||||
if (SGPath(name).lower_extension() == "ac")
|
if (SGPath(name).lower_extension() == "ac")
|
||||||
opt->setInstantiateEffects(true);
|
opt->setInstantiateEffects(true);
|
||||||
else
|
else
|
||||||
opt->setInstantiateEffects(false);
|
opt->setInstantiateEffects(false);
|
||||||
_ObjectStatic obj;
|
_ObjectStatic obj;
|
||||||
obj._errorLocation = absoluteFileName;
|
obj._errorLocation = absoluteFileName;
|
||||||
obj._token = token;
|
obj._token = token;
|
||||||
obj._name = name;
|
obj._name = name;
|
||||||
obj._agl = (token == "OBJECT_SHARED_AGL");
|
obj._agl = (token == "OBJECT_SHARED_AGL");
|
||||||
obj._proxy = false;
|
obj._proxy = false;
|
||||||
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
|
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll >> obj._range;
|
||||||
obj._range = range;
|
obj._range += range;
|
||||||
obj._options = opt;
|
obj._options = opt;
|
||||||
checkInsideBucket(absoluteFileName, obj._lon, obj._lat);
|
checkInsideBucket(absoluteFileName, obj._lon, obj._lat);
|
||||||
_objectStaticList.push_back(obj);
|
_objectStaticList.push_back(obj);
|
||||||
} else if (token == "OBJECT_SIGN" || token == "OBJECT_SIGN_AGL") {
|
} else if (token == "OBJECT_SIGN" || token == "OBJECT_SIGN_AGL") {
|
||||||
_Sign sign;
|
_Sign sign;
|
||||||
sign._token = token;
|
sign._token = token;
|
||||||
sign._name = name;
|
sign._name = name;
|
||||||
sign._agl = (token == "OBJECT_SIGN_AGL");
|
sign._agl = (token == "OBJECT_SIGN_AGL");
|
||||||
in >> sign._lon >> sign._lat >> sign._elev >> sign._hdg >> sign._size;
|
in >> sign._lon >> sign._lat >> sign._elev >> sign._hdg >> sign._size;
|
||||||
_signList.push_back(sign);
|
_signList.push_back(sign);
|
||||||
} else if (token == BUILDING_ROUGH || token == BUILDING_DETAILED ||
|
} else if (token == BUILDING_ROUGH || token == BUILDING_DETAILED ||
|
||||||
token == ROAD_ROUGH || token == ROAD_DETAILED ||
|
token == ROAD_ROUGH || token == ROAD_DETAILED ||
|
||||||
token == RAILWAY_ROUGH || token == RAILWAY_DETAILED) {
|
token == RAILWAY_ROUGH || token == RAILWAY_DETAILED) {
|
||||||
@ -531,18 +530,20 @@ struct ReaderWriterSTG::_ModelBin {
|
|||||||
obj._name = name;
|
obj._name = name;
|
||||||
obj._agl = false;
|
obj._agl = false;
|
||||||
obj._proxy = true;
|
obj._proxy = true;
|
||||||
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
|
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll >> obj._range;
|
||||||
|
|
||||||
opt->setLocation(obj._lon, obj._lat);
|
opt->setLocation(obj._lon, obj._lat);
|
||||||
if (token == BUILDING_DETAILED || token == ROAD_DETAILED || token == RAILWAY_DETAILED ) {
|
if (token == BUILDING_DETAILED || token == ROAD_DETAILED || token == RAILWAY_DETAILED ) {
|
||||||
// Apply a lower LOD range if this is a detailed mesh
|
// Apply a lower LOD range if this is a detailed mesh.
|
||||||
range = _object_range_detailed;
|
range = _object_range_detailed;
|
||||||
double lrand = mt_rand(&seed);
|
double lrand = mt_rand(&seed);
|
||||||
if (lrand < 0.1) range = range * 2.0;
|
if (lrand < 0.1) range = range * 2.0;
|
||||||
else if (lrand < 0.4) range = range * 1.5;
|
else if (lrand < 0.4) range = range * 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obj._range += range;
|
||||||
|
|
||||||
obj._range = range;
|
SG_LOG(SG_TERRAIN, SG_ALERT, "Building list: " << name << " " << obj._range);
|
||||||
|
|
||||||
obj._options = opt;
|
obj._options = opt;
|
||||||
checkInsideBucket(absoluteFileName, obj._lon, obj._lat);
|
checkInsideBucket(absoluteFileName, obj._lon, obj._lat);
|
||||||
@ -596,24 +597,20 @@ struct ReaderWriterSTG::_ModelBin {
|
|||||||
bool vpb_active = SGSceneFeatures::instance()->getVPBActive();
|
bool vpb_active = SGSceneFeatures::instance()->getVPBActive();
|
||||||
if (vpb_active) {
|
if (vpb_active) {
|
||||||
std::string filename = "vpb/" + bucket.gen_vpb_base() + ".osgb";
|
std::string filename = "vpb/" + bucket.gen_vpb_base() + ".osgb";
|
||||||
//std::string filename = "vpb/*.osgb";
|
|
||||||
if (tile_map.count(filename) == 0) {
|
if (tile_map.count(filename) == 0) {
|
||||||
auto vpb_node = osgDB::readRefNodeFile(filename, options);
|
auto vpb_node = osgDB::readRefNodeFile(filename, options);
|
||||||
terrainGroup->addChild(vpb_node);
|
terrainGroup->addChild(vpb_node);
|
||||||
tile_map[filename] = true;
|
tile_map[filename] = true;
|
||||||
SG_LOG(SG_TERRAIN, SG_INFO, "Loading: " << filename);
|
SG_LOG(SG_TERRAIN, SG_INFO, "Loading: " << filename);
|
||||||
}
|
}
|
||||||
}
|
} else if (_foundBase) {
|
||||||
|
|
||||||
if (!vpb_active) {
|
|
||||||
if (_foundBase) {
|
|
||||||
for (auto stgObject : _objectList) {
|
for (auto stgObject : _objectList) {
|
||||||
osg::ref_ptr<osg::Node> node;
|
osg::ref_ptr<osg::Node> node;
|
||||||
node = osgDB::readRefNodeFile(stgObject._name, stgObject._options.get());
|
node = osgDB::readRefNodeFile(stgObject._name, stgObject._options.get());
|
||||||
|
|
||||||
if (!node.valid()) {
|
if (!node.valid()) {
|
||||||
SG_LOG(SG_TERRAIN, SG_ALERT, stgObject._errorLocation << ": Failed to load "
|
SG_LOG(SG_TERRAIN, SG_ALERT, stgObject._errorLocation << ": Failed to load "
|
||||||
<< stgObject._token << " '" << stgObject._name << "'");
|
<< stgObject._token << " '" << stgObject._name << "'");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
terrainGroup->addChild(node.get());
|
terrainGroup->addChild(node.get());
|
||||||
@ -630,7 +627,6 @@ struct ReaderWriterSTG::_ModelBin {
|
|||||||
"Warning: failed to generate ocean tile!" );
|
"Warning: failed to generate ocean tile!" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (std::list<_ObjectStatic>::iterator i = _objectStaticList.begin(); i != _objectStaticList.end(); ++i) {
|
for (std::list<_ObjectStatic>::iterator i = _objectStaticList.begin(); i != _objectStaticList.end(); ++i) {
|
||||||
if (!i->_agl)
|
if (!i->_agl)
|
||||||
|
Loading…
Reference in New Issue
Block a user