소스 검색

Merge pull request #1166 from Azaezel/physnotes

Physics Review Results
Brian Roberts 1 년 전
부모
커밋
d8102a9591
5개의 변경된 파일42개의 추가작업 그리고 70개의 파일을 삭제
  1. 1 1
      Engine/source/T3D/rigid.cpp
  2. 37 64
      Engine/source/T3D/rigidShape.cpp
  3. 1 2
      Engine/source/T3D/rigidShape.h
  4. 1 1
      Engine/source/T3D/shapeBase.h
  5. 2 2
      Engine/source/T3D/vehicles/vehicle.cpp

+ 1 - 1
Engine/source/T3D/rigid.cpp

@@ -156,7 +156,7 @@ bool Rigid::resolveCollision(const Point3F& p, const Point3F &normal, Rigid* rig
       return false;
       return false;
 
 
    // Compute impulse
    // Compute impulse
-   F32 d, n = -nv * (2.0f + restitution * rigid->restitution);
+   F32 d, n = -nv * (1.0+(restitution + rigid->restitution)*0.5);
    Point3F a1,b1,c1;
    Point3F a1,b1,c1;
    mCross(r1,normal,&a1);
    mCross(r1,normal,&a1);
    invWorldInertia.mulV(a1,&b1);
    invWorldInertia.mulV(a1,&b1);

+ 37 - 64
Engine/source/T3D/rigidShape.cpp

@@ -900,9 +900,11 @@ bool RigidShape::onNewDataBlock(GameBaseData* dptr, bool reload)
    mRigid.restitution = mDataBlock->body.restitution;
    mRigid.restitution = mDataBlock->body.restitution;
    mRigid.setCenterOfMass(mDataBlock->massCenter);
    mRigid.setCenterOfMass(mDataBlock->massCenter);
 
 
-   // Ignores massBox, just set sphere for now. Derived objects
-   // can set what they want.
-   mRigid.setObjectInertia();
+   // Set inertial tensor, default for the RigidShape is sphere
+   if (mDataBlock->massBox.x > 0 && mDataBlock->massBox.y > 0 && mDataBlock->massBox.z > 0)
+      mRigid.setObjectInertia(mDataBlock->massBox);
+   else
+      mRigid.setObjectInertia(mObjBox.maxExtents - mObjBox.minExtents);
 
 
    scriptOnNewDataBlock();
    scriptOnNewDataBlock();
 
 
@@ -1115,9 +1117,9 @@ void RigidShape::updatePos(F32 dt)
       if (mCollisionList.getCount())
       if (mCollisionList.getCount())
       {
       {
          F32 k = mRigid.getKineticEnergy();
          F32 k = mRigid.getKineticEnergy();
-         F32 G = mNetGravity * dt;
+         F32 G = mNetGravity;
          F32 Kg = 0.5 * mRigid.mass * G * G;
          F32 Kg = 0.5 * mRigid.mass * G * G;
-         if (k < sRestTol * Kg && ++restCount > sRestCount)
+         if (k < sRestTol * Kg* dt && ++restCount > sRestCount)
             mRigid.setAtRest();
             mRigid.setAtRest();
       }
       }
       else
       else
@@ -1205,8 +1207,12 @@ void RigidShape::updatePos(F32 dt)
 
 
 void RigidShape::updateForces(F32 dt)
 void RigidShape::updateForces(F32 dt)
 {
 {
-   if (mDisableMove) return;
-
+   if (mDisableMove)
+   {
+      mRigid.linVelocity = Point3F::Zero;
+      mRigid.angMomentum = Point3F::Zero;
+      return;
+   }
    Point3F torque(0, 0, 0);
    Point3F torque(0, 0, 0);
    Point3F force(0, 0, mRigid.mass * mNetGravity);
    Point3F force(0, 0, mRigid.mass * mNetGravity);
 
 
@@ -1222,10 +1228,6 @@ void RigidShape::updateForces(F32 dt)
 
 
    mRigid.force  = force;
    mRigid.force  = force;
    mRigid.torque = torque;
    mRigid.torque = torque;
-
-   // If we're still atRest, make sure we're not accumulating anything
-   if ((force.lenSquared() < mDataBlock->contactTol)&& (force.lenSquared() < mDataBlock->contactTol))
-      mRigid.setAtRest();
 }
 }
 
 
 
 
@@ -1260,8 +1262,7 @@ bool RigidShape::updateCollision(F32 dt)
    }
    }
 
 
    // Resolve collisions
    // Resolve collisions
-   bool collided = resolveCollision(mRigid,mCollisionList);
-   resolveContacts(mRigid,mCollisionList,dt);
+   bool collided = resolveCollision(mRigid,mCollisionList, dt);
    return collided;
    return collided;
 }
 }
 
 
@@ -1271,7 +1272,7 @@ bool RigidShape::updateCollision(F32 dt)
 Handle collision impacts, as opposed to contacts. Impulses are calculated based
 Handle collision impacts, as opposed to contacts. Impulses are calculated based
 on standard collision resolution formulas.
 on standard collision resolution formulas.
 */
 */
-bool RigidShape::resolveCollision(Rigid&  ns,CollisionList& cList)
+bool RigidShape::resolveCollision(Rigid&  ns,CollisionList& cList, F32 dt)
 {
 {
    PROFILE_SCOPE(RigidShape_resolveCollision);
    PROFILE_SCOPE(RigidShape_resolveCollision);
    // Apply impulses to resolve collision
    // Apply impulses to resolve collision
@@ -1279,6 +1280,11 @@ bool RigidShape::resolveCollision(Rigid&  ns,CollisionList& cList)
    for (S32 i = 0; i < cList.getCount(); i++)
    for (S32 i = 0; i < cList.getCount(); i++)
    {
    {
       Collision& c = cList[i];
       Collision& c = cList[i];
+      if (c.object == this)
+      {
+         //Con::printf("IMPOSSIBLE!!!!--------------------------------> Self-collision event?");
+         continue;
+      }
       if (c.distance < mDataBlock->collisionTol)
       if (c.distance < mDataBlock->collisionTol)
       {
       {
          // Velocity into surface
          // Velocity into surface
@@ -1288,9 +1294,7 @@ bool RigidShape::resolveCollision(Rigid&  ns,CollisionList& cList)
          F32 vn = mDot(v, c.normal);
          F32 vn = mDot(v, c.normal);
 
 
          // Only interested in velocities greater than sContactTol,
          // Only interested in velocities greater than sContactTol,
-         // velocities less than that will be dealt with as contacts
-         // "constraints".
-         if (vn < -mDataBlock->contactTol)
+         if (mFabs(vn) > mDataBlock->contactTol)
          {
          {
 
 
             // Apply impulses to the rigid body to keep it from
             // Apply impulses to the rigid body to keep it from
@@ -1313,45 +1317,15 @@ bool RigidShape::resolveCollision(Rigid&  ns,CollisionList& cList)
                queueCollision(col, v - col->getVelocity());
                queueCollision(col, v - col->getVelocity());
             }
             }
          }
          }
-      }
-   }
-
-   return collided;
-}
-
-//----------------------------------------------------------------------------
-/** Resolve contact forces
-Resolve contact forces using the "penalty" method. Forces are generated based
-on the depth of penetration and the moment of inertia at the point of contact.
-*/
-bool RigidShape::resolveContacts(Rigid& ns,CollisionList& cList,F32 dt)
-{
-   PROFILE_SCOPE(RigidShape_resolveContacts);
-   // Use spring forces to manage contact constraints.
-   bool collided = false;
-   Point3F t,p(0,0,0),l(0,0,0);
-   for (S32 i = 0; i < cList.getCount(); i++) 
-   {
-      const Collision& c = cList[i];
-      if (c.distance < mDataBlock->collisionTol) 
-      {
-
-         // Velocity into the surface
-         Point3F v,r;
-         ns.getOriginVector(c.point,&r);
-         ns.getVelocity(r,&v);
-         F32 vn = mDot(v,c.normal);
-
-         // Only interested in velocities less than mDataBlock->contactTol,
-         // velocities greater than that are dealt with as collisions.
-         if (mFabs(vn) < mDataBlock->contactTol) 
+         // velocities less than that will be dealt with as contacts
+         // "constraints".
+         else
          {
          {
-            collided = true;
-
+            Point3F t;
             // Penetration force. This is actually a spring which
             // Penetration force. This is actually a spring which
             // will seperate the body from the collision surface.
             // will seperate the body from the collision surface.
-            F32 zi = 2 * mFabs(mRigid.getZeroImpulse(r,c.normal));
-            F32 s = (mDataBlock->collisionTol - c.distance) * zi - ((vn / mDataBlock->contactTol) * zi);
+            F32 zi = 2 * mFabs(mRigid.getZeroImpulse(r, c.normal) / dt);
+            F32 s = mMax((mDataBlock->collisionTol - c.distance) * zi - ((vn / 2.0) * zi),0.0f);
             Point3F f = c.normal * s;
             Point3F f = c.normal * s;
 
 
             // Friction impulse, calculated as a function of the
             // Friction impulse, calculated as a function of the
@@ -1359,10 +1333,10 @@ bool RigidShape::resolveContacts(Rigid& ns,CollisionList& cList,F32 dt)
             // perpendicular to the normal.
             // perpendicular to the normal.
             Point3F uv = v - (c.normal * vn);
             Point3F uv = v - (c.normal * vn);
             F32 ul = uv.len();
             F32 ul = uv.len();
-            if (s > 0 && ul) 
+            if (s > 0 && ul)
             {
             {
                uv /= -ul;
                uv /= -ul;
-               F32 u = ul * ns.getZeroImpulse(r,uv);
+               F32 u = ul * ns.getZeroImpulse(r, uv) / dt;
                s *= mRigid.friction;
                s *= mRigid.friction;
                if (u > s)
                if (u > s)
                   u = s;
                   u = s;
@@ -1370,20 +1344,17 @@ bool RigidShape::resolveContacts(Rigid& ns,CollisionList& cList,F32 dt)
             }
             }
 
 
             // Accumulate forces
             // Accumulate forces
-            p += f;
-            mCross(r,f,&t);
-            l += t;
+            mCross(r, f, &t);
+            ns.linMomentum += f * dt;
+            ns.angMomentum += t * dt;
+            ns.updateVelocity();
          }
          }
       }
       }
    }
    }
 
 
-   // Contact constraint forces act over time...
-   ns.linMomentum += p * dt;
-   ns.angMomentum += l * dt;
-   ns.updateVelocity();
-   return true;
-}
 
 
+   return collided;
+}
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 
 
@@ -1693,6 +1664,8 @@ void RigidShape::initPersistFields()
    docsURL;
    docsURL;
    addField("disableMove", TypeBool, Offset(mDisableMove, RigidShape),
    addField("disableMove", TypeBool, Offset(mDisableMove, RigidShape),
       "When this flag is set, the vehicle will ignore throttle changes.");
       "When this flag is set, the vehicle will ignore throttle changes.");
+   addField("isAtRest", TypeBool, Offset(mRigid.atRest, RigidShape),
+      "Debug read of the rest state. do not set");   
    Parent::initPersistFields();
    Parent::initPersistFields();
 }
 }
 
 

+ 1 - 2
Engine/source/T3D/rigidShape.h

@@ -216,8 +216,7 @@ class RigidShape: public ShapeBase
    bool onNewDataBlock( GameBaseData *dptr, bool reload );
    bool onNewDataBlock( GameBaseData *dptr, bool reload );
    void updatePos(F32 dt);
    void updatePos(F32 dt);
    bool updateCollision(F32 dt);
    bool updateCollision(F32 dt);
-   bool resolveCollision(Rigid& ns,CollisionList& cList);
-   bool resolveContacts(Rigid& ns,CollisionList& cList,F32 dt);
+   bool resolveCollision(Rigid& ns,CollisionList& cList, F32 dt);
    bool resolveDisplacement(Rigid& ns,CollisionState *state,F32 dt);
    bool resolveDisplacement(Rigid& ns,CollisionState *state,F32 dt);
    void checkTriggers();
    void checkTriggers();
    static void findCallback(SceneObject* obj,void * key);
    static void findCallback(SceneObject* obj,void * key);

+ 1 - 1
Engine/source/T3D/shapeBase.h

@@ -91,7 +91,7 @@ class SFXProfile;
 
 
 typedef void* Light;
 typedef void* Light;
 
 
-const F32 gGravity = -20;
+const F32 gGravity = -9.8f;
 
 
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
 
 

+ 2 - 2
Engine/source/T3D/vehicles/vehicle.cpp

@@ -807,9 +807,9 @@ void Vehicle::updatePos(F32 dt)
       if (mCollisionList.getCount()) 
       if (mCollisionList.getCount()) 
       {
       {
          F32 k = mRigid.getKineticEnergy();
          F32 k = mRigid.getKineticEnergy();
-         F32 G = mNetGravity * dt;
+         F32 G = mNetGravity;
          F32 Kg = 0.5 * mRigid.mass * G * G;
          F32 Kg = 0.5 * mRigid.mass * G * G;
-         if (k < sRestTol * Kg && ++restCount > sRestCount)
+         if (k < sRestTol * Kg * dt && ++restCount > sRestCount)
             mRigid.setAtRest();
             mRigid.setAtRest();
       }
       }
       else
       else