*** empty log message ***

This commit is contained in:
David Rose 2001-05-08 00:36:29 +00:00
parent aba01ed56f
commit cdc10dcd48
24 changed files with 769 additions and 725 deletions

View File

@ -179,7 +179,9 @@ build(const string &default_name) {
}
// Only reparent the geom_node if it has no parent already.
if (geom_node->_parents.empty()) {
int num_parents =
geom_node->get_num_parents(RenderRelation::get_class_type());
if (num_parents == 0) {
if (geom_node->get_num_geoms() == 0) {
// If there was nothing added, never mind.
delete geom_node;

View File

@ -7,116 +7,81 @@
putil mathutil
#define SOURCES \
allAttributesWrapper.I nodeAttributes.cxx \
allAttributesWrapper.T nodeAttributes.h \
allAttributesWrapper.cxx nodeRelation.I \
allAttributesWrapper.h nodeRelation.N \
allTransitionsWrapper.I nodeRelation.T \
allTransitionsWrapper.T nodeRelation.cxx \
allTransitionsWrapper.cxx nodeRelation.h \
allTransitionsWrapper.h nodeTransition.I \
arcChain.I nodeTransition.N \
arcChain.cxx nodeTransition.cxx \
arcChain.h nodeTransition.h \
bitMask32Transition.cxx nodeTransitionCache.I \
bitMask32Transition.h nodeTransitionCache.cxx \
bitMaskAttribute.T nodeTransitionCache.h \
bitMaskAttribute.h nodeTransitionCacheEntry.I \
bitMaskTransition.T nodeTransitionCacheEntry.cxx \
bitMaskTransition.h nodeTransitionCacheEntry.h \
boundedObject.I nodeTransitionWrapper.I \
boundedObject.N nodeTransitionWrapper.T \
boundedObject.cxx nodeTransitionWrapper.cxx \
boundedObject.h nodeTransitionWrapper.h \
config_graph.cxx nodeTransitions.I \
config_graph.h nodeTransitions.T \
dftraverser.T nodeTransitions.cxx \
dftraverser.h nodeTransitions.h \
graphReducer.cxx nullAttributeWrapper.I \
graphReducer.h nullAttributeWrapper.cxx \
immediateAttribute.cxx nullAttributeWrapper.h \
immediateAttribute.h nullLevelState.cxx \
immediateTransition.I nullLevelState.h \
immediateTransition.cxx nullTransitionWrapper.I \
immediateTransition.h nullTransitionWrapper.cxx \
lmatrix4fTransition.cxx nullTransitionWrapper.h \
lmatrix4fTransition.h onAttribute.cxx \
matrixAttribute.T onAttribute.h \
matrixAttribute.h onOffAttribute.I \
matrixTransition.T onOffAttribute.cxx \
matrixTransition.h onOffAttribute.h \
multiAttribute.T onOffTransition.I \
multiAttribute.h onOffTransition.cxx \
multiNodeAttribute.cxx onOffTransition.h \
multiNodeAttribute.h onTransition.I \
multiNodeTransition.cxx onTransition.cxx \
multiNodeTransition.h onTransition.h \
multiTransition.T pointerNameClass.h \
multiTransition.h pt_NamedNode.N \
multiTransitionHelpers.I pt_NamedNode.cxx \
multiTransitionHelpers.h pt_NamedNode.h \
namedNode.I pt_Node.N \
namedNode.cxx pt_Node.cxx \
namedNode.h pt_Node.h \
node.I setTransitionHelpers.T \
node.cxx setTransitionHelpers.h \
node.h \
nodeAttribute.I \
nodeAttribute.N \
nodeAttribute.cxx transitionDirection.h \
nodeAttribute.h traverserVisitor.T \
nodeAttributeWrapper.I traverserVisitor.h \
nodeAttributeWrapper.T vector_PT_Node.cxx \
nodeAttributeWrapper.cxx vector_PT_Node.h \
nodeAttributeWrapper.h wrt.I \
nodeAttributes.I wrt.cxx \
nodeAttributes.N wrt.h \
nodeAttributes.T
allAttributesWrapper.I allAttributesWrapper.T \
allAttributesWrapper.cxx allAttributesWrapper.h \
allTransitionsWrapper.I allTransitionsWrapper.T \
allTransitionsWrapper.cxx allTransitionsWrapper.h arcChain.I \
arcChain.cxx arcChain.h bitMask32Transition.cxx \
bitMask32Transition.h bitMaskAttribute.T bitMaskAttribute.h \
bitMaskTransition.T bitMaskTransition.h boundedObject.I \
boundedObject.N boundedObject.cxx boundedObject.h config_graph.cxx \
config_graph.h dftraverser.T dftraverser.h graphReducer.cxx \
graphReducer.h immediateAttribute.cxx immediateAttribute.h \
immediateTransition.I immediateTransition.cxx \
immediateTransition.h lmatrix4fTransition.cxx \
lmatrix4fTransition.h matrixAttribute.T matrixAttribute.h \
matrixTransition.T matrixTransition.h multiAttribute.T \
multiAttribute.h multiNodeAttribute.cxx multiNodeAttribute.h \
multiNodeTransition.cxx multiNodeTransition.h multiTransition.T \
multiTransition.h multiTransitionHelpers.I \
multiTransitionHelpers.h namedNode.I namedNode.cxx namedNode.h \
node.I node.cxx node.h nodeAttribute.I nodeAttribute.N \
nodeAttribute.cxx nodeAttribute.h nodeAttributeWrapper.I \
nodeAttributeWrapper.T nodeAttributeWrapper.cxx \
nodeAttributeWrapper.h nodeAttributes.I nodeAttributes.N \
nodeAttributes.T nodeAttributes.cxx nodeAttributes.h \
nodeConnection.I nodeConnection.cxx nodeConnection.h \
nodeRelation.I nodeRelation.N nodeRelation.T nodeRelation.cxx \
nodeRelation.h nodeTransition.I nodeTransition.N \
nodeTransition.cxx nodeTransition.h nodeTransitionCache.I \
nodeTransitionCache.cxx nodeTransitionCache.h \
nodeTransitionCacheEntry.I nodeTransitionCacheEntry.cxx \
nodeTransitionCacheEntry.h nodeTransitionWrapper.I \
nodeTransitionWrapper.T nodeTransitionWrapper.cxx \
nodeTransitionWrapper.h nodeTransitions.I nodeTransitions.T \
nodeTransitions.cxx nodeTransitions.h nullAttributeWrapper.I \
nullAttributeWrapper.cxx nullAttributeWrapper.h nullLevelState.cxx \
nullLevelState.h nullTransitionWrapper.I nullTransitionWrapper.cxx \
nullTransitionWrapper.h onAttribute.cxx onAttribute.h \
onOffAttribute.I onOffAttribute.cxx onOffAttribute.h \
onOffTransition.I onOffTransition.cxx onOffTransition.h \
onTransition.I onTransition.cxx onTransition.h pointerNameClass.h \
pt_NamedNode.N pt_NamedNode.cxx pt_NamedNode.h pt_Node.N \
pt_Node.cxx pt_Node.h setTransitionHelpers.T \
setTransitionHelpers.h transitionDirection.h traverserVisitor.T \
traverserVisitor.h vector_PT_Node.cxx vector_PT_Node.h wrt.I \
wrt.cxx wrt.h
#define INSTALL_HEADERS \
allAttributesWrapper.I nodeAttributeWrapper.h \
allAttributesWrapper.T nodeAttributes.I \
allAttributesWrapper.h nodeAttributes.T \
allTransitionsWrapper.I nodeAttributes.h \
allTransitionsWrapper.T nodeRelation.I \
allTransitionsWrapper.h nodeRelation.T \
arcChain.I nodeRelation.h \
arcChain.h nodeTransition.I \
bitMask32Transition.h nodeTransition.h \
bitMaskAttribute.T nodeTransitionCache.I \
bitMaskAttribute.h nodeTransitionCache.h \
bitMaskTransition.T nodeTransitionCacheEntry.I \
bitMaskTransition.h nodeTransitionCacheEntry.h \
boundedObject.I nodeTransitionWrapper.I \
boundedObject.h nodeTransitionWrapper.T \
config_graph.h nodeTransitionWrapper.h \
dftraverser.T nodeTransitions.I \
dftraverser.h nodeTransitions.T \
graphReducer.h nodeTransitions.h \
immediateAttribute.h nullAttributeWrapper.I \
immediateTransition.I nullAttributeWrapper.h \
immediateTransition.h nullLevelState.h \
lmatrix4fTransition.h nullTransitionWrapper.I \
matrixAttribute.T nullTransitionWrapper.h \
matrixAttribute.h onAttribute.h \
matrixTransition.T onOffAttribute.I \
matrixTransition.h onOffAttribute.h \
multiAttribute.T onOffTransition.I \
multiAttribute.h onOffTransition.h \
multiNodeAttribute.h onTransition.I \
multiNodeTransition.h onTransition.h \
multiTransition.T pointerNameClass.h \
multiTransition.h pt_NamedNode.h \
multiTransitionHelpers.I pt_Node.h \
multiTransitionHelpers.h setTransitionHelpers.T \
namedNode.I setTransitionHelpers.h \
namedNode.h transitionDirection.h \
node.I traverserVisitor.T \
node.h traverserVisitor.h \
nodeAttribute.I vector_PT_Node.h \
nodeAttribute.h wrt.I \
nodeAttributeWrapper.I wrt.h \
nodeAttributeWrapper.T
allAttributesWrapper.I allAttributesWrapper.T \
allAttributesWrapper.h allTransitionsWrapper.I \
allTransitionsWrapper.T allTransitionsWrapper.h arcChain.I \
arcChain.h bitMask32Transition.h bitMaskAttribute.T \
bitMaskAttribute.h bitMaskTransition.T bitMaskTransition.h \
boundedObject.I boundedObject.h config_graph.h dftraverser.T \
dftraverser.h graphReducer.h immediateAttribute.h \
immediateTransition.I immediateTransition.h lmatrix4fTransition.h \
matrixAttribute.T matrixAttribute.h matrixTransition.T \
matrixTransition.h multiAttribute.T multiAttribute.h \
multiNodeAttribute.h multiNodeTransition.h multiTransition.T \
multiTransition.h multiTransitionHelpers.I \
multiTransitionHelpers.h namedNode.I namedNode.h node.I node.h \
nodeAttribute.I nodeAttribute.h nodeAttributeWrapper.I \
nodeAttributeWrapper.T nodeAttributeWrapper.h nodeAttributes.I \
nodeAttributes.T nodeAttributes.h nodeConnection.I \
nodeConnection.h nodeRelation.I nodeRelation.T nodeRelation.h \
nodeTransition.I nodeTransition.h nodeTransitionCache.I \
nodeTransitionCache.h nodeTransitionCacheEntry.I \
nodeTransitionCacheEntry.h nodeTransitionWrapper.I \
nodeTransitionWrapper.T nodeTransitionWrapper.h nodeTransitions.I \
nodeTransitions.T nodeTransitions.h nullAttributeWrapper.I \
nullAttributeWrapper.h nullLevelState.h nullTransitionWrapper.I \
nullTransitionWrapper.h onAttribute.h onOffAttribute.I \
onOffAttribute.h onOffTransition.I onOffTransition.h \
onTransition.I onTransition.h pointerNameClass.h pt_NamedNode.h \
pt_Node.h setTransitionHelpers.T setTransitionHelpers.h \
transitionDirection.h traverserVisitor.T traverserVisitor.h \
vector_PT_Node.h wrt.I wrt.h
#define IGATESCAN all
@ -133,25 +98,3 @@
#end test_bin_target
#begin test_bin_target
#define TARGET test_graphRead
#define LOCAL_LIBS \
putil graph
#define OTHER_LIBS $[OTHER_LIBS] pystub
#define SOURCES \
test_graphRead.cxx
#end test_bin_target
#begin test_bin_target
#define TARGET test_graphWrite
#define LOCAL_LIBS \
graph putil
#define OTHER_LIBS $[OTHER_LIBS] pystub
#define SOURCES \
test_graphWrite.cxx
#end test_bin_target

View File

@ -84,17 +84,13 @@ traverse(Node *node, AttributeWrapper &state, LevelState &level_state) {
if (_visitor.reached_node(node, state, level_state)) {
// Look for further children of the given NodeRelation.
DownRelations::const_iterator dri;
dri = node->_children.find(_graph_type);
if (dri != node->_children.end()) {
// Here are some!
const DownRelationPointers &drp = (*dri).second;
const DownRelationPointers &drp =
node->find_connection(_graph_type).get_down();
// Now visit each of the children in turn.
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
traverse(*drpi, state, level_state);
}
// Now visit each of the children in turn.
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
traverse(*drpi, state, level_state);
}
}
}

View File

@ -61,21 +61,18 @@ flatten(Node *root, bool combine_siblings) {
do {
num_pass_nodes = 0;
DownRelations::const_iterator dri;
dri = root->_children.find(_graph_type);
if (dri != root->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
const DownRelationPointers &drp =
root->find_connection(_graph_type).get_down();
// Get a copy of the children list, so we don't have to worry
// about self-modifications.
DownRelationPointers drp_copy = drp;
// Get a copy of the children list, so we don't have to worry
// about self-modifications.
DownRelationPointers drp_copy = drp;
// Now visit each of the children in turn.
DownRelationPointers::const_iterator drpi;
for (drpi = drp_copy.begin(); drpi != drp_copy.end(); ++drpi) {
NodeRelation *arc = (*drpi);
num_pass_nodes += r_flatten(arc->get_child(), combine_siblings);
}
// Now visit each of the children in turn.
DownRelationPointers::const_iterator drpi;
for (drpi = drp_copy.begin(); drpi != drp_copy.end(); ++drpi) {
NodeRelation *arc = (*drpi);
num_pass_nodes += r_flatten(arc->get_child(), combine_siblings);
}
num_total_nodes += num_pass_nodes;
@ -100,33 +97,30 @@ int GraphReducer::
r_flatten(Node *root, bool combine_siblings) {
int num_nodes = 0;
DownRelations::const_iterator dri;
dri = root->_children.find(_graph_type);
if (dri != root->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
const DownRelationPointers &drp =
root->find_connection(_graph_type).get_down();
// Get a copy of the children list, so we don't have to worry
// about self-modifications.
DownRelationPointers drp_copy = drp;
// Get a copy of the children list, so we don't have to worry
// about self-modifications.
DownRelationPointers drp_copy = drp;
// Now visit each of the children in turn.
DownRelationPointers::const_iterator drpi;
for (drpi = drp_copy.begin(); drpi != drp_copy.end(); ++drpi) {
NodeRelation *arc = (*drpi);
num_nodes += r_flatten(arc->get_child(), combine_siblings);
}
if (combine_siblings && drp.size() >= 2) {
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++;
}
// Now visit each of the children in turn.
DownRelationPointers::const_iterator drpi;
for (drpi = drp_copy.begin(); drpi != drp_copy.end(); ++drpi) {
NodeRelation *arc = (*drpi);
num_nodes += r_flatten(arc->get_child(), combine_siblings);
}
if (combine_siblings && drp.size() >= 2) {
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++;
}
}
}
@ -161,17 +155,12 @@ flatten_siblings(Node *root) {
typedef map<NodeRelation *, list<NodeRelation *>, SortByTransitions> Children;
Children children;
DownRelations::const_iterator dri;
dri = root->_children.find(_graph_type);
if (dri != root->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
NodeRelation *arc = (*drpi);
children[arc].push_back(arc);
}
const DownRelationPointers &drp =
root->find_connection(_graph_type).get_down();
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
NodeRelation *arc = (*drpi);
children[arc].push_back(arc);
}
// Now visit each of those groups and try to collapse them together.

View File

@ -6,6 +6,47 @@
#include <notify.h>
////////////////////////////////////////////////////////////////////
// Function: Node::find_connection
// Access: Public
// Description: Returns a const reference to the NodeConnection of
// the indicated graph type, if one exists, or a const
// reference to an empty NodeConnection if a connection
// of the indicated type does not exist.
////////////////////////////////////////////////////////////////////
INLINE_GRAPH const NodeConnection &Node::
find_connection(TypeHandle graph_type) const {
if (_connections[0].get_graph_type() == graph_type) {
return _connections[0];
}
if (max_node_graphs > 1) {
return p_find_connection(graph_type);
} else {
return _empty_connection;
}
}
////////////////////////////////////////////////////////////////////
// Function: Node::update_connection
// Access: Public
// Description: Returns a non-const pointer to the NodeConnection of
// the indicated graph type, if one exists. If a
// NodeConnection of the indicated type does not already
// exist, creates one if possible and returns its
// pointer. Otherwise, returns NULL.
////////////////////////////////////////////////////////////////////
INLINE_GRAPH NodeConnection *Node::
update_connection(TypeHandle graph_type) {
if (_connections[0].get_graph_type() == graph_type) {
return &_connections[0];
}
if (max_node_graphs > 1) {
return p_update_connection(graph_type);
} else {
return (NodeConnection *)NULL;
}
}
////////////////////////////////////////////////////////////////////
// Function: remove_child
// Description: Finds the arc that connects the indicated nodes and

View File

@ -11,9 +11,11 @@
#include <datagram.h>
#include <indent.h>
NodeConnection Node::_empty_connection;
TypeHandle Node::_type_handle;
Node* const Node::Null = (Node*)0L;
////////////////////////////////////////////////////////////////////
// Function: Node::Constructor
// Access: Public
@ -26,7 +28,11 @@ Node() {
////////////////////////////////////////////////////////////////////
// Function: Node::Copy Constructor
// Access: Public
// Description:
// Description: The Node copy constructor does not copy children.
// Use copy_subgraph() if you want a deep copy of the
// node and all of its children. Also, you should use
// make_copy() if you just want a typed copy of the Node
// (without children).
////////////////////////////////////////////////////////////////////
Node::
Node(const Node &copy) :
@ -59,22 +65,23 @@ Node::
// We'd better not have any arcs pointing into this node, since
// we're destructing it now. If we do, the destructor was called in
// error.
UpRelations::iterator uri;
for (uri = _parents.begin(); uri != _parents.end(); ++uri) {
nassertv((*uri).second.empty());
int i;
for (i = 0; i < max_node_graphs; i++) {
UpRelationPointers &urp = _connections[i].get_up();
nassertv(urp.empty());
}
DownRelations::iterator dri;
for (dri = _children.begin(); dri != _children.end(); ++dri) {
DownRelationPointers &drp = (*dri).second;
// Now disconnect all the child arcs.
for (i = 0; i < max_node_graphs; i++) {
DownRelationPointers &drp = _connections[i].get_down();
DownRelationPointers::iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
PT(NodeRelation) relation = (*drpi);
NodeRelation *arc = (*drpi);
// This deletes the arc and anything below it through the magic
// of reference-counting.
relation->detach_below();
arc->detach_below();
}
}
}
@ -168,12 +175,8 @@ transform_changed(NodeRelation *) {
////////////////////////////////////////////////////////////////////
int Node::
get_num_parents(TypeHandle type) const {
UpRelations::const_iterator uri;
uri = _parents.find(type);
if (uri == _parents.end()) {
return 0;
}
return (*uri).second.size();
const UpRelationPointers &urp = find_connection(type).get_up();
return urp.size();
}
////////////////////////////////////////////////////////////////////
@ -185,12 +188,10 @@ get_num_parents(TypeHandle type) const {
////////////////////////////////////////////////////////////////////
NodeRelation *Node::
get_parent(TypeHandle type, int index) const {
UpRelations::const_iterator uri;
uri = _parents.find(type);
nassertr(uri != _parents.end(), (NodeRelation *)NULL);
nassertr(index >= 0 && index < (int)(*uri).second.size(),
const UpRelationPointers &urp = find_connection(type).get_up();
nassertr(index >= 0 && index < (int)urp.size(),
(NodeRelation *)NULL);
return (*uri).second[index];
return urp[index];
}
////////////////////////////////////////////////////////////////////
@ -202,12 +203,8 @@ get_parent(TypeHandle type, int index) const {
////////////////////////////////////////////////////////////////////
int Node::
get_num_children(TypeHandle type) const {
DownRelations::const_iterator dri;
dri = _children.find(type);
if (dri == _children.end()) {
return 0;
}
return (*dri).second.size();
const DownRelationPointers &drp = find_connection(type).get_down();
return drp.size();
}
////////////////////////////////////////////////////////////////////
@ -219,12 +216,10 @@ get_num_children(TypeHandle type) const {
////////////////////////////////////////////////////////////////////
NodeRelation *Node::
get_child(TypeHandle type, int index) const {
DownRelations::const_iterator dri;
dri = _children.find(type);
nassertr(dri != _children.end(), (NodeRelation *)NULL);
nassertr(index >= 0 && index < (int)(*dri).second.size(),
const DownRelationPointers &drp = find_connection(type).get_down();
nassertr(index >= 0 && index < (int)drp.size(),
(NodeRelation *)NULL);
return (*dri).second[index];
return drp[index];
}
////////////////////////////////////////////////////////////////////
@ -274,6 +269,49 @@ write(ostream &out, int indent_level) const {
}
////////////////////////////////////////////////////////////////////
// Function: Node::p_find_connection
// Access: Private
// Description: The non-inline implementation of find_connection().
////////////////////////////////////////////////////////////////////
const NodeConnection &Node::
p_find_connection(TypeHandle graph_type) const {
// _connections[0] is already tested by the inline implementation.
for (int i = 1; i < max_node_graphs; i++) {
if (_connections[i].get_graph_type() == graph_type) {
return _connections[i];
}
}
return _empty_connection;
}
////////////////////////////////////////////////////////////////////
// Function: Node::p_update_connection
// Access: Private
// Description: The non-inline implementation of update_connection().
////////////////////////////////////////////////////////////////////
NodeConnection *Node::
p_update_connection(TypeHandle graph_type) {
// _connections[0] is already tested by the inline implementation.
int i;
for (i = 1; i < max_node_graphs; i++) {
if (_connections[i].get_graph_type() == graph_type) {
return &_connections[i];
}
}
// No such connection; can we create a new one?
for (i = 0; i < max_node_graphs; i++) {
if (_connections[i].is_empty()) {
_connections[i].set_graph_type(graph_type);
return &_connections[i];
}
}
// Too bad.
return (NodeConnection *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: Node::propagate_stale_bound
// Access: Protected, Virtual
@ -284,10 +322,8 @@ write(ostream &out, int indent_level) const {
void Node::
propagate_stale_bound() {
// Mark all of our parent arcs, in all graphs, stale as well.
UpRelations::const_iterator uri;
for (uri = _parents.begin(); uri != _parents.end(); ++uri) {
const UpRelationPointers &urp = (*uri).second;
for (int i = 0; i < max_node_graphs; i++) {
const UpRelationPointers &urp = _connections[i].get_up();
UpRelationPointers::const_iterator urpi;
for (urpi = urp.begin(); urpi != urp.end(); ++urpi) {
(*urpi)->mark_bound_stale();
@ -324,10 +360,10 @@ r_copy_subgraph(TypeHandle graph_type, Node::InstanceMap &inst_map) const {
////////////////////////////////////////////////////////////////////
// Function: Node::r_copy_children
// Access: Protected, Virtual
// Description: This is called by r_deep_copy(); the copy has already
// been made of this particular node (and this is the
// copy); this function's job is to copy all of the
// children from the original.
// Description: This is called by r_copy_subgraph(); the copy has
// already been made of this particular node (and this
// is the copy); this function's job is to copy all of
// the children from the original.
//
// Note that it includes the parameter inst_map, which
// is a map type, and is not (and cannot be) exported
@ -339,39 +375,35 @@ r_copy_subgraph(TypeHandle graph_type, Node::InstanceMap &inst_map) const {
void Node::
r_copy_children(const Node *from, TypeHandle graph_type,
Node::InstanceMap &inst_map) {
DownRelations::const_iterator dri;
dri = from->_children.find(graph_type);
if (dri != from->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
const DownRelationPointers &drp =
from->find_connection(graph_type).get_down();
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
NodeRelation *source_arc = (*drpi);
Node *source_child = source_arc->get_child();
nassertv(source_child != (Node *)NULL);
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
NodeRelation *source_arc = (*drpi);
Node *source_child = source_arc->get_child();
nassertv(source_child != (Node *)NULL);
Node *dest_child;
Node *dest_child;
// Check to see if we have already copied this child. If we
// have, use the copy. In this way, a subgraph that contains
// instances will be correctly duplicated into another subgraph
// that also contains its own instances.
InstanceMap::const_iterator ci;
ci = inst_map.find(source_child);
if (ci != inst_map.end()) {
dest_child = (*ci).second;
} else {
dest_child = source_child->r_copy_subgraph(graph_type, inst_map);
inst_map[source_child] = dest_child;
}
NodeRelation *dest_arc =
NodeRelation::create_typed_arc(graph_type, this, dest_child);
nassertv(dest_arc != (NodeRelation *)NULL);
nassertv(dest_arc->is_exact_type(graph_type));
dest_arc->copy_transitions_from(source_arc);
// Check to see if we have already copied this child. If we
// have, use the copy. In this way, a subgraph that contains
// instances will be correctly duplicated into another subgraph
// that also contains its own instances.
InstanceMap::const_iterator ci;
ci = inst_map.find(source_child);
if (ci != inst_map.end()) {
dest_child = (*ci).second;
} else {
dest_child = source_child->r_copy_subgraph(graph_type, inst_map);
inst_map[source_child] = dest_child;
}
NodeRelation *dest_arc =
NodeRelation::create_typed_arc(graph_type, this, dest_child);
nassertv(dest_arc != (NodeRelation *)NULL);
nassertv(dest_arc->is_exact_type(graph_type));
dest_arc->copy_transitions_from(source_arc);
}
}
@ -389,18 +421,29 @@ write_datagram(BamWriter *manager, Datagram &me) {
// write out all of the UpRelations then writing any node in a graph
// would cause the entire graph to be written out.
me.add_uint16(_children.size());
// First, count up the number of NodeConnections that are nonempty.
int num_connections = 0;
int i;
for (i = 0; i < max_node_graphs; i++) {
if (!_connections[i].is_empty()) {
num_connections++;
}
}
DownRelations::iterator dri;
for (dri = _children.begin(); dri != _children.end(); ++dri) {
manager->write_handle(me, (*dri).first);
me.add_uint16(num_connections);
DownRelationPointers &drp = (*dri).second;
me.add_uint16(drp.size());
DownRelationPointers::iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
NodeRelation *relation = (*drpi);
manager->write_pointer(me, relation);
// Now write them out.
for (i = 0; i < max_node_graphs; i++) {
if (!_connections[i].is_empty()) {
manager->write_handle(me, _connections[i].get_graph_type());
const DownRelationPointers &drp = _connections[i].get_down();
me.add_uint16(drp.size());
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
NodeRelation *relation = (*drpi);
manager->write_pointer(me, relation);
}
}
}
}
@ -420,28 +463,37 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
// the arcs are completely responsible for adding themselves to
// our list); we only need to return the number of pointers we
// expected to receive.
return _num_pointers;
// As of 5/7/01, we no longer store this number, as a memory
// optimization. This means bams before 3.3 cannot be reliably
// loaded.
graph_cat.warning()
<< "Unable to reliably load bam version "
<< manager->get_file_major_ver() << "."
<< manager->get_file_minor_ver() << "\n";
return 0;
}
// Beginning at bam version 3.3, we are responsible for adding our
// child arcs directly.
int i = 0;
int count = 0;
DownRelations::iterator dri;
for (dri = _children.begin(); dri != _children.end(); ++dri) {
DownRelationPointers &drp = (*dri).second;
for (int i = 0; i < max_node_graphs; i++) {
if (!_connections[i].is_empty()) {
DownRelationPointers &drp = _connections[i].get_down();
DownRelationPointers::iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
nassertr(i < _num_pointers, _num_pointers);
(*drpi) = DCAST(NodeRelation, plist[i]);
i++;
DownRelationPointers::iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
(*drpi) = DCAST(NodeRelation, plist[count]);
count++;
}
}
}
nassertr(i == _num_pointers, _num_pointers);
return _num_pointers;
return count;
}
////////////////////////////////////////////////////////////////////
@ -450,8 +502,7 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
// Description: Factory method to generate a node object
////////////////////////////////////////////////////////////////////
TypedWriteable* Node::
make_Node(const FactoryParams &params)
{
make_Node(const FactoryParams &params) {
Node *me = new Node;
BamReader *manager;
Datagram packet;
@ -477,14 +528,12 @@ fillin(DatagramIterator &scan, BamReader *manager) {
// In bam versions before 3.3, we only need to count up the total
// number of arcs across all types, because we don't add the arc
// pointers explicitly here.
_num_pointers = 0;
int num_types = scan.get_uint16();
while (num_types > 0) {
int num_arcs = scan.get_uint16();
while (num_arcs > 0) {
manager->read_pointer(scan, this);
_num_pointers++;
num_arcs--;
}
num_types--;
@ -494,24 +543,38 @@ fillin(DatagramIterator &scan, BamReader *manager) {
// Beginning at bam version 3.3, we do all the reading of our
// children arcs of all types, which means we need to record the
// numbers of each type of children. We do this by recording a
// series of NULL pointers, rather than depending on
// _num_pointers.
// series of NULL pointers in our NodeConnections.
_num_pointers = 0;
int num_types = scan.get_uint16();
while (num_types > 0) {
int num_connections = scan.get_uint16();
if (num_connections > max_node_graphs) {
// Oops, too many graph types in this bam file. We'll have to
// discard some.
graph_cat.error()
<< "Bam file specifies " << num_connections << " graph types for "
<< *this << "; this version of Panda can only support "
<< max_node_graphs << " simultaneous graph types.\n";
}
for (int i = 0; i < num_connections; i++) {
TypeHandle type = manager->read_handle(scan);
if (i < max_node_graphs) {
_connections[i].set_graph_type(type);
DownRelationPointers &drp = _children[type];
int num_arcs = scan.get_uint16();
while (num_arcs > 0) {
manager->read_pointer(scan, this);
drp.push_back((NodeRelation *)NULL);
_num_pointers++;
num_arcs--;
DownRelationPointers &drp = _connections[i].get_down();
int num_arcs = scan.get_uint16();
while (num_arcs > 0) {
manager->read_pointer(scan, this);
drp.push_back((NodeRelation *)NULL);
num_arcs--;
}
} else {
// Read and discard.
int num_arcs = scan.get_uint16();
while (num_arcs > 0) {
manager->skip_pointer(scan);
num_arcs--;
}
}
num_types--;
}
}
}
@ -522,8 +585,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
// Description: Factory method to generate a node object
////////////////////////////////////////////////////////////////////
void Node::
register_with_read_factory(void)
{
register_with_read_factory(void) {
BamReader::get_factory()->register_factory(get_class_type(), make_Node);
}
@ -540,16 +602,12 @@ find_arc(Node *parent, Node *child, TypeHandle graph_type) {
// the parent arc, on the assumption there are likely to be fewer
// parents than children.
UpRelations::const_iterator uri = child->_parents.find(graph_type);
if (uri != child->_parents.end()) {
const UpRelationPointers &urp = (*uri).second;
UpRelationPointers::const_iterator urpi;
for (urpi = urp.begin(); urpi != urp.end(); ++urpi) {
if ((*urpi)->get_parent() == parent &&
(*urpi)->get_child() == child) {
return (*urpi);
}
const UpRelationPointers &urp = child->find_connection(graph_type).get_up();
UpRelationPointers::const_iterator urpi;
for (urpi = urp.begin(); urpi != urp.end(); ++urpi) {
NodeRelation *arc = (*urpi);
if (arc->get_parent() == parent && arc->get_child() == child) {
return arc;
}
}

View File

@ -9,6 +9,7 @@
#include "nodeRelation.h"
#include "boundedObject.h"
#include "nodeConnection.h"
#include <typedWriteable.h>
#include <referenceCount.h>
@ -23,6 +24,10 @@ class BamReader;
class Datagram;
class DatagramIterator;
// This is the maximum number of graph types a node may simultaneously
// exist in.
static const int max_node_graphs = 2;
////////////////////////////////////////////////////////////////////
// Class : Node
// Description : The base class for all scene graph nodes. A Node may
@ -77,6 +82,7 @@ PUBLISHED:
virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level = 0) const;
public:
// We reference-count the child pointer, but not the parent pointer,
// to avoid circular reference counting.
@ -84,9 +90,15 @@ PUBLISHED:
// through the scene graph when necessary, but beware! It is not
// safe to access these members directly outside of PANDA.DLL.
// Instead, use the get_parent()/get_child() interface, above.
INLINE_GRAPH const NodeConnection &find_connection(TypeHandle graph_type) const;
INLINE_GRAPH NodeConnection *update_connection(TypeHandle graph_type);
UpRelations _parents;
DownRelations _children;
NodeConnection _connections[max_node_graphs];
private:
const NodeConnection &p_find_connection(TypeHandle graph_type) const;
NodeConnection *p_update_connection(TypeHandle graph_type);
static NodeConnection _empty_connection;
protected:
virtual void propagate_stale_bound();
@ -108,17 +120,6 @@ public:
protected:
void fillin(DatagramIterator& scan, BamReader* manager);
private:
//This variable is set inside fillin to the number of pointers
//that are "read" by Node. This needs to be set, even though
//node does nothing in complete_pointers, because it needs to
//return the number of pointer requests that it made. This
//is necessary because the vector of pointers to TypedWriteables
//that is given to it by BamReader, will be filled with those requests
//and any children of Node, need to be able to ignore those as well.
//So complete_pointers must return the correct number read
int _num_pointers;
public:
static TypeHandle get_class_type() {
return _type_handle;

View File

@ -0,0 +1,127 @@
// Filename: nodeConnection.I
// Created by: drose (07May01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: NodeConnection::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_GRAPH NodeConnection::
NodeConnection(TypeHandle graph_type) : _graph_type(graph_type) {
}
////////////////////////////////////////////////////////////////////
// Function: NodeConnection::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE_GRAPH NodeConnection::
~NodeConnection() {
}
////////////////////////////////////////////////////////////////////
// Function: NodeConnection::Copy Constructor
// Access: Private
// Description: The copy constructor is private. Copying
// NodeConnections is not a good idea.
////////////////////////////////////////////////////////////////////
INLINE_GRAPH NodeConnection::
NodeConnection(const NodeConnection &copy) {
}
////////////////////////////////////////////////////////////////////
// Function: NodeConnection::Copy Assignment Operator
// Access: Private
// Description: The assignment constructor is private. Copying
// NodeConnections is not a good idea.
////////////////////////////////////////////////////////////////////
INLINE_GRAPH void NodeConnection::
operator = (const NodeConnection &copy) {
}
////////////////////////////////////////////////////////////////////
// Function: NodeConnection::is_empty
// Access: Public
// Description: Returns true if the NodeConnection has no arcs, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE_GRAPH bool NodeConnection::
is_empty() const {
return _up.empty() && _down.empty();
}
////////////////////////////////////////////////////////////////////
// Function: NodeConnection::get_graph_type
// Access: Public
// Description: Returns the type of graph represented by this
// NodeConnection. A node can coexist simultaneously in
// several different graphs of different types; each
// type requires a NodeConnection object to be stored
// with the node.
////////////////////////////////////////////////////////////////////
INLINE_GRAPH TypeHandle NodeConnection::
get_graph_type() const {
return _graph_type;
}
////////////////////////////////////////////////////////////////////
// Function: NodeConnection::set_graph_type
// Access: Public
// Description: Changes the type of graph represented by this
// NodeConnection. It is legal to do this only when the
// NodeConnection is empty, i.e. is_empty() returns
// true.
////////////////////////////////////////////////////////////////////
INLINE_GRAPH void NodeConnection::
set_graph_type(TypeHandle graph_type) {
nassertv(is_empty());
_graph_type = graph_type;
}
////////////////////////////////////////////////////////////////////
// Function: NodeConnection::get_up
// Access: Public
// Description: Returns the list of arcs pointing to the node's
// parent(s).
////////////////////////////////////////////////////////////////////
INLINE_GRAPH UpRelationPointers &NodeConnection::
get_up() {
return _up;
}
////////////////////////////////////////////////////////////////////
// Function: NodeConnection::get_up
// Access: Public
// Description: Returns the list of arcs pointing to the node's
// parent(s).
////////////////////////////////////////////////////////////////////
INLINE_GRAPH const UpRelationPointers &NodeConnection::
get_up() const {
return _up;
}
////////////////////////////////////////////////////////////////////
// Function: NodeConnection::get_down
// Access: Public
// Description: Returns the list of arcs pointing to the node's
// child(ren).
////////////////////////////////////////////////////////////////////
INLINE_GRAPH DownRelationPointers &NodeConnection::
get_down() {
return _down;
}
////////////////////////////////////////////////////////////////////
// Function: NodeConnection::get_down
// Access: Public
// Description: Returns the list of arcs pointing to the node's
// child(ren).
////////////////////////////////////////////////////////////////////
INLINE_GRAPH const DownRelationPointers &NodeConnection::
get_down() const {
return _down;
}

View File

@ -0,0 +1,7 @@
// Filename: nodeConnection.cxx
// Created by: drose (07May01)
//
////////////////////////////////////////////////////////////////////
#include "node.h"
#include "nodeConnection.h"

View File

@ -0,0 +1,57 @@
// Filename: nodeConnection.h
// Created by: drose (07May01)
//
////////////////////////////////////////////////////////////////////
#ifndef NODECONNECTION_H
#define NODECONNECTION_H
#include <pandabase.h>
#include "nodeRelation.h"
#include "config_graph.h"
///////////////////////////////////////////////////////////////////
// Class : NodeConnection
// Description : This class represents the table, stored within each
// Node, of all the connected NodeRelations (arcs) of a
// particular graph type.
//
// Node that this class is not exported from PANDA.DLL.
// You should use the get_parent()/get_child() interface
// to Node for code outside of PANDA.DLL.
////////////////////////////////////////////////////////////////////
class NodeConnection {
public:
INLINE_GRAPH NodeConnection(TypeHandle graph_type = TypeHandle::none());
INLINE_GRAPH ~NodeConnection();
private:
INLINE_GRAPH NodeConnection(const NodeConnection &copy);
INLINE_GRAPH void operator = (const NodeConnection &copy);
public:
INLINE_GRAPH bool is_empty() const;
INLINE_GRAPH TypeHandle get_graph_type() const;
INLINE_GRAPH void set_graph_type(TypeHandle graph_type);
INLINE_GRAPH UpRelationPointers &get_up();
INLINE_GRAPH const UpRelationPointers &get_up() const;
INLINE_GRAPH DownRelationPointers &get_down();
INLINE_GRAPH const DownRelationPointers &get_down() const;
private:
TypeHandle _graph_type;
UpRelationPointers _up;
DownRelationPointers _down;
};
#ifndef DONT_INLINE_GRAPH
#include "nodeConnection.I"
#endif
#endif

View File

@ -49,16 +49,16 @@ init_last_graph_update() {
// Following are a handful of local template functions that provide
// support for manipulating the list of arcs on nodes. They are
// template functions because they work as well on UpRelationArcs as
// as they do on DownRelationArcs, which are slightly different things
// (DownRelationArcs are reference-counting).
// template functions because they work as well on UpRelationPointers
// as as they do on DownRelationPointers, which are slightly different
// things (DownRelationPointers are reference-counting).
////////////////////////////////////////////////////////////////////
// Function: verify_arc_list
// Description: A local template function that verifies that the list
// of arcs (either UpRelationArcs or DownRelationArcs)
// is correctly sorted, if paranoid_graph is set.
// Otherwise, it does nothing.
// of arcs (either UpRelationPointers or
// DownRelationPointers) is correctly sorted, if
// paranoid_graph is set. Otherwise, it does nothing.
////////////////////////////////////////////////////////////////////
#ifdef NDEBUG
template<class Iterator>
@ -87,9 +87,9 @@ verify_arc_list(Iterator begin, Iterator end) {
////////////////////////////////////////////////////////////////////
// Function: find_insert_position
// Description: A local template function that performs a binary
// search on the arcs list (either UpRelationArcs or
// DownRelationArcs) and finds the place to insert the
// indicated arc.
// search on the arcs list (either UpRelationPointers or
// DownRelationPointers) and finds the place to insert
// the indicated arc.
//
// This place will be at the end of the similarly-sorted
// arcs.
@ -141,10 +141,10 @@ find_insert_position(Iterator begin, Iterator end, NodeRelation *arc) {
////////////////////////////////////////////////////////////////////
// Function: find_arc
// Description: A local template function that performs a binary
// search on the arcs list (either UpRelationArcs or
// DownRelationArcs) and finds the arc's position within
// the list. It returns end if the arc is not within
// the list.
// search on the arcs list (either UpRelationPointers or
// DownRelationPointers) and finds the arc's position
// within the list. It returns end if the arc is not
// within the list.
////////////////////////////////////////////////////////////////////
template<class Iterator>
static Iterator
@ -609,13 +609,25 @@ attach() {
nassertv(_child != (Node*)NULL);
nassertv(!_attached);
_attached = true;
if (_parent_ref != 0) {
_parent->ref();
NodeConnection *parent_connection = _parent->update_connection(_graph_type);
NodeConnection *child_connection = _child->update_connection(_graph_type);
if (parent_connection == (NodeConnection *)NULL) {
graph_cat.error()
<< "Attempt to attach " << _parent << " simultaneously to more than "
<< max_node_graphs << " different graph types.\n";
nassertv(false);
}
DownRelationPointers &parent_list = _parent->_children[_graph_type];
UpRelationPointers &child_list = _child->_parents[_graph_type];
if (child_connection == (NodeConnection *)NULL) {
graph_cat.error()
<< "Attempt to attach " << _child << " simultaneously to more than "
<< max_node_graphs << " different graph types.\n";
nassertv(false);
}
DownRelationPointers &parent_list = parent_connection->get_down();
UpRelationPointers &child_list = child_connection->get_up();
bool inserted_one = internal_insert_arc(parent_list, this);
bool inserted_two = internal_insert_arc(child_list, this);
@ -634,6 +646,11 @@ attach() {
child_list[1]->_last_update = _last_update;
}
_attached = true;
if (_parent_ref != 0) {
_parent->ref();
}
_parent->force_bound_stale();
mark_bound_stale();
}
@ -664,8 +681,16 @@ detach() {
force_bound_stale();
DownRelationPointers &parent_list = _parent->_children[_graph_type];
UpRelationPointers &child_list = _child->_parents[_graph_type];
NodeConnection *parent_connection = _parent->update_connection(_graph_type);
NodeConnection *child_connection = _child->update_connection(_graph_type);
// These should never be NULL, because we're already attached, after
// all.
nassertr(parent_connection != (NodeConnection *)NULL &&
child_connection != (NodeConnection *)NULL, result);
DownRelationPointers &parent_list = parent_connection->get_down();
UpRelationPointers &child_list = child_connection->get_up();
bool removed_one = internal_remove_arc(parent_list, this);
bool removed_two = internal_remove_arc(child_list, this);
@ -690,16 +715,6 @@ detach() {
child_list[0]->_last_update = _last_update;
}
// If we have completely emptied the parent or child lists, remove
// the entry for this graph type from the node, as a small render
// optimization.
if (parent_list.empty()) {
_parent->_children.erase(_graph_type);
}
if (child_list.empty()) {
_child->_parents.erase(_graph_type);
}
return result;
}
@ -721,7 +736,11 @@ detach_below() {
force_bound_stale();
bool removed = internal_remove_arc(_child->_parents[_graph_type], this);
NodeConnection *child_connection = _child->update_connection(_graph_type);
nassertr(child_connection != (NodeConnection *)NULL, result);
UpRelationPointers &child_list = child_connection->get_up();
bool removed = internal_remove_arc(child_list, this);
nassertr(removed, result);
@ -767,15 +786,10 @@ propagate_stale_bound() {
Node *node = _parent;
nassertv(node != (Node*)NULL);
UpRelations::const_iterator uri;
uri = node->_parents.find(_graph_type);
if (uri != node->_parents.end()) {
const UpRelationPointers &urp = (*uri).second;
UpRelationPointers::const_iterator urpi;
for (urpi = urp.begin(); urpi != urp.end(); ++urpi) {
(*urpi)->mark_bound_stale();
}
const UpRelationPointers &urp = node->find_connection(_graph_type).get_up();
UpRelationPointers::const_iterator urpi;
for (urpi = urp.begin(); urpi != urp.end(); ++urpi) {
(*urpi)->mark_bound_stale();
}
}
@ -800,15 +814,11 @@ recompute_bound() {
child_volumes.push_back(&node->get_bound());
DownRelations::const_iterator dri;
dri = node->_children.find(_graph_type);
if (dri != node->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
child_volumes.push_back(&(*drpi)->get_bound());
}
const DownRelationPointers &drp =
node->find_connection(_graph_type).get_down();
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
child_volumes.push_back(&(*drpi)->get_bound());
}
bool success =
@ -855,8 +865,7 @@ write_datagram(BamWriter *manager, Datagram &me)
//Now write out all the Transitions on this arc
me.add_uint16(_transitions.size());
NodeTransitions::iterator ci;
for(ci = _transitions.begin(); ci != _transitions.end(); ci++)
{
for(ci = _transitions.begin(); ci != _transitions.end(); ci++) {
manager->write_pointer(me, (*ci).second);
}
}
@ -865,13 +874,12 @@ write_datagram(BamWriter *manager, Datagram &me)
////////////////////////////////////////////////////////////////////
// Function: NodeRelation::complete_pointers
// Access: Public
// Description: Takes in a vector of pointes to TypedWriteable
// Description: Takes in a vector of pointers to TypedWriteable
// objects that correspond to all the requests for
// pointers that this object made to BamReader.
////////////////////////////////////////////////////////////////////
int NodeRelation::
complete_pointers(vector_typedWriteable &plist, BamReader *manager)
{
complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
nassertr(plist[0] != TypedWriteable::Null &&
plist[1] != TypedWriteable::Null, 0);
_parent = DCAST(Node, plist[0]);
@ -889,10 +897,13 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager)
// We must explicitly add the arc to its child node, but not to
// its parent node.
UpRelationPointers &child_list = _child->_parents[_graph_type];
bool inserted = internal_insert_arc(child_list, this);
nassertr(inserted, _num_transitions + 2);
_attached = true;
NodeConnection *child_connection = _child->update_connection(_graph_type);
if (child_connection != (NodeConnection *)NULL) {
UpRelationPointers &child_list = child_connection->get_up();
bool inserted = internal_insert_arc(child_list, this);
nassertr(inserted, _num_transitions + 2);
_attached = true;
}
}
//The rest of this is the list of Transitions
@ -1072,4 +1083,3 @@ clear_transition(TypeHandle handle) {
changed_transition(handle);
return old_trans;
}

View File

@ -223,10 +223,7 @@ EXPCL_PANDA INLINE_GRAPH ostream &
operator << (ostream &out, const NodeRelation &arc);
typedef vector< PT(NodeRelation) > DownRelationPointers;
typedef map<TypeHandle, DownRelationPointers> DownRelations;
typedef vector<NodeRelation *> UpRelationPointers;
typedef map<TypeHandle, UpRelationPointers> UpRelations;
#include "nodeRelation.T"

View File

@ -73,8 +73,9 @@ is_identity() const {
////////////////////////////////////////////////////////////////////
int NodeTransitionCache::
compare_to(const NodeTransitionCache &other) const {
return tmap_compare_cache(_cache.begin(), _cache.end(),
other._cache.begin(), other._cache.end());
int result = tmap_compare_cache(_cache.begin(), _cache.end(),
other._cache.begin(), other._cache.end());
return result;
}
////////////////////////////////////////////////////////////////////

View File

@ -1,49 +0,0 @@
// Filename: test_graphRead.cxx
// Created by: jason (15Jun00)
#include "nodeRelation.h"
#include "namedNode.h"
#include "pt_NamedNode.h"
#include <bamWriter.h>
#include <ipc_file.h>
#include <indent.h>
int main() {
string test_file = "graphTest.out";
datagram_file stream(test_file);
BamReader manager(&stream);
stream.open(file::FILE_READ);
manager.init();
PT_NamedNode r = DCAST(NamedNode, manager.read_object());
PT_NamedNode a = DCAST(NamedNode, manager.read_object());
PT_NamedNode b = DCAST(NamedNode, manager.read_object());
PT_NamedNode aa = DCAST(NamedNode, manager.read_object());
PT_NamedNode ab = DCAST(NamedNode, manager.read_object());
PT_NamedNode ba = DCAST(NamedNode, manager.read_object());
NodeRelation *r_a = DCAST(NodeRelation, manager.read_object());
NodeRelation *r_b = DCAST(NodeRelation, manager.read_object());
NodeRelation *a_aa = DCAST(NodeRelation, manager.read_object());
NodeRelation *a_ab = DCAST(NodeRelation, manager.read_object());
NodeRelation *b_ba = DCAST(NodeRelation, manager.read_object());
manager.resolve();
r_a->output(nout);
nout << endl;
r_b->output(nout);
nout << endl;
a_aa->output(nout);
nout << endl;
a_ab->output(nout);
nout << endl;
b_ba->output(nout);
nout << endl;
stream.close();
return 0;
}

View File

@ -1,68 +0,0 @@
// Filename: test_graphWrite.cxx
// Created by: jason (15Jun00)
#include "nodeRelation.h"
#include "namedNode.h"
#include "pt_NamedNode.h"
#include <bamWriter.h>
#include <ipc_file.h>
#include <indent.h>
int main() {
string test_file = "graphTest.out";
datagram_file stream(test_file);
BamWriter manager(&stream);
stream.open(file::FILE_WRITE);
PT_NamedNode r = new NamedNode("r");
PT_NamedNode a = new NamedNode("a");
PT_NamedNode b = new NamedNode("b");
PT_NamedNode aa = new NamedNode("aa");
PT_NamedNode ab = new NamedNode("ab");
PT_NamedNode ba = new NamedNode("ba");
NodeRelation *r_a =
new NodeRelation(r, a, 0, NodeRelation::get_class_type());
NodeRelation *r_b =
new NodeRelation(r, b, 0, NodeRelation::get_class_type());
NodeRelation *a_aa =
new NodeRelation(a, aa, 0, NodeRelation::get_class_type());
NodeRelation *a_ab =
new NodeRelation(a, ab, 0, NodeRelation::get_class_type());
NodeRelation *b_ba =
new NodeRelation(b, ba, 0, NodeRelation::get_class_type());
r_a->output(nout);
nout << endl;
r_b->output(nout);
nout << endl;
a_aa->output(nout);
nout << endl;
a_ab->output(nout);
nout << endl;
b_ba->output(nout);
nout << endl;
if (manager.init())
{
manager.write_object(r);
manager.write_object(a);
manager.write_object(b);
manager.write_object(aa);
manager.write_object(ab);
manager.write_object(ba);
manager.write_object(r_a);
manager.write_object(r_b);
manager.write_object(a_aa);
manager.write_object(a_ab);
manager.write_object(b_ba);
}
stream.close();
return 0;
}

View File

@ -15,18 +15,20 @@ void
describe_ambiguous_wrt(const Node *node,
InputIterator arc_list_begin,
InputIterator arc_list_end,
const UpRelationPointers &urp) {
TypeHandle graph_type) {
if (wrt_cat.is_warning()) {
int num_parents = node->get_num_parents(graph_type);
wrt_cat.warning()
<< *node << " has " << urp.size() << " parents; wrt() ambiguous.\n"
<< *node << " has " << num_parents << " parents; wrt() ambiguous.\n"
<< " parents are: ";
UpRelationPointers::const_iterator urpi;
urpi = urp.begin();
wrt_cat.warning(false) << *(*urpi)->get_parent();
urpi++;
while (urpi != urp.end()) {
wrt_cat.warning(false) << ", " << *(*urpi)->get_parent();
urpi++;
nassertv(num_parents > 1);
NodeRelation *parent_arc = node->get_parent(graph_type, 0);
wrt_cat.warning(false) << *parent_arc->get_parent();
for (int i = 1; i < num_parents; i++) {
parent_arc = node->get_parent(graph_type, 0);
wrt_cat.warning(false)
<< ", " << *node->get_parent(graph_type, i)->get_parent();
}
wrt_cat.warning(false) << "\n";
@ -129,16 +131,15 @@ get_cached_net_transition(NodeRelation *arc, Node *&root,
// Get the node above the arc.
Node *node = arc->get_parent();
UpRelations::const_iterator uri;
uri = node->_parents.find(graph_type);
int num_parents = node->get_num_parents(graph_type);
if (uri == node->_parents.end() || (*uri).second.size() != 1) {
if (num_parents != 1) {
// The node has zero or multiple parents. It's thus either the
// top of the scene graph, or it's the first ancestor with
// multiple parents; in either case, it's as far as we can take
// the caching. Stop here.
if (uri == node->_parents.end() || (*uri).second.empty()) {
if (num_parents == 0) {
// The node is the very top of the scene graph. We'll treat
// this as a special case by setting the node to NULL. This
// will tell our calling function that there's no need to look
@ -154,8 +155,8 @@ get_cached_net_transition(NodeRelation *arc, Node *&root,
} else {
// The node has exactly one parent. Carry on.
NodeRelation *parent = *(*uri).second.begin();
get_cached_net_transition(parent, root, as_of, now, net, graph_type);
NodeRelation *parent_arc = node->get_parent(graph_type, 0);
get_cached_net_transition(parent_arc, root, as_of, now, net, graph_type);
// Now recompute our own cache.
TransitionWrapper cur_value = TransitionWrapper::init_from(net);
@ -222,42 +223,26 @@ get_cached_net_transition(const Node *node,
return;
}
UpRelations::const_iterator uri;
uri = node->_parents.find(graph_type);
if (uri == node->_parents.end()) {
// This node has no parents. Stop here.
result.make_identity();
#ifndef NDEBUG
if (wrt_cat.is_debug()) {
wrt_cat.debug()
<< "get_cached_net_transition(" << *node << ") has no parents.\n";
}
#endif
return;
}
const UpRelationPointers &urp = (*uri).second;
if (urp.empty()) {
// Again, this node has no parents.
result.make_identity();
#ifndef NDEBUG
if (wrt_cat.is_debug()) {
wrt_cat.debug()
<< "get_cached_net_transition(" << *node << ") has no parents.\n";
}
#endif
return;
}
int num_parents = node->get_num_parents(graph_type);
const NodeRelation *parent_arc = (const NodeRelation *)NULL;
if (urp.size() == 1) {
if (num_parents == 1) {
// There is only one parent, so there's no doubt as to which arc
// to choose.
parent_arc = *(urp.begin());
parent_arc = node->get_parent(graph_type, 0);
} else if (num_parents == 0) {
// This node has no parents. Stop here.
result.make_identity();
#ifndef NDEBUG
if (wrt_cat.is_debug()) {
wrt_cat.debug()
<< "get_cached_net_transition(" << *node << ") has no parents.\n";
}
#endif
return;
} else {
// The node has multiple parents, and we have a list of arcs in
@ -275,9 +260,9 @@ get_cached_net_transition(const Node *node,
#ifndef NDEBUG
// No, it wasn't mentioned. Issue a warning and use the first
// one.
describe_ambiguous_wrt(node, arc_list_begin, arc_list_end, urp);
describe_ambiguous_wrt(node, arc_list_begin, arc_list_end, graph_type);
#endif
parent_arc = *(urp.begin());
parent_arc = node->get_parent(graph_type, 0);
}
}
@ -332,10 +317,16 @@ get_uncached_net_transition(const Node *node,
return;
}
UpRelations::const_iterator uri;
uri = node->_parents.find(graph_type);
int num_parents = node->get_num_parents(graph_type);
if (uri == node->_parents.end()) {
const NodeRelation *parent_arc = (const NodeRelation *)NULL;
if (num_parents == 1) {
// There is only one parent, so there's no doubt as to which arc
// to choose.
parent_arc = node->get_parent(graph_type, 0);
} else if (num_parents == 0) {
// This node has no parents. Stop here.
if (wrt_cat.is_spam()) {
wrt_cat.spam()
@ -343,25 +334,6 @@ get_uncached_net_transition(const Node *node,
}
result.make_identity();
return;
}
const UpRelationPointers &urp = (*uri).second;
if (urp.empty()) {
// Again, this node has no parents.
if (wrt_cat.is_spam()) {
wrt_cat.spam()
<< "get_uncached_net_transition(" << *node << ") has no parents.\n";
}
result.make_identity();
return;
}
const NodeRelation *parent_arc = (const NodeRelation *)NULL;
if (urp.size() == 1) {
// There is only one parent, so there's no doubt as to which arc
// to choose.
parent_arc = *(urp.begin());
} else {
// The node has multiple parents, and we have a list of arcs in
@ -379,9 +351,9 @@ get_uncached_net_transition(const Node *node,
#ifndef NDEBUG
// No, it wasn't mentioned. Issue a warning and use the first
// one.
describe_ambiguous_wrt(node, arc_list_begin, arc_list_end, urp);
describe_ambiguous_wrt(node, arc_list_begin, arc_list_end, graph_type);
#endif
parent_arc = *(urp.begin());
parent_arc = node->get_parent(graph_type, 0);
}
}
@ -404,7 +376,7 @@ get_uncached_net_transition(const Node *node,
}
wrt_cat.spam(false)
<< "), " << urp.size() << " parents, is:\n";
<< "), " << num_parents << " parents, is:\n";
result.write(wrt_cat.spam(false), 2);
}
}
@ -647,10 +619,10 @@ Node *
get_uncached_wrt_subtree(Node *node, Node *to, TransitionWrapper &result,
TypeHandle graph_type) {
nassertr(node != (Node *)NULL, to);
UpRelations::const_iterator uri;
uri = node->_parents.find(graph_type);
if (uri == node->_parents.end()) {
int num_parents = node->get_num_parents(graph_type);
if (num_parents == 0) {
// This node has no parents. Stop here.
if (wrt_cat.is_spam()) {
wrt_cat.spam()
@ -660,22 +632,11 @@ get_uncached_wrt_subtree(Node *node, Node *to, TransitionWrapper &result,
return (Node *)NULL;
}
const UpRelationPointers &urp = (*uri).second;
if (urp.empty()) {
// Again, no parents. Stop here.
if (wrt_cat.is_spam()) {
wrt_cat.spam()
<< "get_uncached_wrt_subtree(" << *node << ") has no parents.\n";
}
result.make_identity();
return (Node *)NULL;
}
if (urp.size() != 1) {
if (num_parents != 1) {
// There are multiple parents, so stop here.
if (wrt_cat.is_spam()) {
wrt_cat.spam()
<< "get_uncached_wrt_subtree(" << *node << ") has " << urp.size()
<< "get_uncached_wrt_subtree(" << *node << ") has " << num_parents
<< " parents.\n";
}
result.make_identity();
@ -706,7 +667,7 @@ get_uncached_wrt_subtree(Node *node, Node *to, TransitionWrapper &result,
}
}
const NodeRelation *parent_arc = *(urp.begin());
const NodeRelation *parent_arc = node->get_parent(graph_type, 0);
Node *stop =
get_uncached_wrt_subtree(parent_arc->get_parent(), to,

View File

@ -283,15 +283,16 @@ read_pointer(DatagramIterator& scan, TypedWriteable* forWhom)
{
PN_uint16 objId = scan.get_uint16();
_deferred_pointers[forWhom].push_back(objId);
//This is safe since we have already read the full datagram
//for the object requesting this object. So there can be
//no collision on that front.
//IMPORTANT NOTE: This does make the assumption that
//that objects are requested by other objects in the same
//order that they wrote them originally.
// This is safe since we have already read the full datagram for the
// object requesting this object. So there can be no collision on
// that front.
//Don't queue a read of a null pointer
//or if the object has already been read
// IMPORTANT NOTE: This does make the assumption that objects are
// requested by other objects in the same order that they wrote them
// originally.
// Don't queue a read of a null pointer or if the object has already
// been read
if ((objId != 0) && (_created_objs.find(objId) == _created_objs.end()))
queue(objId);
}
@ -310,6 +311,19 @@ read_pointers(DatagramIterator &scan, TypedWriteable *forWhom, int count) {
}
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::skip_pointer
// Access: Public
// Description: Reads and discards a pointer value from the Bam file.
// This pointer will not be counted among the pointers
// read for a given object, and will not be in the list
// of pointers passed to complete_pointers().
////////////////////////////////////////////////////////////////////
void BamReader::
skip_pointer(DatagramIterator &scan) {
scan.get_uint16();
}
////////////////////////////////////////////////////////////////////
// Function: BamReader::register_finalize
// Access: Public

View File

@ -66,6 +66,7 @@ public:
//can register in itself for later "fixing"
void read_pointer(DatagramIterator &scan, TypedWriteable* forWhom);
void read_pointers(DatagramIterator &scan, TypedWriteable* forWhom, int count);
void skip_pointer(DatagramIterator &scan);
//At any time you can call this function to try and resolve all
//outstanding pointer requests. Will resolve all requests that

View File

@ -68,19 +68,14 @@ consider_node(NodePathCollection &result, FindApproxLevel &next_level,
if (next_is_stashed()) {
next_graph_type = NodeRelation::get_stashed_type();
}
DownRelations::const_iterator dri;
dri = bottom_node->_children.find(next_graph_type);
if (dri != bottom_node->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
NodeRelation *arc = (*drpi);
consider_next_step(result, arc, next_level, max_matches, graph_type);
if (max_matches > 0 && result.get_num_paths() >= max_matches) {
return;
}
int num_children = bottom_node->get_num_children(next_graph_type);
for (int i = 0; i < num_children; i++) {
NodeRelation *child_arc = bottom_node->get_child(next_graph_type, i);
consider_next_step(result, child_arc, next_level, max_matches, graph_type);
if (max_matches > 0 && result.get_num_paths() >= max_matches) {
return;
}
}
}

View File

@ -263,18 +263,13 @@ get_children() const {
nassertr(!is_empty(), result);
Node *bottom_node = node();
DownRelations::const_iterator dri;
dri = bottom_node->_children.find(_graph_type);
if (dri != bottom_node->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
NodeRelation *arc = (*drpi);
NodePath child(*this);
child.extend_by(arc);
result.add_path(child);
}
int num_children = bottom_node->get_num_children(_graph_type);
for (int i = 0; i < num_children; i++) {
NodeRelation *child_arc = bottom_node->get_child(_graph_type, i);
NodePath child(*this);
child.extend_by(child_arc);
result.add_path(child);
}
return result;
@ -297,19 +292,15 @@ get_siblings() const {
parent.shorten(1);
Node *parent_node = parent.node();
DownRelations::const_iterator dri;
dri = parent_node->_children.find(_graph_type);
if (dri != parent_node->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
NodeRelation *arc = (*drpi);
if (arc != my_arc) {
NodePath sib(parent);
sib.extend_by(arc);
result.add_path(sib);
}
int num_children = parent_node->get_num_children(_graph_type);
for (int i = 0; i < num_children; i++) {
NodeRelation *child_arc = parent_node->get_child(_graph_type, i);
if (child_arc != my_arc) {
NodePath sib(parent);
sib.extend_by(child_arc);
result.add_path(sib);
}
}
@ -2710,27 +2701,21 @@ r_list_descendants(ostream &out, int indent_level) const {
Node *bottom_node = node();
nassertv(bottom_node != (Node *)NULL);
indent(out, indent_level) << *bottom_node << "\n";
DownRelations::const_iterator dri;
dri = bottom_node->_children.find(_graph_type);
if (dri != bottom_node->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
NodeRelation *arc = (*drpi);
NodePath next(*this);
next.extend_by(arc);
next.r_list_descendants(out, indent_level + 2);
}
int num_children = bottom_node->get_num_children(_graph_type);
for (int i = 0; i < num_children; i++) {
NodeRelation *child_arc = bottom_node->get_child(_graph_type, i);
NodePath next(*this);
next.extend_by(child_arc);
next.r_list_descendants(out, indent_level + 2);
}
if (_graph_type != NodeRelation::get_stashed_type()) {
// Also report the number of stashed nodes at this level.
dri = bottom_node->_children.find(NodeRelation::get_stashed_type());
if (dri != bottom_node->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
indent(out, indent_level) << "(" << drp.size() << " stashed)\n";
int num_stashed = bottom_node->get_num_children(NodeRelation::get_stashed_type());
if (num_stashed != 0) {
indent(out, indent_level) << "(" << num_stashed << " stashed)\n";
}
}
}
@ -2747,22 +2732,16 @@ r_list_transitions(ostream &out, int indent_level) const {
out << "\n+";
indent(out, indent_level + 1) << *bottom_node << "\n\n";
DownRelations::const_iterator dri;
dri = bottom_node->_children.find(_graph_type);
if (dri != bottom_node->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
NodeRelation *arc = (*drpi);
NodePath next(*this);
next.extend_by(arc);
indent(out, indent_level + 2) << *arc << ":\n";
arc->write_transitions(out, indent_level + 2);
next.r_list_transitions(out, indent_level + 2);
}
int num_children = bottom_node->get_num_children(_graph_type);
for (int i = 0; i < num_children; i++) {
NodeRelation *child_arc = bottom_node->get_child(_graph_type, i);
NodePath next(*this);
next.extend_by(child_arc);
indent(out, indent_level + 2) << *child_arc << ":\n";
child_arc->write_transitions(out, indent_level + 2);
next.r_list_transitions(out, indent_level + 2);
}
}
@ -2778,14 +2757,10 @@ r_adjust_all_priorities(NodeRelation *arc, int adjustment) {
arc->adjust_all_priorities(adjustment);
Node *dnode = arc->get_child();
DownRelations::const_iterator dri;
dri = dnode->_children.find(_graph_type);
if (dri != dnode->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
r_adjust_all_priorities(*drpi, adjustment);
}
int num_children = dnode->get_num_children(_graph_type);
for (int i = 0; i < num_children; i++) {
NodeRelation *child_arc = dnode->get_child(_graph_type, i);
r_adjust_all_priorities(child_arc, adjustment);
}
}

View File

@ -233,17 +233,13 @@ traverse(Node *node, AttributeWrapper &render_state, LevelState &level_state,
if (_visitor.reached_node(node, render_state, level_state)) {
// Look for further children of the given NodeRelation.
DownRelations::const_iterator dri;
dri = node->_children.find(_graph_type);
if (dri != node->_children.end()) {
// Here are some!
const DownRelationPointers &drp = (*dri).second;
const DownRelationPointers &drp =
node->find_connection(_graph_type).get_down();
// Now visit each of the children in turn.
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
traverse(*drpi, render_state, level_state, local_frustum, all_in);
}
// Now visit each of the children in turn.
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
traverse(*drpi, render_state, level_state, local_frustum, all_in);
}
}
}

View File

@ -261,18 +261,14 @@ r_apply_transitions(NodeRelation *arc, int transition_types,
}
}
DownRelations::const_iterator dri;
dri = node->_children.find(_graph_type);
if (dri != node->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
DownRelationPointers drp_copy = drp;
const DownRelationPointers &drp =
node->find_connection(_graph_type).get_down();
DownRelationPointers drp_copy = drp;
DownRelationPointers::const_iterator drpi;
for (drpi = drp_copy.begin(); drpi != drp_copy.end(); ++drpi) {
NodeRelation *child_arc = (*drpi);
r_apply_transitions(child_arc, transition_types, trans, duplicate);
}
DownRelationPointers::const_iterator drpi;
for (drpi = drp_copy.begin(); drpi != drp_copy.end(); ++drpi) {
NodeRelation *child_arc = (*drpi);
r_apply_transitions(child_arc, transition_types, trans, duplicate);
}
}

View File

@ -242,15 +242,12 @@ find_character_gsets(Node *root, Geom *&ch, GeomPoint *&dot,
return found;
} else {
DownRelations::const_iterator dri;
dri = root->_children.find(RenderRelation::get_class_type());
if (dri != root->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
if (find_character_gsets((*drpi)->get_child(), ch, dot, trans)) {
trans.extract_from(*drpi);
}
TypeHandle graph_type = RenderRelation::get_class_type();
int num_children = root->get_num_children(graph_type);
for (int i = 0; i < num_children; i++) {
NodeRelation *child_arc = root->get_child(graph_type, i);
if (find_character_gsets(child_arc->get_child(), ch, dot, trans)) {
trans.extract_from(child_arc);
}
}
return false;
@ -328,15 +325,11 @@ find_characters(Node *root) {
}
} else {
DownRelations::const_iterator dri;
dri = root->_children.find(RenderRelation::get_class_type());
if (dri != root->_children.end()) {
const DownRelationPointers &drp = (*dri).second;
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
Node *node = (*drpi)->get_child();
find_characters(node);
}
TypeHandle graph_type = RenderRelation::get_class_type();
int num_children = root->get_num_children(graph_type);
for (int i = 0; i < num_children; i++) {
NodeRelation *child_arc = root->get_child(graph_type, i);
find_characters(child_arc->get_child());
}
}
}

View File

@ -212,12 +212,13 @@ generate() {
_lr3d.set(0.0, 0.0, 0.0);
_num_rows = 0;
if (_text.empty() || _font.is_null()) {
return (Node *)NULL;
}
// Now build a new sub-tree for all the text components.
PT_Node root = new NamedNode(_text);
if (_text.empty() || _font.is_null()) {
return root;
}
PT_Node sub_root = new NamedNode();
RenderRelation *root_arc = new RenderRelation(root, sub_root);