Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
Body.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
18
20
21class StateRecorder;
23
32class alignas(JPH_RVECTOR_ALIGNMENT) Body : public NonCopyable
33{
34public:
36
38 Body() = default;
39
41 ~Body() { JPH_ASSERT(mMotionProperties == nullptr); }
42
44 inline const BodyID & GetID() const { return mID; }
45
47 inline bool IsActive() const { return mMotionProperties != nullptr && mMotionProperties->mIndexInActiveBodies != cInactiveIndex; }
48
50 inline bool IsStatic() const { return mMotionType == EMotionType::Static; }
51
53 inline bool IsKinematic() const { return mMotionType == EMotionType::Kinematic; }
54
56 inline bool IsDynamic() const { return mMotionType == EMotionType::Dynamic; }
57
59 inline bool CanBeKinematicOrDynamic() const { return mMotionProperties != nullptr; }
60
66 inline void SetIsSensor(bool inIsSensor) { if (inIsSensor) mFlags.fetch_or(uint8(EFlags::IsSensor), memory_order_relaxed); else mFlags.fetch_and(uint8(~uint8(EFlags::IsSensor)), memory_order_relaxed); }
67
69 inline bool IsSensor() const { return (mFlags.load(memory_order_relaxed) & uint8(EFlags::IsSensor)) != 0; }
70
73 inline void SetUseManifoldReduction(bool inUseReduction) { if (inUseReduction) mFlags.fetch_or(uint8(EFlags::UseManifoldReduction), memory_order_relaxed); else mFlags.fetch_and(uint8(~uint8(EFlags::UseManifoldReduction)), memory_order_relaxed); }
74
76 inline bool GetUseManifoldReduction() const { return (mFlags.load(memory_order_relaxed) & uint8(EFlags::UseManifoldReduction)) != 0; }
77
79 inline bool GetUseManifoldReductionWithBody(const Body &inBody2) const { return ((mFlags.load(memory_order_relaxed) & inBody2.mFlags.load(memory_order_relaxed)) & uint8(EFlags::UseManifoldReduction)) != 0; }
80
82 inline EMotionType GetMotionType() const { return mMotionType; }
83 void SetMotionType(EMotionType inMotionType);
84
86 inline BroadPhaseLayer GetBroadPhaseLayer() const { return mBroadPhaseLayer; }
87
89 inline ObjectLayer GetObjectLayer() const { return mObjectLayer; }
90
92 const CollisionGroup & GetCollisionGroup() const { return mCollisionGroup; }
93 CollisionGroup & GetCollisionGroup() { return mCollisionGroup; }
94 void SetCollisionGroup(const CollisionGroup &inGroup) { mCollisionGroup = inGroup; }
95
97 bool GetAllowSleeping() const { return mMotionProperties->mAllowSleeping; }
98 void SetAllowSleeping(bool inAllow);
99
101 inline float GetFriction() const { return mFriction; }
102 void SetFriction(float inFriction) { JPH_ASSERT(inFriction >= 0.0f); mFriction = inFriction; }
103
105 inline float GetRestitution() const { return mRestitution; }
106 void SetRestitution(float inRestitution) { JPH_ASSERT(inRestitution >= 0.0f && inRestitution <= 1.0f); mRestitution = inRestitution; }
107
109 inline Vec3 GetLinearVelocity() const { return !IsStatic()? mMotionProperties->GetLinearVelocity() : Vec3::sZero(); }
110
112 void SetLinearVelocity(Vec3Arg inLinearVelocity) { JPH_ASSERT(!IsStatic()); mMotionProperties->SetLinearVelocity(inLinearVelocity); }
113
115 void SetLinearVelocityClamped(Vec3Arg inLinearVelocity) { JPH_ASSERT(!IsStatic()); mMotionProperties->SetLinearVelocityClamped(inLinearVelocity); }
116
118 inline Vec3 GetAngularVelocity() const { return !IsStatic()? mMotionProperties->GetAngularVelocity() : Vec3::sZero(); }
119
121 void SetAngularVelocity(Vec3Arg inAngularVelocity) { JPH_ASSERT(!IsStatic()); mMotionProperties->SetAngularVelocity(inAngularVelocity); }
122
124 void SetAngularVelocityClamped(Vec3Arg inAngularVelocity) { JPH_ASSERT(!IsStatic()); mMotionProperties->SetAngularVelocityClamped(inAngularVelocity); }
125
127 inline Vec3 GetPointVelocityCOM(Vec3Arg inPointRelativeToCOM) const { return !IsStatic()? mMotionProperties->GetPointVelocityCOM(inPointRelativeToCOM) : Vec3::sZero(); }
128
130 inline Vec3 GetPointVelocity(RVec3Arg inPoint) const { JPH_ASSERT(BodyAccess::sCheckRights(BodyAccess::sPositionAccess, BodyAccess::EAccess::Read)); return GetPointVelocityCOM(Vec3(inPoint - mPosition)); }
131
133 inline void AddForce(Vec3Arg inForce) { JPH_ASSERT(IsDynamic()); (Vec3::sLoadFloat3Unsafe(mMotionProperties->mForce) + inForce).StoreFloat3(&mMotionProperties->mForce); }
134
136 inline void AddForce(Vec3Arg inForce, RVec3Arg inPosition);
137
139 inline void AddTorque(Vec3Arg inTorque) { JPH_ASSERT(IsDynamic()); (Vec3::sLoadFloat3Unsafe(mMotionProperties->mTorque) + inTorque).StoreFloat3(&mMotionProperties->mTorque); }
140
141 // Get the total amount of force applied to the center of mass this time step (through AddForce calls). Note that it will reset to zero after PhysicsSimulation::Update.
142 inline Vec3 GetAccumulatedForce() const { JPH_ASSERT(IsDynamic()); return mMotionProperties->GetAccumulatedForce(); }
143
144 // Get the total amount of torque applied to the center of mass this time step (through AddForce/AddTorque calls). Note that it will reset to zero after PhysicsSimulation::Update.
145 inline Vec3 GetAccumulatedTorque() const { JPH_ASSERT(IsDynamic()); return mMotionProperties->GetAccumulatedTorque(); }
146
148 inline Mat44 GetInverseInertia() const;
149
151 inline void AddImpulse(Vec3Arg inImpulse);
152
154 inline void AddImpulse(Vec3Arg inImpulse, RVec3Arg inPosition);
155
157 inline void AddAngularImpulse(Vec3Arg inAngularImpulse);
158
160 void MoveKinematic(RVec3Arg inTargetPosition, QuatArg inTargetRotation, float inDeltaTime);
161
172 bool ApplyBuoyancyImpulse(RVec3Arg inSurfacePosition, Vec3Arg inSurfaceNormal, float inBuoyancy, float inLinearDrag, float inAngularDrag, Vec3Arg inFluidVelocity, Vec3Arg inGravity, float inDeltaTime);
173
175 inline bool IsInBroadPhase() const { return (mFlags.load(memory_order_relaxed) & uint8(EFlags::IsInBroadPhase)) != 0; }
176
178 inline bool IsCollisionCacheInvalid() const { return (mFlags.load(memory_order_relaxed) & uint8(EFlags::InvalidateContactCache)) != 0; }
179
181 inline const Shape * GetShape() const { return mShape; }
182
184 inline RVec3 GetPosition() const { JPH_ASSERT(BodyAccess::sCheckRights(BodyAccess::sPositionAccess, BodyAccess::EAccess::Read)); return mPosition - mRotation * mShape->GetCenterOfMass(); }
185
187 inline Quat GetRotation() const { JPH_ASSERT(BodyAccess::sCheckRights(BodyAccess::sPositionAccess, BodyAccess::EAccess::Read)); return mRotation; }
188
190 inline RMat44 GetWorldTransform() const;
191
193 inline RVec3 GetCenterOfMassPosition() const { JPH_ASSERT(BodyAccess::sCheckRights(BodyAccess::sPositionAccess, BodyAccess::EAccess::Read)); return mPosition; }
194
196 inline RMat44 GetCenterOfMassTransform() const;
197
199 inline RMat44 GetInverseCenterOfMassTransform() const;
200
202 inline const AABox & GetWorldSpaceBounds() const { return mBounds; }
203
205 const MotionProperties *GetMotionProperties() const { JPH_ASSERT(!IsStatic()); return mMotionProperties; }
206 MotionProperties * GetMotionProperties() { JPH_ASSERT(!IsStatic()); return mMotionProperties; }
207
209 const MotionProperties *GetMotionPropertiesUnchecked() const { return mMotionProperties; }
210 MotionProperties * GetMotionPropertiesUnchecked() { return mMotionProperties; }
211
213 uint64 GetUserData() const { return mUserData; }
214 void SetUserData(uint64 inUserData) { mUserData = inUserData; }
215
217 inline Vec3 GetWorldSpaceSurfaceNormal(const SubShapeID &inSubShapeID, RVec3Arg inPosition) const;
218
220 inline TransformedShape GetTransformedShape() const { JPH_ASSERT(BodyAccess::sCheckRights(BodyAccess::sPositionAccess, BodyAccess::EAccess::Read)); return TransformedShape(mPosition, mRotation, mShape, mID); }
221
223 BodyCreationSettings GetBodyCreationSettings() const;
224
227
230
233 static inline bool sFindCollidingPairsCanCollide(const Body &inBody1, const Body &inBody2);
234
236 inline void AddPositionStep(Vec3Arg inLinearVelocityTimesDeltaTime) { JPH_ASSERT(BodyAccess::sCheckRights(BodyAccess::sPositionAccess, BodyAccess::EAccess::ReadWrite)); mPosition += inLinearVelocityTimesDeltaTime; JPH_ASSERT(!mPosition.IsNaN()); }
237 inline void SubPositionStep(Vec3Arg inLinearVelocityTimesDeltaTime) { JPH_ASSERT(BodyAccess::sCheckRights(BodyAccess::sPositionAccess, BodyAccess::EAccess::ReadWrite)); mPosition -= inLinearVelocityTimesDeltaTime; JPH_ASSERT(!mPosition.IsNaN()); }
238
240 inline void AddRotationStep(Vec3Arg inAngularVelocityTimesDeltaTime);
241 inline void SubRotationStep(Vec3Arg inAngularVelocityTimesDeltaTime);
242
244 inline void SetInBroadPhaseInternal(bool inInBroadPhase) { if (inInBroadPhase) mFlags.fetch_or(uint8(EFlags::IsInBroadPhase), memory_order_relaxed); else mFlags.fetch_and(uint8(~uint8(EFlags::IsInBroadPhase)), memory_order_relaxed); }
245
247 inline bool InvalidateContactCacheInternal() { return (mFlags.fetch_or(uint8(EFlags::InvalidateContactCache), memory_order_relaxed) & uint8(EFlags::InvalidateContactCache)) == 0; }
248
250 inline void ValidateContactCacheInternal() { JPH_IF_ENABLE_ASSERTS(uint8 old_val = ) mFlags.fetch_and(uint8(~uint8(EFlags::InvalidateContactCache)), memory_order_relaxed); JPH_ASSERT((old_val & uint8(EFlags::InvalidateContactCache)) != 0); }
251
253 void CalculateWorldSpaceBoundsInternal();
254
256 void SetPositionAndRotationInternal(RVec3Arg inPosition, QuatArg inRotation);
257
261 void UpdateCenterOfMassInternal(Vec3Arg inPreviousCenterOfMass, bool inUpdateMassProperties);
262
266 void SetShapeInternal(const Shape *inShape, bool inUpdateMassProperties);
267
269 uint32 GetIndexInActiveBodiesInternal() const { return mMotionProperties != nullptr? mMotionProperties->mIndexInActiveBodies : cInactiveIndex; }
270
271 enum class ECanSleep
272 {
273 CannotSleep = 0,
274 CanSleep = 1,
275 };
276
278 ECanSleep UpdateSleepStateInternal(float inDeltaTime, float inMaxMovement, float inTimeBeforeSleep);
279
281 void SaveState(StateRecorder &inStream) const;
282
284 void RestoreState(StateRecorder &inStream);
285
287
288 static constexpr uint32 cInactiveIndex = uint32(-1);
289
290private:
291 friend class BodyManager;
292
293 explicit Body(bool);
294
295 inline void GetSleepTestPoints(RVec3 *outPoints) const;
296 inline void ResetSleepTestSpheres();
297
298 enum class EFlags : uint8
299 {
300 IsSensor = 1 << 0,
301 IsInBroadPhase = 1 << 1,
302 InvalidateContactCache = 1 << 2,
303 UseManifoldReduction = 1 << 3,
304 };
305
306 // 16 byte aligned
307 RVec3 mPosition;
308 Quat mRotation;
309 AABox mBounds;
310
311 // 8 byte aligned
312 RefConst<Shape> mShape;
313 MotionProperties * mMotionProperties = nullptr;
314 uint64 mUserData = 0;
315 CollisionGroup mCollisionGroup;
316
317 // 4 byte aligned
318 float mFriction;
319 float mRestitution;
320 BodyID mID;
321
322 // 2 or 4 bytes aligned
323 ObjectLayer mObjectLayer;
324
325 // 1 byte aligned
326 BroadPhaseLayer mBroadPhaseLayer;
327 EMotionType mMotionType;
328 atomic<uint8> mFlags = 0;
329
330 // 121 bytes up to here (64-bit mode, single precision, 16-bit ObjectLayer)
331
332#if JPH_CPU_ADDRESS_BITS == 32
333 // Padding for mShape, mMotionProperties, mCollisionGroup.mGroupFilter being 4 instead of 8 bytes in 32 bit mode
334 uint8 mPadding[12];
335#endif
336};
337
338static_assert(sizeof(Body) == JPH_IF_SINGLE_PRECISION_ELSE(128, 160), "Body size is incorrect");
339static_assert(alignof(Body) == JPH_RVECTOR_ALIGNMENT, "Body should properly align");
340
342
343#include "Body.inl"
uint32_t uint32
Definition: Core.h:312
#define JPH_NAMESPACE_END
Definition: Core.h:240
#define JPH_IF_SINGLE_PRECISION_ELSE(s, d)
Definition: Core.h:372
uint8_t uint8
Definition: Core.h:310
uint64_t uint64
Definition: Core.h:313
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:234
#define JPH_IF_ENABLE_ASSERTS(...)
Definition: IssueReporting.h:35
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
#define JPH_OVERRIDE_NEW_DELETE
Macro to override the new and delete functions.
Definition: Memory.h:29
EMotionType
Motion type of a physics body.
Definition: MotionType.h:11
uint16 ObjectLayer
Definition: ObjectLayer.h:16
#define JPH_RVECTOR_ALIGNMENT
Definition: Real.h:34
Axis aligned box.
Definition: AABox.h:16
Settings for constructing a rigid body.
Definition: BodyCreationSettings.h:29
Definition: Body.h:33
Vec3 GetPointVelocity(RVec3Arg inPoint) const
Velocity of point inPoint (in world space, e.g. on the surface of the body) of the body (unit: m/s)
Definition: Body.h:130
bool IsInBroadPhase() const
Check if this body has been added to the physics system.
Definition: Body.h:175
const MotionProperties * GetMotionProperties() const
Access to the motion properties.
Definition: Body.h:205
RVec3 GetCenterOfMassPosition() const
Gets the world space position of this body's center of mass.
Definition: Body.h:193
EMotionType GetMotionType() const
Motion type of this body.
Definition: Body.h:82
void SetAngularVelocity(Vec3Arg inAngularVelocity)
Set world space angular velocity of the center of mass (unit: rad/s)
Definition: Body.h:121
void SetCollisionGroup(const CollisionGroup &inGroup)
Definition: Body.h:94
Vec3 GetPointVelocityCOM(Vec3Arg inPointRelativeToCOM) const
Velocity of point inPoint (in center of mass space, e.g. on the surface of the body) of the body (uni...
Definition: Body.h:127
bool IsDynamic() const
Check if this body is dynamic, which means that it moves and forces can act on it.
Definition: Body.h:56
bool GetAllowSleeping() const
If this body can go to sleep. Note that disabling sleeping on a sleeping object wil not wake it up.
Definition: Body.h:97
bool IsSensor() const
Check if this body is a sensor.
Definition: Body.h:69
const AABox & GetWorldSpaceBounds() const
Get world space bounding box.
Definition: Body.h:202
void SubPositionStep(Vec3Arg inLinearVelocityTimesDeltaTime)
Definition: Body.h:237
void SetUserData(uint64 inUserData)
Definition: Body.h:214
const Shape * GetShape() const
Get the shape of this body.
Definition: Body.h:181
bool InvalidateContactCacheInternal()
Invalidate the contact cache (should only be called by the BodyManager), will be reset the next simul...
Definition: Body.h:247
uint64 GetUserData() const
Access to the user data, can be used for anything by the application.
Definition: Body.h:213
BroadPhaseLayer GetBroadPhaseLayer() const
Get broadphase layer, this determines in which broad phase sub-tree the object is placed.
Definition: Body.h:86
ECanSleep
Definition: Body.h:272
float GetRestitution() const
Restitution (dimensionless number, usually between 0 and 1, 0 = completely inelastic collision respon...
Definition: Body.h:105
const CollisionGroup & GetCollisionGroup() const
Collision group and sub-group ID, determines which other objects it collides with.
Definition: Body.h:92
void SetIsSensor(bool inIsSensor)
Definition: Body.h:66
void SetLinearVelocityClamped(Vec3Arg inLinearVelocity)
Set world space linear velocity of the center of mass, will make sure the value is clamped against th...
Definition: Body.h:115
bool GetUseManifoldReductionWithBody(const Body &inBody2) const
Checks if the combination of this body and inBody2 should use manifold reduction.
Definition: Body.h:79
void SetLinearVelocity(Vec3Arg inLinearVelocity)
Set world space linear velocity of the center of mass (unit: m/s)
Definition: Body.h:112
uint32 GetIndexInActiveBodiesInternal() const
Access to the index in the BodyManager::mActiveBodies list.
Definition: Body.h:269
Vec3 GetLinearVelocity() const
Get world space linear velocity of the center of mass (unit: m/s)
Definition: Body.h:109
ObjectLayer GetObjectLayer() const
Get object layer, this determines which other objects it collides with.
Definition: Body.h:89
void SetRestitution(float inRestitution)
Definition: Body.h:106
bool IsCollisionCacheInvalid() const
Check if this body has been changed in such a way that the collision cache should be considered inval...
Definition: Body.h:178
JPH_OVERRIDE_NEW_DELETE Body()=default
Default constructor.
bool IsStatic() const
Check if this body is static (not movable)
Definition: Body.h:50
void SetUseManifoldReduction(bool inUseReduction)
Definition: Body.h:73
static Body sFixedToWorld
A dummy body that can be used by constraints to attach a constraint to the world instead of another b...
Definition: Body.h:226
void SetAngularVelocityClamped(Vec3Arg inAngularVelocity)
Set world space angular velocity of the center of mass, will make sure the value is clamped against t...
Definition: Body.h:124
Vec3 GetAccumulatedTorque() const
Definition: Body.h:145
bool CanBeKinematicOrDynamic() const
Check if a body could be made kinematic or dynamic (if it was created dynamic or with mAllowDynamicOr...
Definition: Body.h:59
void SetInBroadPhaseInternal(bool inInBroadPhase)
Flag if body is in the broadphase (should only be called by the BroadPhase)
Definition: Body.h:244
MotionProperties * GetMotionProperties()
Definition: Body.h:206
Quat GetRotation() const
World space rotation of the body.
Definition: Body.h:187
TransformedShape GetTransformedShape() const
Get the transformed shape of this body, which can be used to do collision detection outside of a body...
Definition: Body.h:220
bool IsKinematic() const
Check if this body is kinematic (keyframed), which means that it will move according to its current v...
Definition: Body.h:53
const BodyID & GetID() const
Get the id of this body.
Definition: Body.h:44
float GetFriction() const
Friction (dimensionless number, usually between 0 and 1, 0 = no friction, 1 = friction force equals f...
Definition: Body.h:101
const MotionProperties * GetMotionPropertiesUnchecked() const
Access to the motion properties (version that does not check if the object is kinematic or dynamic)
Definition: Body.h:209
~Body()
Destructor
Definition: Body.h:41
CollisionGroup & GetCollisionGroup()
Definition: Body.h:93
MotionProperties * GetMotionPropertiesUnchecked()
Definition: Body.h:210
Vec3 GetAccumulatedForce() const
Definition: Body.h:142
Vec3 GetAngularVelocity() const
Get world space angular velocity of the center of mass (unit: rad/s)
Definition: Body.h:118
RVec3 GetPosition() const
World space position of the body.
Definition: Body.h:184
void AddForce(Vec3Arg inForce)
Add force (unit: N) at center of mass for the next time step, will be reset after the next call to Ph...
Definition: Body.h:133
bool IsActive() const
If this body is currently actively simulating (true) or sleeping (false)
Definition: Body.h:47
bool GetUseManifoldReduction() const
Check if this body can use manifold reduction.
Definition: Body.h:76
void AddTorque(Vec3Arg inTorque)
Add torque (unit: N m) for the next time step, will be reset after the next call to PhysicsSimulation...
Definition: Body.h:139
void ValidateContactCacheInternal()
Reset the collision cache invalid flag (should only be called by the BodyManager).
Definition: Body.h:250
void SetFriction(float inFriction)
Definition: Body.h:102
void AddPositionStep(Vec3Arg inLinearVelocityTimesDeltaTime)
Update position using an Euler step (used during position integrate & constraint solving)
Definition: Body.h:236
ID of a body. This is a way of reasoning about bodies in a multithreaded simulation while avoiding ra...
Definition: BodyID.h:13
Class that contains all bodies.
Definition: BodyManager.h:30
Definition: BroadPhaseLayer.h:18
Definition: CollisionGroup.h:20
Holds a 4x4 matrix of floats, but supports also operations on the 3x3 upper left part of the matrix.
Definition: Mat44.h:13
The Body class only keeps track of state for static bodies, the MotionProperties class keeps the addi...
Definition: MotionProperties.h:20
Class that makes another class non-copyable. Usage: Inherit from NonCopyable.
Definition: NonCopyable.h:11
Definition: Quat.h:33
Definition: Reference.h:154
Base class for all shapes (collision volume of a body). Defines a virtual interface for collision det...
Definition: Shape.h:170
Definition: StateRecorder.h:15
A sub shape id contains a path to an element (usually a triangle or other primitive type) of a compou...
Definition: SubShapeID.h:23
Definition: TransformedShape.h:26
Definition: Vec3.h:16
static JPH_INLINE Vec3 sZero()
Vector with all zeros.
Definition: Vec3.inl:107
static JPH_INLINE Vec3 sLoadFloat3Unsafe(const Float3 &inV)
Load 3 floats from memory (reads 32 bits extra which it doesn't use)
Definition: Vec3.inl:134