From 14a3fa8ac9d4b894c5deb67d202d69bcde3e1f70 Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 22 Apr 2005 17:53:59 +0000 Subject: [PATCH] egg-flatten-radius --- panda/src/egg2pg/config_egg2pg.cxx | 31 +++++++++++++---------- panda/src/egg2pg/config_egg2pg.h | 2 +- panda/src/egg2pg/load_egg_file.cxx | 9 ++++--- panda/src/pgraph/sceneGraphReducer.I | 34 +++++++++++++++++++++++++- panda/src/pgraph/sceneGraphReducer.cxx | 29 ++++++++++++++++++++++ panda/src/pgraph/sceneGraphReducer.h | 11 ++++++--- 6 files changed, 95 insertions(+), 21 deletions(-) diff --git a/panda/src/egg2pg/config_egg2pg.cxx b/panda/src/egg2pg/config_egg2pg.cxx index 04c9d3a85e..dedb35a80f 100644 --- a/panda/src/egg2pg/config_egg2pg.cxx +++ b/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); diff --git a/panda/src/egg2pg/config_egg2pg.h b/panda/src/egg2pg/config_egg2pg.h index 2122c1a03f..bb5e9ecae4 100644 --- a/panda/src/egg2pg/config_egg2pg.h +++ b/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; diff --git a/panda/src/egg2pg/load_egg_file.cxx b/panda/src/egg2pg/load_egg_file.cxx index d97fd5370e..20b9e4b581 100644 --- a/panda/src/egg2pg/load_egg_file.cxx +++ b/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"; } diff --git a/panda/src/pgraph/sceneGraphReducer.I b/panda/src/pgraph/sceneGraphReducer.I index f2dd44634c..0fb74fb798 100644 --- a/panda/src/pgraph/sceneGraphReducer.I +++ b/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 diff --git a/panda/src/pgraph/sceneGraphReducer.cxx b/panda/src/pgraph/sceneGraphReducer.cxx index 817903bb1f..c12729517b 100644 --- a/panda/src/pgraph/sceneGraphReducer.cxx +++ b/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(); diff --git a/panda/src/pgraph/sceneGraphReducer.h b/panda/src/pgraph/sceneGraphReducer.h index f04f774e58..0d1f3345e0 100644 --- a/panda/src/pgraph/sceneGraphReducer.h +++ b/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; };