Significant speedup for randomly-placed objects, by taking better
advantage of ssg Frustum culling.
This commit is contained in:
parent
f7a17c9020
commit
f4cfe4c207
3 changed files with 41 additions and 27 deletions
|
@ -181,21 +181,15 @@ FGNewMat::read_properties (const SGPropertyNode * props)
|
||||||
ssgTexturePath((char *)path.dir().c_str());
|
ssgTexturePath((char *)path.dir().c_str());
|
||||||
ssgEntity * model = load_object((char *)path.c_str());
|
ssgEntity * model = load_object((char *)path.c_str());
|
||||||
if (model != 0) {
|
if (model != 0) {
|
||||||
// float ranges[] = {0, object_node->getDoubleValue("range-m", 2000)};
|
|
||||||
// object.model = new ssgRangeSelector;
|
|
||||||
// ((ssgRangeSelector *)object.model)->setRanges(ranges, 2);
|
|
||||||
if (object_node->getBoolValue("billboard", false)) {
|
if (object_node->getBoolValue("billboard", false)) {
|
||||||
ssgCutout * cutout = new ssgCutout(false);
|
ssgCutout * cutout = new ssgCutout(false);
|
||||||
cutout->addKid(model);
|
cutout->addKid(model);
|
||||||
// ((ssgBranch *)object.model)->addKid(cutout);
|
|
||||||
object.model = cutout;
|
object.model = cutout;
|
||||||
} else {
|
} else {
|
||||||
// ((ssgBranch *)object.model)->addKid(model);
|
|
||||||
object.model = model;
|
object.model = model;
|
||||||
}
|
}
|
||||||
object.model->ref();
|
object.model->ref();
|
||||||
object.coverage = object_node->getDoubleValue("coverage", 100000);
|
object.coverage = object_node->getDoubleValue("coverage", 100000);
|
||||||
object.group_lod = object_node->getDoubleValue("group-range-m", 5000);
|
|
||||||
object.lod = object_node->getDoubleValue("range-m", 2000);
|
object.lod = object_node->getDoubleValue("range-m", 2000);
|
||||||
objects.push_back(object);
|
objects.push_back(object);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -167,14 +167,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the group LOD range for a dynamic object for this material.
|
|
||||||
*/
|
|
||||||
virtual double get_object_group_lod (int i) const {
|
|
||||||
return objects[i].group_lod;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the target LOD range for a dynamic object for this material.
|
* Get the target LOD range for a dynamic object for this material.
|
||||||
*/
|
*/
|
||||||
|
@ -261,7 +253,6 @@ private:
|
||||||
{
|
{
|
||||||
ssgEntity * model;
|
ssgEntity * model;
|
||||||
double coverage;
|
double coverage;
|
||||||
double group_lod;
|
|
||||||
double lod;
|
double lod;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -456,19 +456,49 @@ out_of_range_callback (ssgEntity * entity, int mask)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ssgEntity pre-traversal callback to skip a culling test.
|
* Singleton ssgEntity with a dummy bounding sphere, to fool culling.
|
||||||
*
|
*
|
||||||
* This is necessary so that the in-range/out-of-range callbacks will
|
* This forces the in-range and out-of-range branches to be visited
|
||||||
* be reached even when there is no leaf data underneath.
|
* when appropriate, even if they have no children. It's ugly, but
|
||||||
*
|
* it works and seems fairly efficient (since branches can still
|
||||||
* @param entity The entity originating the callback (not used).
|
* be culled when they're out of the view frustum).
|
||||||
* @param mask The entity's traversal mask (not used).
|
|
||||||
* @return Always 2 to allow traversal without a cull test.
|
|
||||||
*/
|
*/
|
||||||
static int
|
class DummyBSphereEntity : public ssgEntity
|
||||||
notest_callback (ssgEntity * entity, int mask)
|
|
||||||
{
|
{
|
||||||
return 2;
|
public:
|
||||||
|
virtual ~DummyBSphereEntity () {}
|
||||||
|
virtual void recalcBSphere () { bsphere_is_invalid = false; }
|
||||||
|
virtual void cull (sgFrustum *f, sgMat4 m, int test_needed) {}
|
||||||
|
virtual void isect (sgSphere *s, sgMat4 m, int test_needed) {}
|
||||||
|
virtual void hot (sgVec3 s, sgMat4 m, int test_needed) {}
|
||||||
|
virtual void los (sgVec3 s, sgMat4 m, int test_needed) {}
|
||||||
|
static ssgEntity * get_entity ();
|
||||||
|
private:
|
||||||
|
DummyBSphereEntity ()
|
||||||
|
{
|
||||||
|
bsphere.setCenter(0, 0, 0);
|
||||||
|
bsphere.setRadius(10);
|
||||||
|
}
|
||||||
|
static DummyBSphereEntity * entity;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
DummyBSphereEntity * DummyBSphereEntity::entity = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that only one copy of the dummy entity exists.
|
||||||
|
*
|
||||||
|
* @return The singleton copy of the DummyBSphereEntity.
|
||||||
|
*/
|
||||||
|
ssgEntity *
|
||||||
|
DummyBSphereEntity::get_entity ()
|
||||||
|
{
|
||||||
|
if (entity == 0) {
|
||||||
|
entity = new DummyBSphereEntity;
|
||||||
|
entity->ref();
|
||||||
|
}
|
||||||
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -503,7 +533,6 @@ setup_triangle (float * p1, float * p2, float * p3,
|
||||||
sgMat4 TRANS;
|
sgMat4 TRANS;
|
||||||
sgMakeTransMat4(TRANS, center);
|
sgMakeTransMat4(TRANS, center);
|
||||||
location->setTransform(TRANS);
|
location->setTransform(TRANS);
|
||||||
location->setTravCallback(SSG_CALLBACK_PRETRAV, notest_callback);
|
|
||||||
branch->addKid(location);
|
branch->addKid(location);
|
||||||
|
|
||||||
// Calculate the triangle area.
|
// Calculate the triangle area.
|
||||||
|
@ -519,7 +548,6 @@ setup_triangle (float * p1, float * p2, float * p3,
|
||||||
float ranges[] = {0, mat->get_object_lod(i), 9999999};
|
float ranges[] = {0, mat->get_object_lod(i), 9999999};
|
||||||
ssgRangeSelector * lod = new ssgRangeSelector;
|
ssgRangeSelector * lod = new ssgRangeSelector;
|
||||||
lod->setRanges(ranges, 3);
|
lod->setRanges(ranges, 3);
|
||||||
lod->setTravCallback(SSG_CALLBACK_PRETRAV, notest_callback);
|
|
||||||
location->addKid(lod);
|
location->addKid(lod);
|
||||||
|
|
||||||
// Create the in-range and out-of-range
|
// Create the in-range and out-of-range
|
||||||
|
@ -550,6 +578,7 @@ setup_triangle (float * p1, float * p2, float * p3,
|
||||||
out_of_range->setUserData(data);
|
out_of_range->setUserData(data);
|
||||||
out_of_range->setTravCallback(SSG_CALLBACK_PRETRAV,
|
out_of_range->setTravCallback(SSG_CALLBACK_PRETRAV,
|
||||||
out_of_range_callback);
|
out_of_range_callback);
|
||||||
|
out_of_range->addKid(DummyBSphereEntity::get_entity());
|
||||||
lod->addKid(out_of_range);
|
lod->addKid(out_of_range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue