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 {
/**
- * 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;
}
sgMat4 TRANS;
sgMakeTransMat4(TRANS, center);
location->setTransform(TRANS);
- location->setTravCallback(SSG_CALLBACK_PRETRAV, notest_callback);
branch->addKid(location);
// Calculate the triangle area.
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
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);
}
}