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_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_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_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_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_max_depth;
double building_range;
// Cosine of the angle of maximum and zero density,
// used to stop buildings and random objects from being
// 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;
static BuildingStateSetMap statesetmap;
static int numBuildings;
typedef std::map<std::string, osg::observer_ptr<Effect> > EffectMap;
static EffectMap buildingEffectMap;
@ -136,6 +135,8 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
smallBuildingFraction = mat->get_building_small_fraction();
mediumBuildingFraction = mat->get_building_medium_fraction();
buildingRange = mat->get_building_range();
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++)
{
// Create a quad tree. Only small and medium buildings are faded out.
BuildingGeometryQuadtree
quadbuilding(GetBuildingCoord(), AddBuildingLeafObject(),
SG_BUILDING_QUAD_TREE_DEPTH,
MakeBuildingLeaf(20000.0, effect));
MakeBuildingLeaf(buildingRange, effect, (i != 2)));
// Transform building positions from the "geocentric" positions we
// get from the scenery polys into the local Z-up coordinate
@ -768,8 +770,8 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
BuildingInstanceTransformer(transInv));
quadbuilding.buildQuadTree(rotatedBuildings.begin(), rotatedBuildings.end());
for (size_t i = 0; i < quadbuilding.getRoot()->getNumChildren(); ++i)
group->addChild(quadbuilding.getRoot()->getChild(i));
for (size_t j = 0; j < quadbuilding.getRoot()->getNumChildren(); ++j)
group->addChild(quadbuilding.getRoot()->getChild(j));
}
return group;
@ -829,7 +831,6 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
BOOST_FOREACH(bin, buildings)
{
numBuildings = numBuildings + bin->getNumBuildings();
ref_ptr<Group> group = bin->createBuildingsGroup(transInv, options);
for (size_t i = 0; i < group->getNumChildren(); ++i)

View File

@ -45,7 +45,7 @@
#include <simgear/scene/util/StateAttributeFactory.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
using namespace osg;
@ -118,6 +118,9 @@ private:
float mediumBuildingMaxDepth;
float largeBuildingMaxDepth;
// Visibility range for buildings
float buildingRange;
// Shared geometries of the building set
ref_ptr<Geometry> smallSharedGeometry;
ref_ptr<Geometry> mediumSharedGeometry;
@ -191,30 +194,38 @@ public:
// Helper classes for creating the quad tree
struct MakeBuildingLeaf
{
MakeBuildingLeaf(float range, Effect* effect) :
_range(range), _effect(effect) {}
MakeBuildingLeaf(float range, Effect* effect, bool fade) :
_range(range), _effect(effect), _fade_out(fade) {}
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* result = new LOD;
// Create a series of LOD nodes so trees cover decreases slightly
// gradually with distance from _range to 2*_range
for (float i = 0.0; i < SG_BUILDING_FADE_OUT_LEVELS; i++)
{
if (_fade_out) {
// Create a series of LOD nodes so buidling cover decreases
// gradually with distance from _range to 2*_range
for (float i = 0.0; i < SG_BUILDING_FADE_OUT_LEVELS; i++)
{
EffectGeode* geode = new EffectGeode;
geode->setEffect(_effect.get());
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, _range * (1.0 + i / (SG_BUILDING_FADE_OUT_LEVELS - 1.0)));
result->addChild(geode, 0, 2.0 * _range);
}
return result;
}
float _range;
ref_ptr<Effect> _effect;
bool _fade_out;
};
struct AddBuildingLeafObject