diff --git a/panda/src/collide/collisionNode.cxx b/panda/src/collide/collisionNode.cxx index 907f0543f8..1f9b330564 100644 --- a/panda/src/collide/collisionNode.cxx +++ b/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 diff --git a/panda/src/collide/collisionNode.h b/panda/src/collide/collisionNode.h index f572d20504..50c333b860 100644 --- a/panda/src/collide/collisionNode.h +++ b/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); diff --git a/panda/src/graph/graphReducer.cxx b/panda/src/graph/graphReducer.cxx index f2a7d9b2ee..5159967957 100644 --- a/panda/src/graph/graphReducer.cxx +++ b/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)); diff --git a/panda/src/graph/namedNode.cxx b/panda/src/graph/namedNode.cxx index f8abf870ae..0cb213482a 100644 --- a/panda/src/graph/namedNode.cxx +++ b/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 diff --git a/panda/src/graph/namedNode.h b/panda/src/graph/namedNode.h index 8f90a4e79f..0b56b6c76f 100644 --- a/panda/src/graph/namedNode.h +++ b/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); diff --git a/panda/src/sgraph/modelNode.cxx b/panda/src/sgraph/modelNode.cxx index 0965ce411e..15a40407cf 100644 --- a/panda/src/sgraph/modelNode.cxx +++ b/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 diff --git a/panda/src/sgraph/modelNode.h b/panda/src/sgraph/modelNode.h index 1fa2667344..a386975c6d 100644 --- a/panda/src/sgraph/modelNode.h +++ b/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);