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
64 struct BodyStats
65 {
66 uint mNumBodies = 0;
67 uint mMaxBodies = 0;
68
69 uint mNumBodiesStatic = 0;
70
71 uint mNumBodiesDynamic = 0;
72 uint mNumActiveBodiesDynamic = 0;
73
74 uint mNumBodiesKinematic = 0;
75 uint mNumActiveBodiesKinematic = 0;
76
77 uint mNumSoftBodies = 0;
78 uint mNumActiveSoftBodies = 0;
79 };
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
234 {
235 bool mDrawGetSupportFunction = false;
236 bool mDrawSupportDirection = false;
237 bool mDrawGetSupportingFace = false;
238 bool mDrawShape = true;
239 bool mDrawShapeWireframe = false;
240 EShapeColor mDrawShapeColor = EShapeColor::MotionTypeColor;
241 bool mDrawBoundingBox = false;
242 bool mDrawCenterOfMassTransform = false;
243 bool mDrawWorldTransform = false;
244 bool mDrawVelocity = false;
245 bool mDrawMassAndInertia = false;
246 bool mDrawSleepStats = false;
247 bool mDrawSoftBodyVertices = false;
248 bool mDrawSoftBodyVertexVelocities = false;
249 bool mDrawSoftBodyEdgeConstraints = false;
250 bool mDrawSoftBodyBendConstraints = false;
251 bool mDrawSoftBodyVolumeConstraints = false;
252 bool mDrawSoftBodySkinConstraints = false;
253 bool mDrawSoftBodyLRAConstraints = false;
254 bool mDrawSoftBodyRods = false;
255 bool mDrawSoftBodyRodStates = false;
256 bool mDrawSoftBodyRodBendTwistConstraints = false;
257 bool mDrawSoftBodyPredictedBounds = false;
259 };
260
262 void Draw(const DrawSettings &inSettings, const PhysicsSettings &inPhysicsSettings, DebugRenderer *inRenderer, const BodyDrawFilter *inBodyFilter = nullptr);
263#endif // JPH_DEBUG_RENDERER
264
265#ifdef JPH_ENABLE_ASSERTS
267 void SetActiveBodiesLocked(bool inLocked) { mActiveBodiesLocked = inLocked; }
268
270 class GrantActiveBodiesAccess
271 {
272 public:
273 inline GrantActiveBodiesAccess(bool inAllowActivation, bool inAllowDeactivation)
274 {
275 JPH_ASSERT(!sGetOverrideAllowActivation());
276 sSetOverrideAllowActivation(inAllowActivation);
277
278 JPH_ASSERT(!sGetOverrideAllowDeactivation());
279 sSetOverrideAllowDeactivation(inAllowDeactivation);
280 }
281
282 inline ~GrantActiveBodiesAccess()
283 {
284 sSetOverrideAllowActivation(false);
285 sSetOverrideAllowDeactivation(false);
286 }
287 };
288#endif
289
290#ifdef JPH_DEBUG
292 void ValidateActiveBodyBounds();
293#endif // JPH_DEBUG
294
295#ifdef JPH_TRACK_SIMULATION_STATS
297 void ResetSimulationStats();
298
299#ifdef JPH_PROFILE_ENABLED
301 void ReportSimulationStats();
302#endif
303#endif
304
305private:
307#ifdef JPH_COMPILER_CLANG
308 __attribute__((no_sanitize("implicit-conversion"))) // We intentionally overflow the uint8 sequence number
309#endif
310 inline uint8 GetNextSequenceNumber(int inBodyIndex) { return ++mBodySequenceNumbers[inBodyIndex]; }
311
313 inline void AddBodyToActiveBodies(Body &ioBody);
314
316 inline void RemoveBodyFromActiveBodies(Body &ioBody);
317
319 JPH_INLINE Body * RemoveBodyInternal(const BodyID &inBodyID);
320
322 inline static void sDeleteBody(Body *inBody);
323
324#if defined(JPH_DEBUG) && defined(JPH_ENABLE_ASSERTS)
326 void ValidateFreeList() const;
327#endif // defined(JPH_DEBUG) && _defined(JPH_ENABLE_ASSERTS)
328
330 BodyVector mBodies;
331
333 uint mNumBodies = 0;
334
336 static constexpr uintptr_t cBodyIDFreeListEnd = ~uintptr_t(0);
337
339 static constexpr uintptr_t cIsFreedBody = uintptr_t(1);
340
342 static constexpr uint cFreedBodyIndexShift = 1;
343
345 uintptr_t mBodyIDFreeListStart = cBodyIDFreeListEnd;
346
348 mutable Mutex mBodiesMutex;
349
351 using BodyMutexes = MutexArray<SharedMutex>;
352 mutable BodyMutexes mBodyMutexes;
353
355 Array<uint8> mBodySequenceNumbers;
356
358 mutable Mutex mActiveBodiesMutex;
359
361 BodyID * mActiveBodies[cBodyTypeCount] = { };
362
364 atomic<uint32> mNumActiveBodies[cBodyTypeCount] = { };
365
367 uint32 mNumActiveCCDBodies = 0;
368
370 mutable Mutex mBodiesCacheInvalidMutex;
371
373 BodyIDVector mBodiesCacheInvalid;
374
376 BodyActivationListener * mActivationListener = nullptr;
377
379 const BroadPhaseLayerInterface *mBroadPhaseLayerInterface = nullptr;
380
381#ifdef JPH_ENABLE_ASSERTS
382 static bool sGetOverrideAllowActivation();
383 static void sSetOverrideAllowActivation(bool inValue);
384
385 static bool sGetOverrideAllowDeactivation();
386 static void sSetOverrideAllowDeactivation(bool inValue);
387
389 bool mActiveBodiesLocked = false;
390#endif
391};
392
ESoftBodyConstraintColor
Defines how to color soft body constraints.
Definition BodyManager.h:28
@ ConstraintGroup
Draw different types of constraints in different colors.
@ ConstraintOrder
Draw constraints in the same group in the same color, non-parallel group will be red.
EBodyType
Type of body.
Definition BodyType.h:11
std::uint8_t uint8
Definition Core.h:493
#define JPH_EXPORT
Definition Core.h:275
std::uint64_t uint64
Definition Core.h:496
unsigned int uint
Definition Core.h:492
#define JPH_NAMESPACE_END
Definition Core.h:419
std::uint32_t uint32
Definition Core.h:495
#define JPH_NAMESPACE_BEGIN
Definition Core.h:413
#define JPH_ASSERT(...)
Definition IssueReporting.h:33
#define JPH_OVERRIDE_NEW_DELETE
Macro to override the new and delete functions.
Definition Memory.h:43
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 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
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
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
SharedMutex & GetMutexForBody(const BodyID &inID) const
Access the mutex for a single body.
Definition BodyManager.h:179
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
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
EShapeColor
Definition BodyManager.h:223
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
uint64 MutexMask
Bodies are protected using an array of mutexes (so a fixed number, not 1 per body)....
Definition BodyManager.h:182
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
Definition MutexArray.h:17
Definition Mutex.h:122
Class that makes another class non-copyable. Usage: Inherit from NonCopyable.
Definition NonCopyable.h:11
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
Draw settings.
Definition BodyManager.h:234
Definition PhysicsSettings.h:28