Pārlūkot izejas kodu

Fixed race condition in narrow phase query (#702)

If a body is removed between the broad phase detecting an overlap and the narrow phase locking the body, callbacks may be called on a body that has already been removed (it will still be a valid body because otherwise the lock would have failed). We ensure that the callbacks can assume that the body is still in the broadphase. The collision collector cannot make this assumption (as before).
Jorrit Rouwe 1 gadu atpakaļ
vecāks
revīzija
22e58e1fea
1 mainītis faili ar 6 papildinājumiem un 6 dzēšanām
  1. 6 6
      Jolt/Physics/Collision/NarrowPhaseQuery.cpp

+ 6 - 6
Jolt/Physics/Collision/NarrowPhaseQuery.cpp

@@ -40,7 +40,7 @@ bool NarrowPhaseQuery::CastRay(const RRayCast &inRay, RayCastResult &ioHit, cons
 			{
 			{
 				// Lock the body
 				// Lock the body
 				BodyLockRead lock(mBodyLockInterface, inResult.mBodyID);
 				BodyLockRead lock(mBodyLockInterface, inResult.mBodyID);
-				if (lock.Succeeded())
+				if (lock.SucceededAndIsInBroadPhase()) // Race condition: body could have been removed since it has been found in the broadphase, ensures body is in the broadphase while we call the callbacks
 				{
 				{
 					const Body &body = lock.GetBody();
 					const Body &body = lock.GetBody();
 
 
@@ -106,7 +106,7 @@ void NarrowPhaseQuery::CastRay(const RRayCast &inRay, const RayCastSettings &inR
 			{
 			{
 				// Lock the body
 				// Lock the body
 				BodyLockRead lock(mBodyLockInterface, inResult.mBodyID);
 				BodyLockRead lock(mBodyLockInterface, inResult.mBodyID);
-				if (lock.Succeeded())
+				if (lock.SucceededAndIsInBroadPhase()) // Race condition: body could have been removed since it has been found in the broadphase, ensures body is in the broadphase while we call the callbacks
 				{
 				{
 					const Body &body = lock.GetBody();
 					const Body &body = lock.GetBody();
 
 
@@ -169,7 +169,7 @@ void NarrowPhaseQuery::CollidePoint(RVec3Arg inPoint, CollidePointCollector &ioC
 			{
 			{
 				// Lock the body
 				// Lock the body
 				BodyLockRead lock(mBodyLockInterface, inResult);
 				BodyLockRead lock(mBodyLockInterface, inResult);
-				if (lock.Succeeded())
+				if (lock.SucceededAndIsInBroadPhase()) // Race condition: body could have been removed since it has been found in the broadphase, ensures body is in the broadphase while we call the callbacks
 				{
 				{
 					const Body &body = lock.GetBody();
 					const Body &body = lock.GetBody();
 
 
@@ -235,7 +235,7 @@ void NarrowPhaseQuery::CollideShape(const Shape *inShape, Vec3Arg inShapeScale,
 			{
 			{
 				// Lock the body
 				// Lock the body
 				BodyLockRead lock(mBodyLockInterface, inResult);
 				BodyLockRead lock(mBodyLockInterface, inResult);
-				if (lock.Succeeded())
+				if (lock.SucceededAndIsInBroadPhase()) // Race condition: body could have been removed since it has been found in the broadphase, ensures body is in the broadphase while we call the callbacks
 				{
 				{
 					const Body &body = lock.GetBody();
 					const Body &body = lock.GetBody();
 
 
@@ -309,7 +309,7 @@ void NarrowPhaseQuery::CastShape(const RShapeCast &inShapeCast, const ShapeCastS
 			{
 			{
 				// Lock the body
 				// Lock the body
 				BodyLockRead lock(mBodyLockInterface, inResult.mBodyID);
 				BodyLockRead lock(mBodyLockInterface, inResult.mBodyID);
-				if (lock.Succeeded())
+				if (lock.SucceededAndIsInBroadPhase()) // Race condition: body could have been removed since it has been found in the broadphase, ensures body is in the broadphase while we call the callbacks
 				{
 				{
 					const Body &body = lock.GetBody();
 					const Body &body = lock.GetBody();
 
 
@@ -371,7 +371,7 @@ void NarrowPhaseQuery::CollectTransformedShapes(const AABox &inBox, TransformedS
 			{
 			{
 				// Lock the body
 				// Lock the body
 				BodyLockRead lock(mBodyLockInterface, inResult);
 				BodyLockRead lock(mBodyLockInterface, inResult);
-				if (lock.Succeeded())
+				if (lock.SucceededAndIsInBroadPhase()) // Race condition: body could have been removed since it has been found in the broadphase, ensures body is in the broadphase while we call the callbacks
 				{
 				{
 					const Body &body = lock.GetBody();
 					const Body &body = lock.GetBody();