Building performance improvements.

Use sensible LoD range of 10km and gradual fade-out to 20km rather
than fixed 20km+ LoD range.  Also make deeper quad-tree to make
culling easier.
This commit is contained in:
Stuart Buchanan 2013-02-06 21:53:57 +00:00
parent 5dea221ad5
commit fd8369142a
4 changed files with 33 additions and 15 deletions

View File

@ -321,6 +321,8 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options,
building_large_min_depth = props->getFloatValue("building-large-min-depth-m", 50.0); 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_large_max_depth = props->getFloatValue("building-large-max-depth-m", 75.0);
building_range = props->getDoubleValue("building-range-m", 10000.0);
cos_object_max_density_slope_angle = cos(props->getFloatValue("object-max-density-angle-deg", 20.0) * osg::PI/180.0); 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); cos_object_zero_density_slope_angle = cos(props->getFloatValue("object-zero-density-angle-deg", 30.0) * osg::PI/180.0);

View File

@ -211,6 +211,8 @@ public:
inline double get_building_large_min_depth () const { return building_large_min_depth; } inline double get_building_large_min_depth () const { return building_large_min_depth; }
inline double get_building_large_max_depth () const { return building_large_max_depth; } inline double get_building_large_max_depth () const { return building_large_max_depth; }
inline double get_building_range () const { return building_range; }
inline double get_cos_object_max_density_slope_angle () const { return cos_object_max_density_slope_angle; } inline double get_cos_object_max_density_slope_angle () const { return cos_object_max_density_slope_angle; }
inline double get_cos_object_zero_density_slope_angle () const { return cos_object_zero_density_slope_angle; } inline double get_cos_object_zero_density_slope_angle () const { return cos_object_zero_density_slope_angle; }
@ -415,6 +417,8 @@ private:
double building_large_min_depth; double building_large_min_depth;
double building_large_max_depth; double building_large_max_depth;
double building_range;
// Cosine of the angle of maximum and zero density, // Cosine of the angle of maximum and zero density,
// used to stop buildings and random objects from being // used to stop buildings and random objects from being
// created on too steep a slope. // created on too steep a slope.

View File

@ -64,7 +64,6 @@ namespace simgear
typedef std::map<std::string, osg::observer_ptr<osg::StateSet> > BuildingStateSetMap; typedef std::map<std::string, osg::observer_ptr<osg::StateSet> > BuildingStateSetMap;
static BuildingStateSetMap statesetmap; static BuildingStateSetMap statesetmap;
static int numBuildings;
typedef std::map<std::string, osg::observer_ptr<Effect> > EffectMap; typedef std::map<std::string, osg::observer_ptr<Effect> > EffectMap;
static EffectMap buildingEffectMap; static EffectMap buildingEffectMap;
@ -136,6 +135,8 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
smallBuildingFraction = mat->get_building_small_fraction(); smallBuildingFraction = mat->get_building_small_fraction();
mediumBuildingFraction = mat->get_building_medium_fraction(); mediumBuildingFraction = mat->get_building_medium_fraction();
buildingRange = mat->get_building_range();
SG_LOG(SG_TERRAIN, SG_DEBUG, "Building fractions " << smallBuildingFraction << " " << mediumBuildingFraction); SG_LOG(SG_TERRAIN, SG_DEBUG, "Building fractions " << smallBuildingFraction << " " << mediumBuildingFraction);
@ -753,10 +754,11 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
// Create a quad tree. Only small and medium buildings are faded out.
BuildingGeometryQuadtree BuildingGeometryQuadtree
quadbuilding(GetBuildingCoord(), AddBuildingLeafObject(), quadbuilding(GetBuildingCoord(), AddBuildingLeafObject(),
SG_BUILDING_QUAD_TREE_DEPTH, SG_BUILDING_QUAD_TREE_DEPTH,
MakeBuildingLeaf(20000.0, effect)); MakeBuildingLeaf(buildingRange, effect, (i != 2)));
// Transform building positions from the "geocentric" positions we // Transform building positions from the "geocentric" positions we
// get from the scenery polys into the local Z-up coordinate // get from the scenery polys into the local Z-up coordinate
@ -768,8 +770,8 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
BuildingInstanceTransformer(transInv)); BuildingInstanceTransformer(transInv));
quadbuilding.buildQuadTree(rotatedBuildings.begin(), rotatedBuildings.end()); quadbuilding.buildQuadTree(rotatedBuildings.begin(), rotatedBuildings.end());
for (size_t i = 0; i < quadbuilding.getRoot()->getNumChildren(); ++i) for (size_t j = 0; j < quadbuilding.getRoot()->getNumChildren(); ++j)
group->addChild(quadbuilding.getRoot()->getChild(i)); group->addChild(quadbuilding.getRoot()->getChild(j));
} }
return group; return group;
@ -829,7 +831,6 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
BOOST_FOREACH(bin, buildings) BOOST_FOREACH(bin, buildings)
{ {
numBuildings = numBuildings + bin->getNumBuildings();
ref_ptr<Group> group = bin->createBuildingsGroup(transInv, options); ref_ptr<Group> group = bin->createBuildingsGroup(transInv, options);
for (size_t i = 0; i < group->getNumChildren(); ++i) for (size_t i = 0; i < group->getNumChildren(); ++i)

View File

@ -45,7 +45,7 @@
#include <simgear/scene/util/StateAttributeFactory.hxx> #include <simgear/scene/util/StateAttributeFactory.hxx>
#include <simgear/structure/OSGUtils.hxx> #include <simgear/structure/OSGUtils.hxx>
#define SG_BUILDING_QUAD_TREE_DEPTH 2 #define SG_BUILDING_QUAD_TREE_DEPTH 4
#define SG_BUILDING_FADE_OUT_LEVELS 4 #define SG_BUILDING_FADE_OUT_LEVELS 4
using namespace osg; using namespace osg;
@ -118,6 +118,9 @@ private:
float mediumBuildingMaxDepth; float mediumBuildingMaxDepth;
float largeBuildingMaxDepth; float largeBuildingMaxDepth;
// Visibility range for buildings
float buildingRange;
// Shared geometries of the building set // Shared geometries of the building set
ref_ptr<Geometry> smallSharedGeometry; ref_ptr<Geometry> smallSharedGeometry;
ref_ptr<Geometry> mediumSharedGeometry; ref_ptr<Geometry> mediumSharedGeometry;
@ -191,18 +194,19 @@ public:
// Helper classes for creating the quad tree // Helper classes for creating the quad tree
struct MakeBuildingLeaf struct MakeBuildingLeaf
{ {
MakeBuildingLeaf(float range, Effect* effect) : MakeBuildingLeaf(float range, Effect* effect, bool fade) :
_range(range), _effect(effect) {} _range(range), _effect(effect), _fade_out(fade) {}
MakeBuildingLeaf(const MakeBuildingLeaf& rhs) : MakeBuildingLeaf(const MakeBuildingLeaf& rhs) :
_range(rhs._range), _effect(rhs._effect) _range(rhs._range), _effect(rhs._effect), _fade_out(rhs._fade_out)
{} {}
LOD* operator() () const LOD* operator() () const
{ {
LOD* result = new LOD; LOD* result = new LOD;
// Create a series of LOD nodes so trees cover decreases slightly if (_fade_out) {
// Create a series of LOD nodes so buidling cover decreases
// gradually with distance from _range to 2*_range // gradually with distance from _range to 2*_range
for (float i = 0.0; i < SG_BUILDING_FADE_OUT_LEVELS; i++) for (float i = 0.0; i < SG_BUILDING_FADE_OUT_LEVELS; i++)
{ {
@ -210,11 +214,18 @@ public:
geode->setEffect(_effect.get()); geode->setEffect(_effect.get());
result->addChild(geode, 0, _range * (1.0 + i / (SG_BUILDING_FADE_OUT_LEVELS - 1.0))); result->addChild(geode, 0, _range * (1.0 + i / (SG_BUILDING_FADE_OUT_LEVELS - 1.0)));
} }
} else {
// No fade-out, so all are visible for 2X range
EffectGeode* geode = new EffectGeode;
geode->setEffect(_effect.get());
result->addChild(geode, 0, 2.0 * _range);
}
return result; return result;
} }
float _range; float _range;
ref_ptr<Effect> _effect; ref_ptr<Effect> _effect;
bool _fade_out;
}; };
struct AddBuildingLeafObject struct AddBuildingLeafObject