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
16struct PhysicsSettings;
17#ifdef JPH_DEBUG_RENDERER
18class DebugRenderer;
19class BodyDrawFilter;
20#endif // JPH_DEBUG_RENDERER
21
24
27
30{
31public:
33
36
38 void Init(uint inMaxBodies, uint inNumBodyMutexes, const BroadPhaseLayerInterface &inLayerInterface);
39
41 uint GetNumBodies() const;
42
44 uint GetMaxBodies() const { return (uint)mBodies.capacity(); }
45
47 struct BodyStats
48 {
51
53
56
59 };
60
62 BodyStats GetBodyStats() const;
63
65 Body * AllocateBody(const BodyCreationSettings &inBodyCreationSettings) const;
66
68 void FreeBody(Body *inBody) const;
69
71 bool AddBody(Body *ioBody);
72
74 bool AddBodyWithCustomID(Body *ioBody, const BodyID &inBodyID);
75
77 void RemoveBodies(const BodyID *inBodyIDs, int inNumber, Body **outBodies);
78
80 void DestroyBodies(const BodyID *inBodyIDs, int inNumber);
81
84 void ActivateBodies(const BodyID *inBodyIDs, int inNumber);
85
88 void DeactivateBodies(const BodyID *inBodyIDs, int inNumber);
89
91 void SetMotionQuality(Body &ioBody, EMotionQuality inMotionQuality);
92
94 void GetActiveBodies(BodyIDVector &outBodyIDs) const;
95
97 const BodyID * GetActiveBodiesUnsafe() const { return mActiveBodies; }
98
100 uint32 GetNumActiveBodies() const { return mNumActiveBodies; }
101
103 uint32 GetNumActiveCCDBodies() const { return mNumActiveCCDBodies; }
104
107 BodyActivationListener * GetBodyActivationListener() const { return mActivationListener; }
108
110 static inline bool sIsValidBodyPointer(const Body *inBody) { return (uintptr_t(inBody) & cIsFreedBody) == 0; }
111
113 const BodyVector & GetBodies() const { return mBodies; }
114
116 BodyVector & GetBodies() { return mBodies; }
117
119 void GetBodyIDs(BodyIDVector &outBodies) const;
120
122 const Body & GetBody(const BodyID &inID) const { return *mBodies[inID.GetIndex()]; }
123
125 Body & GetBody(const BodyID &inID) { return *mBodies[inID.GetIndex()]; }
126
128 const Body * TryGetBody(const BodyID &inID) const { const Body *body = mBodies[inID.GetIndex()]; return sIsValidBodyPointer(body) && body->GetID() == inID? body : nullptr; }
129
131 Body * TryGetBody(const BodyID &inID) { Body *body = mBodies[inID.GetIndex()]; return sIsValidBodyPointer(body) && body->GetID() == inID? body : nullptr; }
132
134 SharedMutex & GetMutexForBody(const BodyID &inID) const { return mBodyMutexes.GetMutexByObjectIndex(inID.GetIndex()); }
135
138
141 MutexMask GetAllBodiesMutexMask() const { return mBodyMutexes.GetNumMutexes() == sizeof(MutexMask) * 8? ~MutexMask(0) : (MutexMask(1) << mBodyMutexes.GetNumMutexes()) - 1; }
142 MutexMask GetMutexMask(const BodyID *inBodies, int inNumber) const;
143 void LockRead(MutexMask inMutexMask) const;
144 void UnlockRead(MutexMask inMutexMask) const;
145 void LockWrite(MutexMask inMutexMask) const;
146 void UnlockWrite(MutexMask inMutexMask) const;
148
150 void LockAllBodies() const;
151
153 void UnlockAllBodies() const;
154
156 inline void SetBodyObjectLayerInternal(Body &ioBody, ObjectLayer inLayer) const { ioBody.mObjectLayer = inLayer; ioBody.mBroadPhaseLayer = mBroadPhaseLayerInterface->GetBroadPhaseLayer(inLayer); }
157
160
163
165 void SaveState(StateRecorder &inStream) const;
166
168 bool RestoreState(StateRecorder &inStream);
169
170 enum class EShapeColor
171 {
175 SleepColor,
178 };
179
180#ifdef JPH_DEBUG_RENDERER
183 {
187 bool mDrawShape = true;
188 bool mDrawShapeWireframe = false;
190 bool mDrawBoundingBox = false;
192 bool mDrawWorldTransform = false;
193 bool mDrawVelocity = false;
194 bool mDrawMassAndInertia = false;
195 bool mDrawSleepStats = false;
196 };
197
199 void Draw(const DrawSettings &inSettings, const PhysicsSettings &inPhysicsSettings, DebugRenderer *inRenderer, const BodyDrawFilter *inBodyFilter = nullptr);
200#endif // JPH_DEBUG_RENDERER
201
202#ifdef JPH_ENABLE_ASSERTS
204 void SetActiveBodiesLocked(bool inLocked) { mActiveBodiesLocked = inLocked; }
205
207 class GrantActiveBodiesAccess
208 {
209 public:
210 inline GrantActiveBodiesAccess(bool inAllowActivation, bool inAllowDeactivation)
211 {
212 JPH_ASSERT(!sOverrideAllowActivation);
213 sOverrideAllowActivation = inAllowActivation;
214
215 JPH_ASSERT(!sOverrideAllowDeactivation);
216 sOverrideAllowDeactivation = inAllowDeactivation;
217 }
218
219 inline ~GrantActiveBodiesAccess()
220 {
221 sOverrideAllowActivation = false;
222 sOverrideAllowDeactivation = false;
223 }
224 };
225#endif
226
227#ifdef _DEBUG
229 void ValidateActiveBodyBounds();
230#endif // _DEBUG
231
232private:
234#ifdef JPH_COMPILER_CLANG
235 __attribute__((no_sanitize("implicit-conversion"))) // We intentionally overflow the uint8 sequence number
236#endif
237 inline uint8 GetNextSequenceNumber(int inBodyIndex) { return ++mBodySequenceNumbers[inBodyIndex]; }
238
240 JPH_INLINE Body * RemoveBodyInternal(const BodyID &inBodyID);
241
243 inline static void sDeleteBody(Body *inBody);
244
245#if defined(_DEBUG) && defined(JPH_ENABLE_ASSERTS)
247 void ValidateFreeList() const;
248#endif // defined(_DEBUG) && _defined(JPH_ENABLE_ASSERTS)
249
251 BodyVector mBodies;
252
254 uint mNumBodies = 0;
255
257 static constexpr uintptr_t cBodyIDFreeListEnd = ~uintptr_t(0);
258
260 static constexpr uintptr_t cIsFreedBody = uintptr_t(1);
261
263 static constexpr uint cFreedBodyIndexShift = 1;
264
266 uintptr_t mBodyIDFreeListStart = cBodyIDFreeListEnd;
267
269 mutable Mutex mBodiesMutex;
270
272 using BodyMutexes = MutexArray<SharedMutex>;
273 mutable BodyMutexes mBodyMutexes;
274
276 Array<uint8> mBodySequenceNumbers;
277
279 mutable Mutex mActiveBodiesMutex;
280
282 BodyID * mActiveBodies = nullptr;
283
285 atomic<uint32> mNumActiveBodies = 0;
286
288 uint32 mNumActiveCCDBodies = 0;
289
291 mutable Mutex mBodiesCacheInvalidMutex;
292
294 BodyIDVector mBodiesCacheInvalid;
295
297 BodyActivationListener * mActivationListener = nullptr;
298
300 const BroadPhaseLayerInterface *mBroadPhaseLayerInterface = nullptr;
301
302#ifdef JPH_ENABLE_ASSERTS
304 bool mActiveBodiesLocked = false;
305 static thread_local bool sOverrideAllowActivation;
306 static thread_local bool sOverrideAllowDeactivation;
307#endif
308};
309
Array< Body * > BodyVector
Array of bodies.
Definition: BodyManager.h:23
Array< BodyID > BodyIDVector
Array of body ID's.
Definition: BodyManager.h:26
uint32_t uint32
Definition: Core.h:312
unsigned int uint
Definition: Core.h:309
#define JPH_NAMESPACE_END
Definition: Core.h:240
uint8_t uint8
Definition: Core.h:310
uint64_t uint64
Definition: Core.h:313
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:234
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
#define JPH_OVERRIDE_NEW_DELETE
Macro to override the new and delete functions.
Definition: Memory.h:29
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
std::vector< T, STLAllocator< T > > Array
Definition: STLAllocator.h:81
Definition: BodyActivationListener.h:14
Settings for constructing a rigid body.
Definition: BodyCreationSettings.h:29
Class function to filter out bodies for debug rendering, returns true if body should be rendered.
Definition: BodyFilter.h:89
Definition: Body.h:33
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:43
Class that contains all bodies.
Definition: BodyManager.h:30
void LockWrite(MutexMask inMutexMask) const
Definition: BodyManager.cpp:583
void UnlockWrite(MutexMask inMutexMask) const
Definition: BodyManager.cpp:593
uint GetNumBodies() const
Gets the current amount of bodies that are in the body manager.
Definition: BodyManager.cpp:83
void RemoveBodies(const BodyID *inBodyIDs, int inNumber, Body **outBodies)
Remove a list of bodies from the body manager.
Definition: BodyManager.cpp:331
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:110
Body & GetBody(const BodyID &inID)
Access a body (not protected by lock)
Definition: BodyManager.h:125
void Init(uint inMaxBodies, uint inNumBodyMutexes, const BroadPhaseLayerInterface &inLayerInterface)
Initialize the manager.
Definition: BodyManager.cpp:59
void InvalidateContactCacheForBody(Body &ioBody)
Set the Body::EFlags::InvalidateContactCache flag for the specified body. This means that the collisi...
Definition: BodyManager.cpp:892
BodyActivationListener * GetBodyActivationListener() const
Definition: BodyManager.h:107
void UnlockRead(MutexMask inMutexMask) const
Definition: BodyManager.cpp:573
void LockAllBodies() const
Lock all bodies. This should only be done during PhysicsSystem::Update().
Definition: BodyManager.cpp:603
MutexMask GetMutexMask(const BodyID *inBodies, int inNumber) const
Definition: BodyManager.cpp:541
uint32 GetNumActiveCCDBodies() const
Get the number of active bodies that are using continuous collision detection.
Definition: BodyManager.h:103
MutexMask GetAllBodiesMutexMask() const
Definition: BodyManager.h:141
void ValidateContactCacheForAllBodies()
Reset the Body::EFlags::InvalidateContactCache flag for all bodies. All contact pairs in the contact ...
Definition: BodyManager.cpp:902
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:131
void UnlockAllBodies() const
Unlock all bodies. This should only be done during PhysicsSystem::Update().
Definition: BodyManager.cpp:611
void DestroyBodies(const BodyID *inBodyIDs, int inNumber)
Remove a set of bodies from the body manager and frees them.
Definition: BodyManager.cpp:364
void SetBodyActivationListener(BodyActivationListener *inListener)
Listener that is notified whenever a body is activated/deactivated.
Definition: BodyManager.cpp:534
SharedMutex & GetMutexForBody(const BodyID &inID) const
Access the mutex for a single body.
Definition: BodyManager.h:134
uint32 GetNumActiveBodies() const
Get the number of active bodies.
Definition: BodyManager.h:100
BodyStats GetBodyStats() const
Get stats about the bodies in the body manager (slow, iterates through all bodies)
Definition: BodyManager.cpp:90
void GetActiveBodies(BodyIDVector &outBodyIDs) const
Get copy of the list of active bodies under protection of a lock.
Definition: BodyManager.cpp:506
void SaveState(StateRecorder &inStream) const
Saving state for replay.
Definition: BodyManager.cpp:619
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:716
void GetBodyIDs(BodyIDVector &outBodies) const
Get all body IDs under the protection of a lock.
Definition: BodyManager.cpp:515
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:182
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:124
void LockRead(MutexMask inMutexMask) const
Definition: BodyManager.cpp:563
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:128
const BodyVector & GetBodies() const
Get all bodies. Note that this can contain invalid body pointers, call sIsValidBodyPointer to check.
Definition: BodyManager.h:113
const BodyID * GetActiveBodiesUnsafe() const
Get the list of active bodies. Note: Not thread safe. The active bodies list can change at any moment...
Definition: BodyManager.h:97
void DeactivateBodies(const BodyID *inBodyIDs, int inNumber)
Definition: BodyManager.cpp:429
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:175
BodyVector & GetBodies()
Get all bodies. Note that this can contain invalid body pointers, call sIsValidBodyPointer to check.
Definition: BodyManager.h:116
uint GetMaxBodies() const
Gets the max bodies that we can support.
Definition: BodyManager.h:44
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:227
EShapeColor
Definition: BodyManager.h:171
@ IslandColor
Static = grey, active = random color per island, sleeping = light grey.
@ InstanceColor
Random color per instance.
@ SleepColor
Static = grey, keyframed = green, dynamic = yellow, sleeping = red.
@ MotionTypeColor
Static = grey, keyframed = green, dynamic = random color per instance.
@ ShapeTypeColor
Convex = green, scaled = yellow, compound = orange, mesh = red.
@ MaterialColor
Color as defined by the PhysicsMaterial of the shape.
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:156
const Body & GetBody(const BodyID &inID) const
Access a body (not protected by lock)
Definition: BodyManager.h:122
void ActivateBodies(const BodyID *inBodyIDs, int inNumber)
Definition: BodyManager.cpp:390
uint64 MutexMask
Bodies are protected using an array of mutexes (so a fixed number, not 1 per body)....
Definition: BodyManager.h:137
void SetMotionQuality(Body &ioBody, EMotionQuality inMotionQuality)
Update the motion quality for a body.
Definition: BodyManager.cpp:486
bool RestoreState(StateRecorder &inStream)
Restoring state for replay. Returns false if failed.
Definition: BodyManager.cpp:656
JPH_OVERRIDE_NEW_DELETE ~BodyManager()
Destructor.
Definition: BodyManager.cpp:47
Interface that the application should implement to allow mapping object layers to broadphase layers.
Definition: BroadPhaseLayer.h:56
virtual BroadPhaseLayer GetBroadPhaseLayer(ObjectLayer inLayer) const =0
Convert an object layer to the corresponding broadphase layer.
Simple triangle renderer for debugging purposes.
Definition: DebugRenderer.h:25
Definition: MutexArray.h:17
MutexType & GetMutexByObjectIndex(uint32 inObjectIndex)
Get the mutex belonging to a certain object by index.
Definition: MutexArray.h:53
uint GetNumMutexes() const
Get the number of mutexes that were allocated.
Definition: MutexArray.h:40
Definition: Mutex.h:122
Class that makes another class non-copyable. Usage: Inherit from NonCopyable.
Definition: NonCopyable.h:11
Definition: Mutex.h:166
Definition: StateRecorder.h:15
Helper struct that counts the number of bodies of each type.
Definition: BodyManager.h:48
uint mNumBodiesStatic
Number of static bodies.
Definition: BodyManager.h:52
uint mNumBodiesDynamic
Number of dynamic bodies.
Definition: BodyManager.h:54
uint mNumActiveBodiesKinematic
Number of kinematic bodies that are currently active.
Definition: BodyManager.h:58
uint mNumActiveBodiesDynamic
Number of dynamic bodies that are currently active.
Definition: BodyManager.h:55
uint mNumBodies
Total number of bodies in the body manager.
Definition: BodyManager.h:49
uint mNumBodiesKinematic
Number of kinematic bodies.
Definition: BodyManager.h:57
uint mMaxBodies
Max allowed number of bodies in the body manager (as configured in Init(...))
Definition: BodyManager.h:50
Draw settings.
Definition: BodyManager.h:183
bool mDrawGetSupportFunction
Draw the GetSupport() function, used for convex collision detection.
Definition: BodyManager.h:184
bool mDrawWorldTransform
Draw the world transform (which can be different than the center of mass) for each body.
Definition: BodyManager.h:192
bool mDrawShapeWireframe
When mDrawShape is true and this is true, the shapes will be drawn in wireframe instead of solid.
Definition: BodyManager.h:188
bool mDrawGetSupportingFace
Draw the faces that were found colliding during collision detection.
Definition: BodyManager.h:186
EShapeColor mDrawShapeColor
Coloring scheme to use for shapes.
Definition: BodyManager.h:189
bool mDrawVelocity
Draw the velocity vector for each body.
Definition: BodyManager.h:193
bool mDrawMassAndInertia
Draw the mass and inertia (as the box equivalent) for each body.
Definition: BodyManager.h:194
bool mDrawSleepStats
Draw stats regarding the sleeping algorithm of each body.
Definition: BodyManager.h:195
bool mDrawCenterOfMassTransform
Draw the center of mass for each body.
Definition: BodyManager.h:191
bool mDrawShape
Draw the shapes of all bodies.
Definition: BodyManager.h:187
bool mDrawBoundingBox
Draw a bounding box per body.
Definition: BodyManager.h:190
bool mDrawSupportDirection
When drawing the support function, also draw which direction mapped to a specific support point.
Definition: BodyManager.h:185
Definition: PhysicsSettings.h:28