Browse Source

fix bugs in flatten

David Rose 24 years ago
parent
commit
0bf2b83727

+ 12 - 0
panda/src/collide/collisionNode.cxx

@@ -131,6 +131,18 @@ xform(const LMatrix4f &mat) {
   mark_bound_stale();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionNode::preserve_name
+//       Access: Public, Virtual
+//  Description: Returns true if the node's name has extrinsic meaning
+//               and must be preserved across a flatten operation,
+//               false otherwise.
+////////////////////////////////////////////////////////////////////
+bool CollisionNode::
+preserve_name() const {
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionNode::draw_traverse
 //       Access: Public, Virtual

+ 1 - 0
panda/src/collide/collisionNode.h

@@ -44,6 +44,7 @@ public:
   virtual ~CollisionNode();
   virtual Node *make_copy() const;
   virtual void xform(const LMatrix4f &mat);
+  virtual bool preserve_name() const;
 
 PUBLISHED:
   INLINE void set_collide_mask(CollideMask mask);

+ 52 - 15
panda/src/graph/graphReducer.cxx

@@ -223,6 +223,9 @@ flatten_siblings(Node *root) {
 ////////////////////////////////////////////////////////////////////
 bool GraphReducer::
 consider_arc(NodeRelation *arc) {
+  // On reflection, there's no reason to forbid the removal of arcs
+  // with sub_render transitions.  It should all work out properly.
+  /*
   if (arc->has_sub_render_trans()) {
     if (graph_cat.is_debug()) {
       graph_cat.debug()
@@ -231,6 +234,7 @@ consider_arc(NodeRelation *arc) {
     }
     return false;
   }
+  */
   return true;
 }
 
@@ -246,7 +250,22 @@ bool GraphReducer::
 consider_siblings(Node *, NodeRelation *arc1, NodeRelation *arc2) {
   // Don't attempt to combine any sibling arcs with different
   // transitions.
-  return (arc1->compare_transitions_to(arc2) == 0);
+  if (arc1->compare_transitions_to(arc2) != 0) {
+    return false;
+  }
+
+  // We can't collapse siblings with arcs that contain sub_render
+  // transitions.  That could be bad.
+  if (arc1->has_sub_render_trans()) {
+    if (graph_cat.is_debug()) {
+      graph_cat.debug()
+        << "Not combining " << *arc1 << " and " << *arc2
+        << " because they contain a sub_render transition.\n";
+    }
+    return false;
+  }
+
+  return true;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -317,17 +336,26 @@ collapse_siblings(Node *parent, NodeRelation *arc1, NodeRelation *arc2) {
   PT_Node node1 = arc1->get_child();
   PT_Node node2 = arc2->get_child();
 
+  if (graph_cat.is_debug()) {
+    graph_cat.debug()
+      << "Collapsing " << *node1 << " and " << *node2 << "\n";
+  }
+
   PT_Node new_node = collapse_nodes(node1, node2, true);
   if (new_node == (Node *)NULL) {
-    graph_cat.debug()
-      << "Decided not to collapse " << *node1 << " and " << *node2 << "\n";
+    if (graph_cat.is_debug()) {
+      graph_cat.debug()
+        << "Decided not to collapse " << *node1 << " and " << *node2 << "\n";
+    }
     return NULL;
   }
 
+  choose_name(new_node, node1, node2);
+
   move_children(new_node, node1);
   move_children(new_node, node2);
 
-  arc1->change_parent_and_child(parent, node1);
+  arc1->change_child(new_node);
   remove_arc(arc2);
 
   return arc1;
@@ -384,25 +412,28 @@ choose_name(Node *preserve, Node *source1, Node *source2) {
   NamedNode *named_preserve;
   DCAST_INTO_V(named_preserve, preserve);
 
+  string name;
+  bool got_name = false;
+
   if (source1->is_of_type(NamedNode::get_class_type())) {
     NamedNode *named_source1;
     DCAST_INTO_V(named_source1, source1);
-
-    if (!named_source1->get_name().empty()) {
-      named_preserve->set_name(named_source1->get_name());
-      return;
-    }
+    name = named_source1->get_name();
+    got_name = !name.empty() || named_source1->preserve_name();
   }
 
   if (source2->is_of_type(NamedNode::get_class_type())) {
     NamedNode *named_source2;
     DCAST_INTO_V(named_source2, source2);
-
-    if (!named_source2->get_name().empty()) {
-      named_preserve->set_name(named_source2->get_name());
-      return;
+    if (named_source2->preserve_name() || !got_name) {
+      name = named_source2->get_name();
+      got_name = !name.empty() || named_source2->preserve_name();
     }
   }
+
+  if (got_name) {
+    named_preserve->set_name(name);
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -414,10 +445,16 @@ choose_name(Node *preserve, Node *source1, Node *source2) {
 void GraphReducer::
 move_children(Node *to, Node *from) {
   if (to != from) {
+    /*
+    if (graph_cat.is_debug()) {
+      graph_cat.debug()
+        << "Moving children to " << *to << " from " << *from << "\n";
+    }
+    */
+
     int num_children = from->get_num_children(_graph_type);
     while (num_children > 0) {
-      NodeRelation *arc =
-        from->get_child(_graph_type, 0);
+      NodeRelation *arc = from->get_child(_graph_type, 0);
       arc->change_parent(to);
       num_children--;
       nassertv(num_children == from->get_num_children(_graph_type));

+ 13 - 0
panda/src/graph/namedNode.cxx

@@ -46,6 +46,19 @@ make_copy() const {
   return new NamedNode(*this);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: NamedNode::preserve_name
+//       Access: Public, Virtual
+//  Description: Returns true if the node's name has extrinsic meaning
+//               and must be preserved across a flatten operation,
+//               false otherwise.
+////////////////////////////////////////////////////////////////////
+bool NamedNode::
+preserve_name() const {
+  return false;
+}
+
+
 ////////////////////////////////////////////////////////////////////
 //     Function: NamedNode::Output
 //       Access: Public, Virtual

+ 3 - 0
panda/src/graph/namedNode.h

@@ -39,6 +39,9 @@ public:
   virtual ~NamedNode();
 
   virtual Node *make_copy() const;
+
+  virtual bool preserve_name() const;
+
   virtual void output(ostream &out) const;
 
   static void register_with_read_factory(void);

+ 12 - 0
panda/src/sgraph/modelNode.cxx

@@ -65,6 +65,18 @@ safe_to_transform() const {
   return !_preserve_transform;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ModelNode::preserve_name
+//       Access: Public, Virtual
+//  Description: Returns true if the node's name has extrinsic meaning
+//               and must be preserved across a flatten operation,
+//               false otherwise.
+////////////////////////////////////////////////////////////////////
+bool ModelNode::
+preserve_name() const {
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ModelNode::register_with_factory
 //       Access: Public, Static

+ 1 - 0
panda/src/sgraph/modelNode.h

@@ -50,6 +50,7 @@ public:
 
   virtual bool safe_to_flatten() const;
   virtual bool safe_to_transform() const;
+  virtual bool preserve_name() const;
 
 public:
   static void register_with_read_factory(void);