support egg2bam -combine-geoms

This commit is contained in:
David Rose 2004-09-21 22:21:53 +00:00
parent d91112167e
commit c3fd483b19
10 changed files with 100 additions and 37 deletions

View File

@ -46,8 +46,17 @@ bool egg_ignore_clamp = config_egg2pg.GetBool("egg-ignore-clamp", false);
bool egg_ignore_decals = config_egg2pg.GetBool("egg-ignore-decals", false);
bool egg_flatten = config_egg2pg.GetBool("egg-flatten", true);
// It is almost always a bad idea to set this true.
bool egg_flatten_siblings = config_egg2pg.GetBool("egg-flatten-siblings", false);
// 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 will be set to true.
bool egg_combine_geoms = config_egg2pg.GetBool("egg-combine-geoms", false);
// 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.
bool egg_combine_siblings = config_egg2pg.GetBool("egg-combine-siblings", false);
bool egg_show_collision_solids = config_egg2pg.GetBool("egg-show-collision-solids", false);

View File

@ -49,7 +49,8 @@ extern EXPCL_PANDAEGG bool egg_ignore_filters;
extern EXPCL_PANDAEGG bool egg_ignore_clamp;
extern EXPCL_PANDAEGG bool egg_ignore_decals;
extern EXPCL_PANDAEGG bool egg_flatten;
extern EXPCL_PANDAEGG bool egg_flatten_siblings;
extern EXPCL_PANDAEGG bool egg_combine_geoms;
extern EXPCL_PANDAEGG bool egg_combine_siblings;
extern EXPCL_PANDAEGG bool egg_show_collision_solids;
extern EXPCL_PANDAEGG bool egg_load_old_curves;
extern EXPCL_PANDAEGG bool egg_load_classic_nurbs_curves;

View File

@ -36,8 +36,16 @@ load_from_loader(EggLoader &loader) {
}
if (loader._root != (PandaNode *)NULL && egg_flatten) {
int combine_siblings_bits = 0;
if (egg_combine_geoms) {
combine_siblings_bits |= SceneGraphReducer::CS_geom_node;
}
if (egg_combine_siblings) {
combine_siblings_bits |= ~0;
}
SceneGraphReducer gr;
int num_reduced = gr.flatten(loader._root, egg_flatten_siblings);
int num_reduced = gr.flatten(loader._root, combine_siblings_bits);
egg2pg_cat.info() << "Flattened " << num_reduced << " nodes.\n";
}

View File

@ -131,7 +131,7 @@ rescale_source_geometry() {
// Now flatten out the geometry as much as we can.
SceneGraphReducer reducer;
reducer.apply_attribs(root);
reducer.flatten(root, true);
reducer.flatten(root, ~0);
return root;
}

View File

@ -4523,7 +4523,7 @@ flatten_medium() {
nassertr_always(!is_empty(), 0);
SceneGraphReducer gr;
gr.apply_attribs(node());
int num_removed = gr.flatten(node(), false);
int num_removed = gr.flatten(node(), 0);
return num_removed;
}
@ -4550,7 +4550,7 @@ flatten_strong() {
nassertr_always(!is_empty(), 0);
SceneGraphReducer gr;
gr.apply_attribs(node());
int num_removed = gr.flatten(node(), true);
int num_removed = gr.flatten(node(), ~0);
return num_removed;
}

View File

@ -39,16 +39,17 @@
// candidate for removal if the node has no siblings and
// the node has no special properties.
//
// If combine_siblings is true, sibling nodes may also
// be collapsed into a single node. This will further
// reduce scene graph complexity, sometimes
// substantially, at the cost of reduced spatial
// separation.
// If combine_siblings_bits is nonzero, some sibling
// nodes (according to the bits set in
// combine_siblings_bits) may also be collapsed into a
// single node. This will further reduce scene graph
// complexity, sometimes substantially, at the cost of
// reduced spatial separation.
//
// Returns the number of nodes removed from the graph.
////////////////////////////////////////////////////////////////////
int SceneGraphReducer::
flatten(PandaNode *root, bool combine_siblings) {
flatten(PandaNode *root, int combine_siblings_bits) {
int num_total_nodes = 0;
int num_pass_nodes;
@ -63,22 +64,20 @@ flatten(PandaNode *root, bool combine_siblings) {
int num_children = cr.get_num_children();
for (int i = 0; i < num_children; i++) {
PandaNode *child_node = cr.get_child(i);
num_pass_nodes += r_flatten(root, child_node, combine_siblings);
num_pass_nodes += r_flatten(root, child_node, combine_siblings_bits);
}
if (combine_siblings && root->get_num_children() >= 2) {
num_pass_nodes += flatten_siblings(root);
if (combine_siblings_bits != 0 && root->get_num_children() >= 2) {
num_pass_nodes += flatten_siblings(root, combine_siblings_bits);
}
num_total_nodes += num_pass_nodes;
// If combine_siblings is true, we should repeat the above until
// we don't get any more benefit from flattening, because each
// pass could convert cousins into siblings, which may get
// flattened next pass. If combine_siblings is not true, the
// first pass will be fully effective, and there's no point in
// trying again.
} while (combine_siblings && num_pass_nodes != 0);
// If combine_siblings_bits has CS_recurse set, we should repeat
// the above until we don't get any more benefit from flattening,
// because each pass could convert cousins into siblings, which
// may get flattened next pass.
} while ((combine_siblings_bits & CS_recurse) != 0 && num_pass_nodes != 0);
return num_total_nodes;
}
@ -218,7 +217,7 @@ r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
////////////////////////////////////////////////////////////////////
int SceneGraphReducer::
r_flatten(PandaNode *grandparent_node, PandaNode *parent_node,
bool combine_siblings) {
int combine_siblings_bits) {
int num_nodes = 0;
// First, recurse on each of the children.
@ -227,16 +226,22 @@ r_flatten(PandaNode *grandparent_node, PandaNode *parent_node,
int num_children = cr.get_num_children();
for (int i = 0; i < num_children; i++) {
PandaNode *child_node = cr.get_child(i);
num_nodes += r_flatten(parent_node, child_node, combine_siblings);
num_nodes += r_flatten(parent_node, child_node, combine_siblings_bits);
}
}
// Now that the above loop has removed some children, the child list
// saved above is no longer accurate, so hereafter we must ask the
// node for its real child list.
if (combine_siblings && parent_node->get_num_children() >= 2) {
// If we have CS_recurse set, then we flatten siblings before trying
// to flatten children. Otherwise, we flatten children first, and
// then flatten siblings, which avoids overly enthusiastic
// flattening.
if ((combine_siblings_bits & CS_recurse) != 0 &&
parent_node->get_num_children() >= 2) {
if (parent_node->safe_to_combine()) {
num_nodes += flatten_siblings(parent_node);
num_nodes += flatten_siblings(parent_node, combine_siblings_bits);
}
}
@ -260,6 +265,14 @@ r_flatten(PandaNode *grandparent_node, PandaNode *parent_node,
}
}
if ((combine_siblings_bits & CS_recurse) == 0 &&
(combine_siblings_bits & ~CS_recurse) != 0 &&
parent_node->get_num_children() >= 2) {
if (parent_node->safe_to_combine()) {
num_nodes += flatten_siblings(parent_node, combine_siblings_bits);
}
}
return num_nodes;
}
@ -295,7 +308,7 @@ operator () (const PandaNode *node1, const PandaNode *node2) const {
// of the indicated node that share the same properties.
////////////////////////////////////////////////////////////////////
int SceneGraphReducer::
flatten_siblings(PandaNode *parent_node) {
flatten_siblings(PandaNode *parent_node, int combine_siblings_bits) {
int num_nodes = 0;
// First, collect the children into groups of nodes with common
@ -312,7 +325,16 @@ flatten_siblings(PandaNode *parent_node) {
int num_children = cr.get_num_children();
for (int i = 0; i < num_children; i++) {
PandaNode *child_node = cr.get_child(i);
if (child_node->safe_to_combine()) {
bool safe_to_combine = child_node->safe_to_combine();
if (safe_to_combine) {
if (child_node->is_geom_node()) {
safe_to_combine = (combine_siblings_bits & CS_geom_node) != 0;
} else {
safe_to_combine = (combine_siblings_bits & CS_other) != 0;
}
}
if (safe_to_combine) {
collected[child_node].push_back(child_node);
}
}

View File

@ -55,19 +55,26 @@ PUBLISHED:
TT_other = 0x010,
};
enum CombineSiblings {
CS_other = 0x001,
CS_geom_node = 0x002,
CS_recurse = 0x004,
};
INLINE void apply_attribs(PandaNode *node, int attrib_types = ~0);
INLINE void apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
int attrib_types, GeomTransformer &transformer);
int flatten(PandaNode *root, bool combine_siblings);
int flatten(PandaNode *root, int combine_siblings_bits);
protected:
void r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
int attrib_types, GeomTransformer &transformer);
int r_flatten(PandaNode *grandparent_node, PandaNode *parent_node,
bool combine_siblings);
int flatten_siblings(PandaNode *parent_node);
int combine_siblings_bits);
int flatten_siblings(PandaNode *parent_node,
int combine_siblings_bits);
bool consider_child(PandaNode *grandparent_node,
PandaNode *parent_node, PandaNode *child_node);

View File

@ -294,7 +294,7 @@ generate() {
if (text_flatten) {
SceneGraphReducer gr;
gr.apply_attribs(root);
gr.flatten(root, true);
gr.flatten(root, ~0);
}
return root;

View File

@ -52,10 +52,19 @@ EggToBam() :
"instead be written to the bam file exactly as it is. If flag is "
"non-zero, the hierarchy will be flattened so that unnecessary nodes "
"(usually group nodes with only one child) are eliminated. The default "
"if this is not specified is taken from the egg-flatten Configrc "
"if this is not specified is taken from the egg-flatten Config.prc "
"variable.",
&EggToBam::dispatch_int, &_has_egg_flatten, &_egg_flatten);
add_option
("combine-geoms", "flag", 0,
"Specifies whether to combine sibling GeomNodes into a common GeomNode "
"when possible. This flag is only respected if flatten, above, is also "
"enabled (or implicitly true from the Config.prc file). The default if "
"this is not specified is taken from the egg-combine-geoms Config.prc "
"variable.",
&EggToBam::dispatch_int, &_has_egg_combine_geoms, &_egg_combine_geoms);
add_option
("suppress-hidden", "flag", 0,
"Specifies whether to suppress hidden geometry. If this is nonzero, "
@ -78,7 +87,7 @@ EggToBam() :
"inclusive, where higher numbers produce larger files with greater "
"quality. Generally, 95 is the highest useful quality level. Use "
"-NC (described below) to disable channel compression. If neither "
"option is specified, the default comes from the Configrc file.",
"option is specified, the default comes from the Config.prc file.",
&EggToBam::dispatch_int, &_has_compression_quality, &_compression_quality);
add_option
@ -107,6 +116,7 @@ EggToBam() :
_force_complete = true;
_egg_flatten = 0;
_egg_combine_geoms = 0;
_egg_suppress_hidden = 1;
}
@ -119,9 +129,13 @@ void EggToBam::
run() {
if (_has_egg_flatten) {
// If the user specified some -flatten, we need to set the
// corresponding Configrc variable.
// corresponding Config.prc variable.
egg_flatten = (_egg_flatten != 0);
}
if (_has_egg_combine_geoms) {
// Ditto with -combine_geoms.
egg_combine_geoms = (_egg_combine_geoms != 0);
}
// We always set egg_suppress_hidden.
egg_suppress_hidden = _egg_suppress_hidden;
@ -183,7 +197,7 @@ run() {
bool EggToBam::
handle_args(ProgramBase::Args &args) {
// If the user specified a path store option, we need to set the
// bam-texture-mode Configrc variable directly to support this
// bam-texture-mode Config.prc variable directly to support this
// (otherwise the bam code will do what it wants to do anyway).
if (_tex_rawdata) {
bam_texture_mode = BTM_rawdata;

View File

@ -39,6 +39,8 @@ protected:
private:
bool _has_egg_flatten;
int _egg_flatten;
bool _has_egg_combine_geoms;
int _egg_combine_geoms;
bool _egg_suppress_hidden;
bool _ls;
bool _has_compression_quality;