Browse Source

Fixed CylinderShape::GetSupportingFace returning the wrong face. (#1539)

When the height of a cylinder was small compared to its radius, it would sink more into the ground than needed during simulation.

See: https://github.com/godot-jolt/godot-jolt/discussions/1049
Jorrit Rouwe 10 months ago
parent
commit
ab6122291f
2 changed files with 5 additions and 4 deletions
  1. 1 0
      Docs/ReleaseNotes.md
  2. 4 4
      Jolt/Physics/Collision/Shape/CylinderShape.cpp

+ 1 - 0
Docs/ReleaseNotes.md

@@ -52,6 +52,7 @@ For breaking API changes see [this document](https://github.com/jrouwe/JoltPhysi
 * When inserting lots of bodies without using batching, a broad phase tree of depth > 128 can be created. If the `PhysicsSystem` was destructed in this situation, a stack overflow would cause a crash.
 * When calling `PhysicsSystem::Update` with a delta time of 0, contact remove callbacks were triggered by accident for all existing contacts.
 * Fixed 'HingeConstraint' not having limits if `LimitsMin` was set to `-JPH_PI` or `LimitsMax` was set to `JPH_PI`. It should only be turned off if both are.
+* Fixed 'CylinderShape::GetSupportingFace' returning the wrong face. When the height of a cylinder was small compared to its radius, it would sink more into the ground than needed during simulation.
 
 ## v5.2.0
 

+ 4 - 4
Jolt/Physics/Collision/Shape/CylinderShape.cpp

@@ -200,13 +200,13 @@ void CylinderShape::GetSupportingFace(const SubShapeID &inSubShapeID, Vec3Arg in
 	float scaled_radius = scale_xz * mRadius;
 
 	float x = inDirection.GetX(), y = inDirection.GetY(), z = inDirection.GetZ();
-	float o = sqrt(Square(x) + Square(z));
+	float xz_sq = Square(x) + Square(z);
 
-	// If o / |y| > scaled_radius / scaled_half_height, we're hitting the side
-	if (o * scaled_half_height > scaled_radius * abs(y))
+	// Check which component is bigger
+	if (xz_sq > Square(y))
 	{
 		// Hitting side
-		float f = -scaled_radius / o;
+		float f = -scaled_radius / sqrt(xz_sq);
 		float vx = x * f;
 		float vz = z * f;
 		outVertices.push_back(inCenterOfMassTransform * Vec3(vx, scaled_half_height, vz));