Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/PhysicsUpdateContext.h
9906 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
#include <Jolt/Physics/Body/BodyPair.h>
8
#include <Jolt/Physics/Collision/ContactListener.h>
9
#include <Jolt/Physics/Collision/BroadPhase/BroadPhase.h>
10
#include <Jolt/Core/StaticArray.h>
11
#include <Jolt/Core/JobSystem.h>
12
#include <Jolt/Core/STLTempAllocator.h>
13
14
JPH_NAMESPACE_BEGIN
15
16
class PhysicsSystem;
17
class IslandBuilder;
18
class Constraint;
19
class TempAllocator;
20
class SoftBodyUpdateContext;
21
22
/// Information used during the Update call
23
class PhysicsUpdateContext : public NonCopyable
24
{
25
public:
26
/// Destructor
27
explicit PhysicsUpdateContext(TempAllocator &inTempAllocator);
28
~PhysicsUpdateContext();
29
30
static constexpr int cMaxConcurrency = 32; ///< Maximum supported amount of concurrent jobs
31
32
using JobHandleArray = StaticArray<JobHandle, cMaxConcurrency>;
33
34
struct Step;
35
36
struct BodyPairQueue
37
{
38
atomic<uint32> mWriteIdx { 0 }; ///< Next index to write in mBodyPair array (need to add thread index * mMaxBodyPairsPerQueue and modulo mMaxBodyPairsPerQueue)
39
uint8 mPadding1[JPH_CACHE_LINE_SIZE - sizeof(atomic<uint32>)];///< Moved to own cache line to avoid conflicts with consumer jobs
40
41
atomic<uint32> mReadIdx { 0 }; ///< Next index to read in mBodyPair array (need to add thread index * mMaxBodyPairsPerQueue and modulo mMaxBodyPairsPerQueue)
42
uint8 mPadding2[JPH_CACHE_LINE_SIZE - sizeof(atomic<uint32>)];///< Moved to own cache line to avoid conflicts with producer/consumer jobs
43
};
44
45
using BodyPairQueues = StaticArray<BodyPairQueue, cMaxConcurrency>;
46
47
using JobMask = uint32; ///< A mask that has as many bits as we can have concurrent jobs
48
static_assert(sizeof(JobMask) * 8 >= cMaxConcurrency);
49
50
/// Structure that contains data needed for each collision step.
51
struct Step
52
{
53
Step() = default;
54
Step(const Step &) { JPH_ASSERT(false); } // vector needs a copy constructor, but we're never going to call it
55
56
PhysicsUpdateContext *mContext; ///< The physics update context
57
58
bool mIsFirst; ///< If this is the first step
59
bool mIsLast; ///< If this is the last step
60
61
BroadPhase::UpdateState mBroadPhaseUpdateState; ///< Handle returned by Broadphase::UpdatePrepare
62
63
uint32 mNumActiveBodiesAtStepStart; ///< Number of bodies that were active at the start of the physics update step. Only these bodies will receive gravity (they are the first N in the active body list).
64
65
atomic<uint32> mDetermineActiveConstraintReadIdx { 0 }; ///< Next constraint for determine active constraints
66
uint8 mPadding1[JPH_CACHE_LINE_SIZE - sizeof(atomic<uint32>)];///< Padding to avoid sharing cache line with the next atomic
67
68
atomic<uint32> mNumActiveConstraints { 0 }; ///< Number of constraints in the mActiveConstraints array
69
uint8 mPadding2[JPH_CACHE_LINE_SIZE - sizeof(atomic<uint32>)];///< Padding to avoid sharing cache line with the next atomic
70
71
atomic<uint32> mSetupVelocityConstraintsReadIdx { 0 }; ///< Next constraint for setting up velocity constraints
72
uint8 mPadding3[JPH_CACHE_LINE_SIZE - sizeof(atomic<uint32>)];///< Padding to avoid sharing cache line with the next atomic
73
74
atomic<uint32> mStepListenerReadIdx { 0 }; ///< Next step listener to call
75
uint8 mPadding4[JPH_CACHE_LINE_SIZE - sizeof(atomic<uint32>)];///< Padding to avoid sharing cache line with the next atomic
76
77
atomic<uint32> mApplyGravityReadIdx { 0 }; ///< Next body to apply gravity to
78
uint8 mPadding5[JPH_CACHE_LINE_SIZE - sizeof(atomic<uint32>)];///< Padding to avoid sharing cache line with the next atomic
79
80
atomic<uint32> mActiveBodyReadIdx { 0 }; ///< Index of fist active body that has not yet been processed by the broadphase
81
uint8 mPadding6[JPH_CACHE_LINE_SIZE - sizeof(atomic<uint32>)];///< Padding to avoid sharing cache line with the next atomic
82
83
BodyPairQueues mBodyPairQueues; ///< Queues in which to put body pairs that need to be tested by the narrowphase
84
85
uint32 mMaxBodyPairsPerQueue; ///< Amount of body pairs that we can queue per queue
86
87
atomic<JobMask> mActiveFindCollisionJobs; ///< A bitmask that indicates which jobs are still active
88
89
atomic<uint> mNumBodyPairs { 0 }; ///< The number of body pairs found in this step (used to size the contact cache in the next step)
90
atomic<uint> mNumManifolds { 0 }; ///< The number of manifolds found in this step (used to size the contact cache in the next step)
91
92
atomic<uint32> mSolveVelocityConstraintsNextIsland { 0 }; ///< Next island that needs to be processed for the solve velocity constraints step (doesn't need own cache line since position jobs don't run at same time)
93
atomic<uint32> mSolvePositionConstraintsNextIsland { 0 }; ///< Next island that needs to be processed for the solve position constraints step (doesn't need own cache line since velocity jobs don't run at same time)
94
95
/// Contains the information needed to cast a body through the scene to do continuous collision detection
96
struct CCDBody
97
{
98
CCDBody(BodyID inBodyID1, Vec3Arg inDeltaPosition, float inLinearCastThresholdSq, float inMaxPenetration) : mDeltaPosition(inDeltaPosition), mBodyID1(inBodyID1), mLinearCastThresholdSq(inLinearCastThresholdSq), mMaxPenetration(inMaxPenetration) { }
99
100
Vec3 mDeltaPosition; ///< Desired rotation step
101
Vec3 mContactNormal; ///< World space normal of closest hit (only valid if mFractionPlusSlop < 1)
102
RVec3 mContactPointOn2; ///< World space contact point on body 2 of closest hit (only valid if mFractionPlusSlop < 1)
103
BodyID mBodyID1; ///< Body 1 (the body that is performing collision detection)
104
BodyID mBodyID2; ///< Body 2 (the body of the closest hit, only valid if mFractionPlusSlop < 1)
105
SubShapeID mSubShapeID2; ///< Sub shape of body 2 that was hit (only valid if mFractionPlusSlop < 1)
106
float mFraction = 1.0f; ///< Fraction at which the hit occurred
107
float mFractionPlusSlop = 1.0f; ///< Fraction at which the hit occurred + extra delta to allow body to penetrate by mMaxPenetration
108
float mLinearCastThresholdSq; ///< Maximum allowed squared movement before doing a linear cast (determined by inner radius of shape)
109
float mMaxPenetration; ///< Maximum allowed penetration (determined by inner radius of shape)
110
ContactSettings mContactSettings; ///< The contact settings for this contact
111
};
112
atomic<uint32> mIntegrateVelocityReadIdx { 0 }; ///< Next active body index to take when integrating velocities
113
CCDBody * mCCDBodies = nullptr; ///< List of bodies that need to do continuous collision detection
114
uint32 mCCDBodiesCapacity = 0; ///< Capacity of the mCCDBodies list
115
atomic<uint32> mNumCCDBodies = 0; ///< Number of CCD bodies in mCCDBodies
116
atomic<uint32> mNextCCDBody { 0 }; ///< Next unprocessed body index in mCCDBodies
117
int * mActiveBodyToCCDBody = nullptr; ///< A mapping between an index in BodyManager::mActiveBodies and the index in mCCDBodies
118
uint32 mNumActiveBodyToCCDBody = 0; ///< Number of indices in mActiveBodyToCCDBody
119
120
// Jobs in order of execution (some run in parallel)
121
JobHandle mBroadPhasePrepare; ///< Prepares the new tree in the background
122
JobHandleArray mStepListeners; ///< Listeners to notify of the beginning of a physics step
123
JobHandleArray mDetermineActiveConstraints; ///< Determine which constraints will be active during this step
124
JobHandleArray mApplyGravity; ///< Update velocities of bodies with gravity
125
JobHandleArray mFindCollisions; ///< Find all collisions between active bodies an the world
126
JobHandle mUpdateBroadphaseFinalize; ///< Swap the newly built tree with the current tree
127
JobHandleArray mSetupVelocityConstraints; ///< Calculate properties for all constraints in the constraint manager
128
JobHandle mBuildIslandsFromConstraints; ///< Go over all constraints and assign the bodies they're attached to to an island
129
JobHandle mFinalizeIslands; ///< Finalize calculation simulation islands
130
JobHandle mBodySetIslandIndex; ///< Set the current island index on each body (not used by the simulation, only for drawing purposes)
131
JobHandleArray mSolveVelocityConstraints; ///< Solve the constraints in the velocity domain
132
JobHandle mPreIntegrateVelocity; ///< Setup integration of all body positions
133
JobHandleArray mIntegrateVelocity; ///< Integrate all body positions
134
JobHandle mPostIntegrateVelocity; ///< Finalize integration of all body positions
135
JobHandle mResolveCCDContacts; ///< Updates the positions and velocities for all bodies that need continuous collision detection
136
JobHandleArray mSolvePositionConstraints; ///< Solve all constraints in the position domain
137
JobHandle mContactRemovedCallbacks; ///< Calls the contact removed callbacks
138
JobHandle mSoftBodyPrepare; ///< Prepares updating the soft bodies
139
JobHandleArray mSoftBodyCollide; ///< Finds all colliding shapes for soft bodies
140
JobHandleArray mSoftBodySimulate; ///< Simulates all particles
141
JobHandle mSoftBodyFinalize; ///< Finalizes the soft body update
142
JobHandle mStartNextStep; ///< Job that kicks the next step (empty for the last step)
143
};
144
145
using Steps = Array<Step, STLTempAllocator<Step>>;
146
147
/// Maximum amount of concurrent jobs on this machine
148
int GetMaxConcurrency() const { const int max_concurrency = PhysicsUpdateContext::cMaxConcurrency; return min(max_concurrency, mJobSystem->GetMaxConcurrency()); } ///< Need to put max concurrency in temp var as min requires a reference
149
150
PhysicsSystem * mPhysicsSystem; ///< The physics system we belong to
151
TempAllocator * mTempAllocator; ///< Temporary allocator used during the update
152
JobSystem * mJobSystem; ///< Job system that processes jobs
153
JobSystem::Barrier * mBarrier; ///< Barrier used to wait for all physics jobs to complete
154
155
float mStepDeltaTime; ///< Delta time for a simulation step (collision step)
156
float mWarmStartImpulseRatio; ///< Ratio of this step delta time vs last step
157
atomic<uint32> mErrors { 0 }; ///< Errors that occurred during the update, actual type is EPhysicsUpdateError
158
159
Constraint ** mActiveConstraints = nullptr; ///< Constraints that were active at the start of the physics update step (activating bodies can activate constraints and we need a consistent snapshot). Only these constraints will be resolved.
160
161
BodyPair * mBodyPairs = nullptr; ///< A list of body pairs found by the broadphase
162
163
IslandBuilder * mIslandBuilder; ///< Keeps track of connected bodies and builds islands for multithreaded velocity/position update
164
165
Steps mSteps;
166
167
uint mNumSoftBodies; ///< Number of active soft bodies in the simulation
168
SoftBodyUpdateContext * mSoftBodyUpdateContexts = nullptr; ///< Contexts for updating soft bodies
169
atomic<uint> mSoftBodyToCollide { 0 }; ///< Next soft body to take when running SoftBodyCollide jobs
170
};
171
172
JPH_NAMESPACE_END
173
174