From e07d4b78476e1f21e366c7d9683aaf45f3b4925e Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 23 Oct 2003 15:35:26 +0000 Subject: [PATCH] first steps toward a NodePath-based interface --- panda/src/collide/collisionEntry.I | 14 ++ panda/src/collide/collisionEntry.cxx | 2 + panda/src/collide/collisionEntry.h | 2 + panda/src/collide/collisionHandlerFloor.cxx | 11 +- panda/src/collide/collisionHandlerPhysical.I | 13 ++ .../src/collide/collisionHandlerPhysical.cxx | 67 ++++--- panda/src/collide/collisionHandlerPhysical.h | 16 +- panda/src/collide/collisionHandlerPusher.cxx | 17 +- panda/src/collide/collisionLevelState.I | 55 +----- panda/src/collide/collisionLevelState.cxx | 14 +- panda/src/collide/collisionLevelState.h | 13 +- panda/src/collide/collisionTraverser.I | 10 +- panda/src/collide/collisionTraverser.cxx | 166 +++++++++--------- panda/src/collide/collisionTraverser.h | 19 +- 14 files changed, 218 insertions(+), 201 deletions(-) diff --git a/panda/src/collide/collisionEntry.I b/panda/src/collide/collisionEntry.I index 01db4c4b77..7e8fec5c28 100644 --- a/panda/src/collide/collisionEntry.I +++ b/panda/src/collide/collisionEntry.I @@ -100,6 +100,20 @@ get_into_node() const { return _into_node; } +//////////////////////////////////////////////////////////////////// +// Function: CollisionEntry::get_from_node_path +// Access: Published +// Description: Returns the NodePath that represents the +// CollisionNode that contains the CollisionSolid that +// triggered this collision. This will be a NodePath +// that has been added to a CollisionTraverser via +// add_collider(). +//////////////////////////////////////////////////////////////////// +INLINE const NodePath &CollisionEntry:: +get_from_node_path() const { + return _from_node_path; +} + //////////////////////////////////////////////////////////////////// // Function: CollisionEntry::get_into_node_path // Access: Published diff --git a/panda/src/collide/collisionEntry.cxx b/panda/src/collide/collisionEntry.cxx index ecdeae47c7..4a8faaed59 100644 --- a/panda/src/collide/collisionEntry.cxx +++ b/panda/src/collide/collisionEntry.cxx @@ -31,6 +31,7 @@ CollisionEntry(const CollisionEntry ©) : _into(copy._into), _from_node(copy._from_node), _into_node(copy._into_node), + _from_node_path(copy._from_node_path), _into_node_path(copy._into_node_path), _from_space(copy._from_space), _into_space(copy._into_space), @@ -55,6 +56,7 @@ operator = (const CollisionEntry ©) { _into = copy._into; _from_node = copy._from_node; _into_node = copy._into_node; + _from_node_path = copy._from_node_path; _into_node_path = copy._into_node_path; _from_space = copy._from_space; _into_space = copy._into_space; diff --git a/panda/src/collide/collisionEntry.h b/panda/src/collide/collisionEntry.h index fee25358b3..e955473c89 100644 --- a/panda/src/collide/collisionEntry.h +++ b/panda/src/collide/collisionEntry.h @@ -59,6 +59,7 @@ PUBLISHED: INLINE CollisionNode *get_from_node() const; INLINE PandaNode *get_into_node() const; + INLINE const NodePath &get_from_node_path() const; INLINE const NodePath &get_into_node_path() const; INLINE const TransformState *get_from_space() const; @@ -106,6 +107,7 @@ private: PT(CollisionNode) _from_node; PT(PandaNode) _into_node; + NodePath _from_node_path; NodePath _into_node_path; CPT(TransformState) _from_space; CPT(TransformState) _into_space; diff --git a/panda/src/collide/collisionHandlerFloor.cxx b/panda/src/collide/collisionHandlerFloor.cxx index dab77a72f0..1070a8a85b 100644 --- a/panda/src/collide/collisionHandlerFloor.cxx +++ b/panda/src/collide/collisionHandlerFloor.cxx @@ -62,25 +62,24 @@ handle_entries() { FromEntries::const_iterator fi; for (fi = _from_entries.begin(); fi != _from_entries.end(); ++fi) { - CollisionNode *from_node = (*fi).first; - nassertr(from_node != (CollisionNode *)NULL, false); + const NodePath &from_node_path = (*fi).first; const Entries &entries = (*fi).second; Colliders::iterator ci; - ci = _colliders.find(from_node); + ci = _colliders.find(from_node_path); if (ci == _colliders.end()) { // Hmm, someone added a CollisionNode to a traverser and gave // it this CollisionHandler pointer--but they didn't tell us // about the node. collide_cat.error() << get_type() << " doesn't know about " - << *from_node << ", disabling.\n"; + << from_node_path << ", disabling.\n"; okflag = false; } else { ColliderDef &def = (*ci).second; if (!def.is_valid()) { collide_cat.error() - << "Removing invalid collider " << *from_node << " from " + << "Removing invalid collider " << from_node_path << " from " << get_type() << "\n"; _colliders.erase(ci); } else { @@ -92,7 +91,7 @@ handle_entries() { for (ei = entries.begin(); ei != entries.end(); ++ei) { CollisionEntry *entry = (*ei); nassertr(entry != (CollisionEntry *)NULL, false); - nassertr(from_node == entry->get_from_node(), false); + nassertr(from_node_path == entry->get_from_node_path(), false); if (entry->has_from_intersection_point()) { LPoint3f point = entry->get_from_intersection_point(); diff --git a/panda/src/collide/collisionHandlerPhysical.I b/panda/src/collide/collisionHandlerPhysical.I index 4b8a8b93d4..7550a93f2a 100644 --- a/panda/src/collide/collisionHandlerPhysical.I +++ b/panda/src/collide/collisionHandlerPhysical.I @@ -39,6 +39,19 @@ set_node(PandaNode *node) { _drive_interface.clear(); } +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerPhysical::ColliderDef::set_target +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void CollisionHandlerPhysical::ColliderDef:: +set_target(const NodePath &target) { + _target = target; + if (!target.is_empty()) { + _node = target.node(); + } +} + //////////////////////////////////////////////////////////////////// // Function: CollisionHandlerPhysical::ColliderDef::is_valid // Access: Public diff --git a/panda/src/collide/collisionHandlerPhysical.cxx b/panda/src/collide/collisionHandlerPhysical.cxx index 62e755cdda..f06f69aece 100644 --- a/panda/src/collide/collisionHandlerPhysical.cxx +++ b/panda/src/collide/collisionHandlerPhysical.cxx @@ -126,40 +126,29 @@ end_group() { } //////////////////////////////////////////////////////////////////// -// Function: CollisionHandlerPhysical::add_collider_drive -// Access: Public -// Description: Adds a new collider to the list with a DriveInterface -// pointer that needs to be told about the collider's -// new position, or updates the existing collider with a -// new DriveInterface pointer. +// Function: CollisionHandlerPhysical::add_collider +// Access: Published +// Description: Adds a new collider to the list with a NodePath +// that will be updated with the collider's new +// position, or updates the existing collider with a new +// NodePath object. //////////////////////////////////////////////////////////////////// void CollisionHandlerPhysical:: -add_collider_drive(CollisionNode *node, DriveInterface *drive_interface) { - _colliders[node].set_drive_interface(drive_interface); -} - -//////////////////////////////////////////////////////////////////// -// Function: CollisionHandlerPhysical::add_collider_node -// Access: Public -// Description: Adds a new collider to the list with a PandaNode -// pointer that will be updated with the collider's -// new position, or updates the existing collider with a -// new PandaNode pointer. -//////////////////////////////////////////////////////////////////// -void CollisionHandlerPhysical:: -add_collider_node(CollisionNode *node, PandaNode *target) { - _colliders[node].set_node(target); +add_collider(const NodePath &collider, const NodePath &target) { + nassertv(!collider.is_empty() && collider.node()->is_of_type(CollisionNode::get_class_type())); + nassertv(!target.is_empty()); + _colliders[collider].set_target(target); } //////////////////////////////////////////////////////////////////// // Function: CollisionHandlerPhysical::remove_collider -// Access: Public +// Access: Published // Description: Removes the collider from the list of colliders that // this handler knows about. //////////////////////////////////////////////////////////////////// bool CollisionHandlerPhysical:: -remove_collider(CollisionNode *node) { - Colliders::iterator ci = _colliders.find(node); +remove_collider(const NodePath &collider) { + Colliders::iterator ci = _colliders.find(collider); if (ci == _colliders.end()) { return false; } @@ -169,19 +158,19 @@ remove_collider(CollisionNode *node) { //////////////////////////////////////////////////////////////////// // Function: CollisionHandlerPhysical::has_collider -// Access: Public +// Access: Published // Description: Returns true if the handler knows about the indicated // collider, false otherwise. //////////////////////////////////////////////////////////////////// bool CollisionHandlerPhysical:: -has_collider(CollisionNode *node) const { - Colliders::const_iterator ci = _colliders.find(node); +has_collider(const NodePath &target) const { + Colliders::const_iterator ci = _colliders.find(target); return (ci != _colliders.end()); } //////////////////////////////////////////////////////////////////// // Function: CollisionHandlerPhysical::clear_colliders -// Access: Public +// Access: Published // Description: Completely empties the list of colliders this handler // knows about. //////////////////////////////////////////////////////////////////// @@ -190,4 +179,26 @@ clear_colliders() { _colliders.clear(); } +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerPhysical::add_collider_node +// Access: Published +// Description: This method is deprecated and will shortly be removed +// in favor of the newer NodePath-based method, above. +//////////////////////////////////////////////////////////////////// +void CollisionHandlerPhysical:: +add_collider_node(CollisionNode *node, PandaNode *target) { + add_collider(NodePath(node), NodePath(target)); +} +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerPhysical::add_collider_drive +// Access: Published +// Description: Adds a new collider to the list with a DriveInterface +// pointer that needs to be told about the collider's +// new position, or updates the existing collider with a +// new DriveInterface pointer. +//////////////////////////////////////////////////////////////////// +void CollisionHandlerPhysical:: +add_collider_drive(CollisionNode *node, DriveInterface *drive_interface) { + _colliders[NodePath(node)].set_drive_interface(drive_interface); +} diff --git a/panda/src/collide/collisionHandlerPhysical.h b/panda/src/collide/collisionHandlerPhysical.h index 2f97ebaf6d..84da4ce96d 100644 --- a/panda/src/collide/collisionHandlerPhysical.h +++ b/panda/src/collide/collisionHandlerPhysical.h @@ -45,23 +45,28 @@ public: virtual bool end_group(); PUBLISHED: - void add_collider_node(CollisionNode *node, PandaNode *target); - bool remove_collider(CollisionNode *node); - bool has_collider(CollisionNode *node) const; + void add_collider(const NodePath &collider, const NodePath &target); + bool remove_collider(const NodePath &collider); + bool has_collider(const NodePath &collider) const; void clear_colliders(); + // The following method is deprecated and exists only as a temporary + // transition to the above new NodePath-based methods. + void add_collider_node(CollisionNode *node, PandaNode *target); + // add_collider_drive() is becoming obsolete. If you need it, let us know. void add_collider_drive(CollisionNode *node, DriveInterface *drive_interface); protected: typedef pvector< PT(CollisionEntry) > Entries; - typedef pmap FromEntries; + typedef pmap FromEntries; FromEntries _from_entries; class ColliderDef { public: INLINE void set_drive_interface(DriveInterface *drive_interface); INLINE void set_node(PandaNode *node); + INLINE void set_target(const NodePath &target); INLINE bool is_valid() const; void get_mat(LMatrix4f &mat) const; @@ -69,9 +74,10 @@ protected: PT(DriveInterface) _drive_interface; PT(PandaNode) _node; + NodePath _target; }; - typedef pmap Colliders; + typedef pmap Colliders; Colliders _colliders; virtual bool handle_entries()=0; diff --git a/panda/src/collide/collisionHandlerPusher.cxx b/panda/src/collide/collisionHandlerPusher.cxx index 9d2ec5da3e..8286332933 100644 --- a/panda/src/collide/collisionHandlerPusher.cxx +++ b/panda/src/collide/collisionHandlerPusher.cxx @@ -76,25 +76,24 @@ handle_entries() { FromEntries::const_iterator fi; for (fi = _from_entries.begin(); fi != _from_entries.end(); ++fi) { - CollisionNode *from_node = (*fi).first; - nassertr(from_node != (CollisionNode *)NULL, false); + const NodePath &from_node_path = (*fi).first; const Entries &entries = (*fi).second; Colliders::iterator ci; - ci = _colliders.find(from_node); + ci = _colliders.find(from_node_path); if (ci == _colliders.end()) { // Hmm, someone added a CollisionNode to a traverser and gave // it this CollisionHandler pointer--but they didn't tell us // about the node. collide_cat.error() << "CollisionHandlerPusher doesn't know about " - << *from_node << ", disabling.\n"; + << from_node_path << ", disabling.\n"; okflag = false; } else { ColliderDef &def = (*ci).second; if (!def.is_valid()) { collide_cat.error() - << "Removing invalid collider " << *from_node << " from " + << "Removing invalid collider " << from_node_path << " from " << get_type() << "\n"; _colliders.erase(ci); } else { @@ -113,14 +112,14 @@ handle_entries() { for (ei = entries.begin(); ei != entries.end(); ++ei) { CollisionEntry *entry = (*ei); nassertr(entry != (CollisionEntry *)NULL, false); - nassertr(from_node == entry->get_from_node(), false); + nassertr(from_node_path == entry->get_from_node_path(), false); if (!entry->has_from_surface_normal() || !entry->has_from_depth()) { #ifndef NDEBUG if (collide_cat.is_debug()) { collide_cat.debug() - << "Cannot shove on " << *from_node << " for collision into " + << "Cannot shove on " << from_node_path << " for collision into " << *entry->get_into_node() << "; no normal/depth information.\n"; } #endif @@ -145,7 +144,7 @@ handle_entries() { #ifndef NDEBUG if (collide_cat.is_debug()) { collide_cat.debug() - << "Shove on " << *from_node << " from " + << "Shove on " << from_node_path << " from " << *entry->get_into_node() << ": " << sd._vector << " times " << sd._length << "\n"; } @@ -244,7 +243,7 @@ handle_entries() { #ifndef NDEBUG if (collide_cat.is_debug()) { collide_cat.debug() - << "Net shove on " << *from_node << " is: " + << "Net shove on " << from_node_path << " is: " << net_shove << "\n"; } #endif diff --git a/panda/src/collide/collisionLevelState.I b/panda/src/collide/collisionLevelState.I index c0dca83e45..fb9cc9f00c 100644 --- a/panda/src/collide/collisionLevelState.I +++ b/panda/src/collide/collisionLevelState.I @@ -150,12 +150,12 @@ get_collider(int n) const { } //////////////////////////////////////////////////////////////////// -// Function: CollisionLevelState::get_node +// Function: CollisionLevelState::get_collider_node // Access: Public // Description: //////////////////////////////////////////////////////////////////// INLINE CollisionNode *CollisionLevelState:: -get_node(int n) const { +get_collider_node(int n) const { nassertr(n >= 0 && n < (int)_colliders.size(), NULL); nassertr(has_collider(n), NULL); @@ -163,55 +163,16 @@ get_node(int n) const { } //////////////////////////////////////////////////////////////////// -// Function: CollisionLevelState::get_space +// Function: CollisionLevelState::get_collider_node_path // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE const TransformState *CollisionLevelState:: -get_space(int n) const { - nassertr(n >= 0 && n < (int)_colliders.size(), TransformState::make_identity()); - nassertr(has_collider(n), TransformState::make_identity()); +INLINE NodePath CollisionLevelState:: +get_collider_node_path(int n) const { + nassertr(n >= 0 && n < (int)_colliders.size(), NodePath::fail()); + nassertr(has_collider(n), NodePath::fail()); - return _colliders[n]._space; -} - -//////////////////////////////////////////////////////////////////// -// Function: CollisionLevelState::get_inv_space -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE const TransformState *CollisionLevelState:: -get_inv_space(int n) const { - nassertr(n >= 0 && n < (int)_colliders.size(), TransformState::make_identity()); - nassertr(has_collider(n), TransformState::make_identity()); - - return _colliders[n]._inv_space; -} - -//////////////////////////////////////////////////////////////////// -// Function: CollisionLevelState::get_prev_space -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE const TransformState *CollisionLevelState:: -get_prev_space(int n) const { - nassertr(n >= 0 && n < (int)_colliders.size(), TransformState::make_identity()); - nassertr(has_collider(n), TransformState::make_identity()); - - return _colliders[n]._prev_space; -} - -//////////////////////////////////////////////////////////////////// -// Function: CollisionLevelState::get_delta -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE const LVector3f &CollisionLevelState:: -get_delta(int n) const { - nassertr(n >= 0 && n < (int)_colliders.size(), LVector3f::zero()); - nassertr(has_collider(n), LVector3f::zero()); - - return _colliders[n]._delta; + return _colliders[n]._node_path; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/collide/collisionLevelState.cxx b/panda/src/collide/collisionLevelState.cxx index ddb8bb03e6..166248b5f1 100644 --- a/panda/src/collide/collisionLevelState.cxx +++ b/panda/src/collide/collisionLevelState.cxx @@ -64,6 +64,11 @@ prepare_collider(const ColliderDef &def) { GeometricBoundingVolume *gbv; DCAST_INTO_V(gbv, bv.make_copy()); + // TODO: we need to make this logic work in the new relative + // world. The bounding volume should be extended by the object's + // motion relative to each object it is considering a collision + // with. That makes things complicated! + /* if (def._delta != LVector3f::zero()) { // If the node has a delta, we have to include the starting // point in the volume as well. @@ -76,8 +81,9 @@ prepare_collider(const ColliderDef &def) { // same results, and is much easier to compute. gbv->extend_by(LPoint3f(-def._delta)); } + */ - gbv->xform(def._space->get_mat()); + gbv->xform(def._node_path.get_mat(NodePath())); _local_bounds.push_back(gbv); } @@ -119,14 +125,14 @@ any_in_bounds() { int num_colliders = get_num_colliders(); for (int c = 0; c < num_colliders; c++) { if (has_collider(c)) { - CollisionNode *collider = get_node(c); + CollisionNode *cnode = get_collider_node(c); bool is_in = false; // Don't even bother testing the bounding volume if there are // no collide bits in common between our collider and this // node. - CollideMask from_mask = collider->get_from_collide_mask(); - if (collider->get_collide_geom() || + CollideMask from_mask = cnode->get_from_collide_mask(); + if (cnode->get_collide_geom() || (from_mask & node()->get_net_collide_mask()) != 0) { // There are bits in common, so go ahead and try the // bounding volume. diff --git a/panda/src/collide/collisionLevelState.h b/panda/src/collide/collisionLevelState.h index 0735b3bd64..306ba469b5 100644 --- a/panda/src/collide/collisionLevelState.h +++ b/panda/src/collide/collisionLevelState.h @@ -26,7 +26,6 @@ #include "geometricBoundingVolume.h" #include "nodePath.h" #include "workingNodePath.h" -#include "transformState.h" #include "pointerTo.h" #include "plist.h" @@ -45,10 +44,7 @@ public: public: CollisionSolid *_collider; CollisionNode *_node; - CPT(TransformState) _space; - CPT(TransformState) _inv_space; - CPT(TransformState) _prev_space; - LVector3f _delta; + NodePath _node_path; }; INLINE CollisionLevelState(const NodePath &node_path); @@ -74,11 +70,8 @@ public: INLINE void reached_collision_node(); INLINE CollisionSolid *get_collider(int n) const; - INLINE CollisionNode *get_node(int n) const; - INLINE const TransformState *get_space(int n) const; - INLINE const TransformState *get_inv_space(int n) const; - INLINE const TransformState *get_prev_space(int n) const; - INLINE const LVector3f &get_delta(int n) const; + INLINE CollisionNode *get_collider_node(int n) const; + INLINE NodePath get_collider_node_path(int n) const; INLINE const GeometricBoundingVolume *get_local_bound(int n) const; INLINE const GeometricBoundingVolume *get_parent_bound(int n) const; diff --git a/panda/src/collide/collisionTraverser.I b/panda/src/collide/collisionTraverser.I index a12b68f76b..80cea3eff9 100644 --- a/panda/src/collide/collisionTraverser.I +++ b/panda/src/collide/collisionTraverser.I @@ -19,7 +19,7 @@ //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::set_respect_prev_transform -// Access: Public +// Access: Published // Description: Sets the flag that indicates whether the // prev_transform stored on a node (as updated via // set_fluid_pos(), etc.) is respected to calculate @@ -36,7 +36,7 @@ set_respect_prev_transform(bool flag) { //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::get_respect_prev_transform -// Access: Public +// Access: Published // Description: Returns the flag that indicates whether the // prev_transform stored on a node is respected to // calculate collisions. See @@ -51,7 +51,7 @@ get_respect_prev_transform() const { //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::has_recorder -// Access: Public +// Access: Published // Description: Returns true if the CollisionTraverser has a // CollisionRecorder object currently assigned, false // otherwise. @@ -63,7 +63,7 @@ has_recorder() const { //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::get_recorder -// Access: Public +// Access: Published // Description: Returns the CollisionRecorder currently assigned, or // NULL if no recorder is assigned. //////////////////////////////////////////////////////////////////// @@ -74,7 +74,7 @@ get_recorder() const { //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::clear_recorder -// Access: Public +// Access: Published // Description: Removes the CollisionRecorder from the traverser and // restores normal low-overhead operation. //////////////////////////////////////////////////////////////////// diff --git a/panda/src/collide/collisionTraverser.cxx b/panda/src/collide/collisionTraverser.cxx index 062b06de1b..66978e4c4d 100644 --- a/panda/src/collide/collisionTraverser.cxx +++ b/panda/src/collide/collisionTraverser.cxx @@ -36,7 +36,7 @@ PStatCollector CollisionTraverser::_collisions_pcollector("App:Collisions"); //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::Constructor -// Access: Public +// Access: Published // Description: //////////////////////////////////////////////////////////////////// CollisionTraverser:: @@ -49,7 +49,7 @@ CollisionTraverser() { //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::Destructor -// Access: Public +// Access: Published // Description: //////////////////////////////////////////////////////////////////// CollisionTraverser:: @@ -61,7 +61,7 @@ CollisionTraverser:: //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::add_collider -// Access: Public +// Access: Published // Description: Adds a new CollisionNode, representing an object that // will be tested for collisions into other objects, // along with the handler that will serve each detected @@ -74,12 +74,12 @@ CollisionTraverser:: // again on the same node. //////////////////////////////////////////////////////////////////// void CollisionTraverser:: -add_collider(CollisionNode *node, CollisionHandler *handler) { +add_collider(const NodePath &collider, CollisionHandler *handler) { nassertv(_ordered_colliders.size() == _colliders.size()); - nassertv(node != (CollisionNode *)NULL); + nassertv(!collider.is_empty() && collider.node()->is_of_type(CollisionNode::get_class_type())); nassertv(handler != (CollisionHandler *)NULL); - Colliders::iterator ci = _colliders.find(node); + Colliders::iterator ci = _colliders.find(collider); if (ci != _colliders.end()) { // We already knew about this collider. if ((*ci).second != handler) { @@ -106,8 +106,8 @@ add_collider(CollisionNode *node, CollisionHandler *handler) { } else { // We hadn't already known about this collider. - _colliders.insert(Colliders::value_type(node, handler)); - _ordered_colliders.push_back(node); + _colliders.insert(Colliders::value_type(collider, handler)); + _ordered_colliders.push_back(collider); Handlers::iterator hi = _handlers.find(handler); if (hi == _handlers.end()) { @@ -122,7 +122,7 @@ add_collider(CollisionNode *node, CollisionHandler *handler) { //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::remove_collider -// Access: Public +// Access: Published // Description: Removes the collider (and its associated handler) // from the set of CollisionNodes that will be tested // each frame for collisions into other objects. @@ -130,10 +130,10 @@ add_collider(CollisionNode *node, CollisionHandler *handler) { // false if it wasn't present to begin with. //////////////////////////////////////////////////////////////////// bool CollisionTraverser:: -remove_collider(CollisionNode *node) { +remove_collider(const NodePath &collider) { nassertr(_ordered_colliders.size() == _colliders.size(), false); - Colliders::iterator ci = _colliders.find(node); + Colliders::iterator ci = _colliders.find(collider); if (ci == _colliders.end()) { // We didn't know about this node. return false; @@ -153,7 +153,7 @@ remove_collider(CollisionNode *node) { _colliders.erase(ci); OrderedColliders::iterator oci = - find(_ordered_colliders.begin(), _ordered_colliders.end(), node); + find(_ordered_colliders.begin(), _ordered_colliders.end(), collider); nassertr(oci != _ordered_colliders.end(), false); _ordered_colliders.erase(oci); @@ -163,20 +163,20 @@ remove_collider(CollisionNode *node) { //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::has_collider -// Access: Public +// Access: Published // Description: Returns true if the indicated node is current in the // set of nodes that will be tested each frame for // collisions into other objects. //////////////////////////////////////////////////////////////////// bool CollisionTraverser:: -has_collider(CollisionNode *node) const { - Colliders::const_iterator ci = _colliders.find(node); +has_collider(const NodePath &collider) const { + Colliders::const_iterator ci = _colliders.find(collider); return (ci != _colliders.end()); } //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::get_num_colliders -// Access: Public +// Access: Published // Description: Returns the number of CollisionNodes that have been // added to the traverser via add_collider(). //////////////////////////////////////////////////////////////////// @@ -188,11 +188,11 @@ get_num_colliders() const { //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::get_collider -// Access: Public +// Access: Published // Description: Returns the nth CollisionNode that has been // added to the traverser via add_collider(). //////////////////////////////////////////////////////////////////// -CollisionNode *CollisionTraverser:: +NodePath CollisionTraverser:: get_collider(int n) const { nassertr(_ordered_colliders.size() == _colliders.size(), NULL); nassertr(n >= 0 && n < (int)_ordered_colliders.size(), NULL); @@ -201,14 +201,14 @@ get_collider(int n) const { //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::get_handler -// Access: Public +// Access: Published // Description: Returns the handler that is currently assigned to // serve the indicated collision node, or NULL if the // node is not on the traverser's set of active nodes. //////////////////////////////////////////////////////////////////// CollisionHandler *CollisionTraverser:: -get_handler(CollisionNode *node) const { - Colliders::const_iterator ci = _colliders.find(node); +get_handler(const NodePath &collider) const { + Colliders::const_iterator ci = _colliders.find(collider); if (ci != _colliders.end()) { return (*ci).second; }; @@ -217,7 +217,7 @@ get_handler(CollisionNode *node) const { //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::clear_colliders -// Access: Public +// Access: Published // Description: Completely empties the set of collision nodes and // their associated handlers. //////////////////////////////////////////////////////////////////// @@ -227,10 +227,31 @@ clear_colliders() { _ordered_colliders.clear(); } +//////////////////////////////////////////////////////////////////// +// Function: CollisionTraverser::add_collider +// Access: Published +// Description: This method is deprecated and will shortly be removed +// in favor of the newer NodePath-based method, above. +//////////////////////////////////////////////////////////////////// +void CollisionTraverser:: +add_collider(CollisionNode *node, CollisionHandler *handler) { + add_collider(NodePath(node), handler); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionTraverser::remove_collider +// Access: Published +// Description: This method is deprecated and will shortly be removed +// in favor of the newer NodePath-based method, above. +//////////////////////////////////////////////////////////////////// +bool CollisionTraverser:: +remove_collider(CollisionNode *node) { + return remove_collider(NodePath(node)); +} //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::traverse -// Access: Public +// Access: Published // Description: //////////////////////////////////////////////////////////////////// void CollisionTraverser:: @@ -272,7 +293,7 @@ traverse(const NodePath &root) { //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::reset_prev_transform -// Access: Public +// Access: Published // Description: Once the collision traversal has finished, resets all // of the velocity deltas in the scene graph by setting // the "previous" transform to the current transform. @@ -287,7 +308,7 @@ reset_prev_transform(const NodePath &root) { #ifdef DO_COLLISION_RECORDING //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::set_recorder -// Access: Public +// Access: Published // Description: Uses the indicated CollisionRecorder object to start // recording the intersection tests made by each // subsequent call to traverse() on this object. A @@ -333,7 +354,7 @@ set_recorder(CollisionRecorder *recorder) { //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::output -// Access: Public +// Access: Published // Description: //////////////////////////////////////////////////////////////////// void CollisionTraverser:: @@ -344,7 +365,7 @@ output(ostream &out) const { //////////////////////////////////////////////////////////////////// // Function: CollisionTraverser::write -// Access: Public +// Access: Published // Description: //////////////////////////////////////////////////////////////////// void CollisionTraverser:: @@ -354,16 +375,19 @@ write(ostream &out, int indent_level) const { << " colliders and " << _handlers.size() << " handlers:\n"; Colliders::const_iterator ci; for (ci = _colliders.begin(); ci != _colliders.end(); ++ci) { - CollisionNode *cnode = (*ci).first; + NodePath cnode_path = (*ci).first; CollisionHandler *handler = (*ci).second; - nassertv(cnode != (CollisionNode *)NULL); nassertv(handler != (CollisionHandler *)NULL); indent(out, indent_level + 2) - << *cnode << " handled by " << handler->get_type() << "\n"; - int num_solids = cnode->get_num_solids(); - for (int i = 0; i < num_solids; i++) { - cnode->get_solid(i)->write(out, indent_level + 4); + << cnode_path << " handled by " << handler->get_type() << "\n"; + if (!cnode_path.is_empty() && cnode_path.node()->is_of_type(CollisionNode::get_class_type())) { + CollisionNode *cnode = DCAST(CollisionNode, cnode_path.node()); + + int num_solids = cnode->get_num_solids(); + for (int i = 0; i < num_solids; i++) { + cnode->get_solid(i)->write(out, indent_level + 4); + } } } } @@ -381,40 +405,23 @@ prepare_colliders(CollisionLevelState &level_state) { int i = 0; while (i < (int)_ordered_colliders.size()) { - CollisionNode *cnode = _ordered_colliders[i]; + NodePath cnode_path = _ordered_colliders[i]; + if (!cnode_path.is_empty() && + cnode_path.node()->is_of_type(CollisionNode::get_class_type())) { + CollisionNode *cnode = DCAST(CollisionNode, cnode_path.node()); - CollisionLevelState::ColliderDef def; - def._node = cnode; - NodePath cnode_path(cnode); - def._space = cnode_path.get_net_transform(); - def._inv_space = def._space->invert_compose(TransformState::make_identity()); - def._prev_space = cnode_path.get_net_prev_transform(); - if (_respect_prev_transform) { - def._delta = cnode_path.get_pos_delta(); - } else { - def._delta = LVector3f::zero(); - } - - -#ifndef NDEBUG - if (def._space->is_invalid()) { - collide_cat.error() - << "Collider " << *cnode - << " has become invalid. Dropping from traverser.\n"; - // This is safe to do while traversing the list of colliders, - // because we do not increment i in this case. - remove_collider(cnode); - } else -#endif - { - 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++; + 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++; + } } } @@ -450,21 +457,20 @@ r_traverse(CollisionLevelState &level_state) { int num_colliders = level_state.get_num_colliders(); for (int c = 0; c < num_colliders; c++) { if (level_state.has_collider(c)) { - entry._from_node = level_state.get_node(c); + entry._from_node = level_state.get_collider_node(c); if ((entry._from_node->get_from_collide_mask() & cnode->get_into_collide_mask()) != 0) { + entry._from_node_path = level_state.get_collider_node_path(c); entry._from = level_state.get_collider(c); - entry._from_space = level_state.get_space(c); + entry._from_space = entry._from_node_path.get_net_transform(); - LVector3f from_delta = level_state.get_delta(c); + entry._wrt_space = entry._from_node_path.get_transform(entry._into_node_path); + entry._inv_wrt_space = entry._into_node_path.get_transform(entry._from_node_path); - entry._wrt_space = entry._into_space->invert_compose(entry._from_space); - entry._inv_wrt_space = entry._from_space->invert_compose(entry._into_space); if (_respect_prev_transform) { - CPT(TransformState) into_prev_space = entry._into_node_path.get_net_prev_transform(); - CPT(TransformState) from_prev_space = level_state.get_prev_space(c); - entry._wrt_prev_space = into_prev_space->invert_compose(from_prev_space); + entry._wrt_prev_space = entry._from_node_path.get_prev_transform(entry._into_node_path); + } else { entry._wrt_prev_space = entry._wrt_space; } @@ -501,13 +507,13 @@ r_traverse(CollisionLevelState &level_state) { int num_colliders = level_state.get_num_colliders(); for (int c = 0; c < num_colliders; c++) { if (level_state.has_collider_with_geom(c)) { - entry._from_node = level_state.get_node(c); - + entry._from_node = level_state.get_collider_node(c); + entry._from_node_path = level_state.get_collider_node_path(c); entry._from = level_state.get_collider(c); - entry._from_space = level_state.get_space(c); + entry._from_space = entry._from_node_path.get_net_transform(); - entry._wrt_space = entry._into_space->invert_compose(entry._from_space); - entry._inv_wrt_space = entry._from_space->invert_compose(entry._into_space); + entry._wrt_space = entry._from_node_path.get_transform(entry._into_node_path); + entry._inv_wrt_space = entry._into_node_path.get_transform(entry._from_node_path); compare_collider_to_geom_node(entry, level_state.get_parent_bound(c), @@ -708,7 +714,7 @@ remove_handler(CollisionTraverser::Handlers::iterator hi) { while (ci != _colliders.end()) { if ((*ci).second == handler) { // This collider references this handler; remove it. - PT(CollisionNode) node = (*ci).first; + NodePath node_path = (*ci).first; Colliders::iterator cnext = ci; ++cnext; @@ -717,7 +723,7 @@ remove_handler(CollisionTraverser::Handlers::iterator hi) { // Also remove it from the ordered list. OrderedColliders::iterator oci = - find(_ordered_colliders.begin(), _ordered_colliders.end(), node); + find(_ordered_colliders.begin(), _ordered_colliders.end(), node_path); nassertr(oci != _ordered_colliders.end(), hi); _ordered_colliders.erase(oci); diff --git a/panda/src/collide/collisionTraverser.h b/panda/src/collide/collisionTraverser.h index 613d624f47..82f6ed4aae 100644 --- a/panda/src/collide/collisionTraverser.h +++ b/panda/src/collide/collisionTraverser.h @@ -56,13 +56,18 @@ PUBLISHED: INLINE void set_respect_prev_transform(bool flag); INLINE bool get_respect_prev_transform() const; + void add_collider(const NodePath &collider, CollisionHandler *handler); + bool remove_collider(const NodePath &collider); + bool has_collider(const NodePath &collider) const; + int get_num_colliders() const; + NodePath get_collider(int n) const; + CollisionHandler *get_handler(const NodePath &collider) const; + void clear_colliders(); + + // The following methods are deprecated and exist only as a temporary + // transition to the above new NodePath-based methods. void add_collider(CollisionNode *node, CollisionHandler *handler); bool remove_collider(CollisionNode *node); - bool has_collider(CollisionNode *node) const; - int get_num_colliders() const; - CollisionNode *get_collider(int n) const; - CollisionHandler *get_handler(CollisionNode *node) const; - void clear_colliders(); void traverse(const NodePath &root); void reset_prev_transform(const NodePath &root); @@ -103,9 +108,9 @@ private: PT(CollisionHandler) _default_handler; TypeHandle _graph_type; - typedef pmap Colliders; + typedef pmap Colliders; Colliders _colliders; - typedef pvector OrderedColliders; + typedef pvector OrderedColliders; OrderedColliders _ordered_colliders; typedef pmap Handlers;