Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Collision/Shape/ConvexHullShape.h
9917 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/ConvexShape.h>
8
#include <Jolt/Physics/PhysicsSettings.h>
9
#include <Jolt/Geometry/Plane.h>
10
#ifdef JPH_DEBUG_RENDERER
11
#include <Jolt/Renderer/DebugRenderer.h>
12
#endif // JPH_DEBUG_RENDERER
13
14
JPH_NAMESPACE_BEGIN
15
16
/// Class that constructs a ConvexHullShape
17
class JPH_EXPORT ConvexHullShapeSettings final : public ConvexShapeSettings
18
{
19
JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, ConvexHullShapeSettings)
20
21
public:
22
/// Default constructor for deserialization
23
ConvexHullShapeSettings() = default;
24
25
/// Create a convex hull from inPoints and maximum convex radius inMaxConvexRadius, the radius is automatically lowered if the hull requires it.
26
/// (internally this will be subtracted so the total size will not grow with the convex radius).
27
ConvexHullShapeSettings(const Vec3 *inPoints, int inNumPoints, float inMaxConvexRadius = cDefaultConvexRadius, const PhysicsMaterial *inMaterial = nullptr) : ConvexShapeSettings(inMaterial), mPoints(inPoints, inPoints + inNumPoints), mMaxConvexRadius(inMaxConvexRadius) { }
28
ConvexHullShapeSettings(const Array<Vec3> &inPoints, float inConvexRadius = cDefaultConvexRadius, const PhysicsMaterial *inMaterial = nullptr) : ConvexShapeSettings(inMaterial), mPoints(inPoints), mMaxConvexRadius(inConvexRadius) { }
29
30
// See: ShapeSettings
31
virtual ShapeResult Create() const override;
32
33
Array<Vec3> mPoints; ///< Points to create the hull from. Note that these points don't need to be the vertices of the convex hull, they can contain interior points or points on faces/edges.
34
float mMaxConvexRadius = 0.0f; ///< Convex radius as supplied by the constructor. Note that during hull creation the convex radius can be made smaller if the value is too big for the hull.
35
float mMaxErrorConvexRadius = 0.05f; ///< Maximum distance between the shrunk hull + convex radius and the actual hull.
36
float mHullTolerance = 1.0e-3f; ///< Points are allowed this far outside of the hull (increasing this yields a hull with less vertices). Note that the actual used value can be larger if the points of the hull are far apart.
37
};
38
39
/// A convex hull
40
class JPH_EXPORT ConvexHullShape final : public ConvexShape
41
{
42
public:
43
JPH_OVERRIDE_NEW_DELETE
44
45
/// Maximum amount of points supported in a convex hull. Note that while constructing a hull, interior points are discarded so you can provide more points.
46
/// The ConvexHullShapeSettings::Create function will return an error when too many points are provided.
47
static constexpr int cMaxPointsInHull = 256;
48
49
/// Constructor
50
ConvexHullShape() : ConvexShape(EShapeSubType::ConvexHull) { }
51
ConvexHullShape(const ConvexHullShapeSettings &inSettings, ShapeResult &outResult);
52
53
// See Shape::GetCenterOfMass
54
virtual Vec3 GetCenterOfMass() const override { return mCenterOfMass; }
55
56
// See Shape::GetLocalBounds
57
virtual AABox GetLocalBounds() const override { return mLocalBounds; }
58
59
// See Shape::GetInnerRadius
60
virtual float GetInnerRadius() const override { return mInnerRadius; }
61
62
// See Shape::GetMassProperties
63
virtual MassProperties GetMassProperties() const override;
64
65
// See Shape::GetSurfaceNormal
66
virtual Vec3 GetSurfaceNormal(const SubShapeID &inSubShapeID, Vec3Arg inLocalSurfacePosition) const override;
67
68
// See Shape::GetSupportingFace
69
virtual void GetSupportingFace(const SubShapeID &inSubShapeID, Vec3Arg inDirection, Vec3Arg inScale, Mat44Arg inCenterOfMassTransform, SupportingFace &outVertices) const override;
70
71
// See ConvexShape::GetSupportFunction
72
virtual const Support * GetSupportFunction(ESupportMode inMode, SupportBuffer &inBuffer, Vec3Arg inScale) const override;
73
74
// See Shape::GetSubmergedVolume
75
virtual void GetSubmergedVolume(Mat44Arg inCenterOfMassTransform, Vec3Arg inScale, const Plane &inSurface, float &outTotalVolume, float &outSubmergedVolume, Vec3 &outCenterOfBuoyancy JPH_IF_DEBUG_RENDERER(, RVec3Arg inBaseOffset)) const override;
76
77
#ifdef JPH_DEBUG_RENDERER
78
// See Shape::Draw
79
virtual void Draw(DebugRenderer *inRenderer, RMat44Arg inCenterOfMassTransform, Vec3Arg inScale, ColorArg inColor, bool inUseMaterialColors, bool inDrawWireframe) const override;
80
81
/// Debugging helper draw function that draws how all points are moved when a shape is shrunk by the convex radius
82
void DrawShrunkShape(DebugRenderer *inRenderer, RMat44Arg inCenterOfMassTransform, Vec3Arg inScale) const;
83
#endif // JPH_DEBUG_RENDERER
84
85
// See Shape::CastRay
86
virtual bool CastRay(const RayCast &inRay, const SubShapeIDCreator &inSubShapeIDCreator, RayCastResult &ioHit) const override;
87
virtual void CastRay(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter = { }) const override;
88
89
// See: Shape::CollidePoint
90
virtual void CollidePoint(Vec3Arg inPoint, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter = { }) const override;
91
92
// See: Shape::CollideSoftBodyVertices
93
virtual void CollideSoftBodyVertices(Mat44Arg inCenterOfMassTransform, Vec3Arg inScale, const CollideSoftBodyVertexIterator &inVertices, uint inNumVertices, int inCollidingShapeIndex) const override;
94
95
// See Shape::GetTrianglesStart
96
virtual void GetTrianglesStart(GetTrianglesContext &ioContext, const AABox &inBox, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale) const override;
97
98
// See Shape::GetTrianglesNext
99
virtual int GetTrianglesNext(GetTrianglesContext &ioContext, int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials = nullptr) const override;
100
101
// See Shape
102
virtual void SaveBinaryState(StreamOut &inStream) const override;
103
104
// See Shape::GetStats
105
virtual Stats GetStats() const override;
106
107
// See Shape::GetVolume
108
virtual float GetVolume() const override { return mVolume; }
109
110
/// Get the convex radius of this convex hull
111
float GetConvexRadius() const { return mConvexRadius; }
112
113
/// Get the planes of this convex hull
114
const Array<Plane> & GetPlanes() const { return mPlanes; }
115
116
/// Get the number of vertices in this convex hull
117
inline uint GetNumPoints() const { return uint(mPoints.size()); }
118
119
/// Get a vertex of this convex hull relative to the center of mass
120
inline Vec3 GetPoint(uint inIndex) const { return mPoints[inIndex].mPosition; }
121
122
/// Get the number of faces in this convex hull
123
inline uint GetNumFaces() const { return uint(mFaces.size()); }
124
125
/// Get the number of vertices in a face
126
inline uint GetNumVerticesInFace(uint inFaceIndex) const { return mFaces[inFaceIndex].mNumVertices; }
127
128
/// Get the vertices indices of a face
129
/// @param inFaceIndex Index of the face.
130
/// @param inMaxVertices Maximum number of vertices to return.
131
/// @param outVertices Array of vertices indices, must be at least inMaxVertices in size, the vertices are returned in counter clockwise order and the positions can be obtained using GetPoint(index).
132
/// @return Number of vertices in face, if this is bigger than inMaxVertices, not all vertices were retrieved.
133
inline uint GetFaceVertices(uint inFaceIndex, uint inMaxVertices, uint *outVertices) const
134
{
135
const Face &face = mFaces[inFaceIndex];
136
const uint8 *first_vertex = mVertexIdx.data() + face.mFirstVertex;
137
uint num_vertices = min<uint>(face.mNumVertices, inMaxVertices);
138
for (uint i = 0; i < num_vertices; ++i)
139
outVertices[i] = first_vertex[i];
140
return face.mNumVertices;
141
}
142
143
// Register shape functions with the registry
144
static void sRegister();
145
146
#ifdef JPH_DEBUG_RENDERER
147
/// Draw the outlines of the faces of the convex hull when drawing the shape
148
inline static bool sDrawFaceOutlines = false;
149
#endif // JPH_DEBUG_RENDERER
150
151
protected:
152
// See: Shape::RestoreBinaryState
153
virtual void RestoreBinaryState(StreamIn &inStream) override;
154
155
private:
156
/// Helper function that returns the min and max fraction along the ray that hits the convex hull. Returns false if there is no hit.
157
bool CastRayHelper(const RayCast &inRay, float &outMinFraction, float &outMaxFraction) const;
158
159
/// Class for GetTrianglesStart/Next
160
class CHSGetTrianglesContext;
161
162
/// Classes for GetSupportFunction
163
class HullNoConvex;
164
class HullWithConvex;
165
class HullWithConvexScaled;
166
167
struct Face
168
{
169
uint16 mFirstVertex; ///< First index in mVertexIdx to use
170
uint16 mNumVertices = 0; ///< Number of vertices in the mVertexIdx to use
171
};
172
173
static_assert(sizeof(Face) == 4, "Unexpected size");
174
static_assert(alignof(Face) == 2, "Unexpected alignment");
175
176
struct Point
177
{
178
Vec3 mPosition; ///< Position of vertex
179
int mNumFaces = 0; ///< Number of faces in the face array below
180
int mFaces[3] = { -1, -1, -1 }; ///< Indices of 3 neighboring faces with the biggest difference in normal (used to shift vertices for convex radius)
181
};
182
183
static_assert(sizeof(Point) == 32, "Unexpected size");
184
static_assert(alignof(Point) == JPH_VECTOR_ALIGNMENT, "Unexpected alignment");
185
186
Vec3 mCenterOfMass; ///< Center of mass of this convex hull
187
Mat44 mInertia; ///< Inertia matrix assuming density is 1 (needs to be multiplied by density)
188
AABox mLocalBounds; ///< Local bounding box for the convex hull
189
Array<Point> mPoints; ///< Points on the convex hull surface
190
Array<Face> mFaces; ///< Faces of the convex hull surface
191
Array<Plane> mPlanes; ///< Planes for the faces (1-on-1 with mFaces array, separate because they need to be 16 byte aligned)
192
Array<uint8> mVertexIdx; ///< A list of vertex indices (indexing in mPoints) for each of the faces
193
float mConvexRadius = 0.0f; ///< Convex radius
194
float mVolume; ///< Total volume of the convex hull
195
float mInnerRadius = FLT_MAX; ///< Radius of the biggest sphere that fits entirely in the convex hull
196
197
#ifdef JPH_DEBUG_RENDERER
198
mutable DebugRenderer::GeometryRef mGeometry;
199
#endif // JPH_DEBUG_RENDERER
200
};
201
202
JPH_NAMESPACE_END
203
204