Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Collision/CollisionCollector.h
9912 views
1
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3
// SPDX-License-Identifier: MIT
4
5
#pragma once
6
7
JPH_NAMESPACE_BEGIN
8
9
class Body;
10
class TransformedShape;
11
12
/// Traits to use for CastRay
13
class CollisionCollectorTraitsCastRay
14
{
15
public:
16
/// For rays the early out fraction is the fraction along the line to order hits.
17
static constexpr float InitialEarlyOutFraction = 1.0f + FLT_EPSILON; ///< Furthest hit: Fraction is 1 + epsilon
18
static constexpr float ShouldEarlyOutFraction = 0.0f; ///< Closest hit: Fraction is 0
19
};
20
21
/// Traits to use for CastShape
22
class CollisionCollectorTraitsCastShape
23
{
24
public:
25
/// For rays the early out fraction is the fraction along the line to order hits.
26
static constexpr float InitialEarlyOutFraction = 1.0f + FLT_EPSILON; ///< Furthest hit: Fraction is 1 + epsilon
27
static constexpr float ShouldEarlyOutFraction = -FLT_MAX; ///< Deepest hit: Penetration is infinite
28
};
29
30
/// Traits to use for CollideShape
31
class CollisionCollectorTraitsCollideShape
32
{
33
public:
34
/// For shape collisions we use -penetration depth to order hits.
35
static constexpr float InitialEarlyOutFraction = FLT_MAX; ///< Most shallow hit: Separation is infinite
36
static constexpr float ShouldEarlyOutFraction = -FLT_MAX; ///< Deepest hit: Penetration is infinite
37
};
38
39
/// Traits to use for CollidePoint
40
using CollisionCollectorTraitsCollidePoint = CollisionCollectorTraitsCollideShape;
41
42
/// Virtual interface that allows collecting multiple collision results
43
template <class ResultTypeArg, class TraitsType>
44
class CollisionCollector
45
{
46
public:
47
/// Declare ResultType so that derived classes can use it
48
using ResultType = ResultTypeArg;
49
50
/// Default constructor
51
CollisionCollector() = default;
52
53
/// Constructor to initialize from another collector
54
template <class ResultTypeArg2>
55
explicit CollisionCollector(const CollisionCollector<ResultTypeArg2, TraitsType> &inRHS) : mEarlyOutFraction(inRHS.GetEarlyOutFraction()), mContext(inRHS.GetContext()) { }
56
CollisionCollector(const CollisionCollector<ResultTypeArg, TraitsType> &inRHS) = default;
57
58
/// Destructor
59
virtual ~CollisionCollector() = default;
60
61
/// If you want to reuse this collector, call Reset()
62
virtual void Reset() { mEarlyOutFraction = TraitsType::InitialEarlyOutFraction; }
63
64
/// When running a query through the NarrowPhaseQuery class, this will be called for every body that is potentially colliding.
65
/// It allows collecting additional information needed by the collision collector implementation from the body under lock protection
66
/// before AddHit is called (e.g. the user data pointer or the velocity of the body).
67
virtual void OnBody([[maybe_unused]] const Body &inBody) { /* Collects nothing by default */ }
68
69
/// When running a query through the NarrowPhaseQuery class, this will be called after all AddHit calls have been made for a particular body.
70
virtual void OnBodyEnd() { /* Does nothing by default */ }
71
72
/// Set by the collision detection functions to the current TransformedShape that we're colliding against before calling the AddHit function.
73
/// Note: Only valid during AddHit! For performance reasons, the pointer is not reset after leaving AddHit so the context may point to freed memory.
74
void SetContext(const TransformedShape *inContext) { mContext = inContext; }
75
const TransformedShape *GetContext() const { return mContext; }
76
77
/// This function can be used to set some user data on the collision collector
78
virtual void SetUserData(uint64 inUserData) { /* Does nothing by default */ }
79
80
/// This function will be called for every hit found, it's up to the application to decide how to store the hit
81
virtual void AddHit(const ResultType &inResult) = 0;
82
83
/// Update the early out fraction (should be lower than before)
84
inline void UpdateEarlyOutFraction(float inFraction) { JPH_ASSERT(inFraction <= mEarlyOutFraction); mEarlyOutFraction = inFraction; }
85
86
/// Reset the early out fraction to a specific value
87
inline void ResetEarlyOutFraction(float inFraction = TraitsType::InitialEarlyOutFraction) { mEarlyOutFraction = inFraction; }
88
89
/// Force the collision detection algorithm to terminate as soon as possible. Call this from the AddHit function when a satisfying hit is found.
90
inline void ForceEarlyOut() { mEarlyOutFraction = TraitsType::ShouldEarlyOutFraction; }
91
92
/// When true, the collector will no longer accept any additional hits and the collision detection routine should early out as soon as possible
93
inline bool ShouldEarlyOut() const { return mEarlyOutFraction <= TraitsType::ShouldEarlyOutFraction; }
94
95
/// Get the current early out value
96
inline float GetEarlyOutFraction() const { return mEarlyOutFraction; }
97
98
/// 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
99
inline float GetPositiveEarlyOutFraction() const { return max(FLT_MIN, mEarlyOutFraction); }
100
101
private:
102
/// 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)
103
float mEarlyOutFraction = TraitsType::InitialEarlyOutFraction;
104
105
/// Set by the collision detection functions to the current TransformedShape of the body that we're colliding against before calling the AddHit function
106
const TransformedShape *mContext = nullptr;
107
};
108
109
JPH_NAMESPACE_END
110
111