Browse Source

Bugfix: Wheel contact point did not return deepest point in certain cases

When the suspension was fully up, the VehicleCollisionTesterCastSphere and VehicleCollisionTesterCastCylinder could possibly not reduce the deepest contact point
Jorrit Rouwe 2 years ago
parent
commit
53122918ce
1 changed files with 14 additions and 8 deletions
  1. 14 8
      Jolt/Physics/Vehicle/VehicleCollisionTester.cpp

+ 14 - 8
Jolt/Physics/Vehicle/VehicleCollisionTester.cpp

@@ -138,8 +138,9 @@ bool VehicleCollisionTesterCastSphere::Collide(PhysicsSystem &inPhysicsSystem, c
 
 		virtual void		AddHit(const ShapeCastResult &inResult) override
 		{
-			// Test if this collision is closer than the previous one
-			if (inResult.mFraction < GetEarlyOutFraction())
+			// Test if this collision is closer/deeper than the previous one
+			float early_out = inResult.GetEarlyOutFraction();
+			if (early_out < GetEarlyOutFraction())
 			{
 				// Lock the body
 				BodyLockRead lock(mPhysicsSystem.GetBodyLockInterfaceNoLock(), inResult.mBodyID2);
@@ -154,13 +155,14 @@ bool VehicleCollisionTesterCastSphere::Collide(PhysicsSystem &inPhysicsSystem, c
 				if (normal.Dot(mUpDirection) > mCosMaxSlopeAngle)
 				{
 					// Update early out fraction to this hit
-					UpdateEarlyOutFraction(inResult.mFraction);
+					UpdateEarlyOutFraction(early_out);
 
 					// Get the contact properties
 					mBody = body;
 					mSubShapeID2 = inResult.mSubShapeID2;
 					mContactPosition = mShapeCast.mCenterOfMassStart.GetTranslation() + inResult.mContactPointOn2;
 					mContactNormal = normal;
+					mFraction = inResult.mFraction;
 				}
 			}
 		}
@@ -176,6 +178,7 @@ bool VehicleCollisionTesterCastSphere::Collide(PhysicsSystem &inPhysicsSystem, c
 		SubShapeID			mSubShapeID2;
 		RVec3				mContactPosition;
 		Vec3				mContactNormal;
+		float				mFraction;
 	};
 
 	MyCollector collector(inPhysicsSystem, shape_cast, mUp, mCosMaxSlopeAngle);
@@ -187,7 +190,7 @@ bool VehicleCollisionTesterCastSphere::Collide(PhysicsSystem &inPhysicsSystem, c
 	outSubShapeID = collector.mSubShapeID2;
 	outContactPosition = collector.mContactPosition;
 	outContactNormal = collector.mContactNormal;
-	outSuspensionLength = max(0.0f, shape_cast_length * collector.GetEarlyOutFraction() + mRadius - wheel_radius);
+	outSuspensionLength = max(0.0f, shape_cast_length * collector.mFraction + mRadius - wheel_radius);
 
 	return true;
 }
@@ -232,8 +235,9 @@ bool VehicleCollisionTesterCastCylinder::Collide(PhysicsSystem &inPhysicsSystem,
 
 		virtual void		AddHit(const ShapeCastResult &inResult) override
 		{
-			// Test if this collision is closer than the previous one
-			if (inResult.mFraction < GetEarlyOutFraction())
+			// Test if this collision is closer/deeper than the previous one
+			float early_out = inResult.GetEarlyOutFraction();
+			if (early_out < GetEarlyOutFraction())
 			{
 				// Lock the body
 				BodyLockRead lock(mPhysicsSystem.GetBodyLockInterfaceNoLock(), inResult.mBodyID2);
@@ -244,13 +248,14 @@ bool VehicleCollisionTesterCastCylinder::Collide(PhysicsSystem &inPhysicsSystem,
 					return;
 
 				// Update early out fraction to this hit
-				UpdateEarlyOutFraction(inResult.mFraction);
+				UpdateEarlyOutFraction(early_out);
 
 				// Get the contact properties
 				mBody = body;
 				mSubShapeID2 = inResult.mSubShapeID2;
 				mContactPosition = mShapeCast.mCenterOfMassStart.GetTranslation() + inResult.mContactPointOn2;
 				mContactNormal = -inResult.mPenetrationAxis.Normalized();
+				mFraction = inResult.mFraction;
 			}
 		}
 
@@ -263,6 +268,7 @@ bool VehicleCollisionTesterCastCylinder::Collide(PhysicsSystem &inPhysicsSystem,
 		SubShapeID			mSubShapeID2;
 		RVec3				mContactPosition;
 		Vec3				mContactNormal;
+		float				mFraction;
 	};
 
 	MyCollector collector(inPhysicsSystem, shape_cast);
@@ -274,7 +280,7 @@ bool VehicleCollisionTesterCastCylinder::Collide(PhysicsSystem &inPhysicsSystem,
 	outSubShapeID = collector.mSubShapeID2;
 	outContactPosition = collector.mContactPosition;
 	outContactNormal = collector.mContactNormal;
-	outSuspensionLength = max_suspension_length * collector.GetEarlyOutFraction();
+	outSuspensionLength = max_suspension_length * collector.mFraction;
 
 	return true;
 }