Просмотр исходного кода

add max_children to SceneGraphReducer

David Rose 24 лет назад
Родитель
Сommit
f1c43d4e48

+ 40 - 6
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++;
+        }
       }
     }
   }

+ 2 - 0
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;
 };
 

+ 12 - 2
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);
 

+ 2 - 2
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;