Browse Source

Ability to override the default vehicle collision filters (#490)

Jorrit Rouwe 2 years ago
parent
commit
94f806fb6a

+ 24 - 9
Jolt/Physics/Vehicle/VehicleCollisionTester.cpp

@@ -18,9 +18,14 @@ JPH_NAMESPACE_BEGIN
 
 
 bool VehicleCollisionTesterRay::Collide(PhysicsSystem &inPhysicsSystem, const VehicleConstraint &inVehicleConstraint, uint inWheelIndex, RVec3Arg inOrigin, Vec3Arg inDirection, const BodyID &inVehicleBodyID, Body *&outBody, SubShapeID &outSubShapeID, RVec3 &outContactPosition, Vec3 &outContactNormal, float &outSuspensionLength) const
 bool VehicleCollisionTesterRay::Collide(PhysicsSystem &inPhysicsSystem, const VehicleConstraint &inVehicleConstraint, uint inWheelIndex, RVec3Arg inOrigin, Vec3Arg inDirection, const BodyID &inVehicleBodyID, Body *&outBody, SubShapeID &outSubShapeID, RVec3 &outContactPosition, Vec3 &outContactNormal, float &outSuspensionLength) const
 {
 {
-	DefaultBroadPhaseLayerFilter broadphase_layer_filter = inPhysicsSystem.GetDefaultBroadPhaseLayerFilter(mObjectLayer);
-	DefaultObjectLayerFilter object_layer_filter = inPhysicsSystem.GetDefaultLayerFilter(mObjectLayer);
-	IgnoreSingleBodyFilter body_filter(inVehicleBodyID);
+	const DefaultBroadPhaseLayerFilter default_broadphase_layer_filter = inPhysicsSystem.GetDefaultBroadPhaseLayerFilter(mObjectLayer);
+	const BroadPhaseLayerFilter &broadphase_layer_filter = mBroadPhaseLayerFilter != nullptr? *mBroadPhaseLayerFilter : default_broadphase_layer_filter;
+
+	const DefaultObjectLayerFilter default_object_layer_filter = inPhysicsSystem.GetDefaultLayerFilter(mObjectLayer);
+	const ObjectLayerFilter &object_layer_filter = mObjectLayerFilter != nullptr? *mObjectLayerFilter : default_object_layer_filter;
+
+	const IgnoreSingleBodyFilter default_body_filter(inVehicleBodyID);
+	const BodyFilter &body_filter = mBodyFilter != nullptr? *mBodyFilter : default_body_filter;
 
 
 	const WheelSettings *wheel_settings = inVehicleConstraint.GetWheel(inWheelIndex)->GetSettings();
 	const WheelSettings *wheel_settings = inVehicleConstraint.GetWheel(inWheelIndex)->GetSettings();
 	float wheel_radius = wheel_settings->mRadius;
 	float wheel_radius = wheel_settings->mRadius;
@@ -99,9 +104,14 @@ bool VehicleCollisionTesterRay::Collide(PhysicsSystem &inPhysicsSystem, const Ve
 
 
 bool VehicleCollisionTesterCastSphere::Collide(PhysicsSystem &inPhysicsSystem, const VehicleConstraint &inVehicleConstraint, uint inWheelIndex, RVec3Arg inOrigin, Vec3Arg inDirection, const BodyID &inVehicleBodyID, Body *&outBody, SubShapeID &outSubShapeID, RVec3 &outContactPosition, Vec3 &outContactNormal, float &outSuspensionLength) const
 bool VehicleCollisionTesterCastSphere::Collide(PhysicsSystem &inPhysicsSystem, const VehicleConstraint &inVehicleConstraint, uint inWheelIndex, RVec3Arg inOrigin, Vec3Arg inDirection, const BodyID &inVehicleBodyID, Body *&outBody, SubShapeID &outSubShapeID, RVec3 &outContactPosition, Vec3 &outContactNormal, float &outSuspensionLength) const
 {
 {
-	DefaultBroadPhaseLayerFilter broadphase_layer_filter = inPhysicsSystem.GetDefaultBroadPhaseLayerFilter(mObjectLayer);
-	DefaultObjectLayerFilter object_layer_filter = inPhysicsSystem.GetDefaultLayerFilter(mObjectLayer);
-	IgnoreSingleBodyFilter body_filter(inVehicleBodyID);
+	const DefaultBroadPhaseLayerFilter default_broadphase_layer_filter = inPhysicsSystem.GetDefaultBroadPhaseLayerFilter(mObjectLayer);
+	const BroadPhaseLayerFilter &broadphase_layer_filter = mBroadPhaseLayerFilter != nullptr? *mBroadPhaseLayerFilter : default_broadphase_layer_filter;
+
+	const DefaultObjectLayerFilter default_object_layer_filter = inPhysicsSystem.GetDefaultLayerFilter(mObjectLayer);
+	const ObjectLayerFilter &object_layer_filter = mObjectLayerFilter != nullptr? *mObjectLayerFilter : default_object_layer_filter;
+
+	const IgnoreSingleBodyFilter default_body_filter(inVehicleBodyID);
+	const BodyFilter &body_filter = mBodyFilter != nullptr? *mBodyFilter : default_body_filter;
 
 
 	SphereShape sphere(mRadius);
 	SphereShape sphere(mRadius);
 	sphere.SetEmbedded();
 	sphere.SetEmbedded();
@@ -184,9 +194,14 @@ bool VehicleCollisionTesterCastSphere::Collide(PhysicsSystem &inPhysicsSystem, c
 
 
 bool VehicleCollisionTesterCastCylinder::Collide(PhysicsSystem &inPhysicsSystem, const VehicleConstraint &inVehicleConstraint, uint inWheelIndex, RVec3Arg inOrigin, Vec3Arg inDirection, const BodyID &inVehicleBodyID, Body *&outBody, SubShapeID &outSubShapeID, RVec3 &outContactPosition, Vec3 &outContactNormal, float &outSuspensionLength) const
 bool VehicleCollisionTesterCastCylinder::Collide(PhysicsSystem &inPhysicsSystem, const VehicleConstraint &inVehicleConstraint, uint inWheelIndex, RVec3Arg inOrigin, Vec3Arg inDirection, const BodyID &inVehicleBodyID, Body *&outBody, SubShapeID &outSubShapeID, RVec3 &outContactPosition, Vec3 &outContactNormal, float &outSuspensionLength) const
 {
 {
-	DefaultBroadPhaseLayerFilter broadphase_layer_filter = inPhysicsSystem.GetDefaultBroadPhaseLayerFilter(mObjectLayer);
-	DefaultObjectLayerFilter object_layer_filter = inPhysicsSystem.GetDefaultLayerFilter(mObjectLayer);
-	IgnoreSingleBodyFilter body_filter(inVehicleBodyID);
+	const DefaultBroadPhaseLayerFilter default_broadphase_layer_filter = inPhysicsSystem.GetDefaultBroadPhaseLayerFilter(mObjectLayer);
+	const BroadPhaseLayerFilter &broadphase_layer_filter = mBroadPhaseLayerFilter != nullptr? *mBroadPhaseLayerFilter : default_broadphase_layer_filter;
+
+	const DefaultObjectLayerFilter default_object_layer_filter = inPhysicsSystem.GetDefaultLayerFilter(mObjectLayer);
+	const ObjectLayerFilter &object_layer_filter = mObjectLayerFilter != nullptr? *mObjectLayerFilter : default_object_layer_filter;
+
+	const IgnoreSingleBodyFilter default_body_filter(inVehicleBodyID);
+	const BodyFilter &body_filter = mBodyFilter != nullptr? *mBodyFilter : default_body_filter;
 
 
 	const WheelSettings *wheel_settings = inVehicleConstraint.GetWheel(inWheelIndex)->GetSettings();
 	const WheelSettings *wheel_settings = inVehicleConstraint.GetWheel(inWheelIndex)->GetSettings();
 	float max_suspension_length = wheel_settings->mSuspensionMaxLength;
 	float max_suspension_length = wheel_settings->mSuspensionMaxLength;

+ 43 - 17
Jolt/Physics/Vehicle/VehicleCollisionTester.h

@@ -10,6 +10,9 @@ JPH_NAMESPACE_BEGIN
 
 
 class PhysicsSystem;
 class PhysicsSystem;
 class VehicleConstraint;
 class VehicleConstraint;
+class BroadPhaseLayerFilter;
+class ObjectLayerFilter;
+class BodyFilter;
 
 
 /// Class that does collision detection between wheels and ground
 /// Class that does collision detection between wheels and ground
 class VehicleCollisionTester : public RefTarget<VehicleCollisionTester>
 class VehicleCollisionTester : public RefTarget<VehicleCollisionTester>
@@ -17,8 +20,28 @@ class VehicleCollisionTester : public RefTarget<VehicleCollisionTester>
 public:
 public:
 	JPH_OVERRIDE_NEW_DELETE
 	JPH_OVERRIDE_NEW_DELETE
 
 
+	/// Constructors
+									VehicleCollisionTester() = default;
+	explicit						VehicleCollisionTester(ObjectLayer inObjectLayer) : mObjectLayer(inObjectLayer) { }
+
 	/// Virtual destructor
 	/// Virtual destructor
-	virtual						~VehicleCollisionTester() = default;
+	virtual							~VehicleCollisionTester() = default;
+
+	/// Object layer to use for collision detection, this is used when the filters are not overridden
+	ObjectLayer						GetObjectLayer() const												{ return mObjectLayer; }
+	void							SetObjectLayer(ObjectLayer inObjectLayer)							{ mObjectLayer = inObjectLayer; }
+
+	/// Access to the broad phase layer filter, when set this overrides the object layer supplied in the constructor
+	void							SetBroadPhaseLayerFilter(const BroadPhaseLayerFilter *inFilter)		{ mBroadPhaseLayerFilter = inFilter; }
+	const BroadPhaseLayerFilter *	GetBroadPhaseLayerFilter() const									{ return mBroadPhaseLayerFilter; }
+
+	/// Access to the object layer filter, when set this overrides the object layer supplied in the constructor
+	void							SetObjectLayerFilter(const ObjectLayerFilter *inFilter)				{ mObjectLayerFilter = inFilter; }
+	const ObjectLayerFilter *		GetObjectLayerFilter() const										{ return mObjectLayerFilter; }
+
+	/// Access to the body filter, when set this overrides the default filter that filters out the vehicle body
+	void							SetBodyFilter(const BodyFilter *inFilter)							{ mBodyFilter = inFilter; }
+	const BodyFilter *				GetBodyFilter() const												{ return mBodyFilter; }
 
 
 	/// Do a collision test with the world
 	/// Do a collision test with the world
 	/// @param inPhysicsSystem The physics system that should be tested against
 	/// @param inPhysicsSystem The physics system that should be tested against
@@ -33,7 +56,13 @@ public:
 	/// @param outContactNormal Contact normal between wheel and floor, pointing away from the floor
 	/// @param outContactNormal Contact normal between wheel and floor, pointing away from the floor
 	/// @param outSuspensionLength New length of the suspension [0, inSuspensionMaxLength]
 	/// @param outSuspensionLength New length of the suspension [0, inSuspensionMaxLength]
 	/// @return True when collision found, false if not
 	/// @return True when collision found, false if not
-	virtual bool				Collide(PhysicsSystem &inPhysicsSystem, const VehicleConstraint &inVehicleConstraint, uint inWheelIndex, RVec3Arg inOrigin, Vec3Arg inDirection, const BodyID &inVehicleBodyID, Body *&outBody, SubShapeID &outSubShapeID, RVec3 &outContactPosition, Vec3 &outContactNormal, float &outSuspensionLength) const = 0;
+	virtual bool					Collide(PhysicsSystem &inPhysicsSystem, const VehicleConstraint &inVehicleConstraint, uint inWheelIndex, RVec3Arg inOrigin, Vec3Arg inDirection, const BodyID &inVehicleBodyID, Body *&outBody, SubShapeID &outSubShapeID, RVec3 &outContactPosition, Vec3 &outContactNormal, float &outSuspensionLength) const = 0;
+
+protected:
+	const BroadPhaseLayerFilter	*	mBroadPhaseLayerFilter = nullptr;
+	const ObjectLayerFilter *		mObjectLayerFilter = nullptr;
+	const BodyFilter *				mBodyFilter = nullptr;
+	ObjectLayer						mObjectLayer = cObjectLayerInvalid;
 };
 };
 
 
 /// Collision tester that tests collision using a raycast
 /// Collision tester that tests collision using a raycast
@@ -46,15 +75,14 @@ public:
 	/// @param inObjectLayer Object layer to test collision with
 	/// @param inObjectLayer Object layer to test collision with
 	/// @param inUp World space up vector, used to avoid colliding with vertical walls.
 	/// @param inUp World space up vector, used to avoid colliding with vertical walls.
 	/// @param inMaxSlopeAngle Max angle (rad) that is considered for colliding wheels. This is to avoid colliding with vertical walls.
 	/// @param inMaxSlopeAngle Max angle (rad) that is considered for colliding wheels. This is to avoid colliding with vertical walls.
-								VehicleCollisionTesterRay(ObjectLayer inObjectLayer, Vec3Arg inUp = Vec3::sAxisY(), float inMaxSlopeAngle = DegreesToRadians(80.0f)) : mObjectLayer(inObjectLayer), mUp(inUp), mCosMaxSlopeAngle(Cos(inMaxSlopeAngle)) { }
+									VehicleCollisionTesterRay(ObjectLayer inObjectLayer, Vec3Arg inUp = Vec3::sAxisY(), float inMaxSlopeAngle = DegreesToRadians(80.0f)) : VehicleCollisionTester(inObjectLayer), mUp(inUp), mCosMaxSlopeAngle(Cos(inMaxSlopeAngle)) { }
 
 
 	// See: VehicleCollisionTester
 	// See: VehicleCollisionTester
-	virtual bool				Collide(PhysicsSystem &inPhysicsSystem, const VehicleConstraint &inVehicleConstraint, uint inWheelIndex, RVec3Arg inOrigin, Vec3Arg inDirection, const BodyID &inVehicleBodyID, Body *&outBody, SubShapeID &outSubShapeID, RVec3 &outContactPosition, Vec3 &outContactNormal, float &outSuspensionLength) const override;
+	virtual bool					Collide(PhysicsSystem &inPhysicsSystem, const VehicleConstraint &inVehicleConstraint, uint inWheelIndex, RVec3Arg inOrigin, Vec3Arg inDirection, const BodyID &inVehicleBodyID, Body *&outBody, SubShapeID &outSubShapeID, RVec3 &outContactPosition, Vec3 &outContactNormal, float &outSuspensionLength) const override;
 
 
 private:
 private:
-	ObjectLayer					mObjectLayer;
-	Vec3						mUp;
-	float						mCosMaxSlopeAngle;
+	Vec3							mUp;
+	float							mCosMaxSlopeAngle;
 };
 };
 
 
 /// Collision tester that tests collision using a sphere cast
 /// Collision tester that tests collision using a sphere cast
@@ -68,16 +96,15 @@ public:
 	/// @param inUp World space up vector, used to avoid colliding with vertical walls.
 	/// @param inUp World space up vector, used to avoid colliding with vertical walls.
 	/// @param inRadius Radius of sphere
 	/// @param inRadius Radius of sphere
 	/// @param inMaxSlopeAngle Max angle (rad) that is considered for colliding wheels. This is to avoid colliding with vertical walls.
 	/// @param inMaxSlopeAngle Max angle (rad) that is considered for colliding wheels. This is to avoid colliding with vertical walls.
-								VehicleCollisionTesterCastSphere(ObjectLayer inObjectLayer, float inRadius, Vec3Arg inUp = Vec3::sAxisY(), float inMaxSlopeAngle = DegreesToRadians(80.0f)) : mObjectLayer(inObjectLayer), mRadius(inRadius), mUp(inUp), mCosMaxSlopeAngle(Cos(inMaxSlopeAngle)) { }
+									VehicleCollisionTesterCastSphere(ObjectLayer inObjectLayer, float inRadius, Vec3Arg inUp = Vec3::sAxisY(), float inMaxSlopeAngle = DegreesToRadians(80.0f)) : VehicleCollisionTester(inObjectLayer), mRadius(inRadius), mUp(inUp), mCosMaxSlopeAngle(Cos(inMaxSlopeAngle)) { }
 
 
 	// See: VehicleCollisionTester
 	// See: VehicleCollisionTester
-	virtual bool				Collide(PhysicsSystem &inPhysicsSystem, const VehicleConstraint &inVehicleConstraint, uint inWheelIndex, RVec3Arg inOrigin, Vec3Arg inDirection, const BodyID &inVehicleBodyID, Body *&outBody, SubShapeID &outSubShapeID, RVec3 &outContactPosition, Vec3 &outContactNormal, float &outSuspensionLength) const override;
+	virtual bool					Collide(PhysicsSystem &inPhysicsSystem, const VehicleConstraint &inVehicleConstraint, uint inWheelIndex, RVec3Arg inOrigin, Vec3Arg inDirection, const BodyID &inVehicleBodyID, Body *&outBody, SubShapeID &outSubShapeID, RVec3 &outContactPosition, Vec3 &outContactNormal, float &outSuspensionLength) const override;
 
 
 private:
 private:
-	ObjectLayer					mObjectLayer;
-	float						mRadius;
-	Vec3						mUp;
-	float						mCosMaxSlopeAngle;
+	float							mRadius;
+	Vec3							mUp;
+	float							mCosMaxSlopeAngle;
 };
 };
 
 
 /// Collision tester that tests collision using a cylinder shape
 /// Collision tester that tests collision using a cylinder shape
@@ -89,14 +116,13 @@ public:
 	/// Constructor
 	/// Constructor
 	/// @param inObjectLayer Object layer to test collision with
 	/// @param inObjectLayer Object layer to test collision with
 	/// @param inConvexRadiusFraction Fraction of half the wheel width (or wheel radius if it is smaller) that is used as the convex radius
 	/// @param inConvexRadiusFraction Fraction of half the wheel width (or wheel radius if it is smaller) that is used as the convex radius
-								VehicleCollisionTesterCastCylinder(ObjectLayer inObjectLayer, float inConvexRadiusFraction = 0.1f) : mObjectLayer(inObjectLayer), mConvexRadiusFraction(inConvexRadiusFraction) { JPH_ASSERT(mConvexRadiusFraction >= 0.0f && mConvexRadiusFraction <= 1.0f); }
+									VehicleCollisionTesterCastCylinder(ObjectLayer inObjectLayer, float inConvexRadiusFraction = 0.1f) : VehicleCollisionTester(inObjectLayer), mConvexRadiusFraction(inConvexRadiusFraction) { JPH_ASSERT(mConvexRadiusFraction >= 0.0f && mConvexRadiusFraction <= 1.0f); }
 
 
 	// See: VehicleCollisionTester
 	// See: VehicleCollisionTester
-	virtual bool				Collide(PhysicsSystem &inPhysicsSystem, const VehicleConstraint &inVehicleConstraint, uint inWheelIndex, RVec3Arg inOrigin, Vec3Arg inDirection, const BodyID &inVehicleBodyID, Body *&outBody, SubShapeID &outSubShapeID, RVec3 &outContactPosition, Vec3 &outContactNormal, float &outSuspensionLength) const override;
+	virtual bool					Collide(PhysicsSystem &inPhysicsSystem, const VehicleConstraint &inVehicleConstraint, uint inWheelIndex, RVec3Arg inOrigin, Vec3Arg inDirection, const BodyID &inVehicleBodyID, Body *&outBody, SubShapeID &outSubShapeID, RVec3 &outContactPosition, Vec3 &outContactNormal, float &outSuspensionLength) const override;
 
 
 private:
 private:
-	ObjectLayer					mObjectLayer;
-	float						mConvexRadiusFraction;
+	float							mConvexRadiusFraction;
 };
 };
 
 
 JPH_NAMESPACE_END
 JPH_NAMESPACE_END