Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/PhysicsSystem.h
20969 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/BodyInterface.h>
8
#include <Jolt/Physics/Collision/NarrowPhaseQuery.h>
9
#include <Jolt/Physics/Collision/ContactListener.h>
10
#include <Jolt/Physics/Constraints/ContactConstraintManager.h>
11
#include <Jolt/Physics/Constraints/ConstraintManager.h>
12
#include <Jolt/Physics/IslandBuilder.h>
13
#include <Jolt/Physics/LargeIslandSplitter.h>
14
#include <Jolt/Physics/PhysicsUpdateContext.h>
15
#include <Jolt/Physics/PhysicsSettings.h>
16
17
JPH_NAMESPACE_BEGIN
18
19
class JobSystem;
20
class StateRecorder;
21
class TempAllocator;
22
class PhysicsStepListener;
23
class SoftBodyContactListener;
24
class SimShapeFilter;
25
26
/// The main class for the physics system. It contains all rigid bodies and simulates them.
27
///
28
/// The main simulation is performed by the Update() call on multiple threads (if the JobSystem is configured to use them). Please refer to the general architecture overview in the Docs folder for more information.
29
class JPH_EXPORT PhysicsSystem : public NonCopyable
30
{
31
public:
32
JPH_OVERRIDE_NEW_DELETE
33
34
/// Constructor / Destructor
35
PhysicsSystem() : mContactManager(mPhysicsSettings) JPH_IF_ENABLE_ASSERTS(, mConstraintManager(&mBodyManager)) { }
36
~PhysicsSystem();
37
38
/// The maximum value that can be passed to Init for inMaxBodies.
39
static constexpr uint cMaxBodiesLimit = BodyID::cMaxBodyIndex + 1;
40
41
/// The maximum value that can be passed to Init for inMaxBodyPairs.
42
/// Note you should really use a lower value, using this value will cost a lot of memory!
43
/// On a 32 bit platform, you'll run out of memory way before you reach this limit.
44
static constexpr uint cMaxBodyPairsLimit = ContactConstraintManager::cMaxBodyPairsLimit;
45
46
/// The maximum value that can be passed to Init for inMaxContactConstraints.
47
/// Note you should really use a lower value, using this value will cost a lot of memory!
48
/// On a 32 bit platform, you'll run out of memory way before you reach this limit.
49
static constexpr uint cMaxContactConstraintsLimit = ContactConstraintManager::cMaxContactConstraintsLimit;
50
51
/// Initialize the system.
52
/// @param inMaxBodies Maximum number of bodies to support.
53
/// @param inNumBodyMutexes Number of body mutexes to use. Should be a power of 2 in the range [1, 64], use 0 to auto detect.
54
/// @param inMaxBodyPairs Maximum amount of body pairs to process (anything else will fall through the world), this number should generally be much higher than the max amount of contact points as there will be lots of bodies close that are not actually touching.
55
/// @param inMaxContactConstraints Maximum amount of contact constraints to process (anything else will fall through the world).
56
/// @param inBroadPhaseLayerInterface Information on the mapping of object layers to broad phase layers. Since this is a virtual interface, the instance needs to stay alive during the lifetime of the PhysicsSystem.
57
/// @param inObjectVsBroadPhaseLayerFilter Filter callback function that is used to determine if an object layer collides with a broad phase layer. Since this is a virtual interface, the instance needs to stay alive during the lifetime of the PhysicsSystem.
58
/// @param inObjectLayerPairFilter Filter callback function that is used to determine if two object layers collide. Since this is a virtual interface, the instance needs to stay alive during the lifetime of the PhysicsSystem.
59
void Init(uint inMaxBodies, uint inNumBodyMutexes, uint inMaxBodyPairs, uint inMaxContactConstraints, const BroadPhaseLayerInterface &inBroadPhaseLayerInterface, const ObjectVsBroadPhaseLayerFilter &inObjectVsBroadPhaseLayerFilter, const ObjectLayerPairFilter &inObjectLayerPairFilter);
60
61
/// Listener that is notified whenever a body is activated/deactivated
62
void SetBodyActivationListener(BodyActivationListener *inListener) { mBodyManager.SetBodyActivationListener(inListener); }
63
BodyActivationListener * GetBodyActivationListener() const { return mBodyManager.GetBodyActivationListener(); }
64
65
/// Listener that is notified whenever a contact point between two bodies is added/updated/removed.
66
/// You can't change contact listener during PhysicsSystem::Update but it can be changed at any other time.
67
void SetContactListener(ContactListener *inListener) { mContactManager.SetContactListener(inListener); }
68
ContactListener * GetContactListener() const { return mContactManager.GetContactListener(); }
69
70
/// Listener that is notified whenever a contact point between a soft body and another body
71
void SetSoftBodyContactListener(SoftBodyContactListener *inListener) { mSoftBodyContactListener = inListener; }
72
SoftBodyContactListener * GetSoftBodyContactListener() const { return mSoftBodyContactListener; }
73
74
/// Set the function that combines the friction of two bodies and returns it
75
/// Default method is the geometric mean: sqrt(friction1 * friction2).
76
void SetCombineFriction(ContactConstraintManager::CombineFunction inCombineFriction) { mContactManager.SetCombineFriction(inCombineFriction); }
77
ContactConstraintManager::CombineFunction GetCombineFriction() const { return mContactManager.GetCombineFriction(); }
78
79
/// Set the function that combines the restitution of two bodies and returns it
80
/// Default method is max(restitution1, restitution1)
81
void SetCombineRestitution(ContactConstraintManager::CombineFunction inCombineRestitution) { mContactManager.SetCombineRestitution(inCombineRestitution); }
82
ContactConstraintManager::CombineFunction GetCombineRestitution() const { return mContactManager.GetCombineRestitution(); }
83
84
/// Set/get the shape filter that will be used during simulation. This can be used to exclude shapes within a body from colliding with each other.
85
/// E.g. if you have a high detail and a low detail collision model, you can attach them to the same body in a StaticCompoundShape and use the ShapeFilter
86
/// to exclude the high detail collision model when simulating and exclude the low detail collision model when casting rays. Note that in this case
87
/// you would need to pass the inverse of inShapeFilter to the CastRay function. Pass a nullptr to disable the shape filter.
88
/// The PhysicsSystem does not own the ShapeFilter, make sure it stays alive during the lifetime of the PhysicsSystem.
89
void SetSimShapeFilter(const SimShapeFilter *inShapeFilter) { mSimShapeFilter = inShapeFilter; }
90
const SimShapeFilter * GetSimShapeFilter() const { return mSimShapeFilter; }
91
92
/// Advanced use only: This function is similar to CollisionDispatch::sCollideShapeVsShape but only used to collide bodies during simulation.
93
/// inBody1 The first body to collide.
94
/// inBody2 The second body to collide.
95
/// inCenterOfMassTransform1 The center of mass transform of the first body (note this will not be the actual world space position of the body, it will be made relative to some position so we can drop down to single precision).
96
/// inCenterOfMassTransform2 The center of mass transform of the second body.
97
/// ioCollideShapeSettings Settings that control the collision detection. Note that the implementation can freely overwrite the shape settings if needed, the caller provides a temporary that will not be used after the function returns.
98
/// ioCollector The collector that will receive the contact points.
99
/// inShapeFilter The shape filter that can be used to exclude shapes from colliding with each other.
100
using SimCollideBodyVsBody = std::function<void(const Body &inBody1, const Body &inBody2, Mat44Arg inCenterOfMassTransform1, Mat44Arg inCenterOfMassTransform2, CollideShapeSettings &ioCollideShapeSettings, CollideShapeCollector &ioCollector, const ShapeFilter &inShapeFilter)>;
101
102
/// Advanced use only: Set the function that will be used to collide two bodies during simulation.
103
/// This function is expected to eventually call CollideShapeCollector::AddHit all contact points between the shapes of body 1 and 2 in their given transforms.
104
void SetSimCollideBodyVsBody(const SimCollideBodyVsBody &inBodyVsBody) { mSimCollideBodyVsBody = inBodyVsBody; }
105
const SimCollideBodyVsBody &GetSimCollideBodyVsBody() const { return mSimCollideBodyVsBody; }
106
107
/// Advanced use only: Default function that is used to collide two bodies during simulation.
108
static void sDefaultSimCollideBodyVsBody(const Body &inBody1, const Body &inBody2, Mat44Arg inCenterOfMassTransform1, Mat44Arg inCenterOfMassTransform2, CollideShapeSettings &ioCollideShapeSettings, CollideShapeCollector &ioCollector, const ShapeFilter &inShapeFilter);
109
110
/// Control the main constants of the physics simulation
111
void SetPhysicsSettings(const PhysicsSettings &inSettings) { mPhysicsSettings = inSettings; }
112
const PhysicsSettings & GetPhysicsSettings() const { return mPhysicsSettings; }
113
114
/// Access to the body interface. This interface allows to to create / remove bodies and to change their properties.
115
const BodyInterface & GetBodyInterface() const { return mBodyInterfaceLocking; }
116
BodyInterface & GetBodyInterface() { return mBodyInterfaceLocking; }
117
const BodyInterface & GetBodyInterfaceNoLock() const { return mBodyInterfaceNoLock; } ///< Version that does not lock the bodies, use with great care!
118
BodyInterface & GetBodyInterfaceNoLock() { return mBodyInterfaceNoLock; } ///< Version that does not lock the bodies, use with great care!
119
120
/// Access to the broadphase interface that allows coarse collision queries
121
const BroadPhaseQuery & GetBroadPhaseQuery() const { return *mBroadPhase; }
122
123
/// Interface that allows fine collision queries against first the broad phase and then the narrow phase.
124
const NarrowPhaseQuery & GetNarrowPhaseQuery() const { return mNarrowPhaseQueryLocking; }
125
const NarrowPhaseQuery & GetNarrowPhaseQueryNoLock() const { return mNarrowPhaseQueryNoLock; } ///< Version that does not lock the bodies, use with great care!
126
127
/// Add constraint to the world
128
void AddConstraint(Constraint *inConstraint) { mConstraintManager.Add(&inConstraint, 1); }
129
130
/// Remove constraint from the world
131
void RemoveConstraint(Constraint *inConstraint) { mConstraintManager.Remove(&inConstraint, 1); }
132
133
/// Batch add constraints.
134
void AddConstraints(Constraint **inConstraints, int inNumber) { mConstraintManager.Add(inConstraints, inNumber); }
135
136
/// Batch remove constraints.
137
void RemoveConstraints(Constraint **inConstraints, int inNumber) { mConstraintManager.Remove(inConstraints, inNumber); }
138
139
/// Get a list of all constraints
140
Constraints GetConstraints() const { return mConstraintManager.GetConstraints(); }
141
142
/// Optimize the broadphase, needed only if you've added many bodies prior to calling Update() for the first time.
143
/// Don't call this every frame as PhysicsSystem::Update spreads out the same work over multiple frames.
144
/// If you add many bodies through BodyInterface::AddBodiesPrepare/AddBodiesFinalize and if the bodies in a batch are
145
/// in a roughly unoccupied space (e.g. a new level section) then a call to OptimizeBroadPhase is also not needed
146
/// as batch adding creates an efficient bounding volume hierarchy.
147
/// Don't call this function while bodies are being modified from another thread or use the locking BodyInterface to modify bodies.
148
void OptimizeBroadPhase();
149
150
/// Adds a new step listener
151
void AddStepListener(PhysicsStepListener *inListener);
152
153
/// Removes a step listener
154
void RemoveStepListener(PhysicsStepListener *inListener);
155
156
/// Simulate the system.
157
/// The world steps for a total of inDeltaTime seconds. This is divided in inCollisionSteps iterations.
158
/// Each iteration consists of collision detection followed by an integration step.
159
/// This function internally spawns jobs using inJobSystem and waits for them to complete, so no jobs will be running when this function returns.
160
/// The temp allocator is used, for example, to store the list of bodies that are in contact, how they form islands together
161
/// and data to solve the contacts between bodies. At the end of the Update call, all allocated memory will have been freed.
162
EPhysicsUpdateError Update(float inDeltaTime, int inCollisionSteps, TempAllocator *inTempAllocator, JobSystem *inJobSystem);
163
164
/// Saving state for replay
165
void SaveState(StateRecorder &inStream, EStateRecorderState inState = EStateRecorderState::All, const StateRecorderFilter *inFilter = nullptr) const;
166
167
/// Restoring state for replay. Returns false if failed.
168
bool RestoreState(StateRecorder &inStream, const StateRecorderFilter *inFilter = nullptr);
169
170
/// Saving state of a single body.
171
void SaveBodyState(const Body &inBody, StateRecorder &inStream) const;
172
173
/// Restoring state of a single body.
174
void RestoreBodyState(Body &ioBody, StateRecorder &inStream);
175
176
#ifdef JPH_DEBUG_RENDERER
177
// Drawing properties
178
static bool sDrawMotionQualityLinearCast; ///< Draw debug info for objects that perform continuous collision detection through the linear cast motion quality
179
180
/// Draw the state of the bodies (debugging purposes)
181
void DrawBodies(const BodyManager::DrawSettings &inSettings, DebugRenderer *inRenderer, const BodyDrawFilter *inBodyFilter = nullptr) { mBodyManager.Draw(inSettings, mPhysicsSettings, inRenderer, inBodyFilter); }
182
183
/// Draw the constraints only (debugging purposes)
184
void DrawConstraints(DebugRenderer *inRenderer) { mConstraintManager.DrawConstraints(inRenderer); }
185
186
/// Draw the constraint limits only (debugging purposes)
187
void DrawConstraintLimits(DebugRenderer *inRenderer) { mConstraintManager.DrawConstraintLimits(inRenderer); }
188
189
/// Draw the constraint reference frames only (debugging purposes)
190
void DrawConstraintReferenceFrame(DebugRenderer *inRenderer) { mConstraintManager.DrawConstraintReferenceFrame(inRenderer); }
191
#endif // JPH_DEBUG_RENDERER
192
193
/// Set gravity value
194
void SetGravity(Vec3Arg inGravity) { mGravity = inGravity; }
195
Vec3 GetGravity() const { return mGravity; }
196
197
/// Returns a locking interface that won't actually lock the body. Use with great care!
198
inline const BodyLockInterfaceNoLock & GetBodyLockInterfaceNoLock() const { return mBodyLockInterfaceNoLock; }
199
200
/// Returns a locking interface that locks the body so other threads cannot modify it.
201
inline const BodyLockInterfaceLocking & GetBodyLockInterface() const { return mBodyLockInterfaceLocking; }
202
203
/// Broadphase layer filter that decides if two objects can collide, this was passed to the Init function.
204
const ObjectVsBroadPhaseLayerFilter &GetObjectVsBroadPhaseLayerFilter() const { return *mObjectVsBroadPhaseLayerFilter; }
205
206
/// Object layer filter that decides if two objects can collide, this was passed to the Init function.
207
const ObjectLayerPairFilter &GetObjectLayerPairFilter() const { return *mObjectLayerPairFilter; }
208
209
/// Get an broadphase layer filter that uses the default pair filter and a specified object layer to determine if broadphase layers collide
210
DefaultBroadPhaseLayerFilter GetDefaultBroadPhaseLayerFilter(ObjectLayer inLayer) const { return DefaultBroadPhaseLayerFilter(*mObjectVsBroadPhaseLayerFilter, inLayer); }
211
212
/// Get an object layer filter that uses the default pair filter and a specified layer to determine if layers collide
213
DefaultObjectLayerFilter GetDefaultLayerFilter(ObjectLayer inLayer) const { return DefaultObjectLayerFilter(*mObjectLayerPairFilter, inLayer); }
214
215
/// Gets the current amount of bodies that are in the body manager
216
uint GetNumBodies() const { return mBodyManager.GetNumBodies(); }
217
218
/// Gets the current amount of active bodies that are in the body manager
219
uint32 GetNumActiveBodies(EBodyType inType) const { return mBodyManager.GetNumActiveBodies(inType); }
220
221
/// Get the maximum amount of bodies that this physics system supports
222
uint GetMaxBodies() const { return mBodyManager.GetMaxBodies(); }
223
224
/// Helper struct that counts the number of bodies of each type
225
using BodyStats = BodyManager::BodyStats;
226
227
/// Get stats about the bodies in the body manager (slow, iterates through all bodies)
228
BodyStats GetBodyStats() const { return mBodyManager.GetBodyStats(); }
229
230
/// Get copy of the list of all bodies under protection of a lock.
231
/// @param outBodyIDs On return, this will contain the list of BodyIDs
232
void GetBodies(BodyIDVector &outBodyIDs) const { return mBodyManager.GetBodyIDs(outBodyIDs); }
233
234
/// Get copy of the list of active bodies under protection of a lock.
235
/// @param inType The type of bodies to get
236
/// @param outBodyIDs On return, this will contain the list of BodyIDs
237
void GetActiveBodies(EBodyType inType, BodyIDVector &outBodyIDs) const { return mBodyManager.GetActiveBodies(inType, outBodyIDs); }
238
239
/// Get the list of active bodies, use GetNumActiveBodies() to find out how long the list is.
240
/// Note: Not thread safe. The active bodies list can change at any moment when other threads are doing work. Use GetActiveBodies() if you need a thread safe version.
241
const BodyID * GetActiveBodiesUnsafe(EBodyType inType) const { return mBodyManager.GetActiveBodiesUnsafe(inType); }
242
243
/// Check if 2 bodies were in contact during the last simulation step. Since contacts are only detected between active bodies, so at least one of the bodies must be active in order for this function to work.
244
/// It queries the state at the time of the last PhysicsSystem::Update and will return true if the bodies were in contact, even if one of the bodies was moved / removed afterwards.
245
/// This function can be called from any thread when the PhysicsSystem::Update is not running. During PhysicsSystem::Update this function is only valid during contact callbacks:
246
/// - During the ContactListener::OnContactAdded callback this function can be used to determine if a different contact pair between the bodies was active in the previous simulation step (function returns true) or if this is the first step that the bodies are touching (function returns false).
247
/// - During the ContactListener::OnContactRemoved callback this function can be used to determine if this is the last contact pair between the bodies (function returns false) or if there are other contacts still present (function returns true).
248
bool WereBodiesInContact(const BodyID &inBody1ID, const BodyID &inBody2ID) const { return mContactManager.WereBodiesInContact(inBody1ID, inBody2ID); }
249
250
/// Get the bounding box of all bodies in the physics system
251
AABox GetBounds() const { return mBroadPhase->GetBounds(); }
252
253
#ifdef JPH_TRACK_BROADPHASE_STATS
254
/// Trace the accumulated broadphase stats to the TTY
255
void ReportBroadphaseStats() { mBroadPhase->ReportStats(); }
256
#endif // JPH_TRACK_BROADPHASE_STATS
257
258
private:
259
using CCDBody = PhysicsUpdateContext::Step::CCDBody;
260
261
// Various job entry points
262
void JobStepListeners(PhysicsUpdateContext::Step *ioStep);
263
void JobDetermineActiveConstraints(PhysicsUpdateContext::Step *ioStep) const;
264
void JobApplyGravity(const PhysicsUpdateContext *ioContext, PhysicsUpdateContext::Step *ioStep);
265
void JobSetupVelocityConstraints(float inDeltaTime, PhysicsUpdateContext::Step *ioStep) const;
266
void JobBuildIslandsFromConstraints(PhysicsUpdateContext *ioContext, PhysicsUpdateContext::Step *ioStep);
267
void JobFindCollisions(PhysicsUpdateContext::Step *ioStep, int inJobIndex);
268
void JobFinalizeIslands(PhysicsUpdateContext *ioContext);
269
void JobBodySetIslandIndex();
270
void JobSolveVelocityConstraints(PhysicsUpdateContext *ioContext, PhysicsUpdateContext::Step *ioStep);
271
void JobPreIntegrateVelocity(PhysicsUpdateContext *ioContext, PhysicsUpdateContext::Step *ioStep);
272
void JobIntegrateVelocity(const PhysicsUpdateContext *ioContext, PhysicsUpdateContext::Step *ioStep);
273
void JobPostIntegrateVelocity(PhysicsUpdateContext *ioContext, PhysicsUpdateContext::Step *ioStep) const;
274
void JobFindCCDContacts(const PhysicsUpdateContext *ioContext, PhysicsUpdateContext::Step *ioStep);
275
void JobResolveCCDContacts(PhysicsUpdateContext *ioContext, PhysicsUpdateContext::Step *ioStep);
276
void JobContactRemovedCallbacks(const PhysicsUpdateContext::Step *ioStep);
277
void JobSolvePositionConstraints(PhysicsUpdateContext *ioContext, PhysicsUpdateContext::Step *ioStep);
278
void JobSoftBodyPrepare(PhysicsUpdateContext *ioContext, PhysicsUpdateContext::Step *ioStep);
279
void JobSoftBodyCollide(PhysicsUpdateContext *ioContext) const;
280
void JobSoftBodySimulate(PhysicsUpdateContext *ioContext, uint inThreadIndex) const;
281
void JobSoftBodyFinalize(PhysicsUpdateContext *ioContext);
282
283
/// Tries to spawn a new FindCollisions job if max concurrency hasn't been reached yet
284
void TrySpawnJobFindCollisions(PhysicsUpdateContext::Step *ioStep) const;
285
286
using ContactAllocator = ContactConstraintManager::ContactAllocator;
287
288
/// Process narrow phase for a single body pair
289
void ProcessBodyPair(ContactAllocator &ioContactAllocator, const BodyPair &inBodyPair);
290
291
/// This helper batches up bodies that need to put to sleep to avoid contention on the activation mutex
292
class BodiesToSleep;
293
294
/// Called at the end of JobSolveVelocityConstraints to check if bodies need to go to sleep and to update their bounding box in the broadphase
295
void CheckSleepAndUpdateBounds(uint32 inIslandIndex, const PhysicsUpdateContext *ioContext, const PhysicsUpdateContext::Step *ioStep, BodiesToSleep &ioBodiesToSleep);
296
297
/// Number of constraints to process at once in JobDetermineActiveConstraints
298
static constexpr int cDetermineActiveConstraintsBatchSize = 64;
299
300
/// Number of constraints to process at once in JobSetupVelocityConstraints, we want a low number of threads working on this so we take fairly large batches
301
static constexpr int cSetupVelocityConstraintsBatchSize = 256;
302
303
/// Number of bodies to process at once in JobApplyGravity
304
static constexpr int cApplyGravityBatchSize = 64;
305
306
/// Number of active bodies to test for collisions per batch
307
static constexpr int cActiveBodiesBatchSize = 16;
308
309
/// Number of active bodies to integrate velocities for
310
static constexpr int cIntegrateVelocityBatchSize = 64;
311
312
/// Number of contacts that need to be queued before another narrow phase job is started
313
static constexpr int cNarrowPhaseBatchSize = 16;
314
315
/// Number of continuous collision shape casts that need to be queued before another job is started
316
static constexpr int cNumCCDBodiesPerJob = 4;
317
318
/// Broadphase layer filter that decides if two objects can collide
319
const ObjectVsBroadPhaseLayerFilter *mObjectVsBroadPhaseLayerFilter = nullptr;
320
321
/// Object layer filter that decides if two objects can collide
322
const ObjectLayerPairFilter *mObjectLayerPairFilter = nullptr;
323
324
/// The body manager keeps track which bodies are in the simulation
325
BodyManager mBodyManager;
326
327
/// Body locking interfaces
328
BodyLockInterfaceNoLock mBodyLockInterfaceNoLock { mBodyManager };
329
BodyLockInterfaceLocking mBodyLockInterfaceLocking { mBodyManager };
330
331
/// Body interfaces
332
BodyInterface mBodyInterfaceNoLock;
333
BodyInterface mBodyInterfaceLocking;
334
335
/// Narrow phase query interface
336
NarrowPhaseQuery mNarrowPhaseQueryNoLock;
337
NarrowPhaseQuery mNarrowPhaseQueryLocking;
338
339
/// The broadphase does quick collision detection between body pairs
340
BroadPhase * mBroadPhase = nullptr;
341
342
/// The soft body contact listener
343
SoftBodyContactListener * mSoftBodyContactListener = nullptr;
344
345
/// The shape filter that is used to filter out sub shapes during simulation
346
const SimShapeFilter * mSimShapeFilter = nullptr;
347
348
/// The collision function that is used to collide two shapes during simulation
349
SimCollideBodyVsBody mSimCollideBodyVsBody = &sDefaultSimCollideBodyVsBody;
350
351
/// Simulation settings
352
PhysicsSettings mPhysicsSettings;
353
354
/// The contact manager resolves all contacts during a simulation step
355
ContactConstraintManager mContactManager;
356
357
/// All non-contact constraints
358
ConstraintManager mConstraintManager;
359
360
/// Keeps track of connected bodies and builds islands for multithreaded velocity/position update
361
IslandBuilder mIslandBuilder;
362
363
/// Will split large islands into smaller groups of bodies that can be processed in parallel
364
LargeIslandSplitter mLargeIslandSplitter;
365
366
/// Mutex protecting mStepListeners
367
Mutex mStepListenersMutex;
368
369
/// List of physics step listeners
370
using StepListeners = Array<PhysicsStepListener *>;
371
StepListeners mStepListeners;
372
373
/// This is the global gravity vector
374
Vec3 mGravity = Vec3(0, -9.81f, 0);
375
376
/// Previous frame's delta time of one sub step to allow scaling previous frame's constraint impulses
377
float mPreviousStepDeltaTime = 0.0f;
378
};
379
380
JPH_NAMESPACE_END
381
382