VehicleCollisionTester.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/Physics/Body/Body.h>
  6. #include <Jolt/Core/NonCopyable.h>
  7. JPH_NAMESPACE_BEGIN
  8. class PhysicsSystem;
  9. class VehicleConstraint;
  10. class BroadPhaseLayerFilter;
  11. class ObjectLayerFilter;
  12. class BodyFilter;
  13. /// Class that does collision detection between wheels and ground
  14. class JPH_EXPORT VehicleCollisionTester : public RefTarget<VehicleCollisionTester>, public NonCopyable
  15. {
  16. public:
  17. JPH_OVERRIDE_NEW_DELETE
  18. /// Constructors
  19. VehicleCollisionTester() = default;
  20. explicit VehicleCollisionTester(ObjectLayer inObjectLayer) : mObjectLayer(inObjectLayer) { }
  21. /// Virtual destructor
  22. virtual ~VehicleCollisionTester() = default;
  23. /// Object layer to use for collision detection, this is used when the filters are not overridden
  24. ObjectLayer GetObjectLayer() const { return mObjectLayer; }
  25. void SetObjectLayer(ObjectLayer inObjectLayer) { mObjectLayer = inObjectLayer; }
  26. /// Access to the broad phase layer filter, when set this overrides the object layer supplied in the constructor
  27. void SetBroadPhaseLayerFilter(const BroadPhaseLayerFilter *inFilter) { mBroadPhaseLayerFilter = inFilter; }
  28. const BroadPhaseLayerFilter * GetBroadPhaseLayerFilter() const { return mBroadPhaseLayerFilter; }
  29. /// Access to the object layer filter, when set this overrides the object layer supplied in the constructor
  30. void SetObjectLayerFilter(const ObjectLayerFilter *inFilter) { mObjectLayerFilter = inFilter; }
  31. const ObjectLayerFilter * GetObjectLayerFilter() const { return mObjectLayerFilter; }
  32. /// Access to the body filter, when set this overrides the default filter that filters out the vehicle body
  33. void SetBodyFilter(const BodyFilter *inFilter) { mBodyFilter = inFilter; }
  34. const BodyFilter * GetBodyFilter() const { return mBodyFilter; }
  35. /// Do a collision test with the world
  36. /// @param inPhysicsSystem The physics system that should be tested against
  37. /// @param inVehicleConstraint The vehicle constraint
  38. /// @param inWheelIndex Index of the wheel that we're testing collision for
  39. /// @param inOrigin Origin for the test, corresponds to the world space position for the suspension attachment point
  40. /// @param inDirection Direction for the test (unit vector, world space)
  41. /// @param inVehicleBodyID This body should be filtered out during collision detection to avoid self collisions
  42. /// @param outBody Body that the wheel collided with
  43. /// @param outSubShapeID Sub shape ID that the wheel collided with
  44. /// @param outContactPosition Contact point between wheel and floor, in world space
  45. /// @param outContactNormal Contact normal between wheel and floor, pointing away from the floor
  46. /// @param outSuspensionLength New length of the suspension [0, inSuspensionMaxLength]
  47. /// @return True when collision found, false if not
  48. 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;
  49. protected:
  50. const BroadPhaseLayerFilter * mBroadPhaseLayerFilter = nullptr;
  51. const ObjectLayerFilter * mObjectLayerFilter = nullptr;
  52. const BodyFilter * mBodyFilter = nullptr;
  53. ObjectLayer mObjectLayer = cObjectLayerInvalid;
  54. };
  55. /// Collision tester that tests collision using a raycast
  56. class JPH_EXPORT VehicleCollisionTesterRay : public VehicleCollisionTester
  57. {
  58. public:
  59. JPH_OVERRIDE_NEW_DELETE
  60. /// Constructor
  61. /// @param inObjectLayer Object layer to test collision with
  62. /// @param inUp World space up vector, used to avoid colliding with vertical walls.
  63. /// @param inMaxSlopeAngle Max angle (rad) that is considered for colliding wheels. This is to avoid colliding with vertical walls.
  64. VehicleCollisionTesterRay(ObjectLayer inObjectLayer, Vec3Arg inUp = Vec3::sAxisY(), float inMaxSlopeAngle = DegreesToRadians(80.0f)) : VehicleCollisionTester(inObjectLayer), mUp(inUp), mCosMaxSlopeAngle(Cos(inMaxSlopeAngle)) { }
  65. // See: VehicleCollisionTester
  66. 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;
  67. private:
  68. Vec3 mUp;
  69. float mCosMaxSlopeAngle;
  70. };
  71. /// Collision tester that tests collision using a sphere cast
  72. class JPH_EXPORT VehicleCollisionTesterCastSphere : public VehicleCollisionTester
  73. {
  74. public:
  75. JPH_OVERRIDE_NEW_DELETE
  76. /// Constructor
  77. /// @param inObjectLayer Object layer to test collision with
  78. /// @param inUp World space up vector, used to avoid colliding with vertical walls.
  79. /// @param inRadius Radius of sphere
  80. /// @param inMaxSlopeAngle Max angle (rad) that is considered for colliding wheels. This is to avoid colliding with vertical walls.
  81. VehicleCollisionTesterCastSphere(ObjectLayer inObjectLayer, float inRadius, Vec3Arg inUp = Vec3::sAxisY(), float inMaxSlopeAngle = DegreesToRadians(80.0f)) : VehicleCollisionTester(inObjectLayer), mRadius(inRadius), mUp(inUp), mCosMaxSlopeAngle(Cos(inMaxSlopeAngle)) { }
  82. // See: VehicleCollisionTester
  83. 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;
  84. private:
  85. float mRadius;
  86. Vec3 mUp;
  87. float mCosMaxSlopeAngle;
  88. };
  89. /// Collision tester that tests collision using a cylinder shape
  90. class JPH_EXPORT VehicleCollisionTesterCastCylinder : public VehicleCollisionTester
  91. {
  92. public:
  93. JPH_OVERRIDE_NEW_DELETE
  94. /// Constructor
  95. /// @param inObjectLayer Object layer to test collision with
  96. /// @param inConvexRadiusFraction Fraction of half the wheel width (or wheel radius if it is smaller) that is used as the convex radius
  97. VehicleCollisionTesterCastCylinder(ObjectLayer inObjectLayer, float inConvexRadiusFraction = 0.1f) : VehicleCollisionTester(inObjectLayer), mConvexRadiusFraction(inConvexRadiusFraction) { JPH_ASSERT(mConvexRadiusFraction >= 0.0f && mConvexRadiusFraction <= 1.0f); }
  98. // See: VehicleCollisionTester
  99. 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;
  100. private:
  101. float mConvexRadiusFraction;
  102. };
  103. JPH_NAMESPACE_END