diff --git a/panda/src/graph/graphReducer.cxx b/panda/src/graph/graphReducer.cxx index 971498065f..29b1c98f40 100644 --- a/panda/src/graph/graphReducer.cxx +++ b/panda/src/graph/graphReducer.cxx @@ -33,6 +33,7 @@ GraphReducer:: GraphReducer(TypeHandle graph_type) : _graph_type(graph_type) { + _max_children = 1; } //////////////////////////////////////////////////////////////////// @@ -44,6 +45,25 @@ GraphReducer:: ~GraphReducer() { } +//////////////////////////////////////////////////////////////////// +// Function: GraphReducer::set_max_children +// Access: Public +// Description: Sets the maximum number of children a node is allowed +// to have and still be flattened. Normally, this is 1; +// we don't typically want to flatten a node that has +// multiple children. However, sometimes this may be +// desirable; set this parameter to control the limit. +// If this is set to -1, there is no limit. +// +// If any of a node's arcs cannot be flattened, +// generally none of them will be, although this depends +// on how late the inability to flatten a particular arc +// is discovered. +//////////////////////////////////////////////////////////////////// +void GraphReducer:: +set_max_children(int count) { + _max_children = count; +} //////////////////////////////////////////////////////////////////// // Function: GraphReducer::flatten @@ -128,12 +148,26 @@ r_flatten(Node *root, bool combine_siblings) { num_nodes += flatten_siblings(root); } - if (drp.size() == 1) { - // If we have exactly one child, consider flattening it. - NodeRelation *arc = *drp.begin(); - if (consider_arc(arc)) { - if (flatten_arc(arc)) { - num_nodes++; + if (!drp.empty() && (_max_children < 0 || (int)drp.size() <= _max_children)) { + // If we don't have too many children, consider flattening each of + // our child arcs. + bool all_ok = true; + for (drpi = drp_copy.begin(); drpi != drp_copy.end() && all_ok; ++drpi) { + NodeRelation *arc = (*drpi); + all_ok = consider_arc(arc); + } + + if (all_ok) { + // All our arcs can (potentially) be flattened; do it. + + // Get a new copy of the children list. + drp_copy = drp; + + for (drpi = drp_copy.begin(); drpi != drp_copy.end(); ++drpi) { + NodeRelation *arc = (*drpi); + if (flatten_arc(arc)) { + num_nodes++; + } } } } diff --git a/panda/src/graph/graphReducer.h b/panda/src/graph/graphReducer.h index e7b2af33a7..78bd8d5466 100644 --- a/panda/src/graph/graphReducer.h +++ b/panda/src/graph/graphReducer.h @@ -39,6 +39,7 @@ public: GraphReducer(TypeHandle graph_type); virtual ~GraphReducer(); + void set_max_children(int count); int flatten(Node *root, bool combine_siblings); protected: @@ -61,6 +62,7 @@ protected: void copy_children(Node *to, Node *from); protected: + int _max_children; TypeHandle _graph_type; }; diff --git a/panda/src/sgmanip/nodePath.cxx b/panda/src/sgmanip/nodePath.cxx index 8bbe096d56..ce41110985 100644 --- a/panda/src/sgmanip/nodePath.cxx +++ b/panda/src/sgmanip/nodePath.cxx @@ -1147,12 +1147,21 @@ flatten_light() { // flatten_light() because the number of nodes in the // scene graph is reduced. // +// If max_children is specified, it represents the +// maximum number of children a node is allowed to have +// and still be flattened. Normally, this is 1; we +// don't typically want to flatten a node that has +// multiple children. However, sometimes this may be +// desirable; set this parameter to control the limit. +// If this is set to -1, there is no limit. +// // The return value is the number of arcs removed. //////////////////////////////////////////////////////////////////// int NodePath:: -flatten_medium() { +flatten_medium(int max_children) { nassertr(!is_empty(), 0); SceneGraphReducer gr(_graph_type); + gr.set_max_children(max_children); gr.apply_transitions(arc()); int num_removed = gr.flatten(node(), false); @@ -1182,9 +1191,10 @@ flatten_medium() { // because of less-effective culling. //////////////////////////////////////////////////////////////////// int NodePath:: -flatten_strong() { +flatten_strong(int max_children) { nassertr(!is_empty(), 0); SceneGraphReducer gr(_graph_type); + gr.set_max_children(max_children); gr.apply_transitions(arc()); int num_removed = gr.flatten(node(), true); diff --git a/panda/src/sgmanip/nodePath.h b/panda/src/sgmanip/nodePath.h index 384f61ae44..5bdc503629 100644 --- a/panda/src/sgmanip/nodePath.h +++ b/panda/src/sgmanip/nodePath.h @@ -255,8 +255,8 @@ PUBLISHED: void analyze() const; int flatten_light(); - int flatten_medium(); - int flatten_strong(); + int flatten_medium(int max_children = 1); + int flatten_strong(int max_children = 1); bool write_bam_file(const string &filename) const;