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:
Stuart Buchanan 2020-11-17 19:56:01 +00:00
parent 02b20462e1
commit 158ac28e60

View File

@ -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;
@ -470,8 +469,8 @@ struct ReaderWriterSTG::_ModelBin {
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);
@ -488,8 +487,8 @@ struct ReaderWriterSTG::_ModelBin {
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);
@ -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,17 +597,13 @@ 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());
@ -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)