Просмотр исходного кода

Merge pull request #422 from kwhatmough/next

Adds strut compression with filtering now fixed.
Sean Paul Taylor 13 лет назад
Родитель
Сommit
02a4999e0b

+ 2 - 1
gameplay/src/PhysicsVehicle.cpp

@@ -204,7 +204,7 @@ float PhysicsVehicle::getSpeedKph() const
     return _vehicle->getCurrentSpeedKmHour();
 }
 
-void PhysicsVehicle::update(float steering, float braking, float driving)
+void PhysicsVehicle::update(float elapsedTime, float steering, float braking, float driving)
 {
     PhysicsVehicleWheel* wheel;
     for (int i = 0; i < _vehicle->getNumWheels(); i++)
@@ -221,6 +221,7 @@ void PhysicsVehicle::update(float steering, float braking, float driving)
             _vehicle->setBrake(braking * _brakingForce, i);
         }
 
+        wheel->update(elapsedTime);
         wheel->transform(wheel->getNode());
     }
 }

+ 2 - 1
gameplay/src/PhysicsVehicle.h

@@ -84,11 +84,12 @@ public:
      * Updates the vehicle state using the specified normalized command
      * inputs, and updates the transform on the visual node for each wheel.
      *
+     * @param elapsedTime The elapsed game time.
      * @param steering steering command (-1 to 1).
      * @param braking braking command (0 to 1).
      * @param driving net drivetrain command (0 to 1).
      */
-    void update(float steering, float braking, float driving);
+    void update(float elapsedTime, float steering, float braking, float driving);
 
     /**
      * Gets steering gain at full deflection.

+ 28 - 3
gameplay/src/PhysicsVehicleWheel.cpp

@@ -182,16 +182,41 @@ void PhysicsVehicleWheel::transform(Node* node) const
 {
     GP_ASSERT(_host);
     GP_ASSERT(_host->_vehicle);
+    GP_ASSERT(_host->_node);
+
+    const btTransform& trans = _host->_vehicle->getWheelInfo(_indexInHost).m_worldTransform;
+    const btVector3& pos = trans.getOrigin();
+    node->setRotation(_orientation);
+
+    // Use only the component parallel to the defined strut line
+    Vector3 strutLine;
+    getWheelDirection(&strutLine);
+    Vector3 wheelPos = _initialOffset;
+    _host->_node->getMatrix().transformPoint(&wheelPos);
+    node->setTranslation(wheelPos + strutLine*(strutLine.dot(_positionDelta) / strutLine.lengthSquared()));
+}
+
+void PhysicsVehicleWheel::update(float elapsedTime)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+    GP_ASSERT(_host->_node);
 
     const btTransform& trans = _host->_vehicle->getWheelInfo(_indexInHost).m_worldTransform;
     const btQuaternion& rot = trans.getRotation();
     const btVector3& pos = trans.getOrigin();
-    node->setRotation(rot.x(), rot.y(), rot.z(), rot.w());
+    _orientation.set(rot.x(), rot.y(), rot.z(), rot.w());
 
-    // Ignore X and Z translation for wheel
+    Vector3 commandedPosition(pos.x(), pos.y(), pos.z());
     Vector3 wheelPos = _initialOffset;
     _host->_node->getMatrix().transformPoint(&wheelPos);
-    node->setTranslation(wheelPos.x, wheelPos.y, wheelPos.z);
+
+    // Filter out noise from Bullet
+    float dt = elapsedTime / 1000.0f;
+    Vector3 delta = commandedPosition - wheelPos - _positionDelta;
+    float threshold = getStrutRestLength() * 2.0f;
+    float tau = (delta.lengthSquared() > threshold*threshold) ? 0 : 0.06f;
+    _positionDelta += (commandedPosition - wheelPos - _positionDelta) * (dt / (dt + tau));
 }
 
 bool PhysicsVehicleWheel::isFront() const

+ 9 - 0
gameplay/src/PhysicsVehicleWheel.h

@@ -326,10 +326,19 @@ private:
      */
     void addToVehicle(btRaycastVehicle* vehicle);
 
+    /**
+     * Update state of this wheel, per frame.
+     *
+     * @param elapsedTime The elapsed game time.
+     */
+    void update(float elapsedTime);
+
     PhysicsRigidBody* _rigidBody;
     PhysicsVehicle* _host;
     unsigned int _indexInHost;
     Vector3 _initialOffset;
+    Vector3 _positionDelta;
+    Quaternion _orientation;
 };
 
 }

+ 8 - 4
gameplay/src/lua/lua_PhysicsVehicle.cpp

@@ -1031,12 +1031,13 @@ int lua_PhysicsVehicle_update(lua_State* state)
     // Attempt to match the parameters to a valid binding.
     switch (paramCount)
     {
-        case 4:
+        case 5:
         {
             if ((lua_type(state, 1) == LUA_TUSERDATA) &&
                 lua_type(state, 2) == LUA_TNUMBER &&
                 lua_type(state, 3) == LUA_TNUMBER &&
-                lua_type(state, 4) == LUA_TNUMBER)
+                lua_type(state, 4) == LUA_TNUMBER &&
+                lua_type(state, 5) == LUA_TNUMBER)
             {
                 // Get parameter 1 off the stack.
                 float param1 = (float)luaL_checknumber(state, 2);
@@ -1047,8 +1048,11 @@ int lua_PhysicsVehicle_update(lua_State* state)
                 // Get parameter 3 off the stack.
                 float param3 = (float)luaL_checknumber(state, 4);
 
+                // Get parameter 4 off the stack.
+                float param4 = (float)luaL_checknumber(state, 5);
+
                 PhysicsVehicle* instance = getInstance(state);
-                instance->update(param1, param2, param3);
+                instance->update(param1, param2, param3, param4);
                 
                 return 0;
             }
@@ -1061,7 +1065,7 @@ int lua_PhysicsVehicle_update(lua_State* state)
         }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 4).");
+            lua_pushstring(state, "Invalid number of parameters (expected 5).");
             lua_error(state);
             break;
         }