CollisionCollector.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. JPH_NAMESPACE_BEGIN
  6. class Body;
  7. class TransformedShape;
  8. /// Traits to use for CastRay
  9. class CollisionCollectorTraitsCastRay
  10. {
  11. public:
  12. /// For rays the early out fraction is the fraction along the line to order hits.
  13. static constexpr float InitialEarlyOutFraction = 1.0f + FLT_EPSILON; ///< Furthest hit: Fraction is 1 + epsilon
  14. static constexpr float ShouldEarlyOutFraction = 0.0f; ///< Closest hit: Fraction is 0
  15. };
  16. /// Traits to use for CastShape
  17. class CollisionCollectorTraitsCastShape
  18. {
  19. public:
  20. /// For rays the early out fraction is the fraction along the line to order hits.
  21. static constexpr float InitialEarlyOutFraction = 1.0f + FLT_EPSILON; ///< Furthest hit: Fraction is 1 + epsilon
  22. static constexpr float ShouldEarlyOutFraction = -FLT_MAX; ///< Deepest hit: Penetration is infinite
  23. };
  24. /// Traits to use for CollideShape
  25. class CollisionCollectorTraitsCollideShape
  26. {
  27. public:
  28. /// For shape collisions we use -penetration depth to order hits.
  29. static constexpr float InitialEarlyOutFraction = FLT_MAX; ///< Most shallow hit: Separation is infinite
  30. static constexpr float ShouldEarlyOutFraction = -FLT_MAX; ///< Deepest hit: Penetration is infinite
  31. };
  32. /// Traits to use for CollidePoint
  33. using CollisionCollectorTraitsCollidePoint = CollisionCollectorTraitsCollideShape;
  34. /// Virtual interface that allows collecting multiple collision results
  35. template <class ResultTypeArg, class TraitsType>
  36. class CollisionCollector
  37. {
  38. public:
  39. /// Declare ResultType so that derived classes can use it
  40. using ResultType = ResultTypeArg;
  41. /// Default constructor
  42. CollisionCollector() = default;
  43. /// Constructor to initialize from another collector
  44. template <class ResultTypeArg2>
  45. explicit CollisionCollector(const CollisionCollector<ResultTypeArg2, TraitsType> &inRHS) : mEarlyOutFraction(inRHS.GetEarlyOutFraction()), mContext(inRHS.GetContext()) { }
  46. CollisionCollector(const CollisionCollector<ResultTypeArg, TraitsType> &inRHS) = default;
  47. /// Destructor
  48. virtual ~CollisionCollector() = default;
  49. /// If you want to reuse this collector, call Reset()
  50. virtual void Reset() { mEarlyOutFraction = TraitsType::InitialEarlyOutFraction; }
  51. /// When running a query through the NarrowPhaseQuery class, this will be called for every body that is potentially colliding.
  52. /// It allows collecting additional information needed by the collision collector implementation from the body under lock protection
  53. /// before AddHit is called (e.g. the user data pointer or the velocity of the body).
  54. virtual void OnBody([[maybe_unused]] const Body &inBody) { /* Collects nothing by default */ }
  55. /// Set by the collision detection functions to the current TransformedShape that we're colliding against before calling the AddHit function
  56. void SetContext(const TransformedShape *inContext) { mContext = inContext; }
  57. const TransformedShape *GetContext() const { return mContext; }
  58. /// This function will be called for every hit found, it's up to the application to decide how to store the hit
  59. virtual void AddHit(const ResultType &inResult) = 0;
  60. /// Update the early out fraction (should be lower than before)
  61. inline void UpdateEarlyOutFraction(float inFraction) { JPH_ASSERT(inFraction <= mEarlyOutFraction); mEarlyOutFraction = inFraction; }
  62. /// Reset the early out fraction to a specific value
  63. inline void ResetEarlyOutFraction(float inFraction = TraitsType::InitialEarlyOutFraction) { mEarlyOutFraction = inFraction; }
  64. /// Force the collision detection algorithm to terminate as soon as possible. Call this from the AddHit function when a satisfying hit is found.
  65. inline void ForceEarlyOut() { mEarlyOutFraction = TraitsType::ShouldEarlyOutFraction; }
  66. /// When true, the collector will no longer accept any additional hits and the collision detection routine should early out as soon as possible
  67. inline bool ShouldEarlyOut() const { return mEarlyOutFraction <= TraitsType::ShouldEarlyOutFraction; }
  68. /// Get the current early out value
  69. inline float GetEarlyOutFraction() const { return mEarlyOutFraction; }
  70. /// Get the current early out value but make sure it's bigger than zero, this is used for shape casting as negative values are used for penetration
  71. inline float GetPositiveEarlyOutFraction() const { return max(FLT_MIN, mEarlyOutFraction); }
  72. private:
  73. /// The early out fraction determines the fraction below which the collector is still accepting a hit (can be used to reduce the amount of work)
  74. float mEarlyOutFraction = TraitsType::InitialEarlyOutFraction;
  75. /// Set by the collision detection functions to the current TransformedShape of the body that we're colliding against before calling the AddHit function
  76. const TransformedShape *mContext = nullptr;
  77. };
  78. JPH_NAMESPACE_END