Make LOD for buildings/trees/STG configurable.
Now based on /sim/rendering/static-lod/rough.
This commit is contained in:
@@ -211,5 +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
|
||||
|
||||
/** Radius of scenery tiles in m **/
|
||||
#define SG_TILE_RADIUS 14000.0
|
||||
|
||||
#endif // _SG_CONSTANTS_H
|
||||
|
||||
@@ -136,6 +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);
|
||||
std::vector<bool> dds;
|
||||
std::vector<SGPropertyNode_ptr> textures = props->getChildren("texture");
|
||||
for (unsigned int i = 0; i < textures.size(); i++)
|
||||
@@ -316,7 +317,7 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options,
|
||||
building_large_min_depth = props->getFloatValue("building-large-min-depth-m", 50.0);
|
||||
building_large_max_depth = props->getFloatValue("building-large-max-depth-m", 75.0);
|
||||
|
||||
building_range = props->getDoubleValue("building-range-m", 10000.0);
|
||||
building_range = props->getDoubleValue("building-range-m", default_object_range);
|
||||
|
||||
cos_object_max_density_slope_angle = cos(props->getFloatValue("object-max-density-angle-deg", 20.0) * osg::PI/180.0);
|
||||
cos_object_zero_density_slope_angle = cos(props->getFloatValue("object-zero-density-angle-deg", 30.0) * osg::PI/180.0);
|
||||
@@ -326,7 +327,7 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options,
|
||||
tree_effect = props->getStringValue("tree-effect", "Effects/tree");
|
||||
tree_height = props->getDoubleValue("tree-height-m", 0.0);
|
||||
tree_width = props->getDoubleValue("tree-width-m", 0.0);
|
||||
tree_range = props->getDoubleValue("tree-range-m", 0.0);
|
||||
tree_range = props->getDoubleValue("tree-range-m", default_object_range);
|
||||
tree_varieties = props->getIntValue("tree-varieties", 1);
|
||||
cos_tree_max_density_slope_angle = cos(props->getFloatValue("tree-max-density-angle-deg", 30.0) * osg::PI/180.0);
|
||||
cos_tree_zero_density_slope_angle = cos(props->getFloatValue("tree-zero-density-angle-deg", 45.0) * osg::PI/180.0);
|
||||
@@ -384,7 +385,7 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options,
|
||||
std::vector<SGPropertyNode_ptr> object_group_nodes =
|
||||
((SGPropertyNode *)props)->getChildren("object-group");
|
||||
for (unsigned int i = 0; i < object_group_nodes.size(); i++)
|
||||
object_groups.push_back(new SGMatModelGroup(object_group_nodes[i]));
|
||||
object_groups.push_back(new SGMatModelGroup(object_group_nodes[i], default_object_range));
|
||||
|
||||
// read glyph table for taxi-/runway-signs
|
||||
std::vector<SGPropertyNode_ptr> glyph_nodes = props->getChildren("glyph");
|
||||
|
||||
@@ -185,8 +185,8 @@ SGMatModel::get_heading_type () const
|
||||
// Implementation of SGMatModelGroup.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SGMatModelGroup::SGMatModelGroup (SGPropertyNode * node)
|
||||
: _range_m(node->getDoubleValue("range-m", 2000))
|
||||
SGMatModelGroup::SGMatModelGroup (SGPropertyNode * node, float default_object_range)
|
||||
: _range_m(node->getDoubleValue("range-m", default_object_range))
|
||||
{
|
||||
// Load the object subnodes
|
||||
std::vector<SGPropertyNode_ptr> object_nodes =
|
||||
|
||||
@@ -195,7 +195,7 @@ protected:
|
||||
|
||||
friend class SGMaterial;
|
||||
|
||||
SGMatModelGroup (SGPropertyNode * node);
|
||||
SGMatModelGroup (SGPropertyNode * node, float default_object_range);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <osgDB/ReaderWriter>
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include <simgear/math/sg_random.h>
|
||||
#include <simgear/math/SGGeometry.hxx>
|
||||
#include <simgear/bucket/newbucket.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
@@ -92,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) { }
|
||||
_ObjectStatic() : _agl(false), _proxy(false), _lon(0), _lat(0), _elev(0), _hdg(0), _pitch(0), _roll(0), _range(SG_OBJECT_RANGE) { }
|
||||
std::string _errorLocation;
|
||||
std::string _token;
|
||||
std::string _name;
|
||||
@@ -100,6 +101,7 @@ struct ReaderWriterSTG::_ModelBin {
|
||||
bool _proxy;
|
||||
double _lon, _lat, _elev;
|
||||
double _hdg, _pitch, _roll;
|
||||
double _range;
|
||||
osg::ref_ptr<SGReaderWriterOptions> _options;
|
||||
};
|
||||
struct _Sign {
|
||||
@@ -159,7 +161,8 @@ struct ReaderWriterSTG::_ModelBin {
|
||||
matrixTransform->setName("rotateStaticObject");
|
||||
matrixTransform->setDataVariance(osg::Object::STATIC);
|
||||
matrixTransform->addChild(node.get());
|
||||
leaf->addChild(matrixTransform, 0, 20000); //TODO: Make configurable?
|
||||
|
||||
leaf->addChild(matrixTransform, 0, o._range);
|
||||
}
|
||||
};
|
||||
struct GetModelLODCoord {
|
||||
@@ -196,6 +199,7 @@ struct ReaderWriterSTG::_ModelBin {
|
||||
return group.release();
|
||||
}
|
||||
|
||||
mt _seed;
|
||||
std::list<_ObjectStatic> _objectStaticList;
|
||||
std::list<_Sign> _signList;
|
||||
|
||||
@@ -205,6 +209,7 @@ struct ReaderWriterSTG::_ModelBin {
|
||||
};
|
||||
|
||||
_ModelBin() :
|
||||
_object_range(SG_OBJECT_RANGE),
|
||||
_foundBase(false)
|
||||
{ }
|
||||
|
||||
@@ -289,6 +294,12 @@ struct ReaderWriterSTG::_ModelBin {
|
||||
|
||||
std::string filePath = osgDB::getFilePath(absoluteFileName);
|
||||
|
||||
// Bucket provides a consistent seed
|
||||
// so we have consistent set of pseudo-random numbers for each STG file
|
||||
mt seed;
|
||||
int bucket = atoi(SGPath(absoluteFileName).file_base().c_str());
|
||||
mt_init(&seed, bucket);
|
||||
|
||||
// do only load airport btg files.
|
||||
bool onlyAirports = options->getPluginStringData("SimGear::FG_ONLY_AIRPORTS") == "ON";
|
||||
// do only load terrain btg files
|
||||
@@ -320,7 +331,13 @@ 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,6 +378,7 @@ struct ReaderWriterSTG::_ModelBin {
|
||||
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);
|
||||
}
|
||||
@@ -380,6 +398,7 @@ struct ReaderWriterSTG::_ModelBin {
|
||||
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);
|
||||
}
|
||||
@@ -409,6 +428,9 @@ 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");
|
||||
@@ -472,12 +494,15 @@ struct ReaderWriterSTG::_ModelBin {
|
||||
pagedLOD->setDatabaseOptions(callbackOptions.get());
|
||||
|
||||
pagedLOD->setFileName(pagedLOD->getNumChildren(), "Dummy name - use the stored data in the read file callback");
|
||||
pagedLOD->setRange(pagedLOD->getNumChildren(), 0, 30000);
|
||||
|
||||
// Objects may end up displayed up to 2x the object range.
|
||||
pagedLOD->setRange(pagedLOD->getNumChildren(), 0, 2.0 * _object_range + SG_TILE_RADIUS);
|
||||
|
||||
return pagedLOD;
|
||||
}
|
||||
}
|
||||
|
||||
double _object_range;
|
||||
bool _foundBase;
|
||||
std::list<_Object> _objectList;
|
||||
std::list<_ObjectStatic> _objectStaticList;
|
||||
|
||||
@@ -206,7 +206,7 @@ public:
|
||||
LOD* result = new LOD;
|
||||
|
||||
if (_fade_out) {
|
||||
// Create a series of LOD nodes so buidling cover decreases
|
||||
// Create a series of LOD nodes so building cover decreases
|
||||
// gradually with distance from _range to 2*_range
|
||||
for (float i = 0.0; i < SG_BUILDING_FADE_OUT_LEVELS; i++)
|
||||
{
|
||||
|
||||
@@ -55,10 +55,7 @@ typedef std::list<SGDirectionalLightBin> SGDirectionalLightListBin;
|
||||
#define SG_SIMPLIFIER_RATIO (0.001)
|
||||
#define SG_SIMPLIFIER_MAX_LENGTH (1000.0)
|
||||
#define SG_SIMPLIFIER_MAX_ERROR (2000.0)
|
||||
#define SG_OBJECT_RANGE (9000.0)
|
||||
#define SG_TILE_RADIUS (14000.0)
|
||||
#define SG_TILE_MIN_EXPIRY (180.0)
|
||||
|
||||
using namespace simgear;
|
||||
|
||||
// QuadTreeBuilder is used by Random Objects Generator
|
||||
@@ -995,6 +992,7 @@ public:
|
||||
bool use_random_buildings = false;
|
||||
float vegetation_density = 1.0f;
|
||||
float building_density = 1.0f;
|
||||
float object_range = SG_OBJECT_RANGE;
|
||||
bool useVBOs = false;
|
||||
|
||||
osg::ref_ptr<osg::Group> randomObjects;
|
||||
@@ -1020,6 +1018,9 @@ public:
|
||||
building_density
|
||||
= propertyNode->getFloatValue("/sim/rendering/building-density",
|
||||
building_density);
|
||||
object_range
|
||||
= propertyNode->getFloatValue("/sim/rendering/static-lod/rough",
|
||||
object_range);
|
||||
}
|
||||
|
||||
useVBOs = (_options->getPluginStringData("SimGear::USE_VBOS") == "ON");
|
||||
@@ -1106,9 +1107,10 @@ public:
|
||||
if (randomObjects.valid() || forestNode.valid() || buildingNode.valid()) {
|
||||
objectLOD = new osg::LOD;
|
||||
|
||||
if (randomObjects.valid()) objectLOD->addChild(randomObjects.get(), 0, 20000);
|
||||
if (forestNode.valid()) objectLOD->addChild(forestNode.get(), 0, 20000);
|
||||
if (buildingNode.valid()) objectLOD->addChild(buildingNode.get(), 0, 20000);
|
||||
// random objects, trees and buildings can be displayed up to 2xrange out.
|
||||
if (randomObjects.valid()) objectLOD->addChild(randomObjects.get(), 0, 2.0 * object_range + SG_TILE_RADIUS);
|
||||
if (forestNode.valid()) objectLOD->addChild(forestNode.get(), 0, 2.0 * object_range + SG_TILE_RADIUS);
|
||||
if (buildingNode.valid()) objectLOD->addChild(buildingNode.get(), 0, 2.0 * object_range + SG_TILE_RADIUS);
|
||||
|
||||
unsigned nodeMask = SG_NODEMASK_CASTSHADOW_BIT | SG_NODEMASK_RECEIVESHADOW_BIT | SG_NODEMASK_TERRAIN_BIT;
|
||||
objectLOD->setNodeMask(nodeMask);
|
||||
|
||||
@@ -129,7 +129,7 @@ SGLoadBTG(const std::string& path, const simgear::SGReaderWriterOptions* options
|
||||
} else if (simplifyDistant) {
|
||||
// Simplified terrain is only used in the distance, the
|
||||
// call-back below will re-generate the closer version
|
||||
pagedLOD->addChild(node, object_range + SG_TILE_RADIUS, FLT_MAX);
|
||||
pagedLOD->addChild(node, 2*object_range + SG_TILE_RADIUS, FLT_MAX);
|
||||
}
|
||||
|
||||
osg::ref_ptr<SGReaderWriterOptions> opt;
|
||||
@@ -152,7 +152,10 @@ SGLoadBTG(const std::string& path, const simgear::SGReaderWriterOptions* options
|
||||
// Ensure that the random objects aren't expired too quickly
|
||||
pagedLOD->setMinimumExpiryTime(pagedLOD->getNumChildren(), tile_min_expiry);
|
||||
pagedLOD->setFileName(pagedLOD->getNumChildren(), "Dummy filename for random objects callback");
|
||||
pagedLOD->setRange(pagedLOD->getNumChildren(), 0, object_range + SG_TILE_RADIUS);
|
||||
|
||||
// LOD Range is 2x the object range plus the tile radius because we display some objects up to 2x the
|
||||
// range to reduce popping.
|
||||
pagedLOD->setRange(pagedLOD->getNumChildren(), 0, 2 *object_range + SG_TILE_RADIUS);
|
||||
transform->addChild(pagedLOD);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user