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());
|
||||
ssgEntity * model = load_object((char *)path.c_str());
|
||||
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)) {
|
||||
ssgCutout * cutout = new ssgCutout(false);
|
||||
cutout->addKid(model);
|
||||
// ((ssgBranch *)object.model)->addKid(cutout);
|
||||
object.model = cutout;
|
||||
} else {
|
||||
// ((ssgBranch *)object.model)->addKid(model);
|
||||
object.model = model;
|
||||
}
|
||||
object.model->ref();
|
||||
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);
|
||||
objects.push_back(object);
|
||||
} 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.
|
||||
*/
|
||||
|
@ -261,7 +253,6 @@ private:
|
|||
{
|
||||
ssgEntity * model;
|
||||
double coverage;
|
||||
double group_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
|
||||
* be reached even when there is no leaf data underneath.
|
||||
*
|
||||
* @param entity The entity originating the callback (not used).
|
||||
* @param mask The entity's traversal mask (not used).
|
||||
* @return Always 2 to allow traversal without a cull test.
|
||||
* This forces the in-range and out-of-range branches to be visited
|
||||
* when appropriate, even if they have no children. It's ugly, but
|
||||
* it works and seems fairly efficient (since branches can still
|
||||
* be culled when they're out of the view frustum).
|
||||
*/
|
||||
static int
|
||||
notest_callback (ssgEntity * entity, int mask)
|
||||
class DummyBSphereEntity : public ssgEntity
|
||||
{
|
||||
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;
|
||||
sgMakeTransMat4(TRANS, center);
|
||||
location->setTransform(TRANS);
|
||||
location->setTravCallback(SSG_CALLBACK_PRETRAV, notest_callback);
|
||||
branch->addKid(location);
|
||||
|
||||
// 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};
|
||||
ssgRangeSelector * lod = new ssgRangeSelector;
|
||||
lod->setRanges(ranges, 3);
|
||||
lod->setTravCallback(SSG_CALLBACK_PRETRAV, notest_callback);
|
||||
location->addKid(lod);
|
||||
|
||||
// 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->setTravCallback(SSG_CALLBACK_PRETRAV,
|
||||
out_of_range_callback);
|
||||
out_of_range->addKid(DummyBSphereEntity::get_entity());
|
||||
lod->addKid(out_of_range);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue