Przeglądaj źródła

egg-flatten-radius

David Rose 20 lat temu
rodzic
commit
14a3fa8ac9

+ 18 - 13
panda/src/egg2pg/config_egg2pg.cxx

@@ -45,23 +45,28 @@ ConfigVariableBool egg_ignore_clamp
 ConfigVariableBool egg_ignore_decals
 ("egg-ignore-decals", false);
 ConfigVariableBool egg_flatten
-("egg-flatten", true);
+("egg-flatten", true,
+ PRC_DESC("This is normally true to flatten out useless nodes after loading "
+          "an egg file.  Set it false if you want to see the complete "
+          "and true hierarchy as the egg loader created it (although the "
+          "extra nodes may have a small impact on render performance)."));
+
+ConfigVariableDouble egg_flatten_radius
+("egg-flatten-radius", 5.0,
+ PRC_DESC("This specifies the minimum cull radius in the egg file.  Nodes "
+          "whose bounding volume is smaller than this radius will be "
+          "flattened tighter than nodes larger than this radius, to "
+          "reduce the node count even further.  The idea is that small "
+          "objects will not need to have their individual components "
+          "culled separately, but large environments should.  This allows "
+          "the user to specify what should be considered \"small\".  Set "
+          "it to 0.0 to disable this feature."));
 
 ConfigVariableBool egg_combine_geoms
 ("egg-combine-geoms", false,
  PRC_DESC("Set this true to combine sibling GeomNodes into a single GeomNode, "
-          "when possible.  This is probably a good idea in general, but we "
-          "have it default to false for now for historical reasons (to avoid "
-          "breaking code that assumes this doesn't happen).  Eventually the "
-          "default may be set to true."));
-
-
-ConfigVariableBool egg_combine_siblings
-("egg-combine-siblings", false,
- PRC_DESC("Set this true to combine siblings of any combinable type into a "
-          "single Node when possible.  It is almost always a bad idea to set "
-          "this true."));
-
+          "when possible.  This usually shouldn't be necessary, since the "
+          "egg loader does a pretty good job of combining these by itself."));
 
 ConfigVariableBool egg_show_collision_solids
 ("egg-show-collision-solids", false);

+ 1 - 1
panda/src/egg2pg/config_egg2pg.h

@@ -41,8 +41,8 @@ extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_filters;
 extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_clamp;
 extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_decals;
 extern EXPCL_PANDAEGG ConfigVariableBool egg_flatten;
+extern EXPCL_PANDAEGG ConfigVariableDouble egg_flatten_radius;
 extern EXPCL_PANDAEGG ConfigVariableBool egg_combine_geoms;
-extern EXPCL_PANDAEGG ConfigVariableBool egg_combine_siblings;
 extern EXPCL_PANDAEGG ConfigVariableBool egg_show_collision_solids;
 extern EXPCL_PANDAEGG ConfigVariableBool egg_load_old_curves;
 extern EXPCL_PANDAEGG ConfigVariableBool egg_load_classic_nurbs_curves;

+ 6 - 3
panda/src/egg2pg/load_egg_file.cxx

@@ -36,17 +36,20 @@ load_from_loader(EggLoader &loader) {
   }
 
   if (loader._root != (PandaNode *)NULL && egg_flatten) {
+    SceneGraphReducer gr;
+
     int combine_siblings_bits = 0;
     if (egg_combine_geoms) {
       combine_siblings_bits |= SceneGraphReducer::CS_geom_node;
     }
-    if (egg_combine_siblings) {
-      combine_siblings_bits |= ~0;
+    if (egg_flatten_radius > 0.0) {
+      combine_siblings_bits |= SceneGraphReducer::CS_within_radius;
+      gr.set_combine_radius(egg_flatten_radius);
     }
 
-    SceneGraphReducer gr;
     int num_reduced = gr.flatten(loader._root, combine_siblings_bits);
     //    gr.collect_vertex_data(loader._root);
+    //    gr.unify(loader._root);
     egg2pg_cat.info() << "Flattened " << num_reduced << " nodes.\n";
   }
 

+ 33 - 1
panda/src/pgraph/sceneGraphReducer.I

@@ -23,7 +23,9 @@
 //  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE SceneGraphReducer::
-SceneGraphReducer() {
+SceneGraphReducer() :
+  _combine_radius(0.0f)
+{
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -61,6 +63,36 @@ get_usage_hint() const {
   return _transformer.get_usage_hint();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: SceneGraphReducer::set_combine_radius
+//       Access: Published
+//  Description: Specifies the radius that is used in conjunction with
+//               CS_within_radius to decide whether a subgraph's
+//               siblings should be combined into a single node or
+//               not.
+//
+//               If the CS_within_radius bit is included in the
+//               combine_siblings_bits parameter passed to flatten,
+//               than any nodes whose bounding volume is smaller than
+//               the indicated radius will be combined together (as if
+//               CS_other were set).
+////////////////////////////////////////////////////////////////////
+INLINE void SceneGraphReducer::
+set_combine_radius(float combine_radius) {
+  _combine_radius = combine_radius;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: SceneGraphReducer::get_combine_radius
+//       Access: Published
+//  Description: Returns the radius that is used in conjunction with
+//               CS_within_radius.  See set_combine_radius().
+////////////////////////////////////////////////////////////////////
+INLINE float SceneGraphReducer::
+get_combine_radius() const {
+  return _combine_radius;
+}
+
 
 ////////////////////////////////////////////////////////////////////
 //     Function: SceneGraphReducer::apply_attribs

+ 29 - 0
panda/src/pgraph/sceneGraphReducer.cxx

@@ -214,9 +214,38 @@ r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
 int SceneGraphReducer::
 r_flatten(PandaNode *grandparent_node, PandaNode *parent_node,
           int combine_siblings_bits) {
+  if (pgraph_cat.is_spam()) {
+    pgraph_cat.spam()
+      << "SceneGraphReducer::r_flatten(" << *grandparent_node << ", " 
+      << *parent_node << ", " << hex << combine_siblings_bits << dec
+      << ")\n";
+  }
   int num_nodes = 0;
 
   if (parent_node->safe_to_flatten_below()) {
+    if ((combine_siblings_bits & CS_within_radius) != 0) {
+      const BoundingVolume *bv = &parent_node->get_bound();
+      if (bv->is_of_type(BoundingSphere::get_class_type())) {
+        const BoundingSphere *bs = DCAST(BoundingSphere, bv);
+        if (pgraph_cat.is_spam()) {
+          pgraph_cat.spam()
+            << "considering radius of " << *parent_node
+            << ": " << *bs << " vs. " << _combine_radius << "\n";
+        }
+        if (bs->is_empty() || bs->get_radius() <= _combine_radius) {
+          // This node fits within the specified radius; from here on
+          // down, we will have CS_other set, instead of
+          // CS_within_radius.
+          if (pgraph_cat.is_spam()) {
+            pgraph_cat.spam()
+              << "node fits within radius; flattening tighter.\n";
+          }
+          combine_siblings_bits &= ~CS_within_radius;
+          combine_siblings_bits |= (CS_geom_node | CS_other | CS_recurse);
+        }
+      }
+    }
+
     // First, recurse on each of the children.
     {
       PandaNode::ChildrenCopy cr = parent_node->get_children_copy();

+ 8 - 3
panda/src/pgraph/sceneGraphReducer.h

@@ -56,9 +56,10 @@ PUBLISHED:
   };
 
   enum CombineSiblings {
-    CS_other           = 0x001,
-    CS_geom_node       = 0x002,
-    CS_recurse         = 0x004,
+    CS_geom_node       = 0x001,
+    CS_within_radius   = 0x002,
+    CS_other           = 0x004,
+    CS_recurse         = 0x008,
   };
 
   enum CollectVertexData {
@@ -106,6 +107,9 @@ PUBLISHED:
   INLINE void set_usage_hint(qpGeom::UsageHint usage_hint);
   INLINE qpGeom::UsageHint get_usage_hint() const;
 
+  INLINE void set_combine_radius(float combine_radius);
+  INLINE float get_combine_radius() const;
+
   INLINE void apply_attribs(PandaNode *node, int attrib_types = ~0);
   INLINE void apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
                             int attrib_types, GeomTransformer &transformer);
@@ -147,6 +151,7 @@ protected:
   void r_unify(PandaNode *node);
 
 private:
+  float _combine_radius;
   GeomTransformer _transformer;
 };