CollisionCollector.h 4.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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: Separatation 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. /// Destructor
  42. virtual ~CollisionCollector() = default;
  43. /// If you want to reuse this collector, call Reset()
  44. virtual void Reset() { mEarlyOutFraction = TraitsType::InitialEarlyOutFraction; }
  45. /// When running a query through the NarrowPhaseQuery class, this will be called for every body that is potentially colliding.
  46. /// It allows collecting additional information needed by the collision collector implementation from the body under lock protection
  47. /// before AddHit is called (e.g. the user data pointer or the velocity of the body).
  48. virtual void OnBody(const Body &inBody) { /* Collects nothing by default */ }
  49. /// Set by the collision detection functions to the current TransformedShape that we're colliding against before calling the AddHit function
  50. void SetContext(const TransformedShape *inContext) { mContext = inContext; }
  51. const TransformedShape *GetContext() const { return mContext; }
  52. /// This function will be called for every hit found, it's up to the application to decide how to store the hit
  53. virtual void AddHit(const ResultType &inResult) = 0;
  54. /// Update the early out fraction (should be lower than before)
  55. inline void UpdateEarlyOutFraction(float inFraction) { JPH_ASSERT(inFraction <= mEarlyOutFraction); mEarlyOutFraction = inFraction; }
  56. /// Reset the early out fraction to a specific value
  57. inline void ResetEarlyOutFraction(float inFraction) { mEarlyOutFraction = inFraction; }
  58. /// Force the collision detection algorithm to terminate as soon as possible. Call this from the AddHit function when a satisfying hit is found.
  59. inline void ForceEarlyOut() { mEarlyOutFraction = TraitsType::ShouldEarlyOutFraction; }
  60. /// When true, the collector will no longer accept any additional hits and the collision detection routine should early out as soon as possible
  61. inline bool ShouldEarlyOut() const { return mEarlyOutFraction <= TraitsType::ShouldEarlyOutFraction; }
  62. /// Get the current early out value
  63. inline float GetEarlyOutFraction() const { return mEarlyOutFraction; }
  64. private:
  65. /// 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)
  66. float mEarlyOutFraction = TraitsType::InitialEarlyOutFraction;
  67. /// Set by the collision detection functions to the current TransformedShape of the body that we're colliding against before calling the AddHit function
  68. const TransformedShape *mContext = nullptr;
  69. };
  70. JPH_NAMESPACE_END