CollisionDispatch.cpp 4.3 KB

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