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;
|
||||
};
|
||||
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;
|
||||
std::string _token;
|
||||
std::string _name;
|
||||
@ -375,8 +375,7 @@ struct ReaderWriterSTG::_ModelBin {
|
||||
double bareRangeDelta = atof(options->getPluginStringData("SimGear::LOD_RANGE_BARE").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 = 1414.0f + detailedRange;
|
||||
_object_range_detailed = detailedRange;
|
||||
_object_range_bare = _object_range_detailed + bareRangeDelta;
|
||||
_object_range_rough = _object_range_detailed + roughRangeDelta;
|
||||
|
||||
@ -450,56 +449,56 @@ struct ReaderWriterSTG::_ModelBin {
|
||||
} else if (!onlyTerrain) {
|
||||
// Load non-terrain objects
|
||||
|
||||
// Determine an appropriate range for the object, which has some randomness
|
||||
double range = _object_range_rough;
|
||||
double lrand = mt_rand(&seed);
|
||||
if (lrand < 0.1) range = range * 2.0;
|
||||
else if (lrand < 0.4) range = range * 1.5;
|
||||
// Determine an appropriate range for the object, which has some randomness
|
||||
double range = _object_range_rough;
|
||||
double lrand = mt_rand(&seed);
|
||||
if (lrand < 0.1) range = range * 2.0;
|
||||
else if (lrand < 0.4) range = range * 1.5;
|
||||
|
||||
if (token == "OBJECT_STATIC" || token == "OBJECT_STATIC_AGL") {
|
||||
osg::ref_ptr<SGReaderWriterOptions> opt;
|
||||
opt = staticOptions(filePath, options);
|
||||
if (SGPath(name).lower_extension() == "ac")
|
||||
opt->setInstantiateEffects(true);
|
||||
else
|
||||
opt->setInstantiateEffects(false);
|
||||
_ObjectStatic obj;
|
||||
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._agl = (token == "OBJECT_STATIC_AGL");
|
||||
obj._proxy = true;
|
||||
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
|
||||
obj._range = range;
|
||||
obj._options = opt;
|
||||
obj._errorLocation = absoluteFileName;
|
||||
obj._token = token;
|
||||
obj._name = name;
|
||||
obj._agl = (token == "OBJECT_STATIC_AGL");
|
||||
obj._proxy = true;
|
||||
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll >> obj._range;
|
||||
obj._range += range;
|
||||
obj._options = opt;
|
||||
checkInsideBucket(absoluteFileName, obj._lon, obj._lat);
|
||||
_objectStaticList.push_back(obj);
|
||||
} else if (token == "OBJECT_SHARED" || token == "OBJECT_SHARED_AGL") {
|
||||
osg::ref_ptr<SGReaderWriterOptions> opt;
|
||||
opt = sharedOptions(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._agl = (token == "OBJECT_SHARED_AGL");
|
||||
obj._proxy = false;
|
||||
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
|
||||
obj._range = range;
|
||||
obj._options = opt;
|
||||
osg::ref_ptr<SGReaderWriterOptions> opt;
|
||||
opt = sharedOptions(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._agl = (token == "OBJECT_SHARED_AGL");
|
||||
obj._proxy = false;
|
||||
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll >> obj._range;
|
||||
obj._range += range;
|
||||
obj._options = opt;
|
||||
checkInsideBucket(absoluteFileName, obj._lon, obj._lat);
|
||||
_objectStaticList.push_back(obj);
|
||||
} else if (token == "OBJECT_SIGN" || token == "OBJECT_SIGN_AGL") {
|
||||
_Sign sign;
|
||||
sign._token = token;
|
||||
sign._name = name;
|
||||
sign._agl = (token == "OBJECT_SIGN_AGL");
|
||||
in >> sign._lon >> sign._lat >> sign._elev >> sign._hdg >> sign._size;
|
||||
_signList.push_back(sign);
|
||||
_Sign sign;
|
||||
sign._token = token;
|
||||
sign._name = name;
|
||||
sign._agl = (token == "OBJECT_SIGN_AGL");
|
||||
in >> sign._lon >> sign._lat >> sign._elev >> sign._hdg >> sign._size;
|
||||
_signList.push_back(sign);
|
||||
} else if (token == BUILDING_ROUGH || token == BUILDING_DETAILED ||
|
||||
token == ROAD_ROUGH || token == ROAD_DETAILED ||
|
||||
token == RAILWAY_ROUGH || token == RAILWAY_DETAILED) {
|
||||
@ -531,18 +530,20 @@ struct ReaderWriterSTG::_ModelBin {
|
||||
obj._name = name;
|
||||
obj._agl = false;
|
||||
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);
|
||||
if (token == BUILDING_DETAILED || token == ROAD_DETAILED || token == RAILWAY_DETAILED ) {
|
||||
// Apply a lower LOD range if this is a detailed mesh
|
||||
range = _object_range_detailed;
|
||||
double lrand = mt_rand(&seed);
|
||||
if (lrand < 0.1) range = range * 2.0;
|
||||
else if (lrand < 0.4) range = range * 1.5;
|
||||
}
|
||||
// Apply a lower LOD range if this is a detailed mesh.
|
||||
range = _object_range_detailed;
|
||||
double lrand = mt_rand(&seed);
|
||||
if (lrand < 0.1) range = range * 2.0;
|
||||
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;
|
||||
checkInsideBucket(absoluteFileName, obj._lon, obj._lat);
|
||||
@ -596,24 +597,20 @@ struct ReaderWriterSTG::_ModelBin {
|
||||
bool vpb_active = SGSceneFeatures::instance()->getVPBActive();
|
||||
if (vpb_active) {
|
||||
std::string filename = "vpb/" + bucket.gen_vpb_base() + ".osgb";
|
||||
//std::string filename = "vpb/*.osgb";
|
||||
if (tile_map.count(filename) == 0) {
|
||||
auto vpb_node = osgDB::readRefNodeFile(filename, options);
|
||||
terrainGroup->addChild(vpb_node);
|
||||
tile_map[filename] = true;
|
||||
SG_LOG(SG_TERRAIN, SG_INFO, "Loading: " << filename);
|
||||
}
|
||||
}
|
||||
|
||||
if (!vpb_active) {
|
||||
if (_foundBase) {
|
||||
} else if (_foundBase) {
|
||||
for (auto stgObject : _objectList) {
|
||||
osg::ref_ptr<osg::Node> node;
|
||||
node = osgDB::readRefNodeFile(stgObject._name, stgObject._options.get());
|
||||
|
||||
if (!node.valid()) {
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, stgObject._errorLocation << ": Failed to load "
|
||||
<< stgObject._token << " '" << stgObject._name << "'");
|
||||
<< stgObject._token << " '" << stgObject._name << "'");
|
||||
continue;
|
||||
}
|
||||
terrainGroup->addChild(node.get());
|
||||
@ -630,7 +627,6 @@ struct ReaderWriterSTG::_ModelBin {
|
||||
"Warning: failed to generate ocean tile!" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::list<_ObjectStatic>::iterator i = _objectStaticList.begin(); i != _objectStaticList.end(); ++i) {
|
||||
if (!i->_agl)
|
||||
|
Loading…
Reference in New Issue
Block a user