Browse Source

first steps toward a NodePath-based interface

David Rose 22 years ago
parent
commit
e07d4b7847

+ 14 - 0
panda/src/collide/collisionEntry.I

@@ -100,6 +100,20 @@ get_into_node() const {
   return _into_node;
   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
 //     Function: CollisionEntry::get_into_node_path
 //       Access: Published
 //       Access: Published

+ 2 - 0
panda/src/collide/collisionEntry.cxx

@@ -31,6 +31,7 @@ CollisionEntry(const CollisionEntry &copy) :
   _into(copy._into),
   _into(copy._into),
   _from_node(copy._from_node),
   _from_node(copy._from_node),
   _into_node(copy._into_node),
   _into_node(copy._into_node),
+  _from_node_path(copy._from_node_path),
   _into_node_path(copy._into_node_path),
   _into_node_path(copy._into_node_path),
   _from_space(copy._from_space),
   _from_space(copy._from_space),
   _into_space(copy._into_space),
   _into_space(copy._into_space),
@@ -55,6 +56,7 @@ operator = (const CollisionEntry &copy) {
   _into = copy._into;
   _into = copy._into;
   _from_node = copy._from_node;
   _from_node = copy._from_node;
   _into_node = copy._into_node;
   _into_node = copy._into_node;
+  _from_node_path = copy._from_node_path;
   _into_node_path = copy._into_node_path;
   _into_node_path = copy._into_node_path;
   _from_space = copy._from_space;
   _from_space = copy._from_space;
   _into_space = copy._into_space;
   _into_space = copy._into_space;

+ 2 - 0
panda/src/collide/collisionEntry.h

@@ -59,6 +59,7 @@ PUBLISHED:
 
 
   INLINE CollisionNode *get_from_node() const;
   INLINE CollisionNode *get_from_node() const;
   INLINE PandaNode *get_into_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 NodePath &get_into_node_path() const;
 
 
   INLINE const TransformState *get_from_space() const;
   INLINE const TransformState *get_from_space() const;
@@ -106,6 +107,7 @@ private:
 
 
   PT(CollisionNode) _from_node;
   PT(CollisionNode) _from_node;
   PT(PandaNode) _into_node;
   PT(PandaNode) _into_node;
+  NodePath _from_node_path;
   NodePath _into_node_path;
   NodePath _into_node_path;
   CPT(TransformState) _from_space;
   CPT(TransformState) _from_space;
   CPT(TransformState) _into_space;
   CPT(TransformState) _into_space;

+ 5 - 6
panda/src/collide/collisionHandlerFloor.cxx

@@ -62,25 +62,24 @@ handle_entries() {
 
 
   FromEntries::const_iterator fi;
   FromEntries::const_iterator fi;
   for (fi = _from_entries.begin(); fi != _from_entries.end(); ++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;
     const Entries &entries = (*fi).second;
 
 
     Colliders::iterator ci;
     Colliders::iterator ci;
-    ci = _colliders.find(from_node);
+    ci = _colliders.find(from_node_path);
     if (ci == _colliders.end()) {
     if (ci == _colliders.end()) {
       // Hmm, someone added a CollisionNode to a traverser and gave
       // Hmm, someone added a CollisionNode to a traverser and gave
       // it this CollisionHandler pointer--but they didn't tell us
       // it this CollisionHandler pointer--but they didn't tell us
       // about the node.
       // about the node.
       collide_cat.error()
       collide_cat.error()
         << get_type() << " doesn't know about "
         << get_type() << " doesn't know about "
-        << *from_node << ", disabling.\n";
+        << from_node_path << ", disabling.\n";
       okflag = false;
       okflag = false;
     } else {
     } else {
       ColliderDef &def = (*ci).second;
       ColliderDef &def = (*ci).second;
       if (!def.is_valid()) {
       if (!def.is_valid()) {
         collide_cat.error()
         collide_cat.error()
-          << "Removing invalid collider " << *from_node << " from "
+          << "Removing invalid collider " << from_node_path << " from "
           << get_type() << "\n";
           << get_type() << "\n";
         _colliders.erase(ci);
         _colliders.erase(ci);
       } else {
       } else {
@@ -92,7 +91,7 @@ handle_entries() {
         for (ei = entries.begin(); ei != entries.end(); ++ei) {
         for (ei = entries.begin(); ei != entries.end(); ++ei) {
           CollisionEntry *entry = (*ei);
           CollisionEntry *entry = (*ei);
           nassertr(entry != (CollisionEntry *)NULL, false);
           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()) {
           if (entry->has_from_intersection_point()) {
             LPoint3f point = entry->get_from_intersection_point();
             LPoint3f point = entry->get_from_intersection_point();

+ 13 - 0
panda/src/collide/collisionHandlerPhysical.I

@@ -39,6 +39,19 @@ set_node(PandaNode *node) {
   _drive_interface.clear();
   _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
 //     Function: CollisionHandlerPhysical::ColliderDef::is_valid
 //       Access: Public
 //       Access: Public

+ 39 - 28
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.
-////////////////////////////////////////////////////////////////////
-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.
+//     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::
 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
 //     Function: CollisionHandlerPhysical::remove_collider
-//       Access: Public
+//       Access: Published
 //  Description: Removes the collider from the list of colliders that
 //  Description: Removes the collider from the list of colliders that
 //               this handler knows about.
 //               this handler knows about.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool CollisionHandlerPhysical::
 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()) {
   if (ci == _colliders.end()) {
     return false;
     return false;
   }
   }
@@ -169,19 +158,19 @@ remove_collider(CollisionNode *node) {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionHandlerPhysical::has_collider
 //     Function: CollisionHandlerPhysical::has_collider
-//       Access: Public
+//       Access: Published
 //  Description: Returns true if the handler knows about the indicated
 //  Description: Returns true if the handler knows about the indicated
 //               collider, false otherwise.
 //               collider, false otherwise.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool CollisionHandlerPhysical::
 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());
   return (ci != _colliders.end());
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionHandlerPhysical::clear_colliders
 //     Function: CollisionHandlerPhysical::clear_colliders
-//       Access: Public
+//       Access: Published
 //  Description: Completely empties the list of colliders this handler
 //  Description: Completely empties the list of colliders this handler
 //               knows about.
 //               knows about.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -190,4 +179,26 @@ clear_colliders() {
   _colliders.clear();
   _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);
+}

+ 11 - 5
panda/src/collide/collisionHandlerPhysical.h

@@ -45,23 +45,28 @@ public:
   virtual bool end_group();
   virtual bool end_group();
 
 
 PUBLISHED:
 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();
   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.
   // add_collider_drive() is becoming obsolete.  If you need it, let us know.
   void add_collider_drive(CollisionNode *node, DriveInterface *drive_interface);
   void add_collider_drive(CollisionNode *node, DriveInterface *drive_interface);
 
 
 protected:
 protected:
   typedef pvector< PT(CollisionEntry) > Entries;
   typedef pvector< PT(CollisionEntry) > Entries;
-  typedef pmap<PT(CollisionNode), Entries> FromEntries;
+  typedef pmap<NodePath, Entries> FromEntries;
   FromEntries _from_entries;
   FromEntries _from_entries;
 
 
   class ColliderDef {
   class ColliderDef {
   public:
   public:
     INLINE void set_drive_interface(DriveInterface *drive_interface);
     INLINE void set_drive_interface(DriveInterface *drive_interface);
     INLINE void set_node(PandaNode *node);
     INLINE void set_node(PandaNode *node);
+    INLINE void set_target(const NodePath &target);
     INLINE bool is_valid() const;
     INLINE bool is_valid() const;
 
 
     void get_mat(LMatrix4f &mat) const;
     void get_mat(LMatrix4f &mat) const;
@@ -69,9 +74,10 @@ protected:
 
 
     PT(DriveInterface) _drive_interface;
     PT(DriveInterface) _drive_interface;
     PT(PandaNode) _node;
     PT(PandaNode) _node;
+    NodePath _target;
   };
   };
 
 
-  typedef pmap<PT(CollisionNode), ColliderDef> Colliders;
+  typedef pmap<NodePath, ColliderDef> Colliders;
   Colliders _colliders;
   Colliders _colliders;
 
 
   virtual bool handle_entries()=0;
   virtual bool handle_entries()=0;

+ 8 - 9
panda/src/collide/collisionHandlerPusher.cxx

@@ -76,25 +76,24 @@ handle_entries() {
 
 
   FromEntries::const_iterator fi;
   FromEntries::const_iterator fi;
   for (fi = _from_entries.begin(); fi != _from_entries.end(); ++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;
     const Entries &entries = (*fi).second;
 
 
     Colliders::iterator ci;
     Colliders::iterator ci;
-    ci = _colliders.find(from_node);
+    ci = _colliders.find(from_node_path);
     if (ci == _colliders.end()) {
     if (ci == _colliders.end()) {
       // Hmm, someone added a CollisionNode to a traverser and gave
       // Hmm, someone added a CollisionNode to a traverser and gave
       // it this CollisionHandler pointer--but they didn't tell us
       // it this CollisionHandler pointer--but they didn't tell us
       // about the node.
       // about the node.
       collide_cat.error()
       collide_cat.error()
         << "CollisionHandlerPusher doesn't know about "
         << "CollisionHandlerPusher doesn't know about "
-        << *from_node << ", disabling.\n";
+        << from_node_path << ", disabling.\n";
       okflag = false;
       okflag = false;
     } else {
     } else {
       ColliderDef &def = (*ci).second;
       ColliderDef &def = (*ci).second;
       if (!def.is_valid()) {
       if (!def.is_valid()) {
         collide_cat.error()
         collide_cat.error()
-          << "Removing invalid collider " << *from_node << " from "
+          << "Removing invalid collider " << from_node_path << " from "
           << get_type() << "\n";
           << get_type() << "\n";
         _colliders.erase(ci);
         _colliders.erase(ci);
       } else {
       } else {
@@ -113,14 +112,14 @@ handle_entries() {
         for (ei = entries.begin(); ei != entries.end(); ++ei) {
         for (ei = entries.begin(); ei != entries.end(); ++ei) {
           CollisionEntry *entry = (*ei);
           CollisionEntry *entry = (*ei);
           nassertr(entry != (CollisionEntry *)NULL, false);
           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() ||
           if (!entry->has_from_surface_normal() ||
               !entry->has_from_depth()) {
               !entry->has_from_depth()) {
             #ifndef NDEBUG          
             #ifndef NDEBUG          
             if (collide_cat.is_debug()) {
             if (collide_cat.is_debug()) {
               collide_cat.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";
                 << *entry->get_into_node() << "; no normal/depth information.\n";
             }
             }
             #endif            
             #endif            
@@ -145,7 +144,7 @@ handle_entries() {
               #ifndef NDEBUG          
               #ifndef NDEBUG          
               if (collide_cat.is_debug()) {
               if (collide_cat.is_debug()) {
                 collide_cat.debug()
                 collide_cat.debug()
-                  << "Shove on " << *from_node << " from "
+                  << "Shove on " << from_node_path << " from "
                   << *entry->get_into_node() << ": " << sd._vector
                   << *entry->get_into_node() << ": " << sd._vector
                   << " times " << sd._length << "\n";
                   << " times " << sd._length << "\n";
               }
               }
@@ -244,7 +243,7 @@ handle_entries() {
           #ifndef NDEBUG          
           #ifndef NDEBUG          
           if (collide_cat.is_debug()) {
           if (collide_cat.is_debug()) {
             collide_cat.debug()
             collide_cat.debug()
-              << "Net shove on " << *from_node << " is: "
+              << "Net shove on " << from_node_path << " is: "
               << net_shove << "\n";
               << net_shove << "\n";
           }
           }
           #endif
           #endif

+ 8 - 47
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
 //       Access: Public
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE CollisionNode *CollisionLevelState::
 INLINE CollisionNode *CollisionLevelState::
-get_node(int n) const {
+get_collider_node(int n) const {
   nassertr(n >= 0 && n < (int)_colliders.size(), NULL);
   nassertr(n >= 0 && n < (int)_colliders.size(), NULL);
   nassertr(has_collider(n), 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
 //       Access: Public
 //  Description:
 //  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());
-
-  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());
+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]._delta;
+  return _colliders[n]._node_path;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 10 - 4
panda/src/collide/collisionLevelState.cxx

@@ -64,6 +64,11 @@ prepare_collider(const ColliderDef &def) {
     GeometricBoundingVolume *gbv;
     GeometricBoundingVolume *gbv;
     DCAST_INTO_V(gbv, bv.make_copy());
     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 (def._delta != LVector3f::zero()) {
       // If the node has a delta, we have to include the starting
       // If the node has a delta, we have to include the starting
       // point in the volume as well.
       // point in the volume as well.
@@ -76,8 +81,9 @@ prepare_collider(const ColliderDef &def) {
       // same results, and is much easier to compute.
       // same results, and is much easier to compute.
       gbv->extend_by(LPoint3f(-def._delta));
       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);
     _local_bounds.push_back(gbv);
   }
   }
 
 
@@ -119,14 +125,14 @@ any_in_bounds() {
     int num_colliders = get_num_colliders();
     int num_colliders = get_num_colliders();
     for (int c = 0; c < num_colliders; c++) {
     for (int c = 0; c < num_colliders; c++) {
       if (has_collider(c)) {
       if (has_collider(c)) {
-        CollisionNode *collider = get_node(c);
+        CollisionNode *cnode = get_collider_node(c);
         bool is_in = false;
         bool is_in = false;
 
 
         // Don't even bother testing the bounding volume if there are
         // Don't even bother testing the bounding volume if there are
         // no collide bits in common between our collider and this
         // no collide bits in common between our collider and this
         // node.
         // 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) {
             (from_mask & node()->get_net_collide_mask()) != 0) {
           // There are bits in common, so go ahead and try the
           // There are bits in common, so go ahead and try the
           // bounding volume.
           // bounding volume.

+ 3 - 10
panda/src/collide/collisionLevelState.h

@@ -26,7 +26,6 @@
 #include "geometricBoundingVolume.h"
 #include "geometricBoundingVolume.h"
 #include "nodePath.h"
 #include "nodePath.h"
 #include "workingNodePath.h"
 #include "workingNodePath.h"
-#include "transformState.h"
 #include "pointerTo.h"
 #include "pointerTo.h"
 #include "plist.h"
 #include "plist.h"
 
 
@@ -45,10 +44,7 @@ public:
   public:
   public:
     CollisionSolid *_collider;
     CollisionSolid *_collider;
     CollisionNode *_node;
     CollisionNode *_node;
-    CPT(TransformState) _space;
-    CPT(TransformState) _inv_space;
-    CPT(TransformState) _prev_space;
-    LVector3f _delta;
+    NodePath _node_path;
   };
   };
 
 
   INLINE CollisionLevelState(const NodePath &node_path);
   INLINE CollisionLevelState(const NodePath &node_path);
@@ -74,11 +70,8 @@ public:
   INLINE void reached_collision_node();
   INLINE void reached_collision_node();
 
 
   INLINE CollisionSolid *get_collider(int n) const;
   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_local_bound(int n) const;
   INLINE const GeometricBoundingVolume *get_parent_bound(int n) const;
   INLINE const GeometricBoundingVolume *get_parent_bound(int n) const;
 
 

+ 5 - 5
panda/src/collide/collisionTraverser.I

@@ -19,7 +19,7 @@
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::set_respect_prev_transform
 //     Function: CollisionTraverser::set_respect_prev_transform
-//       Access: Public
+//       Access: Published
 //  Description: Sets the flag that indicates whether the
 //  Description: Sets the flag that indicates whether the
 //               prev_transform stored on a node (as updated via
 //               prev_transform stored on a node (as updated via
 //               set_fluid_pos(), etc.) is respected to calculate
 //               set_fluid_pos(), etc.) is respected to calculate
@@ -36,7 +36,7 @@ set_respect_prev_transform(bool flag) {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::get_respect_prev_transform
 //     Function: CollisionTraverser::get_respect_prev_transform
-//       Access: Public
+//       Access: Published
 //  Description: Returns the flag that indicates whether the
 //  Description: Returns the flag that indicates whether the
 //               prev_transform stored on a node is respected to
 //               prev_transform stored on a node is respected to
 //               calculate collisions.  See
 //               calculate collisions.  See
@@ -51,7 +51,7 @@ get_respect_prev_transform() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::has_recorder
 //     Function: CollisionTraverser::has_recorder
-//       Access: Public
+//       Access: Published
 //  Description: Returns true if the CollisionTraverser has a
 //  Description: Returns true if the CollisionTraverser has a
 //               CollisionRecorder object currently assigned, false
 //               CollisionRecorder object currently assigned, false
 //               otherwise.
 //               otherwise.
@@ -63,7 +63,7 @@ has_recorder() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::get_recorder
 //     Function: CollisionTraverser::get_recorder
-//       Access: Public
+//       Access: Published
 //  Description: Returns the CollisionRecorder currently assigned, or
 //  Description: Returns the CollisionRecorder currently assigned, or
 //               NULL if no recorder is assigned.
 //               NULL if no recorder is assigned.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -74,7 +74,7 @@ get_recorder() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::clear_recorder
 //     Function: CollisionTraverser::clear_recorder
-//       Access: Public
+//       Access: Published
 //  Description: Removes the CollisionRecorder from the traverser and
 //  Description: Removes the CollisionRecorder from the traverser and
 //               restores normal low-overhead operation.
 //               restores normal low-overhead operation.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 87 - 81
panda/src/collide/collisionTraverser.cxx

@@ -36,7 +36,7 @@ PStatCollector CollisionTraverser::_collisions_pcollector("App:Collisions");
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::Constructor
 //     Function: CollisionTraverser::Constructor
-//       Access: Public
+//       Access: Published
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 CollisionTraverser::
 CollisionTraverser::
@@ -49,7 +49,7 @@ CollisionTraverser() {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::Destructor
 //     Function: CollisionTraverser::Destructor
-//       Access: Public
+//       Access: Published
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 CollisionTraverser::
 CollisionTraverser::
@@ -61,7 +61,7 @@ CollisionTraverser::
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::add_collider
 //     Function: CollisionTraverser::add_collider
-//       Access: Public
+//       Access: Published
 //  Description: Adds a new CollisionNode, representing an object that
 //  Description: Adds a new CollisionNode, representing an object that
 //               will be tested for collisions into other objects,
 //               will be tested for collisions into other objects,
 //               along with the handler that will serve each detected
 //               along with the handler that will serve each detected
@@ -74,12 +74,12 @@ CollisionTraverser::
 //               again on the same node.
 //               again on the same node.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CollisionTraverser::
 void CollisionTraverser::
-add_collider(CollisionNode *node, CollisionHandler *handler) {
+add_collider(const NodePath &collider, CollisionHandler *handler) {
   nassertv(_ordered_colliders.size() == _colliders.size());
   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);
   nassertv(handler != (CollisionHandler *)NULL);
 
 
-  Colliders::iterator ci = _colliders.find(node);
+  Colliders::iterator ci = _colliders.find(collider);
   if (ci != _colliders.end()) {
   if (ci != _colliders.end()) {
     // We already knew about this collider.
     // We already knew about this collider.
     if ((*ci).second != handler) {
     if ((*ci).second != handler) {
@@ -106,8 +106,8 @@ add_collider(CollisionNode *node, CollisionHandler *handler) {
 
 
   } else {
   } else {
     // We hadn't already known about this collider.
     // 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);
     Handlers::iterator hi = _handlers.find(handler);
     if (hi == _handlers.end()) {
     if (hi == _handlers.end()) {
@@ -122,7 +122,7 @@ add_collider(CollisionNode *node, CollisionHandler *handler) {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::remove_collider
 //     Function: CollisionTraverser::remove_collider
-//       Access: Public
+//       Access: Published
 //  Description: Removes the collider (and its associated handler)
 //  Description: Removes the collider (and its associated handler)
 //               from the set of CollisionNodes that will be tested
 //               from the set of CollisionNodes that will be tested
 //               each frame for collisions into other objects.
 //               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.
 //               false if it wasn't present to begin with.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool CollisionTraverser::
 bool CollisionTraverser::
-remove_collider(CollisionNode *node) {
+remove_collider(const NodePath &collider) {
   nassertr(_ordered_colliders.size() == _colliders.size(), false);
   nassertr(_ordered_colliders.size() == _colliders.size(), false);
 
 
-  Colliders::iterator ci = _colliders.find(node);
+  Colliders::iterator ci = _colliders.find(collider);
   if (ci == _colliders.end()) {
   if (ci == _colliders.end()) {
     // We didn't know about this node.
     // We didn't know about this node.
     return false;
     return false;
@@ -153,7 +153,7 @@ remove_collider(CollisionNode *node) {
   _colliders.erase(ci);
   _colliders.erase(ci);
 
 
   OrderedColliders::iterator oci =
   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);
   nassertr(oci != _ordered_colliders.end(), false);
   _ordered_colliders.erase(oci);
   _ordered_colliders.erase(oci);
 
 
@@ -163,20 +163,20 @@ remove_collider(CollisionNode *node) {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::has_collider
 //     Function: CollisionTraverser::has_collider
-//       Access: Public
+//       Access: Published
 //  Description: Returns true if the indicated node is current in the
 //  Description: Returns true if the indicated node is current in the
 //               set of nodes that will be tested each frame for
 //               set of nodes that will be tested each frame for
 //               collisions into other objects.
 //               collisions into other objects.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool CollisionTraverser::
 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());
   return (ci != _colliders.end());
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::get_num_colliders
 //     Function: CollisionTraverser::get_num_colliders
-//       Access: Public
+//       Access: Published
 //  Description: Returns the number of CollisionNodes that have been
 //  Description: Returns the number of CollisionNodes that have been
 //               added to the traverser via add_collider().
 //               added to the traverser via add_collider().
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -188,11 +188,11 @@ get_num_colliders() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::get_collider
 //     Function: CollisionTraverser::get_collider
-//       Access: Public
+//       Access: Published
 //  Description: Returns the nth CollisionNode that has been
 //  Description: Returns the nth CollisionNode that has been
 //               added to the traverser via add_collider().
 //               added to the traverser via add_collider().
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-CollisionNode *CollisionTraverser::
+NodePath CollisionTraverser::
 get_collider(int n) const {
 get_collider(int n) const {
   nassertr(_ordered_colliders.size() == _colliders.size(), NULL);
   nassertr(_ordered_colliders.size() == _colliders.size(), NULL);
   nassertr(n >= 0 && n < (int)_ordered_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
 //     Function: CollisionTraverser::get_handler
-//       Access: Public
+//       Access: Published
 //  Description: Returns the handler that is currently assigned to
 //  Description: Returns the handler that is currently assigned to
 //               serve the indicated collision node, or NULL if the
 //               serve the indicated collision node, or NULL if the
 //               node is not on the traverser's set of active nodes.
 //               node is not on the traverser's set of active nodes.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 CollisionHandler *CollisionTraverser::
 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()) {
   if (ci != _colliders.end()) {
     return (*ci).second;
     return (*ci).second;
   };
   };
@@ -217,7 +217,7 @@ get_handler(CollisionNode *node) const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::clear_colliders
 //     Function: CollisionTraverser::clear_colliders
-//       Access: Public
+//       Access: Published
 //  Description: Completely empties the set of collision nodes and
 //  Description: Completely empties the set of collision nodes and
 //               their associated handlers.
 //               their associated handlers.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -227,10 +227,31 @@ clear_colliders() {
   _ordered_colliders.clear();
   _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
 //     Function: CollisionTraverser::traverse
-//       Access: Public
+//       Access: Published
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CollisionTraverser::
 void CollisionTraverser::
@@ -272,7 +293,7 @@ traverse(const NodePath &root) {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::reset_prev_transform
 //     Function: CollisionTraverser::reset_prev_transform
-//       Access: Public
+//       Access: Published
 //  Description: Once the collision traversal has finished, resets all
 //  Description: Once the collision traversal has finished, resets all
 //               of the velocity deltas in the scene graph by setting
 //               of the velocity deltas in the scene graph by setting
 //               the "previous" transform to the current transform.
 //               the "previous" transform to the current transform.
@@ -287,7 +308,7 @@ reset_prev_transform(const NodePath &root) {
 #ifdef DO_COLLISION_RECORDING
 #ifdef DO_COLLISION_RECORDING
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::set_recorder
 //     Function: CollisionTraverser::set_recorder
-//       Access: Public
+//       Access: Published
 //  Description: Uses the indicated CollisionRecorder object to start
 //  Description: Uses the indicated CollisionRecorder object to start
 //               recording the intersection tests made by each
 //               recording the intersection tests made by each
 //               subsequent call to traverse() on this object.  A
 //               subsequent call to traverse() on this object.  A
@@ -333,7 +354,7 @@ set_recorder(CollisionRecorder *recorder) {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::output
 //     Function: CollisionTraverser::output
-//       Access: Public
+//       Access: Published
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CollisionTraverser::
 void CollisionTraverser::
@@ -344,7 +365,7 @@ output(ostream &out) const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::write
 //     Function: CollisionTraverser::write
-//       Access: Public
+//       Access: Published
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CollisionTraverser::
 void CollisionTraverser::
@@ -354,16 +375,19 @@ write(ostream &out, int indent_level) const {
     << " colliders and " << _handlers.size() << " handlers:\n";
     << " colliders and " << _handlers.size() << " handlers:\n";
   Colliders::const_iterator ci;
   Colliders::const_iterator ci;
   for (ci = _colliders.begin(); ci != _colliders.end(); ++ci) {
   for (ci = _colliders.begin(); ci != _colliders.end(); ++ci) {
-    CollisionNode *cnode = (*ci).first;
+    NodePath cnode_path = (*ci).first;
     CollisionHandler *handler = (*ci).second;
     CollisionHandler *handler = (*ci).second;
-    nassertv(cnode != (CollisionNode *)NULL);
     nassertv(handler != (CollisionHandler *)NULL);
     nassertv(handler != (CollisionHandler *)NULL);
 
 
     indent(out, indent_level + 2)
     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;
   int i = 0;
   while (i < (int)_ordered_colliders.size()) {
   while (i < (int)_ordered_colliders.size()) {
-    CollisionNode *cnode = _ordered_colliders[i];
-
-    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++;
+    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;
+      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();
     int num_colliders = level_state.get_num_colliders();
     for (int c = 0; c < num_colliders; c++) {
     for (int c = 0; c < num_colliders; c++) {
       if (level_state.has_collider(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() &
         if ((entry._from_node->get_from_collide_mask() &
              cnode->get_into_collide_mask()) != 0) {
              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 = 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) {
           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 {
           } else {
             entry._wrt_prev_space = entry._wrt_space;
             entry._wrt_prev_space = entry._wrt_space;
           }
           }
@@ -501,13 +507,13 @@ r_traverse(CollisionLevelState &level_state) {
     int num_colliders = level_state.get_num_colliders();
     int num_colliders = level_state.get_num_colliders();
     for (int c = 0; c < num_colliders; c++) {
     for (int c = 0; c < num_colliders; c++) {
       if (level_state.has_collider_with_geom(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 = 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, 
         compare_collider_to_geom_node(entry, 
                                       level_state.get_parent_bound(c),
                                       level_state.get_parent_bound(c),
@@ -708,7 +714,7 @@ remove_handler(CollisionTraverser::Handlers::iterator hi) {
   while (ci != _colliders.end()) {
   while (ci != _colliders.end()) {
     if ((*ci).second == handler) {
     if ((*ci).second == handler) {
       // This collider references this handler; remove it.
       // This collider references this handler; remove it.
-      PT(CollisionNode) node = (*ci).first;
+      NodePath node_path = (*ci).first;
 
 
       Colliders::iterator cnext = ci;
       Colliders::iterator cnext = ci;
       ++cnext;
       ++cnext;
@@ -717,7 +723,7 @@ remove_handler(CollisionTraverser::Handlers::iterator hi) {
 
 
       // Also remove it from the ordered list.
       // Also remove it from the ordered list.
       OrderedColliders::iterator oci =
       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);
       nassertr(oci != _ordered_colliders.end(), hi);
       _ordered_colliders.erase(oci);
       _ordered_colliders.erase(oci);
       
       

+ 12 - 7
panda/src/collide/collisionTraverser.h

@@ -56,14 +56,19 @@ PUBLISHED:
   INLINE void set_respect_prev_transform(bool flag);
   INLINE void set_respect_prev_transform(bool flag);
   INLINE bool get_respect_prev_transform() const;
   INLINE bool get_respect_prev_transform() const;
 
 
-  void add_collider(CollisionNode *node, CollisionHandler *handler);
-  bool remove_collider(CollisionNode *node);
-  bool has_collider(CollisionNode *node) 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;
   int get_num_colliders() const;
-  CollisionNode *get_collider(int n) const;
-  CollisionHandler *get_handler(CollisionNode *node) const;
+  NodePath get_collider(int n) const;
+  CollisionHandler *get_handler(const NodePath &collider) const;
   void clear_colliders();
   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);
+
   void traverse(const NodePath &root);
   void traverse(const NodePath &root);
   void reset_prev_transform(const NodePath &root);
   void reset_prev_transform(const NodePath &root);
 
 
@@ -103,9 +108,9 @@ private:
   PT(CollisionHandler) _default_handler;
   PT(CollisionHandler) _default_handler;
   TypeHandle _graph_type;
   TypeHandle _graph_type;
 
 
-  typedef pmap<PT(CollisionNode),  PT(CollisionHandler) > Colliders;
+  typedef pmap<NodePath,  PT(CollisionHandler) > Colliders;
   Colliders _colliders;
   Colliders _colliders;
-  typedef pvector<CollisionNode *> OrderedColliders;
+  typedef pvector<NodePath> OrderedColliders;
   OrderedColliders _ordered_colliders;
   OrderedColliders _ordered_colliders;
 
 
   typedef pmap<PT(CollisionHandler), int> Handlers;
   typedef pmap<PT(CollisionHandler), int> Handlers;