Преглед изворни кода

Passing the shapes that are colliding into the ShapeFilter (#474)

* Added demo (thanks @mihe for this!)
* Removed per triangle shape filter callback
* Bugfix: Reversing shapes in CollisionDispatch::sReversedCastShape and sReversedCollideShape
Jorrit Rouwe пре 2 година
родитељ
комит
bc4fa997f1

+ 1 - 6
Jolt/Physics/Collision/CastConvexVsTriangles.cpp

@@ -13,10 +13,9 @@
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
-CastConvexVsTriangles::CastConvexVsTriangles(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, CastShapeCollector &ioCollector) :
+CastConvexVsTriangles::CastConvexVsTriangles(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, Vec3Arg inScale, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, CastShapeCollector &ioCollector) :
 	mShapeCast(inShapeCast),
 	mShapeCast(inShapeCast),
 	mShapeCastSettings(inShapeCastSettings),
 	mShapeCastSettings(inShapeCastSettings),
-	mShapeFilter(inShapeFilter), 
 	mCenterOfMassTransform2(inCenterOfMassTransform2),
 	mCenterOfMassTransform2(inCenterOfMassTransform2),
 	mScale(inScale),
 	mScale(inScale),
 	mSubShapeIDCreator1(inSubShapeIDCreator1),
 	mSubShapeIDCreator1(inSubShapeIDCreator1),
@@ -45,10 +44,6 @@ void CastConvexVsTriangles::Cast(Vec3Arg inV0, Vec3Arg inV1, Vec3Arg inV2, uint8
 	if (mShapeCastSettings.mBackFaceModeTriangles == EBackFaceMode::IgnoreBackFaces && back_facing)
 	if (mShapeCastSettings.mBackFaceModeTriangles == EBackFaceMode::IgnoreBackFaces && back_facing)
 		return;
 		return;
 
 
-	// Test the shape filter if this shape should collide
-	if (!mShapeFilter.ShouldCollide(mSubShapeIDCreator1.GetID(), inSubShapeID2))
-		return;
-
 	// Create triangle support function
 	// Create triangle support function
 	TriangleConvexSupport triangle { v0, v1, v2 };
 	TriangleConvexSupport triangle { v0, v1, v2 };
 
 

+ 1 - 3
Jolt/Physics/Collision/CastConvexVsTriangles.h

@@ -17,11 +17,10 @@ public:
 	/// @param inShapeCast The shape to cast against the triangles and its start and direction
 	/// @param inShapeCast The shape to cast against the triangles and its start and direction
 	/// @param inShapeCastSettings Settings for performing the cast
 	/// @param inShapeCastSettings Settings for performing the cast
 	/// @param inScale Local space scale for the shape to cast against.
 	/// @param inScale Local space scale for the shape to cast against.
-	/// @param inShapeFilter Determines if sub shapes of the shape can collide
 	/// @param inCenterOfMassTransform2 Is the center of mass transform of shape 2 (excluding scale), this is used to provide a transform to the shape cast result so that local quantities can be transformed into world space.
 	/// @param inCenterOfMassTransform2 Is the center of mass transform of shape 2 (excluding scale), this is used to provide a transform to the shape cast result so that local quantities can be transformed into world space.
 	/// @param inSubShapeIDCreator1 Class that tracks the current sub shape ID for the casting shape
 	/// @param inSubShapeIDCreator1 Class that tracks the current sub shape ID for the casting shape
 	/// @param ioCollector The collector that receives the results.
 	/// @param ioCollector The collector that receives the results.
-									CastConvexVsTriangles(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, CastShapeCollector &ioCollector);
+									CastConvexVsTriangles(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, Vec3Arg inScale, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, CastShapeCollector &ioCollector);
 
 
 	/// Cast convex object with a single triangle
 	/// Cast convex object with a single triangle
 	/// @param inV0 , inV1 , inV2: CCW triangle vertices
 	/// @param inV0 , inV1 , inV2: CCW triangle vertices
@@ -33,7 +32,6 @@ public:
 protected:
 protected:
 	const ShapeCast &				mShapeCast;
 	const ShapeCast &				mShapeCast;
 	const ShapeCastSettings &		mShapeCastSettings;
 	const ShapeCastSettings &		mShapeCastSettings;
-	const ShapeFilter &				mShapeFilter;
 	const Mat44 &					mCenterOfMassTransform2;
 	const Mat44 &					mCenterOfMassTransform2;
 	Vec3							mScale;
 	Vec3							mScale;
 	SubShapeIDCreator				mSubShapeIDCreator1;
 	SubShapeIDCreator				mSubShapeIDCreator1;

+ 1 - 6
Jolt/Physics/Collision/CastSphereVsTriangles.cpp

@@ -16,11 +16,10 @@
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
-CastSphereVsTriangles::CastSphereVsTriangles(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, CastShapeCollector &ioCollector) :
+CastSphereVsTriangles::CastSphereVsTriangles(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, Vec3Arg inScale, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, CastShapeCollector &ioCollector) :
 	mStart(inShapeCast.mCenterOfMassStart.GetTranslation()),
 	mStart(inShapeCast.mCenterOfMassStart.GetTranslation()),
 	mDirection(inShapeCast.mDirection),
 	mDirection(inShapeCast.mDirection),
 	mShapeCastSettings(inShapeCastSettings),
 	mShapeCastSettings(inShapeCastSettings),
-	mShapeFilter(inShapeFilter), 
 	mCenterOfMassTransform2(inCenterOfMassTransform2),
 	mCenterOfMassTransform2(inCenterOfMassTransform2),
 	mScale(inScale),
 	mScale(inScale),
 	mSubShapeIDCreator1(inSubShapeIDCreator1),
 	mSubShapeIDCreator1(inSubShapeIDCreator1),
@@ -134,10 +133,6 @@ void CastSphereVsTriangles::Cast(Vec3Arg inV0, Vec3Arg inV1, Vec3Arg inV2, uint8
 	if (mShapeCastSettings.mBackFaceModeTriangles == EBackFaceMode::IgnoreBackFaces && back_facing)
 	if (mShapeCastSettings.mBackFaceModeTriangles == EBackFaceMode::IgnoreBackFaces && back_facing)
 		return;
 		return;
 
 
-	// Test the shape filter if this shape should collide
-	if (!mShapeFilter.ShouldCollide(mSubShapeIDCreator1.GetID(), inSubShapeID2))
-		return;
-
 	// Test if distance between the sphere and plane of triangle is smaller or equal than the radius
 	// Test if distance between the sphere and plane of triangle is smaller or equal than the radius
 	if (abs(v0.Dot(triangle_normal)) <= mRadius)
 	if (abs(v0.Dot(triangle_normal)) <= mRadius)
 	{
 	{

+ 1 - 3
Jolt/Physics/Collision/CastSphereVsTriangles.h

@@ -16,11 +16,10 @@ public:
 	/// @param inShapeCast The sphere to cast against the triangles and its start and direction
 	/// @param inShapeCast The sphere to cast against the triangles and its start and direction
 	/// @param inShapeCastSettings Settings for performing the cast
 	/// @param inShapeCastSettings Settings for performing the cast
 	/// @param inScale Local space scale for the shape to cast against.
 	/// @param inScale Local space scale for the shape to cast against.
-	/// @param inShapeFilter Determines if sub shapes of the shape can collide
 	/// @param inCenterOfMassTransform2 Is the center of mass transform of shape 2 (excluding scale), this is used to provide a transform to the shape cast result so that local quantities can be transformed into world space.
 	/// @param inCenterOfMassTransform2 Is the center of mass transform of shape 2 (excluding scale), this is used to provide a transform to the shape cast result so that local quantities can be transformed into world space.
 	/// @param inSubShapeIDCreator1 Class that tracks the current sub shape ID for the casting shape
 	/// @param inSubShapeIDCreator1 Class that tracks the current sub shape ID for the casting shape
 	/// @param ioCollector The collector that receives the results.
 	/// @param ioCollector The collector that receives the results.
-									CastSphereVsTriangles(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, CastShapeCollector &ioCollector);
+									CastSphereVsTriangles(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, Vec3Arg inScale, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, CastShapeCollector &ioCollector);
 
 
 	/// Cast sphere with a single triangle
 	/// Cast sphere with a single triangle
 	/// @param inV0 , inV1 , inV2: CCW triangle vertices
 	/// @param inV0 , inV1 , inV2: CCW triangle vertices
@@ -34,7 +33,6 @@ protected:
 	Vec3							mDirection;							///< Direction and length of movement of sphere
 	Vec3							mDirection;							///< Direction and length of movement of sphere
 	float							mRadius;							///< Scaled radius of sphere
 	float							mRadius;							///< Scaled radius of sphere
 	const ShapeCastSettings &		mShapeCastSettings;
 	const ShapeCastSettings &		mShapeCastSettings;
-	const ShapeFilter &				mShapeFilter;
 	const Mat44 &					mCenterOfMassTransform2;
 	const Mat44 &					mCenterOfMassTransform2;
 	Vec3							mScale;
 	Vec3							mScale;
 	SubShapeIDCreator				mSubShapeIDCreator1;
 	SubShapeIDCreator				mSubShapeIDCreator1;

+ 4 - 2
Jolt/Physics/Collision/CollisionDispatch.cpp

@@ -56,8 +56,9 @@ void CollisionDispatch::sReversedCollideShape(const Shape *inShape1, const Shape
 		CollideShapeCollector &	mCollector;
 		CollideShapeCollector &	mCollector;
 	};
 	};
 
 
+	ReversedShapeFilter shape_filter(inShapeFilter);
 	ReversedCollector collector(ioCollector);
 	ReversedCollector collector(ioCollector);
-	sCollideShapeVsShape(inShape2, inShape1, inScale2, inScale1, inCenterOfMassTransform2, inCenterOfMassTransform1, inSubShapeIDCreator2, inSubShapeIDCreator1, inCollideShapeSettings, collector, inShapeFilter);
+	sCollideShapeVsShape(inShape2, inShape1, inScale2, inScale1, inCenterOfMassTransform2, inCenterOfMassTransform1, inSubShapeIDCreator2, inSubShapeIDCreator1, inCollideShapeSettings, collector, shape_filter);
 }
 }
 
 
 void CollisionDispatch::sReversedCastShape(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
 void CollisionDispatch::sReversedCastShape(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
@@ -98,8 +99,9 @@ void CollisionDispatch::sReversedCastShape(const ShapeCast &inShapeCast, const S
 	Vec3 world_direction = -inCenterOfMassTransform2.Multiply3x3(inShapeCast.mDirection);
 	Vec3 world_direction = -inCenterOfMassTransform2.Multiply3x3(inShapeCast.mDirection);
 
 
 	// Forward the cast
 	// Forward the cast
+	ReversedShapeFilter shape_filter(inShapeFilter);
 	ReversedCollector collector(ioCollector, world_direction);
 	ReversedCollector collector(ioCollector, world_direction);
-	sCastShapeVsShapeLocalSpace(local_shape_cast, inShapeCastSettings, inShapeCast.mShape, inShapeCast.mScale, inShapeFilter, shape1_com, inSubShapeIDCreator2, inSubShapeIDCreator1, collector);
+	sCastShapeVsShapeLocalSpace(local_shape_cast, inShapeCastSettings, inShapeCast.mShape, inShapeCast.mScale, shape_filter, shape1_com, inSubShapeIDCreator2, inSubShapeIDCreator1, collector);
 }
 }
 
 
 JPH_NAMESPACE_END
 JPH_NAMESPACE_END

+ 2 - 2
Jolt/Physics/Collision/CollisionDispatch.h

@@ -35,7 +35,7 @@ public:
 		JPH_IF_TRACK_NARROWPHASE_STATS(TrackNarrowPhaseStat track(NarrowPhaseStat::sCollideShape[(int)inShape1->GetSubType()][(int)inShape2->GetSubType()]);)
 		JPH_IF_TRACK_NARROWPHASE_STATS(TrackNarrowPhaseStat track(NarrowPhaseStat::sCollideShape[(int)inShape1->GetSubType()][(int)inShape2->GetSubType()]);)
 
 
 		// Only test shape if it passes the shape filter
 		// Only test shape if it passes the shape filter
-		if (inShapeFilter.ShouldCollide(inSubShapeIDCreator1.GetID(), inSubShapeIDCreator2.GetID()))
+		if (inShapeFilter.ShouldCollide(inShape1, inSubShapeIDCreator1.GetID(), inShape2, inSubShapeIDCreator2.GetID()))
 			sCollideShape[(int)inShape1->GetSubType()][(int)inShape2->GetSubType()](inShape1, inShape2, inScale1, inScale2, inCenterOfMassTransform1, inCenterOfMassTransform2, inSubShapeIDCreator1, inSubShapeIDCreator2, inCollideShapeSettings, ioCollector, inShapeFilter);
 			sCollideShape[(int)inShape1->GetSubType()][(int)inShape2->GetSubType()](inShape1, inShape2, inScale1, inScale2, inCenterOfMassTransform1, inCenterOfMassTransform2, inSubShapeIDCreator1, inSubShapeIDCreator2, inCollideShapeSettings, ioCollector, inShapeFilter);
 	}
 	}
 
 
@@ -55,7 +55,7 @@ public:
 		JPH_IF_TRACK_NARROWPHASE_STATS(TrackNarrowPhaseStat track(NarrowPhaseStat::sCastShape[(int)inShapeCast.mShape->GetSubType()][(int)inShape->GetSubType()]);)
 		JPH_IF_TRACK_NARROWPHASE_STATS(TrackNarrowPhaseStat track(NarrowPhaseStat::sCastShape[(int)inShapeCast.mShape->GetSubType()][(int)inShape->GetSubType()]);)
 
 
 		// Only test shape if it passes the shape filter
 		// Only test shape if it passes the shape filter
-		if (inShapeFilter.ShouldCollide(inSubShapeIDCreator1.GetID(), inSubShapeIDCreator2.GetID()))
+		if (inShapeFilter.ShouldCollide(inShapeCastLocal.mShape, inSubShapeIDCreator1.GetID(), inShape, inSubShapeIDCreator2.GetID()))
 			sCastShape[(int)inShapeCastLocal.mShape->GetSubType()][(int)inShape->GetSubType()](inShapeCastLocal, inShapeCastSettings, inShape, inScale, inShapeFilter, inCenterOfMassTransform2, inSubShapeIDCreator1, inSubShapeIDCreator2, ioCollector);
 			sCastShape[(int)inShapeCastLocal.mShape->GetSubType()][(int)inShape->GetSubType()](inShapeCastLocal, inShapeCastSettings, inShape, inScale, inShapeFilter, inCenterOfMassTransform2, inSubShapeIDCreator1, inSubShapeIDCreator2, ioCollector);
 	}
 	}
 
 

+ 2 - 2
Jolt/Physics/Collision/Shape/BoxShape.cpp

@@ -182,7 +182,7 @@ bool BoxShape::CastRay(const RayCast &inRay, const SubShapeIDCreator &inSubShape
 void BoxShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void BoxShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	float min_fraction, max_fraction;
 	float min_fraction, max_fraction;
@@ -216,7 +216,7 @@ void BoxShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSet
 void BoxShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void BoxShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	if (Vec3::sLessOrEqual(inPoint.Abs(), mHalfExtent).TestAllXYZTrue())
 	if (Vec3::sLessOrEqual(inPoint.Abs(), mHalfExtent).TestAllXYZTrue())

+ 1 - 1
Jolt/Physics/Collision/Shape/CapsuleShape.cpp

@@ -300,7 +300,7 @@ bool CapsuleShape::CastRay(const RayCast &inRay, const SubShapeIDCreator &inSubS
 void CapsuleShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void CapsuleShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	float radius_sq = Square(mRadius);
 	float radius_sq = Square(mRadius);

+ 2 - 2
Jolt/Physics/Collision/Shape/ConvexHullShape.cpp

@@ -1011,7 +1011,7 @@ bool ConvexHullShape::CastRay(const RayCast &inRay, const SubShapeIDCreator &inS
 void ConvexHullShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void ConvexHullShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	// Determine if ray hits the shape
 	// Determine if ray hits the shape
@@ -1044,7 +1044,7 @@ void ConvexHullShape::CastRay(const RayCast &inRay, const RayCastSettings &inRay
 void ConvexHullShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void ConvexHullShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	// Check if point is behind all planes
 	// Check if point is behind all planes

+ 2 - 2
Jolt/Physics/Collision/Shape/ConvexShape.cpp

@@ -182,7 +182,7 @@ void ConvexShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCast
 	// Note: This is a fallback routine, most convex shapes should implement a more performant version!
 	// Note: This is a fallback routine, most convex shapes should implement a more performant version!
 
 
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	// First do a normal raycast, limited to the early out fraction
 	// First do a normal raycast, limited to the early out fraction
@@ -226,7 +226,7 @@ void ConvexShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCast
 void ConvexShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void ConvexShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	// First test bounding box
 	// First test bounding box

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

@@ -290,7 +290,7 @@ bool CylinderShape::CastRay(const RayCast &inRay, const SubShapeIDCreator &inSub
 void CylinderShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void CylinderShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	// Check if the point is in the cylinder
 	// Check if the point is in the cylinder

+ 5 - 5
Jolt/Physics/Collision/Shape/HeightFieldShape.cpp

@@ -1472,7 +1472,7 @@ void HeightFieldShape::CastRay(const RayCast &inRay, const RayCastSettings &inRa
 	JPH_PROFILE_FUNCTION();
 	JPH_PROFILE_FUNCTION();
 
 
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	struct Visitor
 	struct Visitor
@@ -1544,7 +1544,7 @@ void HeightFieldShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &in
 	// A height field doesn't have volume, so we can't test insideness
 	// A height field doesn't have volume, so we can't test insideness
 }
 }
 
 
-void HeightFieldShape::sCastConvexVsHeightField(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
+void HeightFieldShape::sCastConvexVsHeightField(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, [[maybe_unused]] const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
 {
 {
 	JPH_PROFILE_FUNCTION();
 	JPH_PROFILE_FUNCTION();
 
 
@@ -1600,7 +1600,7 @@ void HeightFieldShape::sCastConvexVsHeightField(const ShapeCast &inShapeCast, co
 	JPH_ASSERT(inShape->GetSubType() == EShapeSubType::HeightField);
 	JPH_ASSERT(inShape->GetSubType() == EShapeSubType::HeightField);
 	const HeightFieldShape *shape = static_cast<const HeightFieldShape *>(inShape);
 	const HeightFieldShape *shape = static_cast<const HeightFieldShape *>(inShape);
 
 
-	Visitor visitor(inShapeCast, inShapeCastSettings, inScale, inShapeFilter, inCenterOfMassTransform2, inSubShapeIDCreator1, ioCollector);
+	Visitor visitor(inShapeCast, inShapeCastSettings, inScale, inCenterOfMassTransform2, inSubShapeIDCreator1, ioCollector);
 	visitor.mShape2 = shape;
 	visitor.mShape2 = shape;
 	visitor.mInvDirection.Set(inShapeCast.mDirection);
 	visitor.mInvDirection.Set(inShapeCast.mDirection);
 	visitor.mBoxCenter = inShapeCast.mShapeWorldBounds.GetCenter();
 	visitor.mBoxCenter = inShapeCast.mShapeWorldBounds.GetCenter();
@@ -1609,7 +1609,7 @@ void HeightFieldShape::sCastConvexVsHeightField(const ShapeCast &inShapeCast, co
 	shape->WalkHeightField(visitor);
 	shape->WalkHeightField(visitor);
 }
 }
 
 
-void HeightFieldShape::sCastSphereVsHeightField(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
+void HeightFieldShape::sCastSphereVsHeightField(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, [[maybe_unused]] const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
 {
 {
 	JPH_PROFILE_FUNCTION();
 	JPH_PROFILE_FUNCTION();
 
 
@@ -1663,7 +1663,7 @@ void HeightFieldShape::sCastSphereVsHeightField(const ShapeCast &inShapeCast, co
 	JPH_ASSERT(inShape->GetSubType() == EShapeSubType::HeightField);
 	JPH_ASSERT(inShape->GetSubType() == EShapeSubType::HeightField);
 	const HeightFieldShape *shape = static_cast<const HeightFieldShape *>(inShape);
 	const HeightFieldShape *shape = static_cast<const HeightFieldShape *>(inShape);
 
 
-	Visitor visitor(inShapeCast, inShapeCastSettings, inScale, inShapeFilter, inCenterOfMassTransform2, inSubShapeIDCreator1, ioCollector);
+	Visitor visitor(inShapeCast, inShapeCastSettings, inScale, inCenterOfMassTransform2, inSubShapeIDCreator1, ioCollector);
 	visitor.mShape2 = shape;
 	visitor.mShape2 = shape;
 	visitor.mInvDirection.Set(inShapeCast.mDirection);
 	visitor.mInvDirection.Set(inShapeCast.mDirection);
 	visitor.mSubShapeIDCreator2 = inSubShapeIDCreator2;
 	visitor.mSubShapeIDCreator2 = inSubShapeIDCreator2;

+ 5 - 5
Jolt/Physics/Collision/Shape/MeshShape.cpp

@@ -710,7 +710,7 @@ void MeshShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSe
 	JPH_PROFILE_FUNCTION();
 	JPH_PROFILE_FUNCTION();
 
 
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	struct Visitor
 	struct Visitor
@@ -809,7 +809,7 @@ void MeshShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShap
 	}
 	}
 }
 }
 
 
-void MeshShape::sCastConvexVsMesh(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
+void MeshShape::sCastConvexVsMesh(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, [[maybe_unused]] const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
 {
 {
 	JPH_PROFILE_FUNCTION();
 	JPH_PROFILE_FUNCTION();
 
 
@@ -857,14 +857,14 @@ void MeshShape::sCastConvexVsMesh(const ShapeCast &inShapeCast, const ShapeCastS
 	JPH_ASSERT(inShape->GetSubType() == EShapeSubType::Mesh);
 	JPH_ASSERT(inShape->GetSubType() == EShapeSubType::Mesh);
 	const MeshShape *shape = static_cast<const MeshShape *>(inShape);
 	const MeshShape *shape = static_cast<const MeshShape *>(inShape);
 
 
-	Visitor visitor(inShapeCast, inShapeCastSettings, inScale, inShapeFilter, inCenterOfMassTransform2, inSubShapeIDCreator1, ioCollector);
+	Visitor visitor(inShapeCast, inShapeCastSettings, inScale, inCenterOfMassTransform2, inSubShapeIDCreator1, ioCollector);
 	visitor.mInvDirection.Set(inShapeCast.mDirection);
 	visitor.mInvDirection.Set(inShapeCast.mDirection);
 	visitor.mBoxCenter = inShapeCast.mShapeWorldBounds.GetCenter();
 	visitor.mBoxCenter = inShapeCast.mShapeWorldBounds.GetCenter();
 	visitor.mBoxExtent = inShapeCast.mShapeWorldBounds.GetExtent();
 	visitor.mBoxExtent = inShapeCast.mShapeWorldBounds.GetExtent();
 	shape->WalkTreePerTriangle(inSubShapeIDCreator2, visitor);
 	shape->WalkTreePerTriangle(inSubShapeIDCreator2, visitor);
 }
 }
 
 
-void MeshShape::sCastSphereVsMesh(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
+void MeshShape::sCastSphereVsMesh(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, [[maybe_unused]] const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
 {
 {
 	JPH_PROFILE_FUNCTION();
 	JPH_PROFILE_FUNCTION();
 
 
@@ -910,7 +910,7 @@ void MeshShape::sCastSphereVsMesh(const ShapeCast &inShapeCast, const ShapeCastS
 	JPH_ASSERT(inShape->GetSubType() == EShapeSubType::Mesh);
 	JPH_ASSERT(inShape->GetSubType() == EShapeSubType::Mesh);
 	const MeshShape *shape = static_cast<const MeshShape *>(inShape);
 	const MeshShape *shape = static_cast<const MeshShape *>(inShape);
 
 
-	Visitor visitor(inShapeCast, inShapeCastSettings, inScale, inShapeFilter, inCenterOfMassTransform2, inSubShapeIDCreator1, ioCollector);
+	Visitor visitor(inShapeCast, inShapeCastSettings, inScale, inCenterOfMassTransform2, inSubShapeIDCreator1, ioCollector);
 	visitor.mInvDirection.Set(inShapeCast.mDirection);
 	visitor.mInvDirection.Set(inShapeCast.mDirection);
 	shape->WalkTreePerTriangle(inSubShapeIDCreator2, visitor);
 	shape->WalkTreePerTriangle(inSubShapeIDCreator2, visitor);
 }
 }

+ 3 - 3
Jolt/Physics/Collision/Shape/MutableCompoundShape.cpp

@@ -306,7 +306,7 @@ void MutableCompoundShape::CastRay(const RayCast &inRay, const RayCastSettings &
 	JPH_PROFILE_FUNCTION();
 	JPH_PROFILE_FUNCTION();
 
 
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	struct Visitor : public CastRayVisitorCollector
 	struct Visitor : public CastRayVisitorCollector
@@ -341,7 +341,7 @@ void MutableCompoundShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator
 	JPH_PROFILE_FUNCTION();
 	JPH_PROFILE_FUNCTION();
 
 
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	struct Visitor : public CollidePointVisitor
 	struct Visitor : public CollidePointVisitor
@@ -409,7 +409,7 @@ void MutableCompoundShape::CollectTransformedShapes(const AABox &inBox, Vec3Arg
 	JPH_PROFILE_FUNCTION();
 	JPH_PROFILE_FUNCTION();
 
 
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	struct Visitor : public CollectTransformedShapesVisitor
 	struct Visitor : public CollectTransformedShapesVisitor

+ 3 - 3
Jolt/Physics/Collision/Shape/OffsetCenterOfMassShape.cpp

@@ -107,7 +107,7 @@ bool OffsetCenterOfMassShape::CastRay(const RayCast &inRay, const SubShapeIDCrea
 void OffsetCenterOfMassShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void OffsetCenterOfMassShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	// Transform the ray to local space
 	// Transform the ray to local space
@@ -120,7 +120,7 @@ void OffsetCenterOfMassShape::CastRay(const RayCast &inRay, const RayCastSetting
 void OffsetCenterOfMassShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void OffsetCenterOfMassShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	// Pass the point on to the inner shape in local space
 	// Pass the point on to the inner shape in local space
@@ -130,7 +130,7 @@ void OffsetCenterOfMassShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCrea
 void OffsetCenterOfMassShape::CollectTransformedShapes(const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale, const SubShapeIDCreator &inSubShapeIDCreator, TransformedShapeCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void OffsetCenterOfMassShape::CollectTransformedShapes(const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale, const SubShapeIDCreator &inSubShapeIDCreator, TransformedShapeCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	mInnerShape->CollectTransformedShapes(inBox, inPositionCOM - inRotation * mOffset, inRotation, inScale, inSubShapeIDCreator, ioCollector, inShapeFilter);
 	mInnerShape->CollectTransformedShapes(inBox, inPositionCOM - inRotation * mOffset, inRotation, inScale, inSubShapeIDCreator, ioCollector, inShapeFilter);

+ 3 - 3
Jolt/Physics/Collision/Shape/RotatedTranslatedShape.cpp

@@ -140,7 +140,7 @@ bool RotatedTranslatedShape::CastRay(const RayCast &inRay, const SubShapeIDCreat
 void RotatedTranslatedShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void RotatedTranslatedShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	// Transform the ray
 	// Transform the ray
@@ -153,7 +153,7 @@ void RotatedTranslatedShape::CastRay(const RayCast &inRay, const RayCastSettings
 void RotatedTranslatedShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void RotatedTranslatedShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	// Transform the point
 	// Transform the point
@@ -164,7 +164,7 @@ void RotatedTranslatedShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreat
 void RotatedTranslatedShape::CollectTransformedShapes(const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale, const SubShapeIDCreator &inSubShapeIDCreator, TransformedShapeCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void RotatedTranslatedShape::CollectTransformedShapes(const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale, const SubShapeIDCreator &inSubShapeIDCreator, TransformedShapeCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	mInnerShape->CollectTransformedShapes(inBox, inPositionCOM, inRotation * mRotation, TransformScale(inScale), inSubShapeIDCreator, ioCollector, inShapeFilter);
 	mInnerShape->CollectTransformedShapes(inBox, inPositionCOM, inRotation * mRotation, TransformScale(inScale), inSubShapeIDCreator, ioCollector, inShapeFilter);

+ 3 - 3
Jolt/Physics/Collision/Shape/ScaledShape.cpp

@@ -114,7 +114,7 @@ bool ScaledShape::CastRay(const RayCast &inRay, const SubShapeIDCreator &inSubSh
 void ScaledShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void ScaledShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	Vec3 inv_scale = mScale.Reciprocal();
 	Vec3 inv_scale = mScale.Reciprocal();
@@ -125,7 +125,7 @@ void ScaledShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCast
 void ScaledShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void ScaledShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	Vec3 inv_scale = mScale.Reciprocal();
 	Vec3 inv_scale = mScale.Reciprocal();
@@ -135,7 +135,7 @@ void ScaledShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubSh
 void ScaledShape::CollectTransformedShapes(const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale, const SubShapeIDCreator &inSubShapeIDCreator, TransformedShapeCollector &ioCollector, const ShapeFilter &inShapeFilter) const 
 void ScaledShape::CollectTransformedShapes(const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale, const SubShapeIDCreator &inSubShapeIDCreator, TransformedShapeCollector &ioCollector, const ShapeFilter &inShapeFilter) const 
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	mInnerShape->CollectTransformedShapes(inBox, inPositionCOM, inRotation, inScale * mScale, inSubShapeIDCreator, ioCollector, inShapeFilter);
 	mInnerShape->CollectTransformedShapes(inBox, inPositionCOM, inRotation, inScale * mScale, inSubShapeIDCreator, ioCollector, inShapeFilter);

+ 1 - 1
Jolt/Physics/Collision/Shape/Shape.cpp

@@ -43,7 +43,7 @@ TransformedShape Shape::GetSubShapeTransformedShape(const SubShapeID &inSubShape
 void Shape::CollectTransformedShapes(const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale, const SubShapeIDCreator &inSubShapeIDCreator, TransformedShapeCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void Shape::CollectTransformedShapes(const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale, const SubShapeIDCreator &inSubShapeIDCreator, TransformedShapeCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	TransformedShape ts(RVec3(inPositionCOM), inRotation, this, TransformedShape::sGetBodyID(ioCollector.GetContext()), inSubShapeIDCreator);
 	TransformedShape ts(RVec3(inPositionCOM), inRotation, this, TransformedShape::sGetBodyID(ioCollector.GetContext()), inSubShapeIDCreator);

+ 2 - 2
Jolt/Physics/Collision/Shape/SphereShape.cpp

@@ -232,7 +232,7 @@ bool SphereShape::CastRay(const RayCast &inRay, const SubShapeIDCreator &inSubSh
 void SphereShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void SphereShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	float min_fraction, max_fraction;
 	float min_fraction, max_fraction;
@@ -267,7 +267,7 @@ void SphereShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCast
 void SphereShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void SphereShape::CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	if (inPoint.LengthSq() <= Square(mRadius))
 	if (inPoint.LengthSq() <= Square(mRadius))

+ 2 - 2
Jolt/Physics/Collision/Shape/StaticCompoundShape.cpp

@@ -439,7 +439,7 @@ bool StaticCompoundShape::CastRay(const RayCast &inRay, const SubShapeIDCreator
 void StaticCompoundShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void StaticCompoundShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	JPH_PROFILE_FUNCTION();
 	JPH_PROFILE_FUNCTION();
@@ -531,7 +531,7 @@ void StaticCompoundShape::CollectTransformedShapes(const AABox &inBox, Vec3Arg i
 	JPH_PROFILE_FUNCTION();
 	JPH_PROFILE_FUNCTION();
 
 
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	struct Visitor : public CollectTransformedShapesVisitor
 	struct Visitor : public CollectTransformedShapesVisitor

+ 5 - 5
Jolt/Physics/Collision/Shape/TriangleShape.cpp

@@ -232,7 +232,7 @@ bool TriangleShape::CastRay(const RayCast &inRay, const SubShapeIDCreator &inSub
 void TriangleShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 void TriangleShape::CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) const
 {
 {
 	// Test shape filter
 	// Test shape filter
-	if (!inShapeFilter.ShouldCollide(inSubShapeIDCreator.GetID()))
+	if (!inShapeFilter.ShouldCollide(this, inSubShapeIDCreator.GetID()))
 		return;
 		return;
 
 
 	// Back facing check
 	// Back facing check
@@ -279,21 +279,21 @@ void TriangleShape::sCollideSphereVsTriangle(const Shape *inShape1, const Shape
 	collider.Collide(shape2->mV1, shape2->mV2, shape2->mV3, 0b111, inSubShapeIDCreator2.GetID());
 	collider.Collide(shape2->mV1, shape2->mV2, shape2->mV3, 0b111, inSubShapeIDCreator2.GetID());
 }
 }
 
 
-void TriangleShape::sCastConvexVsTriangle(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
+void TriangleShape::sCastConvexVsTriangle(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, [[maybe_unused]] const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
 {
 {
 	JPH_ASSERT(inShape->GetSubType() == EShapeSubType::Triangle);
 	JPH_ASSERT(inShape->GetSubType() == EShapeSubType::Triangle);
 	const TriangleShape *shape = static_cast<const TriangleShape *>(inShape);
 	const TriangleShape *shape = static_cast<const TriangleShape *>(inShape);
 
 
-	CastConvexVsTriangles caster(inShapeCast, inShapeCastSettings, inScale, inShapeFilter, inCenterOfMassTransform2, inSubShapeIDCreator1, ioCollector);
+	CastConvexVsTriangles caster(inShapeCast, inShapeCastSettings, inScale, inCenterOfMassTransform2, inSubShapeIDCreator1, ioCollector);
 	caster.Cast(shape->mV1, shape->mV2, shape->mV3, 0b111, inSubShapeIDCreator2.GetID());
 	caster.Cast(shape->mV1, shape->mV2, shape->mV3, 0b111, inSubShapeIDCreator2.GetID());
 }
 }
 
 
-void TriangleShape::sCastSphereVsTriangle(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
+void TriangleShape::sCastSphereVsTriangle(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, [[maybe_unused]] const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
 {
 {
 	JPH_ASSERT(inShape->GetSubType() == EShapeSubType::Triangle);
 	JPH_ASSERT(inShape->GetSubType() == EShapeSubType::Triangle);
 	const TriangleShape *shape = static_cast<const TriangleShape *>(inShape);
 	const TriangleShape *shape = static_cast<const TriangleShape *>(inShape);
 
 
-	CastSphereVsTriangles caster(inShapeCast, inShapeCastSettings, inScale, inShapeFilter, inCenterOfMassTransform2, inSubShapeIDCreator1, ioCollector);
+	CastSphereVsTriangles caster(inShapeCast, inShapeCastSettings, inScale, inCenterOfMassTransform2, inSubShapeIDCreator1, ioCollector);
 	caster.Cast(shape->mV1, shape->mV2, shape->mV3, 0b111, inSubShapeIDCreator2.GetID());
 	caster.Cast(shape->mV1, shape->mV2, shape->mV3, 0b111, inSubShapeIDCreator2.GetID());
 }
 }
 
 

+ 36 - 3
Jolt/Physics/Collision/ShapeFilter.h

@@ -9,6 +9,7 @@
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
+class Shape;
 class SubShapeID;
 class SubShapeID;
 
 
 /// Filter class
 /// Filter class
@@ -20,14 +21,22 @@ public:
 
 
 	/// Filter function to determine if we should collide with a shape. Returns true if the filter passes.
 	/// Filter function to determine if we should collide with a shape. Returns true if the filter passes.
 	/// This overload is called when the query doesn't have a source shape (e.g. ray cast / collide point)
 	/// This overload is called when the query doesn't have a source shape (e.g. ray cast / collide point)
-	virtual bool			ShouldCollide(const SubShapeID &inSubShapeID2) const
+	/// @param inShape2 Shape we're colliding against
+	/// @param inSubShapeIDOfShape2 The sub shape ID that will lead from the root shape to inShape2 (i.e. the shape of mBodyID2)
+	virtual bool			ShouldCollide(const Shape *inShape2, const SubShapeID &inSubShapeIDOfShape2) const
 	{
 	{
 		return true;
 		return true;
 	}
 	}
 
 
 	/// Filter function to determine if two shapes should collide. Returns true if the filter passes.
 	/// Filter function to determine if two shapes should collide. Returns true if the filter passes.
-	/// This overload is called when querying a shape vs a shape (e.g. collide object / cast object)
-	virtual bool			ShouldCollide(const SubShapeID &inSubShapeID1, const SubShapeID &inSubShapeID2) const
+	/// This overload is called when querying a shape vs a shape (e.g. collide object / cast object).
+	/// It is called at each level of the shape hierarchy, so if you have a compound shape with a box, this function will be called twice.
+	/// It will not be called on triangles that are part of another shape, i.e a mesh shape will not trigger a callback per triangle. You can filter out individual triangles in the CollisionCollector::AddHit function by their sub shape ID.
+	/// @param inShape1 1st shape that is colliding
+	/// @param inSubShapeIDOfShape1 The sub shape ID that will lead from the root shape to inShape1 (i.e. the shape that is used to collide or cast against shape 2)
+	/// @param inShape2 2nd shape that is colliding
+	/// @param inSubShapeIDOfShape2 The sub shape ID that will lead from the root shape to inShape2 (i.e. the shape of mBodyID2)
+	virtual bool			ShouldCollide(const Shape *inShape1, const SubShapeID &inSubShapeIDOfShape1, const Shape *inShape2, const SubShapeID &inSubShapeIDOfShape2) const
 	{
 	{
 		return true;
 		return true;
 	}
 	}
@@ -36,4 +45,28 @@ public:
 	mutable BodyID			mBodyID2;
 	mutable BodyID			mBodyID2;
 };
 };
 
 
+/// Helper class to reverse the order of the shapes in the ShouldCollide function
+class ReversedShapeFilter : public ShapeFilter
+{
+public:
+	/// Constructor
+	explicit				ReversedShapeFilter(const ShapeFilter &inFilter) : mFilter(inFilter)
+	{
+		mBodyID2 = inFilter.mBodyID2;
+	}
+
+	virtual bool			ShouldCollide(const Shape *inShape2, const SubShapeID &inSubShapeIDOfShape2) const override
+	{
+		return mFilter.ShouldCollide(inShape2, inSubShapeIDOfShape2);
+	}
+
+	virtual bool			ShouldCollide(const Shape *inShape1, const SubShapeID &inSubShapeIDOfShape1, const Shape *inShape2, const SubShapeID &inSubShapeIDOfShape2) const override
+	{
+		return mFilter.ShouldCollide(inShape2, inSubShapeIDOfShape2, inShape1, inSubShapeIDOfShape1);
+	}
+
+private:
+	const ShapeFilter &		mFilter;
+};
+
 JPH_NAMESPACE_END
 JPH_NAMESPACE_END

+ 2 - 0
Samples/Samples.cmake

@@ -75,6 +75,8 @@ set(SAMPLES_SRC_FILES
 	${SAMPLES_ROOT}/Tests/General/ActiveEdgesTest.h
 	${SAMPLES_ROOT}/Tests/General/ActiveEdgesTest.h
 	${SAMPLES_ROOT}/Tests/General/BigVsSmallTest.cpp
 	${SAMPLES_ROOT}/Tests/General/BigVsSmallTest.cpp
 	${SAMPLES_ROOT}/Tests/General/BigVsSmallTest.h
 	${SAMPLES_ROOT}/Tests/General/BigVsSmallTest.h
+	${SAMPLES_ROOT}/Tests/General/ShapeFilterTest.cpp
+	${SAMPLES_ROOT}/Tests/General/ShapeFilterTest.h
 	${SAMPLES_ROOT}/Tests/General/CenterOfMassTest.cpp
 	${SAMPLES_ROOT}/Tests/General/CenterOfMassTest.cpp
 	${SAMPLES_ROOT}/Tests/General/CenterOfMassTest.h
 	${SAMPLES_ROOT}/Tests/General/CenterOfMassTest.h
 	${SAMPLES_ROOT}/Tests/General/ChangeMotionQualityTest.cpp
 	${SAMPLES_ROOT}/Tests/General/ChangeMotionQualityTest.cpp

+ 2 - 0
Samples/SamplesApp.cpp

@@ -93,6 +93,7 @@ JPH_DECLARE_RTTI_FOR_FACTORY(ActivateDuringUpdateTest)
 JPH_DECLARE_RTTI_FOR_FACTORY(SensorTest)
 JPH_DECLARE_RTTI_FOR_FACTORY(SensorTest)
 JPH_DECLARE_RTTI_FOR_FACTORY(DynamicMeshTest)
 JPH_DECLARE_RTTI_FOR_FACTORY(DynamicMeshTest)
 JPH_DECLARE_RTTI_FOR_FACTORY(TwoDFunnelTest)
 JPH_DECLARE_RTTI_FOR_FACTORY(TwoDFunnelTest)
+JPH_DECLARE_RTTI_FOR_FACTORY(ShapeFilterTest)
 
 
 static TestNameAndRTTI sGeneralTests[] =
 static TestNameAndRTTI sGeneralTests[] =
 {
 {
@@ -127,6 +128,7 @@ static TestNameAndRTTI sGeneralTests[] =
 	{ "Activate During Update",				JPH_RTTI(ActivateDuringUpdateTest) },
 	{ "Activate During Update",				JPH_RTTI(ActivateDuringUpdateTest) },
 	{ "Sensor",								JPH_RTTI(SensorTest) },
 	{ "Sensor",								JPH_RTTI(SensorTest) },
 	{ "Dynamic Mesh",						JPH_RTTI(DynamicMeshTest) },
 	{ "Dynamic Mesh",						JPH_RTTI(DynamicMeshTest) },
+	{ "Shape Filter",						JPH_RTTI(ShapeFilterTest) },
 };
 };
 
 
 JPH_DECLARE_RTTI_FOR_FACTORY(DistanceConstraintTest)
 JPH_DECLARE_RTTI_FOR_FACTORY(DistanceConstraintTest)

+ 115 - 0
Samples/Tests/General/ShapeFilterTest.cpp

@@ -0,0 +1,115 @@
+#include <TestFramework.h>
+
+#include <Tests/General/ShapeFilterTest.h>
+#include <Jolt/Physics/Body/BodyCreationSettings.h>
+#include <Jolt/Physics/Collision/CollisionCollectorImpl.h>
+#include <Jolt/Physics/Collision/Shape/BoxShape.h>
+#include <Jolt/Physics/Collision/Shape/SphereShape.h>
+#include <Jolt/Physics/Collision/Shape/StaticCompoundShape.h>
+#include <Jolt/Physics/Collision/ShapeCast.h>
+#include <Renderer/DebugRendererImp.h>
+#include <Layers.h>
+
+JPH_IMPLEMENT_RTTI_VIRTUAL(ShapeFilterTest)
+{
+	JPH_ADD_BASE_CLASS(ShapeFilterTest, Test)
+}
+
+void ShapeFilterTest::Initialize()
+{
+	// Create geometry to cast against
+	mBodyInterface->CreateAndAddBody(BodyCreationSettings(new BoxShape(Vec3(20, 1, 3)), RVec3(0, -1, 0), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING), EActivation::Activate);
+	mBodyInterface->CreateAndAddBody(BodyCreationSettings(new BoxShape(Vec3::sReplicate(3)), RVec3(0, 3, 0), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING), EActivation::Activate);
+
+	// Create shape to cast
+	Ref box_shape = new BoxShapeSettings(Vec3::sReplicate(1));
+	box_shape->mUserData = (uint64)ShapeIdentifier::Box;
+
+	Ref sphere_shape = new SphereShapeSettings(1);
+	sphere_shape->mUserData = (uint64)ShapeIdentifier::Sphere;
+
+	StaticCompoundShapeSettings cast_shape;
+	cast_shape.AddShape(Vec3(3, 2, 0), Quat::sIdentity(), box_shape);
+	cast_shape.AddShape(Vec3(0, 0, 0), Quat::sIdentity(), sphere_shape);
+	cast_shape.mUserData = (uint64)ShapeIdentifier::Compound;
+
+	mCastShape = cast_shape.Create().Get();
+}
+
+void ShapeFilterTest::PostPhysicsUpdate(float inDeltaTime)
+{
+	mElapsedTime += inDeltaTime;
+	float phase = mElapsedTime;
+
+	const RVec3 cast_origin = RVec3(Cos(phase) * 10, 10, 0);
+	const Vec3 cast_motion = Vec3(0, -15, 0);
+
+	ClosestHitCollisionCollector<CastShapeCollector> cast_shape_collector;
+
+	class MyShapeFilter : public ShapeFilter
+	{
+	public:
+		// Not used in this example
+		virtual bool	ShouldCollide(const Shape *inShape2, const SubShapeID &inSubShapeIDOfShape2) const override
+		{
+			return true;
+		}
+
+		virtual bool	ShouldCollide(const Shape *inShape1, const SubShapeID &inSubShapeID1, const Shape *inShape2, const SubShapeID &inSubShapeID2) const override
+		{
+			return inShape1->GetUserData() != mUserDataOfShapeToIgnore;
+		}
+
+		uint64			mUserDataOfShapeToIgnore = (uint64)ShapeIdentifier::Sphere;
+	};
+
+	MyShapeFilter shape_filter;
+
+	// Select which shape to ignore
+	float shape_select = fmod(phase, 6.0f * JPH_PI);
+	const char *text;
+	if (shape_select < 2.0f * JPH_PI)
+	{
+		shape_filter.mUserDataOfShapeToIgnore = (uint64)ShapeIdentifier::Box;
+		text = "Box";
+	}
+	else if (shape_select < 4.0f * JPH_PI)
+	{
+		shape_filter.mUserDataOfShapeToIgnore = (uint64)ShapeIdentifier::Sphere;
+		text = "Sphere";
+	}
+	else
+	{
+		shape_filter.mUserDataOfShapeToIgnore = (uint64)ShapeIdentifier::Compound;
+		text = "Compound";
+	}
+	mDebugRenderer->DrawText3D(cast_origin, StringFormat("Ignoring shape: %s", text), Color::sWhite);
+
+	// Do the cast
+	mPhysicsSystem->GetNarrowPhaseQuery().CastShape(
+		RShapeCast(mCastShape, Vec3::sReplicate(1), RMat44::sTranslation(cast_origin), cast_motion),
+		ShapeCastSettings(),
+		RVec3::sZero(),
+		cast_shape_collector,
+		{ },
+		{ },
+		{ },
+		shape_filter
+	);
+
+	// Show the result
+	RVec3 cast_point;
+	Color color;
+	if (cast_shape_collector.HadHit())
+	{
+		cast_point = cast_origin + cast_motion * cast_shape_collector.mHit.mFraction;
+		color = Color::sGreen;
+	}
+    else
+	{
+		cast_point = cast_origin + cast_motion;
+		color = Color::sRed;
+	}
+	mDebugRenderer->DrawArrow(cast_origin, cast_point, Color::sOrange, 0.1f);
+	JPH_IF_DEBUG_RENDERER(mCastShape->Draw(mDebugRenderer, RMat44::sTranslation(RVec3(cast_point)), Vec3::sReplicate(1.0f), color, false, true);)
+}

+ 26 - 0
Samples/Tests/General/ShapeFilterTest.h

@@ -0,0 +1,26 @@
+#pragma once
+
+#include <Tests/Test.h>
+
+/// This test demonstrates how to use the ShapeFilter to filter out shapes during a collision query.
+class ShapeFilterTest : public Test
+{
+public:
+	JPH_DECLARE_RTTI_VIRTUAL(ShapeFilterTest)
+
+	// See: Test
+	virtual void	Initialize() override;
+	virtual void	PostPhysicsUpdate(float inDeltaTime) override;
+
+private:
+	/// A value used as user data for a shape
+	enum class ShapeIdentifier : uint64
+	{
+		Box = 42,
+		Sphere = 43,
+		Compound = 44
+	};
+
+	float			mElapsedTime = 0.0f;
+	ShapeRefC		mCastShape;
+};