Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
CompoundShape.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
10
12
14class OrientedBox;
15
18{
19public:
21
22
24
26 void AddShape(Vec3Arg inPosition, QuatArg inRotation, const ShapeSettings *inShape, uint32 inUserData = 0);
27
29 void AddShape(Vec3Arg inPosition, QuatArg inRotation, const Shape *inShape, uint32 inUserData = 0);
30
32 {
34
36 RefConst<Shape> mShapePtr;
37 Vec3 mPosition;
38 Quat mRotation;
39 uint32 mUserData = 0;
40 };
41
43
44 SubShapes mSubShapes;
45};
46
49{
50public:
52
54 explicit CompoundShape(EShapeSubType inSubType) : Shape(EShapeType::Compound, inSubType) { }
55 CompoundShape(EShapeSubType inSubType, const ShapeSettings &inSettings, ShapeResult &outResult) : Shape(EShapeType::Compound, inSubType, inSettings, outResult) { }
56
57 // See Shape::GetCenterOfMass
58 virtual Vec3 GetCenterOfMass() const override { return mCenterOfMass; }
59
60 // See Shape::MustBeStatic
61 virtual bool MustBeStatic() const override;
62
63 // See Shape::GetLocalBounds
64 virtual AABox GetLocalBounds() const override { return mLocalBounds; }
65
66 // See Shape::GetSubShapeIDBitsRecursive
67 virtual uint GetSubShapeIDBitsRecursive() const override;
68
69 // See Shape::GetWorldSpaceBounds
70 virtual AABox GetWorldSpaceBounds(Mat44Arg inCenterOfMassTransform, Vec3Arg inScale) const override;
72
73 // See Shape::GetInnerRadius
74 virtual float GetInnerRadius() const override { return mInnerRadius; }
75
76 // See Shape::GetMassProperties
77 virtual MassProperties GetMassProperties() const override;
78
79 // See Shape::GetMaterial
80 virtual const PhysicsMaterial * GetMaterial(const SubShapeID &inSubShapeID) const override;
81
82 // See Shape::GetSubShapeUserData
83 virtual uint64 GetSubShapeUserData(const SubShapeID &inSubShapeID) const override;
84
85 // See Shape::GetSubShapeTransformedShape
86 virtual TransformedShape GetSubShapeTransformedShape(const SubShapeID &inSubShapeID, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale, SubShapeID &outRemainder) const override;
87
88 // See Shape::GetSurfaceNormal
89 virtual Vec3 GetSurfaceNormal(const SubShapeID &inSubShapeID, Vec3Arg inLocalSurfacePosition) const override;
90
91 // See Shape::GetSupportingFace
92 virtual void GetSupportingFace(const SubShapeID &inSubShapeID, Vec3Arg inDirection, Vec3Arg inScale, Mat44Arg inCenterOfMassTransform, SupportingFace &outVertices) const override;
93
94 // See Shape::GetSubmergedVolume
95 virtual void GetSubmergedVolume(Mat44Arg inCenterOfMassTransform, Vec3Arg inScale, const Plane &inSurface, float &outTotalVolume, float &outSubmergedVolume, Vec3 &outCenterOfBuoyancy JPH_IF_DEBUG_RENDERER(, RVec3Arg inBaseOffset)) const override;
96
97#ifdef JPH_DEBUG_RENDERER
98 // See Shape::Draw
99 virtual void Draw(DebugRenderer *inRenderer, RMat44Arg inCenterOfMassTransform, Vec3Arg inScale, ColorArg inColor, bool inUseMaterialColors, bool inDrawWireframe) const override;
100
101 // See Shape::DrawGetSupportFunction
102 virtual void DrawGetSupportFunction(DebugRenderer *inRenderer, RMat44Arg inCenterOfMassTransform, Vec3Arg inScale, ColorArg inColor, bool inDrawSupportDirection) const override;
103
104 // See Shape::DrawGetSupportingFace
105 virtual void DrawGetSupportingFace(DebugRenderer *inRenderer, RMat44Arg inCenterOfMassTransform, Vec3Arg inScale) const override;
106#endif // JPH_DEBUG_RENDERER
107
108 // See: Shape::CollideSoftBodyVertices
109 virtual void CollideSoftBodyVertices(Mat44Arg inCenterOfMassTransform, Vec3Arg inScale, SoftBodyVertex *ioVertices, uint inNumVertices, float inDeltaTime, Vec3Arg inDisplacementDueToGravity, int inCollidingShapeIndex) const override;
110
111 // See Shape::TransformShape
112 virtual void TransformShape(Mat44Arg inCenterOfMassTransform, TransformedShapeCollector &ioCollector) const override;
113
114 // See Shape::GetTrianglesStart
115 virtual void GetTrianglesStart(GetTrianglesContext &ioContext, const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale) const override { JPH_ASSERT(false, "Cannot call on non-leaf shapes, use CollectTransformedShapes to collect the leaves first!"); }
116
117 // See Shape::GetTrianglesNext
118 virtual int GetTrianglesNext(GetTrianglesContext &ioContext, int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials = nullptr) const override { JPH_ASSERT(false, "Cannot call on non-leaf shapes, use CollectTransformedShapes to collect the leaves first!"); return 0; }
119
125 virtual int GetIntersectingSubShapes(const AABox &inBox, uint *outSubShapeIndices, int inMaxSubShapeIndices) const = 0;
126
132 virtual int GetIntersectingSubShapes(const OrientedBox &inBox, uint *outSubShapeIndices, int inMaxSubShapeIndices) const = 0;
133
134 struct SubShape
135 {
141 {
142 if (inSettings.mShapePtr != nullptr)
143 {
144 // Use provided shape
145 mShape = inSettings.mShapePtr;
146 }
147 else
148 {
149 // Create child shape
150 ShapeResult child_result = inSettings.mShape->Create();
151 if (!child_result.IsValid())
152 {
153 outResult = child_result;
154 return false;
155 }
156 mShape = child_result.Get();
157 }
158
159 // Copy user data
160 mUserData = inSettings.mUserData;
161
162 SetTransform(inSettings.mPosition, inSettings.mRotation, Vec3::sZero() /* Center of mass not yet calculated */);
163 return true;
164 }
165
170 JPH_INLINE void SetTransform(Vec3Arg inPosition, QuatArg inRotation, Vec3Arg inCenterOfMass)
171 {
172 SetPositionCOM(inPosition - inCenterOfMass + inRotation * mShape->GetCenterOfMass());
173
174 mIsRotationIdentity = inRotation.IsClose(Quat::sIdentity()) || inRotation.IsClose(-Quat::sIdentity());
175 SetRotation(mIsRotationIdentity? Quat::sIdentity() : inRotation);
176 }
177
181 JPH_INLINE Mat44 GetLocalTransformNoScale(Vec3Arg inScale) const
182 {
183 JPH_ASSERT(IsValidScale(inScale));
184 return Mat44::sRotationTranslation(GetRotation(), inScale * GetPositionCOM());
185 }
186
188 inline bool IsValidScale(Vec3Arg inScale) const
189 {
190 // We can always handle uniform scale or identity rotations
191 if (mIsRotationIdentity || ScaleHelpers::IsUniformScale(inScale))
192 return true;
193
194 return ScaleHelpers::CanScaleBeRotated(GetRotation(), inScale);
195 }
196
198 inline Vec3 TransformScale(Vec3Arg inScale) const
199 {
200 // We don't need to transform uniform scale or if the rotation is identity
201 if (mIsRotationIdentity || ScaleHelpers::IsUniformScale(inScale))
202 return inScale;
203
204 return ScaleHelpers::RotateScale(GetRotation(), inScale);
205 }
206
208 JPH_INLINE void SetPositionCOM(Vec3Arg inPositionCOM)
209 {
210 inPositionCOM.StoreFloat3(&mPositionCOM);
211 }
212
214 JPH_INLINE Vec3 GetPositionCOM() const
215 {
216 return Vec3::sLoadFloat3Unsafe(mPositionCOM);
217 }
218
220 JPH_INLINE void SetRotation(QuatArg inRotation)
221 {
222 inRotation.StoreFloat3(&mRotation);
223 }
224
226 JPH_INLINE Quat GetRotation() const
227 {
228 return mIsRotationIdentity? Quat::sIdentity() : Quat::sLoadFloat3Unsafe(mRotation);
229 }
230
236 // 3 padding bytes left
237 };
238
239 static_assert(sizeof(SubShape) == (JPH_CPU_ADDRESS_BITS == 64? 40 : 36), "Compiler added unexpected padding");
240
242
244 const SubShapes & GetSubShapes() const { return mSubShapes; }
245
247 uint GetNumSubShapes() const { return uint(mSubShapes.size()); }
248
250 const SubShape & GetSubShape(uint inIdx) const { return mSubShapes[inIdx]; }
251
253 uint32 GetCompoundUserData(uint inIdx) const { return mSubShapes[inIdx].mUserData; }
254
256 void SetCompoundUserData(uint inIdx, uint32 inUserData) { mSubShapes[inIdx].mUserData = inUserData; }
257
261 inline bool IsSubShapeIDValid(SubShapeID inSubShapeID) const
262 {
263 SubShapeID remainder;
264 return inSubShapeID.PopID(GetSubShapeIDBits(), remainder) < mSubShapes.size();
265 }
266
271 inline uint32 GetSubShapeIndexFromID(SubShapeID inSubShapeID, SubShapeID &outRemainder) const
272 {
273 uint32 idx = inSubShapeID.PopID(GetSubShapeIDBits(), outRemainder);
274 JPH_ASSERT(idx < mSubShapes.size(), "Invalid SubShapeID");
275 return idx;
276 }
277
282 inline SubShapeIDCreator GetSubShapeIDFromIndex(int inIdx, const SubShapeIDCreator &inParentSubShapeID) const
283 {
284 return inParentSubShapeID.PushID(inIdx, GetSubShapeIDBits());
285 }
286
287 // See Shape
288 virtual void SaveBinaryState(StreamOut &inStream) const override;
289 virtual void SaveSubShapeState(ShapeList &outSubShapes) const override;
290 virtual void RestoreSubShapeState(const ShapeRefC *inSubShapes, uint inNumShapes) override;
291
292 // See Shape::GetStatsRecursive
293 virtual Stats GetStatsRecursive(VisitedShapes &ioVisitedShapes) const override;
294
295 // See Shape::GetVolume
296 virtual float GetVolume() const override;
297
298 // See Shape::IsValidScale
299 virtual bool IsValidScale(Vec3Arg inScale) const override;
300
301 // Register shape functions with the registry
302 static void sRegister();
303
304protected:
305 // See: Shape::RestoreBinaryState
306 virtual void RestoreBinaryState(StreamIn &inStream) override;
307
308 // Visitors for collision detection
309 struct CastRayVisitor;
310 struct CastRayVisitorCollector;
311 struct CollidePointVisitor;
312 struct CastShapeVisitor;
313 struct CollectTransformedShapesVisitor;
314 struct CollideCompoundVsShapeVisitor;
315 struct CollideShapeVsCompoundVisitor;
316 template <class BoxType> struct GetIntersectingSubShapesVisitor;
317
319 inline uint GetSubShapeIDBits() const
320 {
321 // Ensure we have enough bits to encode our shape [0, n - 1]
322 uint32 n = uint32(mSubShapes.size()) - 1;
323 return 32 - CountLeadingZeros(n);
324 }
325
328 {
329 mInnerRadius = FLT_MAX;
330 for (const SubShape &s : mSubShapes)
331 mInnerRadius = min(mInnerRadius, s.mShape->GetInnerRadius());
332 }
333
334 Vec3 mCenterOfMass { Vec3::sZero() };
337 float mInnerRadius = FLT_MAX;
338
339private:
340 // Helper functions called by CollisionDispatch
341 static void sCastCompoundVsShape(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector);
342};
343
#define JPH_EXPORT
Definition: Core.h:227
std::uint64_t uint64
Definition: Core.h:443
unsigned int uint
Definition: Core.h:439
#define JPH_NAMESPACE_END
Definition: Core.h:367
std::uint32_t uint32
Definition: Core.h:442
#define JPH_IF_DEBUG_RENDERER(...)
Definition: Core.h:510
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:361
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
uint CountLeadingZeros(uint32 inValue)
Compute the number of leading zero bits (how many high bits are zero)
Definition: Math.h:129
#define JPH_OVERRIDE_NEW_DELETE
Macro to override the new and delete functions.
Definition: Memory.h:29
std::vector< T, STLAllocator< T > > Array
Definition: STLAllocator.h:81
#define JPH_DECLARE_SERIALIZABLE_ABSTRACT(linkage, class_name)
Definition: SerializableObject.h:111
#define JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(linkage, class_name)
Definition: SerializableObject.h:71
EShapeSubType
This enumerates all shape types, each shape can return its type through Shape::GetSubType.
Definition: Shape.h:74
Array< ShapeRefC > ShapeList
Definition: Shape.h:51
EShapeType
Shapes are categorized in groups, each shape can return which group it belongs to through its Shape::...
Definition: Shape.h:57
@ Compound
Used by CompoundShape.
Axis aligned box.
Definition: AABox.h:16
Settings to be passed with a collision query.
Definition: CollideShape.h:94
Virtual interface that allows collecting multiple collision results.
Definition: CollisionCollector.h:45
Class that holds an RGBA color with 8-bits per component.
Definition: Color.h:16
Base class for a compound shape.
Definition: CompoundShape.h:49
virtual void GetTrianglesStart(GetTrianglesContext &ioContext, const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale) const override
Definition: CompoundShape.h:115
AABox mLocalBounds
Definition: CompoundShape.h:335
const SubShapes & GetSubShapes() const
Access to the sub shapes of this compound.
Definition: CompoundShape.h:244
virtual int GetIntersectingSubShapes(const OrientedBox &inBox, uint *outSubShapeIndices, int inMaxSubShapeIndices) const =0
uint GetSubShapeIDBits() const
Determine amount of bits needed to encode sub shape id.
Definition: CompoundShape.h:319
bool IsSubShapeIDValid(SubShapeID inSubShapeID) const
Definition: CompoundShape.h:261
Array< SubShape > SubShapes
Definition: CompoundShape.h:241
uint32 GetCompoundUserData(uint inIdx) const
Get the user data associated with a shape in this compound.
Definition: CompoundShape.h:253
SubShapeIDCreator GetSubShapeIDFromIndex(int inIdx, const SubShapeIDCreator &inParentSubShapeID) const
Convert a sub shape index to a sub shape ID.
Definition: CompoundShape.h:282
JPH_OVERRIDE_NEW_DELETE CompoundShape(EShapeSubType inSubType)
Constructor.
Definition: CompoundShape.h:54
uint32 GetSubShapeIndexFromID(SubShapeID inSubShapeID, SubShapeID &outRemainder) const
Definition: CompoundShape.h:271
void SetCompoundUserData(uint inIdx, uint32 inUserData)
Set the user data associated with a shape in this compound.
Definition: CompoundShape.h:256
virtual int GetTrianglesNext(GetTrianglesContext &ioContext, int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials=nullptr) const override
Definition: CompoundShape.h:118
void CalculateInnerRadius()
Determine the inner radius of this shape.
Definition: CompoundShape.h:327
uint GetNumSubShapes() const
Get the total number of sub shapes.
Definition: CompoundShape.h:247
virtual int GetIntersectingSubShapes(const AABox &inBox, uint *outSubShapeIndices, int inMaxSubShapeIndices) const =0
CompoundShape(EShapeSubType inSubType, const ShapeSettings &inSettings, ShapeResult &outResult)
Definition: CompoundShape.h:55
SubShapes mSubShapes
Definition: CompoundShape.h:336
virtual float GetInnerRadius() const override
Definition: CompoundShape.h:74
virtual AABox GetLocalBounds() const override
Get local bounding box including convex radius, this box is centered around the center of mass rather...
Definition: CompoundShape.h:64
virtual Vec3 GetCenterOfMass() const override
All shapes are centered around their center of mass. This function returns the center of mass positio...
Definition: CompoundShape.h:58
const SubShape & GetSubShape(uint inIdx) const
Access to a particular sub shape.
Definition: CompoundShape.h:250
Base class settings to construct a compound shape.
Definition: CompoundShape.h:18
Array< SubShapeSettings > SubShapes
Definition: CompoundShape.h:42
Definition: DebugRenderer.h:47
Class that holds 3 floats. Used as a storage class. Convert to Vec3 for calculations.
Definition: Float3.h:13
Describes the mass and inertia properties of a body. Used during body construction only.
Definition: MassProperties.h:16
Holds a 4x4 matrix of floats, but supports also operations on the 3x3 upper left part of the matrix.
Definition: Mat44.h:13
static JPH_INLINE Mat44 sRotationTranslation(QuatArg inR, Vec3Arg inT)
Get matrix that rotates and translates.
Definition: Mat44.inl:149
Oriented box.
Definition: OrientedBox.h:18
Definition: PhysicsMaterial.h:23
An infinite plane described by the formula X . Normal + Constant = 0.
Definition: Plane.h:11
Definition: Quat.h:33
static JPH_INLINE Quat sLoadFloat3Unsafe(const Float3 &inV)
Load 3 floats from memory (X, Y and Z component and then calculates W) reads 32 bits extra which it d...
Definition: Quat.inl:321
static JPH_INLINE Quat sIdentity()
Definition: Quat.h:103
bool IsClose(QuatArg inRHS, float inMaxDistSq=1.0e-12f) const
If this quaternion is close to inRHS. Note that q and -q represent the same rotation,...
Definition: Quat.h:56
JPH_INLINE void StoreFloat3(Float3 *outV) const
Store 3 as floats to memory (X, Y and Z component)
Definition: Quat.inl:315
Definition: Reference.h:151
bool IsValid() const
Checks if the result is valid.
Definition: Result.h:137
const Type & Get() const
Get the result value.
Definition: Result.h:140
Settings to be passed with a shape cast.
Definition: ShapeCast.h:92
Filter class.
Definition: ShapeFilter.h:17
Base class for all shapes (collision volume of a body). Defines a virtual interface for collision det...
Definition: Shape.h:178
virtual AABox GetWorldSpaceBounds(Mat44Arg inCenterOfMassTransform, Vec3Arg inScale) const
Definition: Shape.h:214
Definition: Shape.h:139
virtual ShapeResult Create() const =0
Create a shape according to the settings specified by this object.
Definition: SoftBodyVertex.h:16
Simple binary input stream.
Definition: StreamIn.h:13
Simple binary output stream.
Definition: StreamOut.h:13
Definition: SubShapeID.h:108
SubShapeIDCreator PushID(uint inValue, uint inBits) const
Add a new id to the chain of id's and return it.
Definition: SubShapeID.h:111
A sub shape id contains a path to an element (usually a triangle or other primitive type) of a compou...
Definition: SubShapeID.h:23
Type PopID(uint inBits, SubShapeID &outRemainder) const
Get the next id in the chain of ids (pops parents before children)
Definition: SubShapeID.h:42
Definition: TransformedShape.h:26
Definition: Vec3.h:16
JPH_INLINE void StoreFloat3(Float3 *outV) const
Store 3 floats to memory.
Definition: Vec3.inl:757
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
bool CanScaleBeRotated(QuatArg inRotation, Vec3Arg inScale)
Definition: ScaleHelpers.h:36
Vec3 RotateScale(QuatArg inRotation, Vec3Arg inScale)
Definition: ScaleHelpers.h:60
bool IsUniformScale(Vec3Arg inScale)
Test if a scale is uniform.
Definition: ScaleHelpers.h:21
Definition: CompoundShape.h:135
JPH_INLINE Quat GetRotation() const
Uncompress the rotation.
Definition: CompoundShape.h:226
Float3 mPositionCOM
Note: Position of center of mass of sub shape!
Definition: CompoundShape.h:232
JPH_INLINE Mat44 GetLocalTransformNoScale(Vec3Arg inScale) const
Definition: CompoundShape.h:181
bool mIsRotationIdentity
If mRotation is close to identity (put here because it falls in padding bytes)
Definition: CompoundShape.h:235
bool FromSettings(const CompoundShapeSettings::SubShapeSettings &inSettings, ShapeResult &outResult)
Definition: CompoundShape.h:140
bool IsValidScale(Vec3Arg inScale) const
Test if inScale is valid for this sub shape.
Definition: CompoundShape.h:188
JPH_INLINE void SetTransform(Vec3Arg inPosition, QuatArg inRotation, Vec3Arg inCenterOfMass)
Definition: CompoundShape.h:170
Float3 mRotation
Note: X, Y, Z of rotation quaternion - note we read 4 bytes beyond this so make sure there's somethin...
Definition: CompoundShape.h:233
uint32 mUserData
User data value (put here because it falls in padding bytes)
Definition: CompoundShape.h:234
Vec3 TransformScale(Vec3Arg inScale) const
Transform the scale to the local space of the child shape.
Definition: CompoundShape.h:198
JPH_INLINE Vec3 GetPositionCOM() const
Uncompress the center of mass position.
Definition: CompoundShape.h:214
JPH_INLINE void SetPositionCOM(Vec3Arg inPositionCOM)
Compress the center of mass position.
Definition: CompoundShape.h:208
JPH_INLINE void SetRotation(QuatArg inRotation)
Compress the rotation.
Definition: CompoundShape.h:220
RefConst< Shape > mShape
Definition: CompoundShape.h:231
Definition: CompoundShape.h:32
uint32 mUserData
User data value (can be used by the application for any purpose)
Definition: CompoundShape.h:39
Quat mRotation
Rotation of the sub shape.
Definition: CompoundShape.h:38
RefConst< ShapeSettings > mShape
Sub shape (either this or mShapePtr needs to be filled up)
Definition: CompoundShape.h:35
Vec3 mPosition
Position of the sub shape.
Definition: CompoundShape.h:37
RefConst< Shape > mShapePtr
Sub shape (either this or mShape needs to be filled up)
Definition: CompoundShape.h:36
An opaque buffer that holds shape specific information during GetTrianglesStart/Next.
Definition: Shape.h:336
Definition: ShapeCast.h:69