egg-flatten-radius

This commit is contained in:
David Rose 2005-04-22 17:53:59 +00:00
parent c748fb4fee
commit 14a3fa8ac9
6 changed files with 95 additions and 21 deletions

View File

@ -45,23 +45,28 @@ ConfigVariableBool egg_ignore_clamp
ConfigVariableBool egg_ignore_decals ConfigVariableBool egg_ignore_decals
("egg-ignore-decals", false); ("egg-ignore-decals", false);
ConfigVariableBool egg_flatten 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 ConfigVariableBool egg_combine_geoms
("egg-combine-geoms", false, ("egg-combine-geoms", false,
PRC_DESC("Set this true to combine sibling GeomNodes into a single GeomNode, " 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 " "when possible. This usually shouldn't be necessary, since the "
"have it default to false for now for historical reasons (to avoid " "egg loader does a pretty good job of combining these by itself."));
"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."));
ConfigVariableBool egg_show_collision_solids ConfigVariableBool egg_show_collision_solids
("egg-show-collision-solids", false); ("egg-show-collision-solids", false);

View File

@ -41,8 +41,8 @@ extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_filters;
extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_clamp; extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_clamp;
extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_decals; extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_decals;
extern EXPCL_PANDAEGG ConfigVariableBool egg_flatten; 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_geoms;
extern EXPCL_PANDAEGG ConfigVariableBool egg_combine_siblings;
extern EXPCL_PANDAEGG ConfigVariableBool egg_show_collision_solids; extern EXPCL_PANDAEGG ConfigVariableBool egg_show_collision_solids;
extern EXPCL_PANDAEGG ConfigVariableBool egg_load_old_curves; extern EXPCL_PANDAEGG ConfigVariableBool egg_load_old_curves;
extern EXPCL_PANDAEGG ConfigVariableBool egg_load_classic_nurbs_curves; extern EXPCL_PANDAEGG ConfigVariableBool egg_load_classic_nurbs_curves;

View File

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

View File

@ -23,7 +23,9 @@
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE SceneGraphReducer:: INLINE SceneGraphReducer::
SceneGraphReducer() { SceneGraphReducer() :
_combine_radius(0.0f)
{
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -61,6 +63,36 @@ get_usage_hint() const {
return _transformer.get_usage_hint(); 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 // Function: SceneGraphReducer::apply_attribs

View File

@ -214,9 +214,38 @@ r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
int SceneGraphReducer:: int SceneGraphReducer::
r_flatten(PandaNode *grandparent_node, PandaNode *parent_node, r_flatten(PandaNode *grandparent_node, PandaNode *parent_node,
int combine_siblings_bits) { 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; int num_nodes = 0;
if (parent_node->safe_to_flatten_below()) { 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. // First, recurse on each of the children.
{ {
PandaNode::ChildrenCopy cr = parent_node->get_children_copy(); PandaNode::ChildrenCopy cr = parent_node->get_children_copy();

View File

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