Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
Body.inl
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
10{
11 JPH_ASSERT(BodyAccess::sCheckRights(BodyAccess::sPositionAccess, BodyAccess::EAccess::Read));
12
13 return RMat44::sRotationTranslation(mRotation, mPosition).PreTranslated(-mShape->GetCenterOfMass());
14}
15
17{
18 JPH_ASSERT(BodyAccess::sCheckRights(BodyAccess::sPositionAccess, BodyAccess::EAccess::Read));
19
20 return RMat44::sRotationTranslation(mRotation, mPosition);
21}
22
24{
25 JPH_ASSERT(BodyAccess::sCheckRights(BodyAccess::sPositionAccess, BodyAccess::EAccess::Read));
26
27 return RMat44::sInverseRotationTranslation(mRotation, mPosition);
28}
29
31{
32 // First body should never be a soft body
33 JPH_ASSERT(!inBody1.IsSoftBody());
34
35 // One of these conditions must be true
36 // - We always allow detecting collisions between kinematic and non-dynamic bodies
37 // - One of the bodies must be dynamic to collide
38 // - A kinematic object can collide with a sensor
39 if (!inBody1.GetCollideKinematicVsNonDynamic()
40 && !inBody2.GetCollideKinematicVsNonDynamic()
41 && (!inBody1.IsDynamic() && !inBody2.IsDynamic())
42 && !(inBody1.IsKinematic() && inBody2.IsSensor())
43 && !(inBody2.IsKinematic() && inBody1.IsSensor()))
44 return false;
45
46 // Check that body 1 is active
47 uint32 body1_index_in_active_bodies = inBody1.GetIndexInActiveBodiesInternal();
48 JPH_ASSERT(!inBody1.IsStatic() && body1_index_in_active_bodies != Body::cInactiveIndex, "This function assumes that Body 1 is active");
49
50 // If the pair A, B collides we need to ensure that the pair B, A does not collide or else we will handle the collision twice.
51 // If A is the same body as B we don't want to collide (1)
52 // If A is dynamic / kinematic and B is static we should collide (2)
53 // If A is dynamic / kinematic and B is dynamic / kinematic we should only collide if
54 // - A is active and B is not active (3)
55 // - A is active and B will become active during this simulation step (4)
56 // - A is active and B is active, we require a condition that makes A, B collide and B, A not (5)
57 //
58 // In order to implement this we use the index in the active body list and make use of the fact that
59 // a body not in the active list has Body.Index = 0xffffffff which is the highest possible value for an uint32.
60 //
61 // Because we know that A is active we know that A.Index != 0xffffffff:
62 // (1) Because A.Index != 0xffffffff, if A.Index = B.Index then A = B, so to collide A.Index != B.Index
63 // (2) A.Index != 0xffffffff, B.Index = 0xffffffff (because it's static and cannot be in the active list), so to collide A.Index != B.Index
64 // (3) A.Index != 0xffffffff, B.Index = 0xffffffff (because it's not yet active), so to collide A.Index != B.Index
65 // (4) A.Index != 0xffffffff, B.Index = 0xffffffff currently. But it can activate during the Broad/NarrowPhase step at which point it
66 // will be added to the end of the active list which will make B.Index > A.Index (this holds only true when we don't deactivate
67 // bodies during the Broad/NarrowPhase step), so to collide A.Index < B.Index.
68 // (5) As tie breaker we can use the same condition A.Index < B.Index to collide, this means that if A, B collides then B, A won't
69 static_assert(Body::cInactiveIndex == 0xffffffff, "The algorithm below uses this value");
70 if (!inBody2.IsSoftBody() && body1_index_in_active_bodies >= inBody2.GetIndexInActiveBodiesInternal())
71 return false;
72 JPH_ASSERT(inBody1.GetID() != inBody2.GetID(), "Read the comment above, A and B are the same body which should not be possible!");
73
74 // Check collision group filter
75 if (!inBody1.GetCollisionGroup().CanCollide(inBody2.GetCollisionGroup()))
76 return false;
77
78 return true;
79}
80
82{
84 JPH_ASSERT(BodyAccess::sCheckRights(BodyAccess::sPositionAccess, BodyAccess::EAccess::ReadWrite));
85
86 // This used to use the equation: d/dt R(t) = 1/2 * w(t) * R(t) so that R(t + dt) = R(t) + 1/2 * w(t) * R(t) * dt
87 // See: Appendix B of An Introduction to Physically Based Modeling: Rigid Body Simulation II-Nonpenetration Constraints
88 // URL: https://www.cs.cmu.edu/~baraff/sigcourse/notesd2.pdf
89 // But this is a first order approximation and does not work well for kinematic ragdolls that are driven to a new
90 // pose if the poses differ enough. So now we split w(t) * dt into an axis and angle part and create a quaternion with it.
91 // Note that the resulting quaternion is normalized since otherwise numerical drift will eventually make the rotation non-normalized.
92 float len = inAngularVelocityTimesDeltaTime.Length();
93 if (len > 1.0e-6f)
94 {
95 mRotation = (Quat::sRotation(inAngularVelocityTimesDeltaTime / len, len) * mRotation).Normalized();
96 JPH_ASSERT(!mRotation.IsNaN());
97 }
98}
99
101{
103 JPH_ASSERT(BodyAccess::sCheckRights(BodyAccess::sPositionAccess, BodyAccess::EAccess::ReadWrite));
104
105 // See comment at Body::AddRotationStep
106 float len = inAngularVelocityTimesDeltaTime.Length();
107 if (len > 1.0e-6f)
108 {
109 mRotation = (Quat::sRotation(inAngularVelocityTimesDeltaTime / len, -len) * mRotation).Normalized();
110 JPH_ASSERT(!mRotation.IsNaN());
111 }
112}
113
119
126
132
134{
136
137 SetLinearVelocityClamped(mMotionProperties->GetLinearVelocity() + inImpulse * mMotionProperties->GetInverseMass());
138}
139
141{
143
144 SetLinearVelocityClamped(mMotionProperties->GetLinearVelocity() + inImpulse * mMotionProperties->GetInverseMass());
145
146 SetAngularVelocityClamped(mMotionProperties->GetAngularVelocity() + mMotionProperties->MultiplyWorldSpaceInverseInertiaByVector(mRotation, Vec3(inPosition - mPosition).Cross(inImpulse)));
147}
148
155
156void Body::GetSleepTestPoints(RVec3 *outPoints) const
157{
158 JPH_ASSERT(BodyAccess::sCheckRights(BodyAccess::sPositionAccess, BodyAccess::EAccess::Read));
159
160 // Center of mass is the first position
161 outPoints[0] = mPosition;
162
163 // The second and third position are on the largest axis of the bounding box
164 Vec3 extent = mShape->GetLocalBounds().GetExtent();
166 Mat44 rotation = Mat44::sRotation(mRotation);
167 switch (lowest_component)
168 {
169 case 0:
170 outPoints[1] = mPosition + extent.GetY() * rotation.GetColumn3(1);
171 outPoints[2] = mPosition + extent.GetZ() * rotation.GetColumn3(2);
172 break;
173
174 case 1:
175 outPoints[1] = mPosition + extent.GetX() * rotation.GetColumn3(0);
176 outPoints[2] = mPosition + extent.GetZ() * rotation.GetColumn3(2);
177 break;
178
179 case 2:
180 outPoints[1] = mPosition + extent.GetX() * rotation.GetColumn3(0);
181 outPoints[2] = mPosition + extent.GetY() * rotation.GetColumn3(1);
182 break;
183
184 default:
185 JPH_ASSERT(false);
186 break;
187 }
188}
189
191{
192 RVec3 points[3];
193 GetSleepTestPoints(points);
194 mMotionProperties->ResetSleepTestSpheres(points);
195}
196
#define JPH_NAMESPACE_END
Definition Core.h:367
std::uint32_t uint32
Definition Core.h:442
#define JPH_NAMESPACE_BEGIN
Definition Core.h:361
#define JPH_ASSERT(...)
Definition IssueReporting.h:33
AllocateFunction Allocate
Definition Memory.cpp:59
Vec3 GetExtent() const
Get extent of bounding box (half of the size)
Definition AABox.h:111
Definition Body.h:35
const MotionProperties * GetMotionProperties() const
Access to the motion properties.
Definition Body.h:255
Vec3 GetWorldSpaceSurfaceNormal(const SubShapeID &inSubShapeID, RVec3Arg inPosition) const
Get surface normal of a particular sub shape and its world space surface position on this body.
Definition Body.inl:114
bool IsDynamic() const
Check if this body is dynamic, which means that it moves and forces can act on it.
Definition Body.h:67
void AddRotationStep(Vec3Arg inAngularVelocityTimesDeltaTime)
Update rotation using an Euler step (using during position integrate & constraint solving)
Definition Body.inl:81
RMat44 GetWorldTransform() const
Calculates the transform of this body.
Definition Body.inl:9
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:156
static constexpr uint32 cInactiveIndex
Constant indicating that body is not active.
Definition Body.h:335
static bool sFindCollidingPairsCanCollide(const Body &inBody1, const Body &inBody2)
Definition Body.inl:30
Mat44 GetInverseInertia() const
Get inverse inertia tensor in world space.
Definition Body.inl:120
bool IsRigidBody() const
Check if this body is a rigid body.
Definition Body.h:52
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:165
RMat44 GetCenterOfMassTransform() const
Calculates the transform for this body's center of mass.
Definition Body.inl:16
void ResetSleepTimer()
Resets the sleep timer. This does not wake up the body if it is sleeping, but allows resetting the sy...
Definition Body.inl:190
RMat44 GetInverseCenterOfMassTransform() const
Calculates the inverse of the transform for this body's center of mass.
Definition Body.inl:23
void AddAngularImpulse(Vec3Arg inAngularImpulse)
Add angular impulse in world space (unit: N m s)
Definition Body.inl:149
void SubRotationStep(Vec3Arg inAngularVelocityTimesDeltaTime)
Definition Body.inl:100
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:174
void AddTorque(Vec3Arg inTorque)
Add torque (unit: N m) for the next time step, will be reset after the next call to PhysicsSystem::Up...
Definition Body.h:180
void AddImpulse(Vec3Arg inImpulse)
Add impulse to center of mass (unit: kg m/s)
Definition Body.inl:133
Holds a 4x4 matrix of floats, but supports also operations on the 3x3 upper left part of the matrix.
Definition Mat44.h:13
JPH_INLINE Mat44 PreTranslated(Vec3Arg inTranslation) const
Pre multiply by translation matrix: result = this * Mat44::sTranslation(inTranslation)
Definition Mat44.inl:898
static JPH_INLINE Mat44 sRotationTranslation(QuatArg inR, Vec3Arg inT)
Get matrix that rotates and translates.
Definition Mat44.inl:149
static JPH_INLINE Mat44 sRotation(Vec3Arg inAxis, float inAngle)
Rotate around arbitrary axis.
Definition Mat44.inl:139
static JPH_INLINE Mat44 sInverseRotationTranslation(QuatArg inR, Vec3Arg inT)
Get inverse matrix of sRotationTranslation.
Definition Mat44.inl:156
Vec3 GetLinearVelocity() const
Get world space linear velocity of the center of mass.
Definition MotionProperties.h:43
Vec3 GetAngularVelocity() const
Get world space angular velocity of the center of mass.
Definition MotionProperties.h:52
float GetInverseMass() const
Get inverse mass (1 / mass). Should only be called on a dynamic object (static or kinematic bodies ha...
Definition MotionProperties.h:95
JPH_INLINE Vec3 MultiplyWorldSpaceInverseInertiaByVector(QuatArg inBodyRotation, Vec3Arg inV) const
Multiply a vector with the inverse world space inertia tensor ( ). Zero if object is static or kinema...
Definition MotionProperties.inl:76
void ResetSleepTestSpheres(const RVec3 *inPoints)
Reset spheres to center around inPoints with radius 0.
Definition MotionProperties.inl:144
Mat44 GetInverseInertiaForRotation(Mat44Arg inRotation) const
Get inverse inertia matrix ( ) for a given object rotation (translation will be ignored)....
Definition MotionProperties.inl:59
static JPH_INLINE Quat sRotation(Vec3Arg inAxis, float inAngle)
Rotation from axis and angle.
Definition Quat.inl:74
bool IsNaN() const
If any component of this quaternion is a NaN (not a number)
Definition Quat.h:62
virtual AABox GetLocalBounds() const =0
Get local bounding box including convex radius, this box is centered around the center of mass rather...
virtual Vec3 GetCenterOfMass() const
All shapes are centered around their center of mass. This function returns the center of mass positio...
Definition Shape.h:203
virtual Vec3 GetSurfaceNormal(const SubShapeID &inSubShapeID, Vec3Arg inLocalSurfacePosition) const =0
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 Vec3.h:16
JPH_INLINE float GetX() const
Get individual components.
Definition Vec3.h:123
JPH_INLINE int GetLowestComponentIndex() const
Get index of component with lowest value.
Definition Vec3.inl:554
JPH_INLINE float GetY() const
Definition Vec3.h:124
JPH_INLINE float GetZ() const
Definition Vec3.h:125