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:
parent
5dea221ad5
commit
fd8369142a
@ -320,6 +320,8 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options,
|
|||||||
building_large_max_width = props->getFloatValue("building-large-max-width-m", 75.0);
|
building_large_max_width = props->getFloatValue("building-large-max-width-m", 75.0);
|
||||||
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);
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
@ -826,10 +828,9 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
|
|||||||
MatrixTransform* mt = new MatrixTransform(transform);
|
MatrixTransform* mt = new MatrixTransform(transform);
|
||||||
|
|
||||||
SGBuildingBin* bin = NULL;
|
SGBuildingBin* bin = NULL;
|
||||||
|
|
||||||
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)
|
||||||
|
@ -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,30 +194,38 @@ 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) {
|
||||||
// gradually with distance from _range to 2*_range
|
// Create a series of LOD nodes so buidling cover decreases
|
||||||
for (float i = 0.0; i < SG_BUILDING_FADE_OUT_LEVELS; i++)
|
// 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;
|
EffectGeode* geode = new EffectGeode;
|
||||||
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, 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
|
||||||
|
Loading…
Reference in New Issue
Block a user