insist on same graph for colliders

This commit is contained in:
David Rose 2003-10-27 21:30:52 +00:00
parent f6fe58c262
commit 8a45c38537
4 changed files with 50 additions and 25 deletions

View File

@ -265,7 +265,7 @@ traverse(const NodePath &root) {
#endif // DO_COLLISION_RECORDING #endif // DO_COLLISION_RECORDING
CollisionLevelState level_state(root); CollisionLevelState level_state(root);
prepare_colliders(level_state); prepare_colliders(level_state, root);
Handlers::iterator hi; Handlers::iterator hi;
for (hi = _handlers.begin(); hi != _handlers.end(); ++hi) { for (hi = _handlers.begin(); hi != _handlers.end(); ++hi) {
@ -399,29 +399,38 @@ write(ostream &out, int indent_level) const {
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CollisionTraverser:: void CollisionTraverser::
prepare_colliders(CollisionLevelState &level_state) { prepare_colliders(CollisionLevelState &level_state, const NodePath &root) {
level_state.clear(); level_state.clear();
level_state.reserve(_colliders.size()); level_state.reserve(_colliders.size());
int i = 0; int i = 0;
while (i < (int)_ordered_colliders.size()) { while (i < (int)_ordered_colliders.size()) {
NodePath cnode_path = _ordered_colliders[i]; NodePath cnode_path = _ordered_colliders[i];
if (!cnode_path.is_empty() && #ifndef NDEBUG
cnode_path.node()->is_of_type(CollisionNode::get_class_type())) { if (!cnode_path.is_same_graph(root)) {
CollisionNode *cnode = DCAST(CollisionNode, cnode_path.node()); collide_cat.error()
<< "Collider " << cnode_path
CollisionLevelState::ColliderDef def; << " is not in scene graph. Dropping from traverser.\n";
def._node = cnode; // This is safe to do while traversing the list of colliders,
def._node_path = cnode_path; // because we do not increment i in this case.
remove_collider(cnode_path);
int num_solids = cnode->get_num_solids(); } else
for (int s = 0; s < num_solids; s++) { #endif
CollisionSolid *collider = cnode->get_solid(s); {
def._collider = collider; CollisionNode *cnode = DCAST(CollisionNode, cnode_path.node());
level_state.prepare_collider(def);
CollisionLevelState::ColliderDef def;
def._node = cnode;
def._node_path = cnode_path;
int num_solids = cnode->get_num_solids();
for (int s = 0; s < num_solids; s++) {
CollisionSolid *collider = cnode->get_solid(s);
def._collider = collider;
level_state.prepare_collider(def);
}
i++;
} }
i++;
}
} }
} }

View File

@ -83,7 +83,7 @@ PUBLISHED:
void write(ostream &out, int indent_level) const; void write(ostream &out, int indent_level) const;
private: private:
void prepare_colliders(CollisionLevelState &state); void prepare_colliders(CollisionLevelState &state, const NodePath &root);
void r_traverse(CollisionLevelState &level_state); void r_traverse(CollisionLevelState &level_state);

View File

@ -262,13 +262,6 @@ node() const {
// given key will never be reused for a different // given key will never be reused for a different
// instance (unless the app has been running long enough // instance (unless the app has been running long enough
// that we overflow the integer key value). // that we overflow the integer key value).
//
// There are a few special case circumstances that can
// cause the key for a particular instance to be
// changed. These all involve different instances being
// collapsed into the same instance by some scene graph
// operation (for instance, detaching a node below an
// instanced node).
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE int NodePath:: INLINE int NodePath::
get_key() const { get_key() const {
@ -278,6 +271,27 @@ get_key() const {
return _head->get_key(); return _head->get_key();
} }
////////////////////////////////////////////////////////////////////
// Function: NodePath::is_same_graph
// Access: Published
// Description: Returns true if the node represented by this NodePath
// is parented within the same graph as that of the
// other NodePath. This is essentially the same thing
// as asking whether the top node of both NodePaths is
// the same (e.g., both "render").
////////////////////////////////////////////////////////////////////
INLINE bool NodePath::
is_same_graph(const NodePath &other) const {
// Actually, it's possible for the top nodes to be the same, but the
// NodePaths still to be considered in different graphs. This will
// happen if one of the top nodes is considered a different
// instance--for instance, render.instance_to(NodePath()) returns a
// different instance of render that appears to have the same top
// node. But this is a very rare thing to do.
int a_count, b_count;
return (find_common_ancestor(*this, other, a_count, b_count) != (NodePathComponent *)NULL);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: NodePath::get_num_children // Function: NodePath::get_num_children
// Access: Published // Access: Published

View File

@ -179,6 +179,8 @@ PUBLISHED:
INLINE int get_key() const; INLINE int get_key() const;
INLINE bool is_same_graph(const NodePath &other) const;
// Methods that return collections of NodePaths derived from or // Methods that return collections of NodePaths derived from or
// related to this one. // related to this one.