better system for combining nodes in flattenStrong
This commit is contained in:
parent
e161452942
commit
25ba7f73a8
|
|
@ -417,22 +417,7 @@ collapse_nodes(Node *node1, Node *node2, bool) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// We get to choose whether to remove node1 or node2.
|
||||
if (node2->is_exact_type(Node::get_class_type()) ||
|
||||
node2->is_exact_type(NamedNode::get_class_type())) {
|
||||
// Node2 isn't anything special, so preserve node1.
|
||||
return node1;
|
||||
|
||||
} else if (node1->is_exact_type(Node::get_class_type()) ||
|
||||
node1->is_exact_type(NamedNode::get_class_type())) {
|
||||
// Node1 isn't anything special, so preserve node2.
|
||||
return node2;
|
||||
|
||||
} else {
|
||||
// Both node1 and node2 are some special kind of node. Don't
|
||||
// want to risk removing either of them.
|
||||
return NULL;
|
||||
}
|
||||
return node2->combine_with(node1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -46,6 +46,41 @@ make_copy() const {
|
|||
return new NamedNode(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NamedNode::combine_with
|
||||
// Access: Public, Virtual
|
||||
// Description: Collapses this node with the other node, if possible,
|
||||
// and returns a pointer to the combined node, or NULL
|
||||
// if the two nodes cannot safely be combined.
|
||||
//
|
||||
// The return value may be this, other, or a new node
|
||||
// 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 nodes and what the
|
||||
// collapsed node should look like.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Node *NamedNode::
|
||||
combine_with(Node *other) {
|
||||
// An unadorned NamedNode combines with other Nodes by yielding
|
||||
// completely. However, if we are actually some fancy Node type
|
||||
// that derives from NamedNode but didn't redefine this function, we
|
||||
// should refuse to combine.
|
||||
if (is_exact_type(get_class_type())) {
|
||||
// No, we're an ordinary NamedNode.
|
||||
if (other->is_exact_type(Node::get_class_type())) {
|
||||
// And the other node isn't even named, so we override.
|
||||
return this;
|
||||
}
|
||||
// The other node is also a NamedNode, or better, so it wins.
|
||||
return other;
|
||||
}
|
||||
|
||||
// We're something other than an ordinary NamedNode. Don't combine.
|
||||
return (Node *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NamedNode::preserve_name
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public:
|
|||
virtual ~NamedNode();
|
||||
|
||||
virtual Node *make_copy() const;
|
||||
virtual Node *combine_with(Node *other);
|
||||
|
||||
virtual bool preserve_name() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -184,6 +184,36 @@ void Node::
|
|||
xform(const LMatrix4f &) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Node::combine_with
|
||||
// Access: Public, Virtual
|
||||
// Description: Collapses this node with the other node, if possible,
|
||||
// and returns a pointer to the combined node, or NULL
|
||||
// if the two nodes cannot safely be combined.
|
||||
//
|
||||
// The return value may be this, other, or a new node
|
||||
// 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 nodes and what the
|
||||
// collapsed node should look like.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Node *Node::
|
||||
combine_with(Node *other) {
|
||||
// An unadorned Node always combines with any other Nodes by
|
||||
// yielding completely. However, if we are actually some fancy Node
|
||||
// type that derives from Node but didn't redefine this function, we
|
||||
// should refuse to combine.
|
||||
if (is_exact_type(get_class_type())) {
|
||||
// No, we're an ordinary Node.
|
||||
return other;
|
||||
}
|
||||
|
||||
// We're something other than an ordinary Node. Don't combine.
|
||||
return (Node *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Node::transform_changed
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ public:
|
|||
virtual bool safe_to_transform() const;
|
||||
virtual bool safe_to_combine() const;
|
||||
virtual void xform(const LMatrix4f &mat);
|
||||
virtual Node *combine_with(Node *other);
|
||||
|
||||
virtual void transform_changed(NodeRelation *arc);
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,34 @@ xform(const LMatrix4f &mat) {
|
|||
transformer.transform_vertices(this, mat);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomNode::combine_with
|
||||
// Access: Public, Virtual
|
||||
// Description: Collapses this node with the other node, if possible,
|
||||
// and returns a pointer to the combined node, or NULL
|
||||
// if the two nodes cannot safely be combined.
|
||||
//
|
||||
// The return value may be this, other, or a new node
|
||||
// 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 nodes and what the
|
||||
// collapsed node should look like.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Node *GeomNode::
|
||||
combine_with(Node *other) {
|
||||
if (is_exact_type(get_class_type()) &&
|
||||
other->is_exact_type(get_class_type())) {
|
||||
// Two GeomNodes can combine by moving Geoms from one to the other.
|
||||
GeomNode *gother = DCAST(GeomNode, other);
|
||||
add_geoms_from(gother);
|
||||
return this;
|
||||
}
|
||||
|
||||
return (Node *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomNode::write
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ public:
|
|||
|
||||
virtual Node *make_copy() const;
|
||||
virtual void xform(const LMatrix4f &mat);
|
||||
virtual Node *combine_with(Node *other);
|
||||
|
||||
virtual void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -304,17 +304,12 @@ collapse_nodes(Node *node1, Node *node2, bool siblings) {
|
|||
// We can collapse two GeomNodes easily, if they're siblings. If
|
||||
// they're parent-child, we'd probably better not (it might
|
||||
// interfere with decaling).
|
||||
if (siblings &&
|
||||
node1->is_exact_type(GeomNode::get_class_type()) &&
|
||||
if (node1->is_exact_type(GeomNode::get_class_type()) &&
|
||||
node2->is_exact_type(GeomNode::get_class_type())) {
|
||||
GeomNode *gnode1;
|
||||
DCAST_INTO_R(gnode1, node1, NULL);
|
||||
GeomNode *gnode2;
|
||||
DCAST_INTO_R(gnode2, node2, NULL);
|
||||
gnode1->add_geoms_from(gnode2);
|
||||
return gnode1;
|
||||
|
||||
} else {
|
||||
return GraphReducer::collapse_nodes(node1, node2, siblings);
|
||||
if (!siblings) {
|
||||
return (Node *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return GraphReducer::collapse_nodes(node1, node2, siblings);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue