Преглед на файлове

changed force coordinate frame

Dave Schuyler преди 22 години
родител
ревизия
e88c6726d7
променени са 1 файла, в които са добавени 41 реда и са изтрити 18 реда
  1. 41 18
      panda/src/physics/physicsCollisionHandler.cxx

+ 41 - 18
panda/src/physics/physicsCollisionHandler.cxx

@@ -59,37 +59,60 @@ apply_linear_force(ColliderDef &def, const LVector3f &force) {
     return;
     return;
   }
   }
   ActorNode *actor=DCAST(ActorNode, def._node);
   ActorNode *actor=DCAST(ActorNode, def._node);
-  float friction=0.9f;
   LVector3f vel=actor->get_physics_object()->get_velocity();
   LVector3f vel=actor->get_physics_object()->get_velocity();
   physics_debug("apply_linear_force() {");
   physics_debug("apply_linear_force() {");
   physics_debug("  vel "<<vel<<" len "<<vel.length());
   physics_debug("  vel "<<vel<<" len "<<vel.length());
   physics_debug("  force "<<force<<" len "<<force.length());
   physics_debug("  force "<<force<<" len "<<force.length());
   LVector3f old_vel=vel;
   LVector3f old_vel=vel;
-  LVector3f adjustment=force;
+  // Copy the force vector while translating it 
+  // into the physics object coordinate system:
+  LVector3f adjustment=force*actor->get_physics_object()->get_lcs();
+  physics_debug("  adjustment set "<<adjustment<<" len "<<adjustment.length());
   adjustment.normalize();
   adjustment.normalize();
-  adjustment*=adjustment.dot(vel);
-  physics_debug("  adjustment "<<adjustment<<" len "<<adjustment.length());
-  float angle=adjustment.dot(vel);
-  vel-=adjustment;
-  physics_debug("  vel "<<vel<<" len "<<vel.length());
-  physics_debug("  angle "<<angle);
-  if (angle<=0.0f) {
-    // ...avoid amplifying the velocity by checking to see
-    // that the adjustment and the velocity are more than 
-    // right-angles (i.e. obtuse angle).
-    float almostStationary=0.1f;
-    if (vel.length()>almostStationary) {
-      physics_debug("  vel > almostStationary");
-      friction*=0.01f;
+  physics_debug("  adjustment nrm "<<adjustment<<" len "<<adjustment.length());
+  float adjustmentLength=-(adjustment.dot(vel));
+  physics_debug("  adjustmentLength "<<adjustmentLength);
+  // Are we in contact with something:
+  if (adjustmentLength>0.0f) {
+    physics_debug("  positive contact");
+    adjustment*=adjustmentLength;
+    physics_debug("  adjustment mul "<<adjustment<<" len "<<adjustment.length());
+    // This adjustment to our velocity will not reflect us off the surface,
+    // but will deflect us parallel (or tangent) to the surface:
+    vel+=adjustment;
+    physics_debug("  vel "<<vel<<" len "<<vel.length());
+    physics_debug("  angle "<<adjustmentLength);
+    const float almostStationary=0.1f;
+    float friction=0.9f;
+    // This velocity is not very accurate, but it's better than using 
+    // the pre-collision-tested velocity for now.  This may need to be 
+    // better:
+    LVector3f implicitVel=actor->get_physics_object()->get_implicit_velocity();
+    physics_debug("  implicitVel "<<implicitVel<<" len "<<implicitVel.length());
+    // Determine the friction:
+    if (implicitVel.length()<almostStationary) {
+      physics_debug("  static friction");
+      friction=0.9f;
+    } else {
+      physics_debug("  dynamic friction");
+      friction=0.1f;
     }
     }
-    //vel*=1.0f-friction;
+    // Apply the friction:
+    vel*=1.0f-friction;
+  } else if (adjustmentLength==0.0f) {
+    physics_debug("  brushing contact");
+  } else {
+    physics_debug("  negative contact");
   }
   }
 
 
   #ifndef NDEBUG //[
   #ifndef NDEBUG //[
   if (vel.length() > old_vel.length()) {
   if (vel.length() > old_vel.length()) {
+    // This is a check to avoid adding engergy:
     physics_debug("  vel.length() > old_vel.length()  "<<vel.length()<<" > "<<old_vel.length());
     physics_debug("  vel.length() > old_vel.length()  "<<vel.length()<<" > "<<old_vel.length());
   }
   }
   if (vel.length() > 10.0f) {
   if (vel.length() > 10.0f) {
+    // This is a check to see if the velocity is higher than I expect it
+    // to go.  The check value is arbitrary.
     physics_debug("  vel.length() > 10.0f  "<<vel.length());
     physics_debug("  vel.length() > 10.0f  "<<vel.length());
   }
   }
   #endif //]
   #endif //]
@@ -97,6 +120,6 @@ apply_linear_force(ColliderDef &def, const LVector3f &force) {
   physics_debug("  force "<<force<<" len "<<force.length());
   physics_debug("  force "<<force<<" len "<<force.length());
   physics_debug("  vel "<<vel<<" len "<<vel.length());
   physics_debug("  vel "<<vel<<" len "<<vel.length());
   physics_debug("}");
   physics_debug("}");
-  actor->set_contact_vector(force);
+  actor->set_contact_vector(adjustment);
   actor->get_physics_object()->set_velocity(vel);
   actor->get_physics_object()->set_velocity(vel);
 }
 }