CollisionDispatch.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <Jolt/Jolt.h>
  5. #include <Jolt/Physics/Collision/CollisionDispatch.h>
  6. #include <Jolt/Physics/Collision/CastResult.h>
  7. JPH_NAMESPACE_BEGIN
  8. CollisionDispatch::CollideShape CollisionDispatch::sCollideShape[NumSubShapeTypes][NumSubShapeTypes];
  9. CollisionDispatch::CastShape CollisionDispatch::sCastShape[NumSubShapeTypes][NumSubShapeTypes];
  10. void CollisionDispatch::sInit()
  11. {
  12. for (uint i = 0; i < NumSubShapeTypes; ++i)
  13. for (uint j = 0; j < NumSubShapeTypes; ++j)
  14. {
  15. if (sCollideShape[i][j] == nullptr)
  16. sCollideShape[i][j] = [](const Shape *, const Shape *, Vec3Arg, Vec3Arg, Mat44Arg, Mat44Arg, const SubShapeIDCreator &, const SubShapeIDCreator &, const CollideShapeSettings &, CollideShapeCollector &, const ShapeFilter &)
  17. {
  18. JPH_ASSERT(false, "Unsupported shape pair");
  19. };
  20. if (sCastShape[i][j] == nullptr)
  21. sCastShape[i][j] = [](const ShapeCast &, const ShapeCastSettings &, const Shape *, Vec3Arg, const ShapeFilter &, Mat44Arg, const SubShapeIDCreator &, const SubShapeIDCreator &, CastShapeCollector &)
  22. {
  23. JPH_ASSERT(false, "Unsupported shape pair");
  24. };
  25. }
  26. }
  27. void CollisionDispatch::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)
  28. {
  29. // A collision collector that flips the collision results
  30. class ReversedCollector : public CollideShapeCollector
  31. {
  32. public:
  33. explicit ReversedCollector(CollideShapeCollector &ioCollector) :
  34. CollideShapeCollector(ioCollector),
  35. mCollector(ioCollector)
  36. {
  37. }
  38. virtual void AddHit(const CollideShapeResult &inResult) override
  39. {
  40. // Add the reversed hit
  41. mCollector.AddHit(inResult.Reversed());
  42. // If our chained collector updated its early out fraction, we need to follow
  43. UpdateEarlyOutFraction(mCollector.GetEarlyOutFraction());
  44. }
  45. private:
  46. CollideShapeCollector & mCollector;
  47. };
  48. ReversedShapeFilter shape_filter(inShapeFilter);
  49. ReversedCollector collector(ioCollector);
  50. sCollideShapeVsShape(inShape2, inShape1, inScale2, inScale1, inCenterOfMassTransform2, inCenterOfMassTransform1, inSubShapeIDCreator2, inSubShapeIDCreator1, inCollideShapeSettings, collector, shape_filter);
  51. }
  52. 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)
  53. {
  54. // A collision collector that flips the collision results
  55. class ReversedCollector : public CastShapeCollector
  56. {
  57. public:
  58. explicit ReversedCollector(CastShapeCollector &ioCollector, Vec3Arg inWorldDirection) :
  59. CastShapeCollector(ioCollector),
  60. mCollector(ioCollector),
  61. mWorldDirection(inWorldDirection)
  62. {
  63. }
  64. virtual void AddHit(const ShapeCastResult &inResult) override
  65. {
  66. // Add the reversed hit
  67. mCollector.AddHit(inResult.Reversed(mWorldDirection));
  68. // If our chained collector updated its early out fraction, we need to follow
  69. UpdateEarlyOutFraction(mCollector.GetEarlyOutFraction());
  70. }
  71. private:
  72. CastShapeCollector & mCollector;
  73. Vec3 mWorldDirection;
  74. };
  75. // Reverse the shape cast (shape cast is in local space to shape 2)
  76. Mat44 com_start_inv = inShapeCast.mCenterOfMassStart.InversedRotationTranslation();
  77. ShapeCast local_shape_cast(inShape, inScale, com_start_inv, -com_start_inv.Multiply3x3(inShapeCast.mDirection));
  78. // Calculate the center of mass of shape 1 at start of sweep
  79. Mat44 shape1_com = inCenterOfMassTransform2 * inShapeCast.mCenterOfMassStart;
  80. // Calculate the world space direction vector of the shape cast
  81. Vec3 world_direction = -inCenterOfMassTransform2.Multiply3x3(inShapeCast.mDirection);
  82. // Forward the cast
  83. ReversedShapeFilter shape_filter(inShapeFilter);
  84. ReversedCollector collector(ioCollector, world_direction);
  85. sCastShapeVsShapeLocalSpace(local_shape_cast, inShapeCastSettings, inShapeCast.mShape, inShapeCast.mScale, shape_filter, shape1_com, inSubShapeIDCreator2, inSubShapeIDCreator1, collector);
  86. }
  87. JPH_NAMESPACE_END