CollisionCollector.h 4.1 KB

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