From f4cfe4c207c5219d98d3c31311ae13fdb0e245ff Mon Sep 17 00:00:00 2001 From: david Date: Thu, 18 Jul 2002 13:23:29 +0000 Subject: [PATCH] Significant speedup for randomly-placed objects, by taking better advantage of ssg Frustum culling. --- src/Objects/newmat.cxx | 6 ----- src/Objects/newmat.hxx | 9 -------- src/Objects/obj.cxx | 51 +++++++++++++++++++++++++++++++++--------- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/Objects/newmat.cxx b/src/Objects/newmat.cxx index 0bcb9f887..67d4fba2a 100644 --- a/src/Objects/newmat.cxx +++ b/src/Objects/newmat.cxx @@ -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 { diff --git a/src/Objects/newmat.hxx b/src/Objects/newmat.hxx index fedfda1d4..3e9f05a66 100644 --- a/src/Objects/newmat.hxx +++ b/src/Objects/newmat.hxx @@ -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; }; diff --git a/src/Objects/obj.cxx b/src/Objects/obj.cxx index de92cf219..d3c76f913 100644 --- a/src/Objects/obj.cxx +++ b/src/Objects/obj.cxx @@ -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. + * 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). + */ +class DummyBSphereEntity : public ssgEntity +{ +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. * - * @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. + * @return The singleton copy of the DummyBSphereEntity. */ -static int -notest_callback (ssgEntity * entity, int mask) +ssgEntity * +DummyBSphereEntity::get_entity () { - return 2; + 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); } } -- 2.39.5