Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Collision/CollisionCollector.h
9912 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56JPH_NAMESPACE_BEGIN78class Body;9class TransformedShape;1011/// Traits to use for CastRay12class CollisionCollectorTraitsCastRay13{14public:15/// For rays the early out fraction is the fraction along the line to order hits.16static constexpr float InitialEarlyOutFraction = 1.0f + FLT_EPSILON; ///< Furthest hit: Fraction is 1 + epsilon17static constexpr float ShouldEarlyOutFraction = 0.0f; ///< Closest hit: Fraction is 018};1920/// Traits to use for CastShape21class CollisionCollectorTraitsCastShape22{23public:24/// For rays the early out fraction is the fraction along the line to order hits.25static constexpr float InitialEarlyOutFraction = 1.0f + FLT_EPSILON; ///< Furthest hit: Fraction is 1 + epsilon26static constexpr float ShouldEarlyOutFraction = -FLT_MAX; ///< Deepest hit: Penetration is infinite27};2829/// Traits to use for CollideShape30class CollisionCollectorTraitsCollideShape31{32public:33/// For shape collisions we use -penetration depth to order hits.34static constexpr float InitialEarlyOutFraction = FLT_MAX; ///< Most shallow hit: Separation is infinite35static constexpr float ShouldEarlyOutFraction = -FLT_MAX; ///< Deepest hit: Penetration is infinite36};3738/// Traits to use for CollidePoint39using CollisionCollectorTraitsCollidePoint = CollisionCollectorTraitsCollideShape;4041/// Virtual interface that allows collecting multiple collision results42template <class ResultTypeArg, class TraitsType>43class CollisionCollector44{45public:46/// Declare ResultType so that derived classes can use it47using ResultType = ResultTypeArg;4849/// Default constructor50CollisionCollector() = default;5152/// Constructor to initialize from another collector53template <class ResultTypeArg2>54explicit CollisionCollector(const CollisionCollector<ResultTypeArg2, TraitsType> &inRHS) : mEarlyOutFraction(inRHS.GetEarlyOutFraction()), mContext(inRHS.GetContext()) { }55CollisionCollector(const CollisionCollector<ResultTypeArg, TraitsType> &inRHS) = default;5657/// Destructor58virtual ~CollisionCollector() = default;5960/// If you want to reuse this collector, call Reset()61virtual void Reset() { mEarlyOutFraction = TraitsType::InitialEarlyOutFraction; }6263/// When running a query through the NarrowPhaseQuery class, this will be called for every body that is potentially colliding.64/// It allows collecting additional information needed by the collision collector implementation from the body under lock protection65/// before AddHit is called (e.g. the user data pointer or the velocity of the body).66virtual void OnBody([[maybe_unused]] const Body &inBody) { /* Collects nothing by default */ }6768/// When running a query through the NarrowPhaseQuery class, this will be called after all AddHit calls have been made for a particular body.69virtual void OnBodyEnd() { /* Does nothing by default */ }7071/// Set by the collision detection functions to the current TransformedShape that we're colliding against before calling the AddHit function.72/// Note: Only valid during AddHit! For performance reasons, the pointer is not reset after leaving AddHit so the context may point to freed memory.73void SetContext(const TransformedShape *inContext) { mContext = inContext; }74const TransformedShape *GetContext() const { return mContext; }7576/// This function can be used to set some user data on the collision collector77virtual void SetUserData(uint64 inUserData) { /* Does nothing by default */ }7879/// This function will be called for every hit found, it's up to the application to decide how to store the hit80virtual void AddHit(const ResultType &inResult) = 0;8182/// Update the early out fraction (should be lower than before)83inline void UpdateEarlyOutFraction(float inFraction) { JPH_ASSERT(inFraction <= mEarlyOutFraction); mEarlyOutFraction = inFraction; }8485/// Reset the early out fraction to a specific value86inline void ResetEarlyOutFraction(float inFraction = TraitsType::InitialEarlyOutFraction) { mEarlyOutFraction = inFraction; }8788/// Force the collision detection algorithm to terminate as soon as possible. Call this from the AddHit function when a satisfying hit is found.89inline void ForceEarlyOut() { mEarlyOutFraction = TraitsType::ShouldEarlyOutFraction; }9091/// When true, the collector will no longer accept any additional hits and the collision detection routine should early out as soon as possible92inline bool ShouldEarlyOut() const { return mEarlyOutFraction <= TraitsType::ShouldEarlyOutFraction; }9394/// Get the current early out value95inline float GetEarlyOutFraction() const { return mEarlyOutFraction; }9697/// 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 penetration98inline float GetPositiveEarlyOutFraction() const { return max(FLT_MIN, mEarlyOutFraction); }99100private:101/// 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)102float mEarlyOutFraction = TraitsType::InitialEarlyOutFraction;103104/// Set by the collision detection functions to the current TransformedShape of the body that we're colliding against before calling the AddHit function105const TransformedShape *mContext = nullptr;106};107108JPH_NAMESPACE_END109110111