Add STG verbs for building mesh integration.

Add OBJECT_BUILDING_MESH_ROUGH and OBJECT_BUILDING_MESH_DETAILED

Intended for use by OSM buildings.
This commit is contained in:
Stuart Buchanan
2016-09-22 20:38:58 +01:00
parent 38bab59c1a
commit 809ddb21c9
5 changed files with 103 additions and 66 deletions

View File

@@ -211,8 +211,10 @@ const float SG_RADIANS_TO_DEGREES = 180.0f / SG_PI;
/** for backwards compatibility */
#define SG_SCENERY_FILE_FORMAT "0.4"
/** Default range in m at which all objects are displayed. Overridden by /sim/rendering/static-lod/rough **/
#define SG_OBJECT_RANGE 9000.0
/** Default object ranges. Overridden by /sim/rendering/static-lod/[bare|rough|detailed] **/
#define SG_OBJECT_RANGE_BARE 30000.0
#define SG_OBJECT_RANGE_ROUGH 9000.0
#define SG_OBJECT_RANGE_DETAILED 1500.0
/** Radius of scenery tiles in m **/
#define SG_TILE_RADIUS 14000.0

View File

@@ -136,7 +136,7 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options,
const SGPropertyNode *props,
SGPropertyNode *prop_root)
{
float default_object_range = prop_root->getFloatValue("/sim/rendering/static-lod/rough", SG_OBJECT_RANGE);
float default_object_range = prop_root->getFloatValue("/sim/rendering/static-lod/rough", SG_OBJECT_RANGE_ROUGH);
std::vector<bool> dds;
std::vector<SGPropertyNode_ptr> textures = props->getChildren("texture");
for (unsigned int i = 0; i < textures.size(); i++)

View File

@@ -93,7 +93,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) { }
_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;
std::string _token;
std::string _name;
@@ -209,7 +209,10 @@ struct ReaderWriterSTG::_ModelBin {
};
_ModelBin() :
_object_range(SG_OBJECT_RANGE),
_object_range_bare(SG_OBJECT_RANGE_BARE),
_object_range_rough(SG_OBJECT_RANGE_ROUGH),
_object_range_detailed(SG_OBJECT_RANGE_DETAILED),
_building_mesh_enabled(false),
_foundBase(false)
{ }
@@ -283,6 +286,13 @@ struct ReaderWriterSTG::_ModelBin {
bool read(const std::string& absoluteFileName, const osgDB::Options* options)
{
// Determine object ranges
_object_range_bare = atof(options->getPluginStringData("SimGear::BARE_LOD_RANGE").c_str());
_object_range_rough = atof(options->getPluginStringData("SimGear::ROUGH_LOD_RANGE").c_str());
_object_range_detailed = atof(options->getPluginStringData("SimGear::DETAILED_LOD_RANGE").c_str());
_building_mesh_enabled = (options->getPluginStringData("SimGear::RENDER_BUILDING_MESH") == "true");
if (absoluteFileName.empty())
return false;
@@ -332,12 +342,6 @@ struct ReaderWriterSTG::_ModelBin {
SGPath path = filePath;
path.append(name);
// Determine an appropriate range for the object, which has some randomness
double range = _object_range;
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_BASE") {
// Load only once (first found)
SG_LOG( SG_TERRAIN, SG_BULK, " " << token << " " << name );
@@ -361,62 +365,93 @@ struct ReaderWriterSTG::_ModelBin {
_objectList.push_back(obj);
}
} else {
// Always OK to load
} 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;
if (token == "OBJECT_STATIC" || token == "OBJECT_STATIC_AGL") {
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._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;
_objectStaticList.push_back(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;
_objectStaticList.push_back(obj);
} else if (token == "OBJECT_SHARED" || token == "OBJECT_SHARED_AGL") {
if (!onlyTerrain) {
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;
_objectStaticList.push_back(obj);
}
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;
_objectStaticList.push_back(obj);
} else if (token == "OBJECT_SIGN" || token == "OBJECT_SIGN_AGL") {
if (!onlyTerrain) {
_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 == "OBJECT_BUILDING_MESH_ROUGH" || token == "OBJECT_BUILDING_MESH_DETAILED") {
// Only load if building mesh enabled to avoid impacting low-powered systems
if (_building_mesh_enabled) {
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 = false;
obj._proxy = true;
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
if (token == "OBJECT_BUILDING_MESH_DETAILED") {
// Apply a lower LOD range if this is a detailed building
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._options = opt;
_objectStaticList.push_back(obj);
}
} else {
SG_LOG( SG_TERRAIN, SG_ALERT, absoluteFileName
<< ": Unknown token '" << token << "'" );
}
} else {
SG_LOG( SG_TERRAIN, SG_ALERT, absoluteFileName
<< ": Unknown token '" << token << "'" );
}
}
@@ -428,9 +463,6 @@ struct ReaderWriterSTG::_ModelBin {
osg::ref_ptr<SGReaderWriterOptions> options;
options = SGReaderWriterOptions::copyOrCreate(opt);
// Determine object ranges
_object_range = atof(options->getPluginStringData("SimGear::ROUGH_LOD_RANGE").c_str());
osg::ref_ptr<osg::Group> terrainGroup = new osg::Group;
terrainGroup->setDataVariance(osg::Object::STATIC);
terrainGroup->setName("terrain");
@@ -496,13 +528,16 @@ struct ReaderWriterSTG::_ModelBin {
pagedLOD->setFileName(pagedLOD->getNumChildren(), "Dummy name - use the stored data in the read file callback");
// Objects may end up displayed up to 2x the object range.
pagedLOD->setRange(pagedLOD->getNumChildren(), 0, 2.0 * _object_range + SG_TILE_RADIUS);
pagedLOD->setRange(pagedLOD->getNumChildren(), 0, 2.0 * _object_range_rough + SG_TILE_RADIUS);
return pagedLOD;
}
}
double _object_range;
double _object_range_bare;
double _object_range_rough;
double _object_range_detailed;
bool _building_mesh_enabled;
bool _foundBase;
std::list<_Object> _objectList;
std::list<_ObjectStatic> _objectStaticList;

View File

@@ -992,7 +992,7 @@ public:
bool use_random_buildings = false;
float vegetation_density = 1.0f;
float building_density = 1.0f;
float object_range = SG_OBJECT_RANGE;
float object_range = SG_OBJECT_RANGE_ROUGH;
bool useVBOs = false;
osg::ref_ptr<osg::Group> randomObjects;

View File

@@ -52,7 +52,7 @@ SGLoadBTG(const std::string& path, const simgear::SGReaderWriterOptions* options
double ratio = SG_SIMPLIFIER_RATIO;
double maxLength = SG_SIMPLIFIER_MAX_LENGTH;
double maxError = SG_SIMPLIFIER_MAX_ERROR;
double object_range = SG_OBJECT_RANGE;
double object_range = SG_OBJECT_RANGE_ROUGH;
double tile_min_expiry = SG_TILE_MIN_EXPIRY;
if (options) {