CollisionDispatch.h 8.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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/Collision/Shape/Shape.h>
  6. #include <Jolt/Physics/Collision/Shape/SubShapeID.h>
  7. #include <Jolt/Physics/Collision/ShapeCast.h>
  8. #include <Jolt/Physics/Collision/ShapeFilter.h>
  9. #include <Jolt/Physics/Collision/NarrowPhaseStats.h>
  10. JPH_NAMESPACE_BEGIN
  11. class CollideShapeSettings;
  12. /// Dispatch function, main function to handle collisions between shapes
  13. class CollisionDispatch
  14. {
  15. public:
  16. /// Collide 2 shapes and pass any collision on to ioCollector
  17. /// @param inShape1 The first shape
  18. /// @param inShape2 The second shape
  19. /// @param inScale1 Local space scale of shape 1
  20. /// @param inScale2 Local space scale of shape 2
  21. /// @param inCenterOfMassTransform1 Transform to transform center of mass of shape 1 into world space
  22. /// @param inCenterOfMassTransform2 Transform to transform center of mass of shape 2 into world space
  23. /// @param inSubShapeIDCreator1 Class that tracks the current sub shape ID for shape 1
  24. /// @param inSubShapeIDCreator2 Class that tracks the current sub shape ID for shape 2
  25. /// @param inCollideShapeSettings Options for the CollideShape test
  26. /// @param ioCollector The collector that receives the results.
  27. /// @param inShapeFilter allows selectively disabling collisions between pairs of (sub) shapes.
  28. static inline void sCollideShapeVsShape(const Shape *inShape1, const Shape *inShape2, Vec3Arg inScale1, Vec3Arg inScale2, Mat44Arg inCenterOfMassTransform1, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, const CollideShapeSettings &inCollideShapeSettings, CollideShapeCollector &ioCollector, const ShapeFilter &inShapeFilter = { })
  29. {
  30. JPH_IF_TRACK_NARROWPHASE_STATS(TrackNarrowPhaseStat track(NarrowPhaseStat::sCollideShape[(int)inShape1->GetSubType()][(int)inShape2->GetSubType()]);)
  31. // Only test shape if it passes the shape filter
  32. if (inShapeFilter.ShouldCollide(inShape1, inSubShapeIDCreator1.GetID(), inShape2, inSubShapeIDCreator2.GetID()))
  33. sCollideShape[(int)inShape1->GetSubType()][(int)inShape2->GetSubType()](inShape1, inShape2, inScale1, inScale2, inCenterOfMassTransform1, inCenterOfMassTransform2, inSubShapeIDCreator1, inSubShapeIDCreator2, inCollideShapeSettings, ioCollector, inShapeFilter);
  34. }
  35. /// Cast a shape againt this shape, passes any hits found to ioCollector.
  36. /// Note: This version takes the shape cast in local space relative to the center of mass of inShape, take a look at sCastShapeVsShapeWorldSpace if you have a shape cast in world space.
  37. /// @param inShapeCastLocal The shape to cast against the other shape and its start and direction.
  38. /// @param inShapeCastSettings Settings for performing the cast
  39. /// @param inShape The shape to cast against.
  40. /// @param inScale Local space scale for the shape to cast against.
  41. /// @param inShapeFilter allows selectively disabling collisions between pairs of (sub) shapes.
  42. /// @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 hit result quantities can be transformed into world space.
  43. /// @param inSubShapeIDCreator1 Class that tracks the current sub shape ID for the casting shape
  44. /// @param inSubShapeIDCreator2 Class that tracks the current sub shape ID for the shape we're casting against
  45. /// @param ioCollector The collector that receives the results.
  46. static inline void sCastShapeVsShapeLocalSpace(const ShapeCast &inShapeCastLocal, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
  47. {
  48. JPH_IF_TRACK_NARROWPHASE_STATS(TrackNarrowPhaseStat track(NarrowPhaseStat::sCastShape[(int)inShapeCast.mShape->GetSubType()][(int)inShape->GetSubType()]);)
  49. // Only test shape if it passes the shape filter
  50. if (inShapeFilter.ShouldCollide(inShapeCastLocal.mShape, inSubShapeIDCreator1.GetID(), inShape, inSubShapeIDCreator2.GetID()))
  51. sCastShape[(int)inShapeCastLocal.mShape->GetSubType()][(int)inShape->GetSubType()](inShapeCastLocal, inShapeCastSettings, inShape, inScale, inShapeFilter, inCenterOfMassTransform2, inSubShapeIDCreator1, inSubShapeIDCreator2, ioCollector);
  52. }
  53. /// See: sCastShapeVsShapeLocalSpace.
  54. /// The only difference is that the shape cast (inShapeCastWorld) is provided in world space.
  55. /// Note: A shape cast contains the center of mass start of the shape, if you have the world transform of the shape you probably want to construct it using ShapeCast::sFromWorldTransform.
  56. static inline void sCastShapeVsShapeWorldSpace(const ShapeCast &inShapeCastWorld, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector)
  57. {
  58. ShapeCast local_shape_cast = inShapeCastWorld.PostTransformed(inCenterOfMassTransform2.InversedRotationTranslation());
  59. sCastShapeVsShapeLocalSpace(local_shape_cast, inShapeCastSettings, inShape, inScale, inShapeFilter, inCenterOfMassTransform2, inSubShapeIDCreator1, inSubShapeIDCreator2, ioCollector);
  60. }
  61. /// Function that collides 2 shapes (see sCollideShapeVsShape)
  62. using CollideShape = void (*)(const Shape *inShape1, const Shape *inShape2, Vec3Arg inScale1, Vec3Arg inScale2, Mat44Arg inCenterOfMassTransform1, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, const CollideShapeSettings &inCollideShapeSettings, CollideShapeCollector &ioCollector, const ShapeFilter &inShapeFilter);
  63. /// Function that casts a shape vs another shape (see sCastShapeVsShapeLocalSpace)
  64. using CastShape = void (*)(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector);
  65. /// Initialize all collision functions with a function that asserts and returns no collision
  66. static void sInit();
  67. /// Register a collide shape function in the collision table
  68. static void sRegisterCollideShape(EShapeSubType inType1, EShapeSubType inType2, CollideShape inFunction) { sCollideShape[(int)inType1][(int)inType2] = inFunction; }
  69. /// Register a cast shape function in the collision table
  70. static void sRegisterCastShape(EShapeSubType inType1, EShapeSubType inType2, CastShape inFunction) { sCastShape[(int)inType1][(int)inType2] = inFunction; }
  71. /// An implementation of CollideShape that swaps inShape1 and inShape2 and swaps the result back, can be registered if the collision function only exists the other way around
  72. static void sReversedCollideShape(const Shape *inShape1, const Shape *inShape2, Vec3Arg inScale1, Vec3Arg inScale2, Mat44Arg inCenterOfMassTransform1, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, const CollideShapeSettings &inCollideShapeSettings, CollideShapeCollector &ioCollector, const ShapeFilter &inShapeFilter);
  73. /// An implementation of CastShape that swaps inShape1 and inShape2 and swaps the result back, can be registered if the collision function only exists the other way around
  74. static void 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);
  75. private:
  76. static CollideShape sCollideShape[NumSubShapeTypes][NumSubShapeTypes];
  77. static CastShape sCastShape[NumSubShapeTypes][NumSubShapeTypes];
  78. };
  79. JPH_NAMESPACE_END