CollideShape.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Jolt/Core/StaticArray.h>
  5. #include <Jolt/Physics/Collision/BackFaceMode.h>
  6. #include <Jolt/Physics/Collision/ActiveEdgeMode.h>
  7. #include <Jolt/Physics/Collision/CollectFacesMode.h>
  8. #include <Jolt/Physics/Collision/Shape/SubShapeID.h>
  9. #include <Jolt/Physics/Body/BodyID.h>
  10. #include <Jolt/Physics/PhysicsSettings.h>
  11. JPH_NAMESPACE_BEGIN
  12. /// Class that contains all information of two colliding shapes
  13. class CollideShapeResult
  14. {
  15. public:
  16. JPH_OVERRIDE_NEW_DELETE
  17. /// Default constructor
  18. CollideShapeResult() = default;
  19. /// Constructor
  20. CollideShapeResult(Vec3Arg inContactPointOn1, Vec3Arg inContactPointOn2, Vec3Arg inPenetrationAxis, float inPenetrationDepth, const SubShapeID &inSubShapeID1, const SubShapeID &inSubShapeID2, const BodyID &inBodyID2) :
  21. mContactPointOn1(inContactPointOn1),
  22. mContactPointOn2(inContactPointOn2),
  23. mPenetrationAxis(inPenetrationAxis),
  24. mPenetrationDepth(inPenetrationDepth),
  25. mSubShapeID1(inSubShapeID1),
  26. mSubShapeID2(inSubShapeID2),
  27. mBodyID2(inBodyID2)
  28. {
  29. }
  30. /// Function required by the CollisionCollector. A smaller fraction is considered to be a 'better hit'. We use -penetration depth to get the hit with the biggest penetration depth
  31. inline float GetEarlyOutFraction() const { return -mPenetrationDepth; }
  32. /// Reverses the hit result, swapping contact point 1 with contact point 2 etc.
  33. inline CollideShapeResult Reversed() const
  34. {
  35. CollideShapeResult result;
  36. result.mContactPointOn2 = mContactPointOn1;
  37. result.mContactPointOn1 = mContactPointOn2;
  38. result.mPenetrationAxis = -mPenetrationAxis;
  39. result.mPenetrationDepth = mPenetrationDepth;
  40. result.mSubShapeID2 = mSubShapeID1;
  41. result.mSubShapeID1 = mSubShapeID2;
  42. result.mBodyID2 = mBodyID2;
  43. result.mShape2Face = mShape1Face;
  44. result.mShape1Face = mShape2Face;
  45. return result;
  46. }
  47. using Face = StaticArray<Vec3, 32>;
  48. Vec3 mContactPointOn1; ///< Contact point on the surface of shape 1 (in world space or relative to base offset)
  49. Vec3 mContactPointOn2; ///< Contact point on the surface of shape 2 (in world space or relative to base offset). If the penetration depth is 0, this will be the same as mContactPointOn1.
  50. Vec3 mPenetrationAxis; ///< Direction to move shape 2 out of collision along the shortest path (magnitude is meaningless, in world space). You can use -mPenetrationAxis.Normalized() as contact normal.
  51. float mPenetrationDepth; ///< Penetration depth (move shape 2 by this distance to resolve the collision)
  52. SubShapeID mSubShapeID1; ///< Sub shape ID that identifies the face on shape 1
  53. SubShapeID mSubShapeID2; ///< Sub shape ID that identifies the face on shape 2
  54. BodyID mBodyID2; ///< BodyID to which shape 2 belongs to
  55. Face mShape1Face; ///< Colliding face on shape 1 (optional result, in world space or relative to base offset)
  56. Face mShape2Face; ///< Colliding face on shape 2 (optional result, in world space or relative to base offset)
  57. };
  58. /// Settings to be passed with a collision query
  59. class CollideSettingsBase
  60. {
  61. public:
  62. JPH_OVERRIDE_NEW_DELETE
  63. /// How active edges (edges that a moving object should bump into) are handled
  64. EActiveEdgeMode mActiveEdgeMode = EActiveEdgeMode::CollideOnlyWithActive;
  65. /// If colliding faces should be collected or only the collision point
  66. ECollectFacesMode mCollectFacesMode = ECollectFacesMode::NoFaces;
  67. /// If objects are closer than this distance, they are considered to be colliding (used for GJK) (unit: meter)
  68. float mCollisionTolerance = cDefaultCollisionTolerance;
  69. /// A factor that determines the accuracy of the penetration depth calculation. If the change of the squared distance is less than tolerance * current_penetration_depth^2 the algorithm will terminate. (unit: dimensionless)
  70. float mPenetrationTolerance = cDefaultPenetrationTolerance;
  71. /// When mActiveEdgeMode is CollideOnlyWithActive a movement direction can be provided. When hitting an inactive edge, the system will select the triangle normal as penetration depth only if it impedes the movement less than with the calculated penetration depth.
  72. Vec3 mActiveEdgeMovementDirection = Vec3::sZero();
  73. };
  74. /// Settings to be passed with a collision query
  75. class CollideShapeSettings : public CollideSettingsBase
  76. {
  77. public:
  78. JPH_OVERRIDE_NEW_DELETE
  79. /// When > 0 contacts in the vicinity of the query shape can be found. All nearest contacts that are not further away than this distance will be found (uint: meter)
  80. float mMaxSeparationDistance = 0.0f;
  81. /// How backfacing triangles should be treated
  82. EBackFaceMode mBackFaceMode = EBackFaceMode::IgnoreBackFaces;
  83. };
  84. JPH_NAMESPACE_END