瀏覽代碼

fix turning error in collision pos delta

David Rose 22 年之前
父節點
當前提交
41d7c6d6dd

+ 30 - 39
panda/src/collide/collisionEntry.I

@@ -29,6 +29,7 @@ CollisionEntry() {
   _into_space = TransformState::make_identity();
   _wrt_space = TransformState::make_identity();
   _inv_wrt_space = TransformState::make_identity();
+  _wrt_prev_space = TransformState::make_identity();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -143,7 +144,8 @@ get_into_space() const {
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionEntry::get_wrt_space
 //       Access: Published
-//  Description:
+//  Description: Returns the relative transform of the from node as
+//               seen from the into node.
 ////////////////////////////////////////////////////////////////////
 INLINE const TransformState *CollisionEntry::
 get_wrt_space() const {
@@ -153,13 +155,27 @@ get_wrt_space() const {
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionEntry::get_inv_wrt_space
 //       Access: Published
-//  Description:
+//  Description: Returns the relative transform of the into node as
+//               seen from the from node.
 ////////////////////////////////////////////////////////////////////
 INLINE const TransformState *CollisionEntry::
 get_inv_wrt_space() const {
   return _inv_wrt_space;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionEntry::get_wrt_prev_space
+//       Access: Published
+//  Description: Returns the relative transform of the from node as
+//               seen from the into node, as of the previous frame
+//               (according to set_prev_transform(), set_fluid_pos(),
+//               etc.)
+////////////////////////////////////////////////////////////////////
+INLINE const TransformState *CollisionEntry::
+get_wrt_prev_space() const {
+  return _wrt_prev_space;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionEntry::get_from_mat
 //       Access: Published
@@ -188,7 +204,8 @@ get_into_mat() const {
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionEntry::get_wrt_mat
 //       Access: Published
-//  Description:
+//  Description: Returns the relative transform of the from node as
+//               seen from the into node.
 ////////////////////////////////////////////////////////////////////
 INLINE const LMatrix4f &CollisionEntry::
 get_wrt_mat() const {
@@ -198,7 +215,8 @@ get_wrt_mat() const {
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionEntry::get_inv_wrt_mat
 //       Access: Published
-//  Description:
+//  Description: Returns the relative transform of the into node as
+//               seen from the from node.
 ////////////////////////////////////////////////////////////////////
 INLINE const LMatrix4f &CollisionEntry::
 get_inv_wrt_mat() const {
@@ -206,43 +224,16 @@ get_inv_wrt_mat() const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: CollisionEntry::set_from_pos_delta
+//     Function: CollisionEntry::get_wrt_prev_mat
 //       Access: Published
-//  Description: Indicates the pos_delta associated with the "from"
-//               object, in the object's coordinate space.
+//  Description: Returns the relative transform of the from node as
+//               seen from the into node, as of the previous frame
+//               (according to set_prev_transform(), set_fluid_pos(),
+//               etc.)
 ////////////////////////////////////////////////////////////////////
-INLINE void CollisionEntry::
-set_from_pos_delta(const LVector3f &vel) {
-  _from_pos_delta = vel;
-  _flags |= F_has_from_pos_delta;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: CollisionEntry::has_from_pos_delta
-//       Access: Published
-//  Description: Returns true if the objects appeared to be moving
-//               relative to each other, false otherwise.
-////////////////////////////////////////////////////////////////////
-INLINE bool CollisionEntry::
-has_from_pos_delta() const {
-  return (_flags & F_has_from_pos_delta) != 0;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: CollisionEntry::get_from_pos_delta
-//       Access: Published
-//  Description: Returns the position delta between the two objects,
-//               in the coordinate space of the "from" object.  This
-//               is the delta between their relative position in the
-//               previous frame and their relative position this
-//               frame.
-////////////////////////////////////////////////////////////////////
-INLINE const LVector3f &CollisionEntry::
-get_from_pos_delta() const {
-  if (!has_from_pos_delta()) {
-    return LVector3f::zero();
-  }
-  return _from_pos_delta;
+INLINE const LMatrix4f &CollisionEntry::
+get_wrt_prev_mat() const {
+  return _wrt_prev_space->get_mat();
 }
 
 ////////////////////////////////////////////////////////////////////

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

@@ -36,8 +36,8 @@ CollisionEntry(const CollisionEntry &copy) :
   _into_space(copy._into_space),
   _wrt_space(copy._wrt_space),
   _inv_wrt_space(copy._inv_wrt_space),
+  _wrt_prev_space(copy._wrt_prev_space),
   _flags(copy._flags),
-  _from_pos_delta(copy._from_pos_delta),
   _into_intersection_point(copy._into_intersection_point),
   _into_surface_normal(copy._into_surface_normal),
   _into_depth(copy._into_depth)
@@ -60,8 +60,8 @@ operator = (const CollisionEntry &copy) {
   _into_space = copy._into_space;
   _wrt_space = copy._wrt_space;
   _inv_wrt_space = copy._inv_wrt_space;
+  _wrt_prev_space = copy._wrt_prev_space;
   _flags = copy._flags;
-  _from_pos_delta = copy._from_pos_delta;
   _into_intersection_point = copy._into_intersection_point;
   _into_surface_normal = copy._into_surface_normal;
   _into_depth = copy._into_depth;

+ 3 - 6
panda/src/collide/collisionEntry.h

@@ -65,15 +65,13 @@ PUBLISHED:
   INLINE const TransformState *get_into_space() const;
   INLINE const TransformState *get_wrt_space() const;
   INLINE const TransformState *get_inv_wrt_space() const;
+  INLINE const TransformState *get_wrt_prev_space() const;
 
   INLINE const LMatrix4f &get_from_mat() const;
   INLINE const LMatrix4f &get_into_mat() const;
   INLINE const LMatrix4f &get_wrt_mat() const;
   INLINE const LMatrix4f &get_inv_wrt_mat() const;
-
-  INLINE void set_from_pos_delta(const LVector3f &vel);
-  INLINE bool has_from_pos_delta() const;
-  INLINE const LVector3f &get_from_pos_delta() const;
+  INLINE const LMatrix4f &get_wrt_prev_mat() const;
 
   INLINE void set_into_intersection_point(const LPoint3f &point);
   INLINE bool has_into_intersection_point() const;
@@ -113,6 +111,7 @@ private:
   CPT(TransformState) _into_space;
   CPT(TransformState) _wrt_space;
   CPT(TransformState) _inv_wrt_space;
+  CPT(TransformState) _wrt_prev_space;
 
   enum Flags {
     F_has_into_intersection_point = 0x0001,
@@ -120,12 +119,10 @@ private:
     F_has_from_surface_normal     = 0x0004,
     F_has_into_depth              = 0x0008,
     F_has_from_depth              = 0x0010,
-    F_has_from_pos_delta          = 0x0020,
   };
 
   int _flags;
 
-  LVector3f _from_pos_delta;
   LPoint3f _into_intersection_point;
   LVector3f _into_surface_normal;
   LVector3f _from_surface_normal;

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

@@ -277,13 +277,14 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
   LPoint3f from_center = orig_center;
   bool moved_from_center = false;
 
-  if (entry.has_from_pos_delta()) {
-    // If we have a pos_delta indication, we use that to determine some
-    // more properties of the collision.
+  if (entry.get_wrt_prev_space() != entry.get_wrt_space()) {
+    // If we have a delta between the previous position and the
+    // current position, we use that to determine some more properties
+    // of the collision.
     LPoint3f b = from_center;
-    LPoint3f a = (sphere->get_center() - entry.get_from_pos_delta()) * entry.get_wrt_mat();
-
+    LPoint3f a = sphere->get_center() * entry.get_wrt_prev_mat();
     LVector3f delta = b - a;
+
     // First, there is no collision if the "from" object is moving in
     // the same direction as the plane's normal.
     float dot = delta.dot(get_normal());

+ 4 - 13
panda/src/collide/collisionTraverser.cxx

@@ -462,20 +462,11 @@ r_traverse(CollisionLevelState &level_state) {
           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);
-            CPT(TransformState) inv_wrt_prev_space = from_prev_space->invert_compose(entry._into_node_path.get_net_prev_transform());
-            
-            LVector3f into_delta = entry._inv_wrt_space->get_pos() - inv_wrt_prev_space->get_pos();
-            LVector3f delta = from_delta - into_delta;
-            if (delta != LVector3f::zero()) {
-              /*
-                if (entry._from_node->get_name() == "cSphereNode" && entry._into_node->get_name() == "MickeyBlatherSphere") {
-                cerr << "from_delta = " << from_delta << " into_delta = "
-                << into_delta << " delta = " << delta << "\n";
-                }
-              */
-              entry.set_from_pos_delta(delta);
-            }
+            entry._wrt_prev_space = into_prev_space->invert_compose(from_prev_space);
+          } else {
+            entry._wrt_prev_space = entry._wrt_space;
           }
 
           compare_collider_to_node(entry, 

+ 4 - 2
panda/src/collide/collisionTube.cxx

@@ -133,8 +133,10 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
   LPoint3f from_a = sphere->get_center() * entry.get_wrt_mat();
   LPoint3f from_b = from_a;
 
-  if (entry.has_from_pos_delta()) {
-    from_a = (sphere->get_center() - entry.get_from_pos_delta()) * entry.get_wrt_mat();
+  if (entry.get_wrt_prev_space() != entry.get_wrt_space()) {
+    // If the sphere is moving relative to the tube, it becomes a tube
+    // itself.
+    from_a = sphere->get_center() * entry.get_wrt_prev_mat();
   }
 
   LVector3f from_direction = from_b - from_a;