Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
BodyManager.h
Go to the documentation of this file.
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
8#include <Jolt/Core/Mutex.h>
10
12
13// Classes
18struct PhysicsSettings;
19#ifdef JPH_DEBUG_RENDERER
20class DebugRenderer;
21class BodyDrawFilter;
22#endif // JPH_DEBUG_RENDERER
23
24#ifdef JPH_DEBUG_RENDERER
25
33
34#endif // JPH_DEBUG_RENDERER
35
38
41
47{
48public:
50
53
55 void Init(uint inMaxBodies, uint inNumBodyMutexes, const BroadPhaseLayerInterface &inLayerInterface);
56
58 uint GetNumBodies() const;
59
61 uint GetMaxBodies() const { return uint(mBodies.capacity()); }
62
80
82 BodyStats GetBodyStats() const;
83
85 Body * AllocateBody(const BodyCreationSettings &inBodyCreationSettings) const;
86
88 Body * AllocateSoftBody(const SoftBodyCreationSettings &inSoftBodyCreationSettings) const;
89
91 void FreeBody(Body *inBody) const;
92
94 bool AddBody(Body *ioBody);
95
97 bool AddBodyWithCustomID(Body *ioBody, const BodyID &inBodyID);
98
100 void RemoveBodies(const BodyID *inBodyIDs, int inNumber, Body **outBodies);
101
103 void DestroyBodies(const BodyID *inBodyIDs, int inNumber);
104
107 void ActivateBodies(const BodyID *inBodyIDs, int inNumber);
108
111 void DeactivateBodies(const BodyID *inBodyIDs, int inNumber);
112
114 void SetMotionQuality(Body &ioBody, EMotionQuality inMotionQuality);
115
117 void GetActiveBodies(EBodyType inType, BodyIDVector &outBodyIDs) const;
118
120 const BodyID * GetActiveBodiesUnsafe(EBodyType inType) const { return mActiveBodies[int(inType)]; }
121
123 uint32 GetNumActiveBodies(EBodyType inType) const { return mNumActiveBodies[int(inType)].load(memory_order_acquire); }
124
126 uint32 GetNumActiveCCDBodies() const { return mNumActiveCCDBodies; }
127
129 void SetBodyActivationListener(BodyActivationListener *inListener);
130 BodyActivationListener * GetBodyActivationListener() const { return mActivationListener; }
131
133 static inline bool sIsValidBodyPointer(const Body *inBody) { return (uintptr_t(inBody) & cIsFreedBody) == 0; }
134
136 const BodyVector & GetBodies() const { return mBodies; }
137
139 BodyVector & GetBodies() { return mBodies; }
140
142 void GetBodyIDs(BodyIDVector &outBodies) const;
143
145 const Body & GetBody(const BodyID &inID) const { return *mBodies[inID.GetIndex()]; }
146
148 Body & GetBody(const BodyID &inID) { return *mBodies[inID.GetIndex()]; }
149
151 const Body * TryGetBody(const BodyID &inID) const
152 {
153 uint32 idx = inID.GetIndex();
154 if (idx >= mBodies.size())
155 return nullptr;
156
157 const Body *body = mBodies[idx];
158 if (sIsValidBodyPointer(body) && body->GetID() == inID)
159 return body;
160
161 return nullptr;
162 }
163
165 Body * TryGetBody(const BodyID &inID)
166 {
167 uint32 idx = inID.GetIndex();
168 if (idx >= mBodies.size())
169 return nullptr;
170
171 Body *body = mBodies[idx];
172 if (sIsValidBodyPointer(body) && body->GetID() == inID)
173 return body;
174
175 return nullptr;
176 }
177
179 SharedMutex & GetMutexForBody(const BodyID &inID) const { return mBodyMutexes.GetMutexByObjectIndex(inID.GetIndex()); }
180
183
186 MutexMask GetAllBodiesMutexMask() const { return mBodyMutexes.GetNumMutexes() == sizeof(MutexMask) * 8? ~MutexMask(0) : (MutexMask(1) << mBodyMutexes.GetNumMutexes()) - 1; }
187 MutexMask GetMutexMask(const BodyID *inBodies, int inNumber) const;
188 void LockRead(MutexMask inMutexMask) const;
189 void UnlockRead(MutexMask inMutexMask) const;
190 void LockWrite(MutexMask inMutexMask) const;
191 void UnlockWrite(MutexMask inMutexMask) const;
193
195 void LockAllBodies() const;
196
198 void UnlockAllBodies() const;
199
201 inline void SetBodyObjectLayerInternal(Body &ioBody, ObjectLayer inLayer) const { ioBody.mObjectLayer = inLayer; ioBody.mBroadPhaseLayer = mBroadPhaseLayerInterface->GetBroadPhaseLayer(inLayer); }
202
204 void InvalidateContactCacheForBody(Body &ioBody);
205
207 void ValidateContactCacheForAllBodies();
208
210 void SaveState(StateRecorder &inStream, const StateRecorderFilter *inFilter) const;
211
213 bool RestoreState(StateRecorder &inStream);
214
216 void SaveBodyState(const Body &inBody, StateRecorder &inStream) const;
217
219 void RestoreBodyState(Body &inBody, StateRecorder &inStream);
220
221#ifdef JPH_DEBUG_RENDERER
222 enum class EShapeColor
223 {
224 InstanceColor,
225 ShapeTypeColor,
226 MotionTypeColor,
227 SleepColor,
228 IslandColor,
229 MaterialColor,
230 };
231
270
272 void Draw(const DrawSettings &inSettings, const PhysicsSettings &inPhysicsSettings, DebugRenderer *inRenderer, const BodyDrawFilter *inBodyFilter = nullptr);
273#endif // JPH_DEBUG_RENDERER
274
275#ifdef JPH_ENABLE_ASSERTS
277 void SetActiveBodiesLocked(bool inLocked) { mActiveBodiesLocked = inLocked; }
278
280 class GrantActiveBodiesAccess
281 {
282 public:
283 inline GrantActiveBodiesAccess(bool inAllowActivation, bool inAllowDeactivation)
284 {
285 JPH_ASSERT(!sGetOverrideAllowActivation());
286 sSetOverrideAllowActivation(inAllowActivation);
287
288 JPH_ASSERT(!sGetOverrideAllowDeactivation());
289 sSetOverrideAllowDeactivation(inAllowDeactivation);
290 }
291
292 inline ~GrantActiveBodiesAccess()
293 {
294 sSetOverrideAllowActivation(false);
295 sSetOverrideAllowDeactivation(false);
296 }
297 };
298#endif
299
300#ifdef JPH_DEBUG
302 void ValidateActiveBodyBounds();
303#endif // JPH_DEBUG
304
305#ifdef JPH_TRACK_SIMULATION_STATS
307 void ResetSimulationStats();
308
309#ifdef JPH_PROFILE_ENABLED
311 void ReportSimulationStats();
312#endif
313#endif
314
315private:
317#ifdef JPH_COMPILER_CLANG
318 __attribute__((no_sanitize("implicit-conversion"))) // We intentionally overflow the uint8 sequence number
319#endif
320 inline uint8 GetNextSequenceNumber(int inBodyIndex) { return ++mBodySequenceNumbers[inBodyIndex]; }
321
323 inline void AddBodyToActiveBodies(Body &ioBody);
324
326 inline void RemoveBodyFromActiveBodies(Body &ioBody);
327
329 JPH_INLINE Body * RemoveBodyInternal(const BodyID &inBodyID);
330
332 inline static void sDeleteBody(Body *inBody);
333
334#if defined(JPH_DEBUG) && defined(JPH_ENABLE_ASSERTS)
336 void ValidateFreeList() const;
337#endif // defined(JPH_DEBUG) && _defined(JPH_ENABLE_ASSERTS)
338
340 BodyVector mBodies;
341
343 uint mNumBodies = 0;
344
346 static constexpr uintptr_t cBodyIDFreeListEnd = ~uintptr_t(0);
347
349 static constexpr uintptr_t cIsFreedBody = uintptr_t(1);
350
352 static constexpr uint cFreedBodyIndexShift = 1;
353
355 uintptr_t mBodyIDFreeListStart = cBodyIDFreeListEnd;
356
358 mutable Mutex mBodiesMutex;
359
361 using BodyMutexes = MutexArray<SharedMutex>;
362 mutable BodyMutexes mBodyMutexes;
363
365 Array<uint8> mBodySequenceNumbers;
366
368 mutable Mutex mActiveBodiesMutex;
369
371 BodyID * mActiveBodies[cBodyTypeCount] = { };
372
374 atomic<uint32> mNumActiveBodies[cBodyTypeCount] = { };
375
377 uint32 mNumActiveCCDBodies = 0;
378
380 mutable Mutex mBodiesCacheInvalidMutex;
381
383 BodyIDVector mBodiesCacheInvalid;
384
386 BodyActivationListener * mActivationListener = nullptr;
387
389 const BroadPhaseLayerInterface *mBroadPhaseLayerInterface = nullptr;
390
391#ifdef JPH_ENABLE_ASSERTS
392 static bool sGetOverrideAllowActivation();
393 static void sSetOverrideAllowActivation(bool inValue);
394
395 static bool sGetOverrideAllowDeactivation();
396 static void sSetOverrideAllowDeactivation(bool inValue);
397
399 bool mActiveBodiesLocked = false;
400#endif
401};
402
Array< Body * > BodyVector
Array of bodies.
Definition BodyManager.h:37
ESoftBodyConstraintColor
Defines how to color soft body constraints.
Definition BodyManager.h:28
@ ConstraintType
Definition BodyManager.h:29
@ ConstraintGroup
Draw different types of constraints in different colors.
Definition BodyManager.h:30
@ ConstraintOrder
Draw constraints in the same group in the same color, non-parallel group will be red.
Definition BodyManager.h:31
Array< BodyID > BodyIDVector
Array of body ID's.
Definition BodyManager.h:40
EBodyType
Type of body.
Definition BodyType.h:11
std::uint8_t uint8
Definition Core.h:501
#define JPH_EXPORT
Definition Core.h:275
std::uint64_t uint64
Definition Core.h:504
unsigned int uint
Definition Core.h:500
#define JPH_NAMESPACE_END
Definition Core.h:425
std::uint32_t uint32
Definition Core.h:503
#define JPH_NAMESPACE_BEGIN
Definition Core.h:419
#define JPH_ASSERT(...)
Definition IssueReporting.h:33
#define JPH_OVERRIDE_NEW_DELETE
Macro to override the new and delete functions.
Definition Memory.h:50
EMotionQuality
Motion quality, or how well it detects collisions when it has a high velocity.
Definition MotionQuality.h:11
uint16 ObjectLayer
Definition ObjectLayer.h:16
Definition Array.h:36
Definition BodyActivationListener.h:14
Settings for constructing a rigid body.
Definition BodyCreationSettings.h:31
Class function to filter out bodies for debug rendering, returns true if body should be rendered.
Definition BodyFilter.h:117
Definition Body.h:39
JPH_OVERRIDE_NEW_DELETE const BodyID & GetID() const
Get the id of this body.
Definition Body.h:44
ID of a body. This is a way of reasoning about bodies in a multithreaded simulation while avoiding ra...
Definition BodyID.h:13
uint32 GetIndex() const
Get index in body array.
Definition BodyID.h:44
Definition BodyManager.h:47
Body * AllocateSoftBody(const SoftBodyCreationSettings &inSoftBodyCreationSettings) const
Create a soft body using creation settings. The returned body will not be part of the body manager ye...
Definition BodyManager.cpp:246
uint GetNumBodies() const
Gets the current amount of bodies that are in the body manager.
Definition BodyManager.cpp:136
void RemoveBodies(const BodyID *inBodyIDs, int inNumber, Body **outBodies)
Remove a list of bodies from the body manager.
Definition BodyManager.cpp:438
static bool sIsValidBodyPointer(const Body *inBody)
Check if this is a valid body pointer. When a body is freed the memory that the pointer occupies is r...
Definition BodyManager.h:133
Body & GetBody(const BodyID &inID)
Access a body (not protected by lock).
Definition BodyManager.h:148
void Init(uint inMaxBodies, uint inNumBodyMutexes, const BroadPhaseLayerInterface &inLayerInterface)
Initialize the manager.
Definition BodyManager.cpp:106
BodyActivationListener * GetBodyActivationListener() const
Definition BodyManager.h:130
uint32 GetNumActiveCCDBodies() const
Get the number of active bodies that are using continuous collision detection.
Definition BodyManager.h:126
MutexMask GetAllBodiesMutexMask() const
Definition BodyManager.h:186
Body * TryGetBody(const BodyID &inID)
Access a body, will return a nullptr if the body ID is no longer valid (not protected by lock).
Definition BodyManager.h:165
void DestroyBodies(const BodyID *inBodyIDs, int inNumber)
Remove a set of bodies from the body manager and frees them.
Definition BodyManager.cpp:471
SharedMutex & GetMutexForBody(const BodyID &inID) const
Access the mutex for a single body.
Definition BodyManager.h:179
BodyStats GetBodyStats() const
Get stats about the bodies in the body manager (slow, iterates through all bodies).
Definition BodyManager.cpp:143
void Draw(const DrawSettings &inSettings, const PhysicsSettings &inPhysicsSettings, DebugRenderer *inRenderer, const BodyDrawFilter *inBodyFilter=nullptr)
Draw the state of the bodies (debugging purposes).
Definition BodyManager.cpp:916
bool AddBody(Body *ioBody)
Add a body to the body manager, assigning it the next available ID. Returns false if no more IDs are ...
Definition BodyManager.cpp:289
void GetActiveBodies(EBodyType inType, BodyIDVector &outBodyIDs) const
Get copy of the list of active bodies under protection of a lock.
Definition BodyManager.cpp:649
Body * AllocateBody(const BodyCreationSettings &inBodyCreationSettings) const
Create a body using creation settings. The returned body will not be part of the body manager yet.
Definition BodyManager.cpp:186
const Body * TryGetBody(const BodyID &inID) const
Access a body, will return a nullptr if the body ID is no longer valid (not protected by lock).
Definition BodyManager.h:151
const BodyID * GetActiveBodiesUnsafe(EBodyType inType) const
Get the list of active bodies. Note: Not thread safe. The active bodies list can change at any moment...
Definition BodyManager.h:120
const BodyVector & GetBodies() const
Get all bodies. Note that this can contain invalid body pointers, call sIsValidBodyPointer to check.
Definition BodyManager.h:136
void DeactivateBodies(const BodyID *inBodyIDs, int inNumber)
Definition BodyManager.cpp:585
void FreeBody(Body *inBody) const
Free a body that has not been added to the body manager yet (if it has, use DestroyBodies).
Definition BodyManager.cpp:282
BodyVector & GetBodies()
Get all bodies. Note that this can contain invalid body pointers, call sIsValidBodyPointer to check.
Definition BodyManager.h:139
uint GetMaxBodies() const
Gets the max bodies that we can support.
Definition BodyManager.h:61
bool AddBodyWithCustomID(Body *ioBody, const BodyID &inBodyID)
Add a body to the body manager, assigning it a custom ID. Returns false if the ID is not valid.
Definition BodyManager.cpp:334
EShapeColor
Definition BodyManager.h:223
@ MotionTypeColor
Static = grey, keyframed = green, dynamic = random color per instance.
Definition BodyManager.h:226
void SetBodyObjectLayerInternal(Body &ioBody, ObjectLayer inLayer) const
Function to update body's layer (should only be called by the BodyInterface since it also requires up...
Definition BodyManager.h:201
const Body & GetBody(const BodyID &inID) const
Access a body (not protected by lock).
Definition BodyManager.h:145
void ActivateBodies(const BodyID *inBodyIDs, int inNumber)
Definition BodyManager.cpp:548
uint64 MutexMask
Bodies are protected using an array of mutexes (so a fixed number, not 1 per body)....
Definition BodyManager.h:182
void SetMotionQuality(Body &ioBody, EMotionQuality inMotionQuality)
Update the motion quality for a body.
Definition BodyManager.cpp:629
uint32 GetNumActiveBodies(EBodyType inType) const
Get the number of active bodies.
Definition BodyManager.h:123
Interface that the application should implement to allow mapping object layers to broadphase layers.
Definition BroadPhaseLayer.h:61
Definition DebugRenderer.h:47
NonCopyable()=default
Definition Mutex.h:166
Definition SoftBodyCreationSettings.h:18
User callbacks that allow determining which parts of the simulation should be saved by a StateRecorde...
Definition StateRecorder.h:79
Definition StateRecorder.h:110
Helper struct that counts the number of bodies of each type.
Definition BodyManager.h:65
uint mNumBodiesStatic
Number of static bodies.
Definition BodyManager.h:69
uint mNumBodiesDynamic
Number of dynamic bodies.
Definition BodyManager.h:71
uint mNumActiveBodiesKinematic
Number of kinematic bodies that are currently active.
Definition BodyManager.h:75
uint mNumActiveBodiesDynamic
Number of dynamic bodies that are currently active.
Definition BodyManager.h:72
uint mNumBodies
Total number of bodies in the body manager.
Definition BodyManager.h:66
uint mNumBodiesKinematic
Number of kinematic bodies.
Definition BodyManager.h:74
uint mNumActiveSoftBodies
Number of soft bodies that are currently active.
Definition BodyManager.h:78
uint mNumSoftBodies
Number of soft bodies.
Definition BodyManager.h:77
uint mMaxBodies
Max allowed number of bodies in the body manager (as configured in Init(...)).
Definition BodyManager.h:67
Definition BodyManager.h:244
bool mDrawGetSupportFunction
Draw the GetSupport() function, used for convex collision detection.
Definition BodyManager.h:245
bool mDrawWorldTransform
Draw the world transform (which can be different than the center of mass) for each body.
Definition BodyManager.h:253
ESoftBodyConstraintColor mDrawSoftBodyConstraintColor
Coloring scheme to use for soft body constraints.
Definition BodyManager.h:268
bool mDrawShapeWireframe
When mDrawShape is true and this is true, the shapes will be drawn in wireframe instead of solid.
Definition BodyManager.h:249
bool mDrawSoftBodyRodStates
Draw the rod states (orientation and angular velocity) of soft bodies.
Definition BodyManager.h:265
bool mDrawGetSupportingFace
Draw the faces that were found colliding during collision detection.
Definition BodyManager.h:247
bool mDrawSoftBodyPredictedBounds
Draw the predicted bounds of soft bodies.
Definition BodyManager.h:267
bool mDrawSoftBodyVertices
Draw the vertices of soft bodies.
Definition BodyManager.h:257
EShapeColor mDrawShapeColor
Coloring scheme to use for shapes.
Definition BodyManager.h:250
bool mDrawSoftBodyVolumeConstraints
Draw the volume constraints of soft bodies.
Definition BodyManager.h:261
bool mDrawVelocity
Draw the velocity vector for each body.
Definition BodyManager.h:254
bool mDrawSoftBodyLRAConstraints
Draw the LRA constraints of soft bodies.
Definition BodyManager.h:263
bool mDrawSoftBodyRodBendTwistConstraints
Draw the rod bend twist constraints of soft bodies.
Definition BodyManager.h:266
bool mDrawMassAndInertia
Draw the mass and inertia (as the box equivalent) for each body.
Definition BodyManager.h:255
bool mDrawSoftBodyEdgeConstraints
Draw the edge constraints of soft bodies.
Definition BodyManager.h:259
bool mDrawSleepStats
Draw stats regarding the sleeping algorithm of each body.
Definition BodyManager.h:256
bool mDrawCenterOfMassTransform
Draw the center of mass for each body.
Definition BodyManager.h:252
bool mDrawSoftBodyRods
Draw the rods of soft bodies.
Definition BodyManager.h:264
bool mDrawSoftBodyBendConstraints
Draw the bend constraints of soft bodies.
Definition BodyManager.h:260
bool mDrawShape
Draw the shapes of all bodies.
Definition BodyManager.h:248
bool mDrawSoftBodyVertexVelocities
Draw the velocities of the vertices of soft bodies.
Definition BodyManager.h:258
bool mDrawBoundingBox
Draw a bounding box per body.
Definition BodyManager.h:251
bool mDrawSoftBodySkinConstraints
Draw the skin constraints of soft bodies.
Definition BodyManager.h:262
bool mDrawSupportDirection
When drawing the support function, also draw which direction mapped to a specific support point.
Definition BodyManager.h:246
Definition PhysicsSettings.h:28