Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Collision/Shape/MutableCompoundShape.h
9913 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/Collision/Shape/CompoundShape.h>
8
9
JPH_NAMESPACE_BEGIN
10
11
class CollideShapeSettings;
12
13
/// Class that constructs a MutableCompoundShape.
14
class JPH_EXPORT MutableCompoundShapeSettings final : public CompoundShapeSettings
15
{
16
JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, MutableCompoundShapeSettings)
17
18
public:
19
// See: ShapeSettings
20
virtual ShapeResult Create() const override;
21
};
22
23
/// A compound shape, sub shapes can be rotated and translated.
24
/// This shape is optimized for adding / removing and changing the rotation / translation of sub shapes but is less efficient in querying.
25
/// Shifts all child objects so that they're centered around the center of mass (which needs to be kept up to date by calling AdjustCenterOfMass).
26
///
27
/// Note: If you're using MutableCompoundShape and are querying data while modifying the shape you'll have a race condition.
28
/// In this case it is best to create a new MutableCompoundShape using the Clone function. You replace the shape on a body using BodyInterface::SetShape.
29
/// If a query is still working on the old shape, it will have taken a reference and keep the old shape alive until the query finishes.
30
///
31
/// When you modify a MutableCompoundShape, beware that the SubShapeIDs of all other shapes can change. So be careful when storing SubShapeIDs.
32
class JPH_EXPORT MutableCompoundShape final : public CompoundShape
33
{
34
public:
35
JPH_OVERRIDE_NEW_DELETE
36
37
/// Constructor
38
MutableCompoundShape() : CompoundShape(EShapeSubType::MutableCompound) { }
39
MutableCompoundShape(const MutableCompoundShapeSettings &inSettings, ShapeResult &outResult);
40
41
/// Clone this shape. Can be used to avoid race conditions. See the documentation of this class for more information.
42
Ref<MutableCompoundShape> Clone() const;
43
44
// See Shape::CastRay
45
virtual bool CastRay(const RayCast &inRay, const SubShapeIDCreator &inSubShapeIDCreator, RayCastResult &ioHit) const override;
46
virtual void CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter = { }) const override;
47
48
// See: Shape::CollidePoint
49
virtual void CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter = { }) const override;
50
51
// See Shape::CollectTransformedShapes
52
virtual void CollectTransformedShapes(const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale, const SubShapeIDCreator &inSubShapeIDCreator, TransformedShapeCollector &ioCollector, const ShapeFilter &inShapeFilter) const override;
53
54
// See: CompoundShape::GetIntersectingSubShapes
55
virtual int GetIntersectingSubShapes(const AABox &inBox, uint *outSubShapeIndices, int inMaxSubShapeIndices) const override;
56
57
// See: CompoundShape::GetIntersectingSubShapes
58
virtual int GetIntersectingSubShapes(const OrientedBox &inBox, uint *outSubShapeIndices, int inMaxSubShapeIndices) const override;
59
60
// See Shape
61
virtual void SaveBinaryState(StreamOut &inStream) const override;
62
63
// See Shape::GetStats
64
virtual Stats GetStats() const override { return Stats(sizeof(*this) + mSubShapes.size() * sizeof(SubShape) + mSubShapeBounds.size() * sizeof(Bounds), 0); }
65
66
///@{
67
/// @name Mutating shapes. Note that this is not thread safe, so you need to ensure that any bodies that use this shape are locked at the time of modification using BodyLockWrite. After modification you need to call BodyInterface::NotifyShapeChanged to update the broadphase and collision caches.
68
69
/// Adding a new shape.
70
/// Beware this can create a race condition if you're running collision queries in parallel. See class documentation for more information.
71
/// @param inPosition The position of the new shape
72
/// @param inRotation The orientation of the new shape
73
/// @param inShape The shape to add
74
/// @param inUserData User data that will be stored with the shape and can be retrieved using GetCompoundUserData
75
/// @param inIndex Index where to insert the shape, UINT_MAX to add to the end
76
/// @return The index of the newly added shape
77
uint AddShape(Vec3Arg inPosition, QuatArg inRotation, const Shape *inShape, uint32 inUserData = 0, uint inIndex = UINT_MAX);
78
79
/// Remove a shape by index.
80
/// Beware this can create a race condition if you're running collision queries in parallel. See class documentation for more information.
81
void RemoveShape(uint inIndex);
82
83
/// Modify the position / orientation of a shape.
84
/// Beware this can create a race condition if you're running collision queries in parallel. See class documentation for more information.
85
void ModifyShape(uint inIndex, Vec3Arg inPosition, QuatArg inRotation);
86
87
/// Modify the position / orientation and shape at the same time.
88
/// Beware this can create a race condition if you're running collision queries in parallel. See class documentation for more information.
89
void ModifyShape(uint inIndex, Vec3Arg inPosition, QuatArg inRotation, const Shape *inShape);
90
91
/// @brief Batch set positions / orientations, this avoids duplicate work due to bounding box calculation.
92
/// Beware this can create a race condition if you're running collision queries in parallel. See class documentation for more information.
93
/// @param inStartIndex Index of first shape to update
94
/// @param inNumber Number of shapes to update
95
/// @param inPositions A list of positions with arbitrary stride
96
/// @param inRotations A list of orientations with arbitrary stride
97
/// @param inPositionStride The position stride (the number of bytes between the first and second element)
98
/// @param inRotationStride The orientation stride (the number of bytes between the first and second element)
99
void ModifyShapes(uint inStartIndex, uint inNumber, const Vec3 *inPositions, const Quat *inRotations, uint inPositionStride = sizeof(Vec3), uint inRotationStride = sizeof(Quat));
100
101
/// Recalculate the center of mass and shift all objects so they're centered around it
102
/// (this needs to be done of dynamic bodies and if the center of mass changes significantly due to adding / removing / repositioning sub shapes or else the simulation will look unnatural)
103
/// Note that after adjusting the center of mass of an object you need to call BodyInterface::NotifyShapeChanged and Constraint::NotifyShapeChanged on the relevant bodies / constraints.
104
/// Beware this can create a race condition if you're running collision queries in parallel. See class documentation for more information.
105
void AdjustCenterOfMass();
106
107
///@}
108
109
// Register shape functions with the registry
110
static void sRegister();
111
112
protected:
113
// See: Shape::RestoreBinaryState
114
virtual void RestoreBinaryState(StreamIn &inStream) override;
115
116
private:
117
// Visitor for GetIntersectingSubShapes
118
template <class BoxType>
119
struct GetIntersectingSubShapesVisitorMC : public GetIntersectingSubShapesVisitor<BoxType>
120
{
121
using GetIntersectingSubShapesVisitor<BoxType>::GetIntersectingSubShapesVisitor;
122
123
using Result = UVec4;
124
125
JPH_INLINE Result TestBlock(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
126
{
127
return GetIntersectingSubShapesVisitor<BoxType>::TestBounds(inBoundsMinX, inBoundsMinY, inBoundsMinZ, inBoundsMaxX, inBoundsMaxY, inBoundsMaxZ);
128
}
129
130
JPH_INLINE bool ShouldVisitBlock(UVec4Arg inResult) const
131
{
132
return inResult.TestAnyTrue();
133
}
134
135
JPH_INLINE bool ShouldVisitSubShape(UVec4Arg inResult, uint inIndexInBlock) const
136
{
137
return inResult[inIndexInBlock] != 0;
138
}
139
};
140
141
/// Get the number of blocks of 4 bounding boxes
142
inline uint GetNumBlocks() const { return ((uint)mSubShapes.size() + 3) >> 2; }
143
144
/// Ensure that the mSubShapeBounds has enough space to store bounding boxes equivalent to the number of shapes in mSubShapes
145
void EnsureSubShapeBoundsCapacity();
146
147
/// Update mSubShapeBounds
148
/// @param inStartIdx First sub shape to update
149
/// @param inNumber Number of shapes to update
150
void CalculateSubShapeBounds(uint inStartIdx, uint inNumber);
151
152
/// Calculate mLocalBounds from mSubShapeBounds
153
void CalculateLocalBounds();
154
155
template <class Visitor>
156
JPH_INLINE void WalkSubShapes(Visitor &ioVisitor) const; ///< Walk the sub shapes and call Visitor::VisitShape for each sub shape encountered
157
158
// Helper functions called by CollisionDispatch
159
static void sCollideCompoundVsShape(const Shape *inShape1, const Shape *inShape2, Vec3Arg inScale1, Vec3Arg inScale2, Mat44Arg inCenterOfMassTransform1, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, const CollideShapeSettings &inCollideShapeSettings, CollideShapeCollector &ioCollector, const ShapeFilter &inShapeFilter);
160
static void sCollideShapeVsCompound(const Shape *inShape1, const Shape *inShape2, Vec3Arg inScale1, Vec3Arg inScale2, Mat44Arg inCenterOfMassTransform1, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, const CollideShapeSettings &inCollideShapeSettings, CollideShapeCollector &ioCollector, const ShapeFilter &inShapeFilter);
161
static void sCastShapeVsCompound(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const Shape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector);
162
163
struct Bounds
164
{
165
Vec4 mMinX;
166
Vec4 mMinY;
167
Vec4 mMinZ;
168
Vec4 mMaxX;
169
Vec4 mMaxY;
170
Vec4 mMaxZ;
171
};
172
173
Array<Bounds> mSubShapeBounds; ///< Bounding boxes of all sub shapes in SOA format (in blocks of 4 boxes), MinX 0..3, MinY 0..3, MinZ 0..3, MaxX 0..3, MaxY 0..3, MaxZ 0..3, MinX 4..7, MinY 4..7, ...
174
};
175
176
JPH_NAMESPACE_END
177
178