ShapeFilter.h 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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/BodyID.h>
  6. #include <Jolt/Core/NonCopyable.h>
  7. JPH_NAMESPACE_BEGIN
  8. class Shape;
  9. class SubShapeID;
  10. /// Filter class
  11. class ShapeFilter : public NonCopyable
  12. {
  13. public:
  14. /// Destructor
  15. virtual ~ShapeFilter() = default;
  16. /// Filter function to determine if we should collide with a shape. Returns true if the filter passes.
  17. /// This overload is called when the query doesn't have a source shape (e.g. ray cast / collide point)
  18. /// @param inShape2 Shape we're colliding against
  19. /// @param inSubShapeIDOfShape2 The sub shape ID that will lead from the root shape to inShape2 (i.e. the shape of mBodyID2)
  20. virtual bool ShouldCollide([[maybe_unused]] const Shape *inShape2, [[maybe_unused]] const SubShapeID &inSubShapeIDOfShape2) const
  21. {
  22. return true;
  23. }
  24. /// Filter function to determine if two shapes should collide. Returns true if the filter passes.
  25. /// This overload is called when querying a shape vs a shape (e.g. collide object / cast object).
  26. /// It is called at each level of the shape hierarchy, so if you have a compound shape with a box, this function will be called twice.
  27. /// It will not be called on triangles that are part of another shape, i.e a mesh shape will not trigger a callback per triangle. You can filter out individual triangles in the CollisionCollector::AddHit function by their sub shape ID.
  28. /// @param inShape1 1st shape that is colliding
  29. /// @param inSubShapeIDOfShape1 The sub shape ID that will lead from the root shape to inShape1 (i.e. the shape that is used to collide or cast against shape 2 or the shape of mBodyID1)
  30. /// @param inShape2 2nd shape that is colliding
  31. /// @param inSubShapeIDOfShape2 The sub shape ID that will lead from the root shape to inShape2 (i.e. the shape of mBodyID2)
  32. virtual bool ShouldCollide([[maybe_unused]] const Shape *inShape1, [[maybe_unused]] const SubShapeID &inSubShapeIDOfShape1, [[maybe_unused]] const Shape *inShape2, [[maybe_unused]] const SubShapeID &inSubShapeIDOfShape2) const
  33. {
  34. return true;
  35. }
  36. /// Used during PhysicsSystem::Update only. Set to the body ID of inShape1 before calling ShouldCollide.
  37. /// Provides context to the filter to indicate which body is colliding.
  38. mutable BodyID mBodyID1;
  39. /// Used during PhysicsSystem::Update, NarrowPhase queries and TransformedShape queries. Set to the body ID of inShape2 before calling ShouldCollide.
  40. /// Provides context to the filter to indicate which body is colliding.
  41. mutable BodyID mBodyID2;
  42. };
  43. /// Helper class to reverse the order of the shapes in the ShouldCollide function
  44. class ReversedShapeFilter : public ShapeFilter
  45. {
  46. public:
  47. /// Constructor
  48. explicit ReversedShapeFilter(const ShapeFilter &inFilter) : mFilter(inFilter)
  49. {
  50. if (inFilter.mBodyID1.IsInvalid())
  51. {
  52. // If body 1 is not set then we're coming from a regular query and we should not swap the bodies
  53. // because conceptually we're still colliding a shape against a body and not a body against a body.
  54. mBodyID2 = inFilter.mBodyID2;
  55. }
  56. else
  57. {
  58. // If both bodies have been filled in then we swap the bodies
  59. mBodyID1 = inFilter.mBodyID2;
  60. mBodyID2 = inFilter.mBodyID1;
  61. }
  62. }
  63. virtual bool ShouldCollide(const Shape *inShape2, const SubShapeID &inSubShapeIDOfShape2) const override
  64. {
  65. return mFilter.ShouldCollide(inShape2, inSubShapeIDOfShape2);
  66. }
  67. virtual bool ShouldCollide(const Shape *inShape1, const SubShapeID &inSubShapeIDOfShape1, const Shape *inShape2, const SubShapeID &inSubShapeIDOfShape2) const override
  68. {
  69. return mFilter.ShouldCollide(inShape2, inSubShapeIDOfShape2, inShape1, inSubShapeIDOfShape1);
  70. }
  71. private:
  72. const ShapeFilter & mFilter;
  73. };
  74. JPH_NAMESPACE_END