Browse Source

add clear_model_nodes

David Rose 17 years ago
parent
commit
a89acc64a2

+ 30 - 4
panda/src/pgraph/modelNode.cxx

@@ -34,6 +34,32 @@ make_copy() const {
   return new ModelNode(*this);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ModelNode::combine_with
+//       Access: Public, Virtual
+//  Description: Collapses this PandaNode with the other PandaNode, if
+//               possible, and returns a pointer to the combined
+//               PandaNode, or NULL if the two PandaNodes cannot
+//               safely be combined.
+//
+//               The return value may be this, other, or a new
+//               PandaNode altogether.
+//
+//               This function is called from GraphReducer::flatten(),
+//               and need not deal with children; its job is just to
+//               decide whether to collapse the two PandaNodes and
+//               what the collapsed PandaNode should look like.
+////////////////////////////////////////////////////////////////////
+PandaNode *ModelNode::
+combine_with(PandaNode *other) {
+  if (_preserve_transform == PT_drop_node) {
+    // If we have PT_drop_node set, we always yield to the other node.
+    return other;
+  }
+
+  return PandaNode::combine_with(other);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ModelNode::safe_to_flatten
 //       Access: Public, Virtual
@@ -45,7 +71,7 @@ make_copy() const {
 ////////////////////////////////////////////////////////////////////
 bool ModelNode::
 safe_to_flatten() const {
-  return false;
+  return _preserve_transform == PT_drop_node;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -58,7 +84,7 @@ safe_to_flatten() const {
 ////////////////////////////////////////////////////////////////////
 bool ModelNode::
 safe_to_transform() const {
-  return _preserve_transform == PT_none;
+  return _preserve_transform == PT_none || _preserve_transform == PT_drop_node;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -90,7 +116,7 @@ safe_to_modify_transform() const {
 ////////////////////////////////////////////////////////////////////
 bool ModelNode::
 safe_to_combine() const {
-  return false;
+  return _preserve_transform == PT_drop_node;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -102,7 +128,7 @@ safe_to_combine() const {
 ////////////////////////////////////////////////////////////////////
 bool ModelNode::
 preserve_name() const {
-  return true;
+  return _preserve_transform != PT_drop_node;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 3 - 1
panda/src/pgraph/modelNode.h

@@ -41,6 +41,7 @@ protected:
 public:
   virtual PandaNode *make_copy() const;
 
+  virtual PandaNode *combine_with(PandaNode *other); 
   virtual bool safe_to_flatten() const;
   virtual bool safe_to_transform() const;
   virtual bool safe_to_modify_transform() const;
@@ -52,7 +53,8 @@ PUBLISHED:
   enum PreserveTransform {
     PT_none,
     PT_local,
-    PT_net
+    PT_net,
+    PT_drop_node,
   };
 
   INLINE void set_preserve_transform(PreserveTransform preserve_transform);

+ 17 - 0
panda/src/pgraph/nodePath.I

@@ -2131,6 +2131,23 @@ compare_to(const NodePath &other) const {
   return 0;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: NodePath::clear_model_nodes
+//       Access: Published
+//  Description: Recursively walks through the scene graph at this
+//               level and below, looking for ModelNodes, and calls
+//               model_node->set_preserve_transform(PT_drop_node) on
+//               each one.  This allows a subsequent call to
+//               flatten_strong() to eliminate all of the ModelNodes.
+//
+//               Returns the number of ModelNodes found.
+////////////////////////////////////////////////////////////////////
+INLINE int NodePath::
+clear_model_nodes() {
+  nassertr_always(!is_empty(), 0);
+  return r_clear_model_nodes(node());
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: NodePath::set_tag
 //       Access: Published

+ 28 - 0
panda/src/pgraph/nodePath.cxx

@@ -64,6 +64,7 @@
 #include "dcast.h"
 #include "pStatCollector.h"
 #include "pStatTimer.h"
+#include "modelNode.h"
 
 // stack seems to overflow on Intel C++ at 7000.  If we need more than 
 // 7000, need to increase stack size.
@@ -6303,6 +6304,33 @@ find_matches(NodePathCollection &result, FindApproxLevelEntry *level,
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: NodePath::r_clear_model_nodes
+//       Access: Private
+//  Description: The recursive implementation of
+//               clear_model_nodes().  This walks through the
+//               subgraph defined by the indicated node and below.
+////////////////////////////////////////////////////////////////////
+int NodePath::
+r_clear_model_nodes(PandaNode *node) {
+  int count = 0;
+
+  if (node->is_of_type(ModelNode::get_class_type())) {
+    ModelNode *mnode;
+    DCAST_INTO_R(mnode, node, count);
+    mnode->set_preserve_transform(ModelNode::PT_drop_node);
+    ++count;
+  }
+
+  PandaNode::Children cr = node->get_children();
+  int num_children = cr.get_num_children();
+  for (int i = 0; i < num_children; i++) {
+    count += r_clear_model_nodes(cr.get_child(i));
+  }
+
+  return count;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: NodePath::r_adjust_all_priorities
 //       Access: Private

+ 2 - 0
panda/src/pgraph/nodePath.h

@@ -807,6 +807,7 @@ PUBLISHED:
   int flatten_light();
   int flatten_medium();
   int flatten_strong();
+  INLINE int clear_model_nodes();
 
   INLINE void set_tag(const string &key, const string &value);
   INLINE string get_tag(const string &key) const;
@@ -863,6 +864,7 @@ private:
                     FindApproxLevelEntry *level,
                     int max_matches) const;
 
+  int r_clear_model_nodes(PandaNode *node);
   void r_adjust_all_priorities(PandaNode *node, int adjustment);
 
   void r_force_recompute_bounds(PandaNode *node);