Jelajahi Sumber

Added ability to filter out bodies after locking the body so that all… (#5)

Added ability to filter out bodies after locking the body so that all body properties are available for checking
jrouwe 3 tahun lalu
induk
melakukan
0ec1f65364
2 mengubah file dengan 95 tambahan dan 61 penghapusan
  1. 8 0
      Jolt/Physics/Body/BodyFilter.h
  2. 87 61
      Jolt/Physics/Collision/NarrowPhaseQuery.cpp

+ 8 - 0
Jolt/Physics/Body/BodyFilter.h

@@ -8,6 +8,8 @@
 
 namespace JPH {
 
+class Body;
+
 /// Class function to filter out bodies, returns true if test should collide with body
 class BodyFilter : public NonCopyable
 {
@@ -20,6 +22,12 @@ public:
 	{
 		return true;
 	}
+
+	/// Filter function. Returns true if we should collide with inBody (this is called after the body is locked and makes it possible to filter based on body members)
+	virtual bool			ShouldCollideLocked(const Body &inBody) const
+	{
+		return true;
+	}
 };
 
 /// A simple body filter implementation that ignores a single, specified body

+ 87 - 61
Jolt/Physics/Collision/NarrowPhaseQuery.cpp

@@ -41,20 +41,26 @@ bool NarrowPhaseQuery::CastRay(const RayCast &inRay, RayCastResult &ioHit, const
 				BodyLockRead lock(mBodyLockInterface, inResult.mBodyID);
 				if (lock.Succeeded())
 				{
-					// Collect the transformed shape
-					TransformedShape ts = lock.GetBody().GetTransformedShape();
-
-					// Release the lock now, we have all the info we need in the transformed shape
-					lock.ReleaseLock();
+					const Body &body = lock.GetBody();
 
-					// Do narrow phase collision check
-					if (ts.CastRay(mRay, mHit))
+					// Check body filter again now that we've locked the body
+					if (mBodyFilter.ShouldCollideLocked(body))
 					{
-						// Test that we didn't find a further hit by accident
-						JPH_ASSERT(mHit.mFraction >= 0.0f && mHit.mFraction < GetEarlyOutFraction());
+						// Collect the transformed shape
+						TransformedShape ts = body.GetTransformedShape();
 
-						// Update early out fraction based on narrow phase collector
-						UpdateEarlyOutFraction(mHit.mFraction);
+						// Release the lock now, we have all the info we need in the transformed shape
+						lock.ReleaseLock();
+
+						// Do narrow phase collision check
+						if (ts.CastRay(mRay, mHit))
+						{
+							// Test that we didn't find a further hit by accident
+							JPH_ASSERT(mHit.mFraction >= 0.0f && mHit.mFraction < GetEarlyOutFraction());
+
+							// Update early out fraction based on narrow phase collector
+							UpdateEarlyOutFraction(mHit.mFraction);
+						}
 					}
 				}
 			}
@@ -102,20 +108,24 @@ void NarrowPhaseQuery::CastRay(const RayCast &inRay, const RayCastSettings &inRa
 				{
 					const Body &body = lock.GetBody();
 
-					// Collect the transformed shape
-					TransformedShape ts = body.GetTransformedShape();
+					// Check body filter again now that we've locked the body
+					if (mBodyFilter.ShouldCollideLocked(body))
+					{
+						// Collect the transformed shape
+						TransformedShape ts = body.GetTransformedShape();
 
-					// Notify collector of new body
-					mCollector.OnBody(body);
+						// Notify collector of new body
+						mCollector.OnBody(body);
 
-					// Release the lock now, we have all the info we need in the transformed shape
-					lock.ReleaseLock();
+						// Release the lock now, we have all the info we need in the transformed shape
+						lock.ReleaseLock();
 
-					// Do narrow phase collision check
-					ts.CastRay(mRay, mRayCastSettings, mCollector);
+						// Do narrow phase collision check
+						ts.CastRay(mRay, mRayCastSettings, mCollector);
 
-					// Update early out fraction based on narrow phase collector
-					UpdateEarlyOutFraction(mCollector.GetEarlyOutFraction());
+						// Update early out fraction based on narrow phase collector
+						UpdateEarlyOutFraction(mCollector.GetEarlyOutFraction());
+					}
 				}
 			}
 		}
@@ -158,20 +168,24 @@ void NarrowPhaseQuery::CollidePoint(Vec3Arg inPoint, CollidePointCollector &ioCo
 				{
 					const Body &body = lock.GetBody();
 
-					// Collect the transformed shape
-					TransformedShape ts = body.GetTransformedShape();
+					// Check body filter again now that we've locked the body
+					if (mBodyFilter.ShouldCollideLocked(body))
+					{
+						// Collect the transformed shape
+						TransformedShape ts = body.GetTransformedShape();
 
-					// Notify collector of new body
-					mCollector.OnBody(body);
+						// Notify collector of new body
+						mCollector.OnBody(body);
 
-					// Release the lock now, we have all the info we need in the transformed shape
-					lock.ReleaseLock();
+						// Release the lock now, we have all the info we need in the transformed shape
+						lock.ReleaseLock();
 
-					// Do narrow phase collision check
-					ts.CollidePoint(mPoint, mCollector);
+						// Do narrow phase collision check
+						ts.CollidePoint(mPoint, mCollector);
 
-					// Update early out fraction based on narrow phase collector
-					UpdateEarlyOutFraction(mCollector.GetEarlyOutFraction());
+						// Update early out fraction based on narrow phase collector
+						UpdateEarlyOutFraction(mCollector.GetEarlyOutFraction());
+					}
 				}
 			}
 		}
@@ -216,20 +230,24 @@ void NarrowPhaseQuery::CollideShape(const Shape *inShape, Vec3Arg inShapeScale,
 				{
 					const Body &body = lock.GetBody();
 
-					// Collect the transformed shape
-					TransformedShape ts = body.GetTransformedShape();
+					// Check body filter again now that we've locked the body
+					if (mBodyFilter.ShouldCollideLocked(body))
+					{
+						// Collect the transformed shape
+						TransformedShape ts = body.GetTransformedShape();
 
-					// Notify collector of new body
-					mCollector.OnBody(body);
+						// Notify collector of new body
+						mCollector.OnBody(body);
 
-					// Release the lock now, we have all the info we need in the transformed shape
-					lock.ReleaseLock();
+						// Release the lock now, we have all the info we need in the transformed shape
+						lock.ReleaseLock();
 
-					// Do narrow phase collision check
-					ts.CollideShape(mShape, mShapeScale, mCenterOfMassTransform, mCollideShapeSettings, mCollector);
+						// Do narrow phase collision check
+						ts.CollideShape(mShape, mShapeScale, mCenterOfMassTransform, mCollideShapeSettings, mCollector);
 
-					// Update early out fraction based on narrow phase collector
-					UpdateEarlyOutFraction(mCollector.GetEarlyOutFraction());
+						// Update early out fraction based on narrow phase collector
+						UpdateEarlyOutFraction(mCollector.GetEarlyOutFraction());
+					}
 				}
 			}
 		}
@@ -294,20 +312,24 @@ void NarrowPhaseQuery::CastShape(const ShapeCast &inShapeCast, const ShapeCastSe
 				{
 					const Body &body = lock.GetBody();
 
-					// Collect the transformed shape
-					TransformedShape ts = body.GetTransformedShape();
+					// Check body filter again now that we've locked the body
+					if (mBodyFilter.ShouldCollideLocked(body))
+					{
+						// Collect the transformed shape
+						TransformedShape ts = body.GetTransformedShape();
 
-					// Notify collector of new body
-					mCollector.OnBody(body);
+						// Notify collector of new body
+						mCollector.OnBody(body);
 
-					// Release the lock now, we have all the info we need in the transformed shape
-					lock.ReleaseLock();
+						// Release the lock now, we have all the info we need in the transformed shape
+						lock.ReleaseLock();
 
-					// Do narrow phase collision check
-					ts.CastShape(mShapeCast, mShapeCastSettings, mCollector, mShapeFilter);
+						// Do narrow phase collision check
+						ts.CastShape(mShapeCast, mShapeCastSettings, mCollector, mShapeFilter);
 
-					// Update early out fraction based on narrow phase collector
-					PropagateEarlyOutFraction();
+						// Update early out fraction based on narrow phase collector
+						PropagateEarlyOutFraction();
+					}
 				}
 			}
 		}
@@ -349,20 +371,24 @@ void NarrowPhaseQuery::CollectTransformedShapes(const AABox &inBox, TransformedS
 				{
 					const Body &body = lock.GetBody();
 
-					// Collect the transformed shape
-					TransformedShape ts = body.GetTransformedShape();
+					// Check body filter again now that we've locked the body
+					if (mBodyFilter.ShouldCollideLocked(body))
+					{
+						// Collect the transformed shape
+						TransformedShape ts = body.GetTransformedShape();
 
-					// Notify collector of new body
-					mCollector.OnBody(body);
+						// Notify collector of new body
+						mCollector.OnBody(body);
 
-					// Release the lock now, we have all the info we need in the transformed shape
-					lock.ReleaseLock();
+						// Release the lock now, we have all the info we need in the transformed shape
+						lock.ReleaseLock();
 
-					// Do narrow phase collision check
-					ts.CollectTransformedShapes(mBox, mCollector);
+						// Do narrow phase collision check
+						ts.CollectTransformedShapes(mBox, mCollector);
 
-					// Update early out fraction based on narrow phase collector
-					UpdateEarlyOutFraction(mCollector.GetEarlyOutFraction());
+						// Update early out fraction based on narrow phase collector
+						UpdateEarlyOutFraction(mCollector.GetEarlyOutFraction());
+					}
 				}
 			}
 		}