Prechádzať zdrojové kódy

Crash fix when vehicle goes to sleep on an active kinematic body (#485)

Jorrit Rouwe 2 rokov pred
rodič
commit
200c1c56ce

+ 3 - 1
Jolt/Physics/IslandBuilder.cpp

@@ -161,7 +161,9 @@ void IslandBuilder::LinkConstraint(uint32 inConstraintIndex, uint32 inFirst, uin
 	LinkBodies(inFirst, inSecond);
 
 	JPH_ASSERT(inConstraintIndex < mNumConstraints);
-	mConstraintLinks[inConstraintIndex] = min(inFirst, inSecond); // Use fact that invalid index is 0xffffffff, we want the active body of two
+	uint32 min_value = min(inFirst, inSecond); // Use fact that invalid index is 0xffffffff, we want the active body of two
+	JPH_ASSERT(min_value != Body::cInactiveIndex); // At least one of the bodies must be active
+	mConstraintLinks[inConstraintIndex] = min_value;
 }
 
 void IslandBuilder::LinkContact(uint32 inContactIndex, uint32 inFirst, uint32 inSecond)

+ 13 - 14
Jolt/Physics/Vehicle/VehicleConstraint.cpp

@@ -249,24 +249,23 @@ void VehicleConstraint::BuildIslands(uint32 inConstraintIndex, IslandBuilder &io
 				continue;
 
 			if (w->mContactBody->IsDynamic())
+			{
 				body_ids[num_bodies++] = id;
-			needs_to_activate |= !w->mContactBody->IsActive();
+				needs_to_activate |= !w->mContactBody->IsActive();
+			}
 		}
 
-	// Activate bodies
-	if (needs_to_activate)
+	// Activate bodies, note that if we get here we have already told the system that we're active so that means our main body needs to be active too
+	if (!mBody->IsActive())
 	{
-		if (!mBody->IsActive())
-		{
-			// Our main body is not active, activate it too
-			body_ids[num_bodies] = mBody->GetID();
-			inBodyManager.ActivateBodies(body_ids, num_bodies + 1);
-		}
-		else
-		{
-			// Only activate bodies the wheels are touching
-			inBodyManager.ActivateBodies(body_ids, num_bodies);
-		}
+		// Our main body is not active, activate it too
+		body_ids[num_bodies] = mBody->GetID();
+		inBodyManager.ActivateBodies(body_ids, num_bodies + 1);
+	}
+	else if (needs_to_activate)
+	{
+		// Only activate bodies the wheels are touching
+		inBodyManager.ActivateBodies(body_ids, num_bodies);
 	}
 
 	// Link the bodies into the same island