Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
GetTrianglesContext.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
8
10
11class PhysicsMaterial;
12
15{
16public:
18 GetTrianglesContextVertexList(Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale, Mat44Arg inLocalTransform, const Vec3 *inTriangleVertices, size_t inNumTriangleVertices, const PhysicsMaterial *inMaterial) :
19 mLocalToWorld(Mat44::sRotationTranslation(inRotation, inPositionCOM) * Mat44::sScale(inScale) * inLocalTransform),
20 mTriangleVertices(inTriangleVertices),
21 mNumTriangleVertices(inNumTriangleVertices),
22 mMaterial(inMaterial),
23 mIsInsideOut(ScaleHelpers::IsInsideOut(inScale))
24 {
25 static_assert(sizeof(GetTrianglesContextVertexList) <= sizeof(Shape::GetTrianglesContext), "GetTrianglesContext too small");
27 JPH_ASSERT(inNumTriangleVertices % 3 == 0);
28 }
29
31 int GetTrianglesNext(int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials)
32 {
33 JPH_ASSERT(inMaxTrianglesRequested >= Shape::cGetTrianglesMinTrianglesRequested);
34
35 int total_num_vertices = min(inMaxTrianglesRequested * 3, int(mNumTriangleVertices - mCurrentVertex));
36
37 if (mIsInsideOut)
38 {
39 // Store triangles flipped
40 for (const Vec3 *v = mTriangleVertices + mCurrentVertex, *v_end = v + total_num_vertices; v < v_end; v += 3)
41 {
42 (mLocalToWorld * v[0]).StoreFloat3(outTriangleVertices++);
43 (mLocalToWorld * v[2]).StoreFloat3(outTriangleVertices++);
44 (mLocalToWorld * v[1]).StoreFloat3(outTriangleVertices++);
45 }
46 }
47 else
48 {
49 // Store triangles
50 for (const Vec3 *v = mTriangleVertices + mCurrentVertex, *v_end = v + total_num_vertices; v < v_end; v += 3)
51 {
52 (mLocalToWorld * v[0]).StoreFloat3(outTriangleVertices++);
53 (mLocalToWorld * v[1]).StoreFloat3(outTriangleVertices++);
54 (mLocalToWorld * v[2]).StoreFloat3(outTriangleVertices++);
55 }
56 }
57
58 // Update the current vertex to point to the next vertex to get
59 mCurrentVertex += total_num_vertices;
60 int total_num_triangles = total_num_vertices / 3;
61
62 // Store materials
63 if (outMaterials != nullptr)
64 for (const PhysicsMaterial **m = outMaterials, **m_end = outMaterials + total_num_triangles; m < m_end; ++m)
65 *m = mMaterial;
66
67 return total_num_triangles;
68 }
69
71 static void sCreateHalfUnitSphereTop(std::vector<Vec3> &ioVertices, int inDetailLevel)
72 {
73 sCreateUnitSphereHelper(ioVertices, Vec3::sAxisX(), Vec3::sAxisY(), Vec3::sAxisZ(), inDetailLevel);
74 sCreateUnitSphereHelper(ioVertices, Vec3::sAxisY(), -Vec3::sAxisX(), Vec3::sAxisZ(), inDetailLevel);
75 sCreateUnitSphereHelper(ioVertices, Vec3::sAxisY(), Vec3::sAxisX(), -Vec3::sAxisZ(), inDetailLevel);
76 sCreateUnitSphereHelper(ioVertices, -Vec3::sAxisX(), Vec3::sAxisY(), -Vec3::sAxisZ(), inDetailLevel);
77 }
78
80 static void sCreateHalfUnitSphereBottom(std::vector<Vec3> &ioVertices, int inDetailLevel)
81 {
82 sCreateUnitSphereHelper(ioVertices, -Vec3::sAxisX(), -Vec3::sAxisY(), Vec3::sAxisZ(), inDetailLevel);
83 sCreateUnitSphereHelper(ioVertices, -Vec3::sAxisY(), Vec3::sAxisX(), Vec3::sAxisZ(), inDetailLevel);
84 sCreateUnitSphereHelper(ioVertices, Vec3::sAxisX(), -Vec3::sAxisY(), -Vec3::sAxisZ(), inDetailLevel);
85 sCreateUnitSphereHelper(ioVertices, -Vec3::sAxisY(), -Vec3::sAxisX(), -Vec3::sAxisZ(), inDetailLevel);
86 }
87
89 static void sCreateUnitOpenCylinder(std::vector<Vec3> &ioVertices, int inDetailLevel)
90 {
91 const Vec3 bottom_offset(0.0f, -2.0f, 0.0f);
92 int num_verts = 4 * (1 << inDetailLevel);
93 for (int i = 0; i < num_verts; ++i)
94 {
95 float angle1 = 2.0f * JPH_PI * (float(i) / num_verts);
96 float angle2 = 2.0f * JPH_PI * (float(i + 1) / num_verts);
97
98 Vec3 t1(Sin(angle1), 1.0f, Cos(angle1));
99 Vec3 t2(Sin(angle2), 1.0f, Cos(angle2));
100 Vec3 b1 = t1 + bottom_offset;
101 Vec3 b2 = t2 + bottom_offset;
102
103 ioVertices.push_back(t1);
104 ioVertices.push_back(b1);
105 ioVertices.push_back(t2);
106
107 ioVertices.push_back(t2);
108 ioVertices.push_back(b1);
109 ioVertices.push_back(b2);
110 }
111 }
112
113private:
115 static void sCreateUnitSphereHelper(std::vector<Vec3> &ioVertices, Vec3Arg inV1, Vec3Arg inV2, Vec3Arg inV3, int inLevel)
116 {
117 Vec3 center1 = (inV1 + inV2).Normalized();
118 Vec3 center2 = (inV2 + inV3).Normalized();
119 Vec3 center3 = (inV3 + inV1).Normalized();
120
121 if (inLevel > 0)
122 {
123 int new_level = inLevel - 1;
124 sCreateUnitSphereHelper(ioVertices, inV1, center1, center3, new_level);
125 sCreateUnitSphereHelper(ioVertices, center1, center2, center3, new_level);
126 sCreateUnitSphereHelper(ioVertices, center1, inV2, center2, new_level);
127 sCreateUnitSphereHelper(ioVertices, center3, center2, inV3, new_level);
128 }
129 else
130 {
131 ioVertices.push_back(inV1);
132 ioVertices.push_back(inV2);
133 ioVertices.push_back(inV3);
134 }
135 }
136
137 Mat44 mLocalToWorld;
138 const Vec3 * mTriangleVertices;
139 size_t mNumTriangleVertices;
140 size_t mCurrentVertex = 0;
141 const PhysicsMaterial * mMaterial;
142 bool mIsInsideOut;
143};
144
147{
148public:
150 GetTrianglesContextMultiVertexList(bool inIsInsideOut, const PhysicsMaterial *inMaterial) :
151 mMaterial(inMaterial),
152 mIsInsideOut(inIsInsideOut)
153 {
154 static_assert(sizeof(GetTrianglesContextMultiVertexList) <= sizeof(Shape::GetTrianglesContext), "GetTrianglesContext too small");
156 }
157
159 void AddPart(Mat44Arg inLocalToWorld, const Vec3 *inTriangleVertices, size_t inNumTriangleVertices)
160 {
161 JPH_ASSERT(inNumTriangleVertices % 3 == 0);
162
163 mParts.push_back({ inLocalToWorld, inTriangleVertices, inNumTriangleVertices });
164 }
165
167 int GetTrianglesNext(int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials)
168 {
169 JPH_ASSERT(inMaxTrianglesRequested >= Shape::cGetTrianglesMinTrianglesRequested);
170
171 int total_num_vertices = 0;
172 int max_vertices_requested = inMaxTrianglesRequested * 3;
173
174 // Loop over parts
175 for (; mCurrentPart < mParts.size(); ++mCurrentPart)
176 {
177 const Part &part = mParts[mCurrentPart];
178
179 // Calculate how many vertices to take from this part
180 int part_num_vertices = min(max_vertices_requested, int(part.mNumTriangleVertices - mCurrentVertex));
181 if (part_num_vertices == 0)
182 break;
183
184 max_vertices_requested -= part_num_vertices;
185 total_num_vertices += part_num_vertices;
186
187 if (mIsInsideOut)
188 {
189 // Store triangles flipped
190 for (const Vec3 *v = part.mTriangleVertices + mCurrentVertex, *v_end = v + part_num_vertices; v < v_end; v += 3)
191 {
192 (part.mLocalToWorld * v[0]).StoreFloat3(outTriangleVertices++);
193 (part.mLocalToWorld * v[2]).StoreFloat3(outTriangleVertices++);
194 (part.mLocalToWorld * v[1]).StoreFloat3(outTriangleVertices++);
195 }
196 }
197 else
198 {
199 // Store triangles
200 for (const Vec3 *v = part.mTriangleVertices + mCurrentVertex, *v_end = v + part_num_vertices; v < v_end; v += 3)
201 {
202 (part.mLocalToWorld * v[0]).StoreFloat3(outTriangleVertices++);
203 (part.mLocalToWorld * v[1]).StoreFloat3(outTriangleVertices++);
204 (part.mLocalToWorld * v[2]).StoreFloat3(outTriangleVertices++);
205 }
206 }
207
208 // Update the current vertex to point to the next vertex to get
209 mCurrentVertex += part_num_vertices;
210
211 // Check if we completed this part
212 if (mCurrentVertex < part.mNumTriangleVertices)
213 break;
214
215 // Reset current vertex for the next part
216 mCurrentVertex = 0;
217 }
218
219 int total_num_triangles = total_num_vertices / 3;
220
221 // Store materials
222 if (outMaterials != nullptr)
223 for (const PhysicsMaterial **m = outMaterials, **m_end = outMaterials + total_num_triangles; m < m_end; ++m)
224 *m = mMaterial;
225
226 return total_num_triangles;
227 }
228
229private:
230 struct Part
231 {
232 Mat44 mLocalToWorld;
233 const Vec3 * mTriangleVertices;
234 size_t mNumTriangleVertices;
235 };
236
238 uint mCurrentPart = 0;
239 size_t mCurrentVertex = 0;
240 const PhysicsMaterial * mMaterial;
241 bool mIsInsideOut;
242};
243
unsigned int uint
Definition: Core.h:439
#define JPH_NAMESPACE_END
Definition: Core.h:367
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:361
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
bool IsAligned(T inV, uint64 inAlignment)
Check if inV is inAlignment aligned.
Definition: Math.h:88
JPH_INLINE float Cos(float inX)
Cosine of x (input in radians)
Definition: Trigonometry.h:20
JPH_NAMESPACE_BEGIN JPH_INLINE float Sin(float inX)
Sine of x (input in radians)
Definition: Trigonometry.h:12
Class that holds 3 floats. Used as a storage class. Convert to Vec3 for calculations.
Definition: Float3.h:13
Implementation of GetTrianglesStart/Next that uses a multiple fixed lists of vertices for the triangl...
Definition: GetTrianglesContext.h:147
void AddPart(Mat44Arg inLocalToWorld, const Vec3 *inTriangleVertices, size_t inNumTriangleVertices)
Add a mesh part and its transform.
Definition: GetTrianglesContext.h:159
GetTrianglesContextMultiVertexList(bool inIsInsideOut, const PhysicsMaterial *inMaterial)
Constructor, to be called in GetTrianglesStart.
Definition: GetTrianglesContext.h:150
int GetTrianglesNext(int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials)
Definition: GetTrianglesContext.h:167
Implementation of GetTrianglesStart/Next that uses a fixed list of vertices for the triangles....
Definition: GetTrianglesContext.h:15
static void sCreateHalfUnitSphereTop(std::vector< Vec3 > &ioVertices, int inDetailLevel)
Helper function that creates a vertex list of a half unit sphere (top part)
Definition: GetTrianglesContext.h:71
static void sCreateHalfUnitSphereBottom(std::vector< Vec3 > &ioVertices, int inDetailLevel)
Helper function that creates a vertex list of a half unit sphere (bottom part)
Definition: GetTrianglesContext.h:80
int GetTrianglesNext(int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials)
Definition: GetTrianglesContext.h:31
GetTrianglesContextVertexList(Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale, Mat44Arg inLocalTransform, const Vec3 *inTriangleVertices, size_t inNumTriangleVertices, const PhysicsMaterial *inMaterial)
Constructor, to be called in GetTrianglesStart.
Definition: GetTrianglesContext.h:18
static void sCreateUnitOpenCylinder(std::vector< Vec3 > &ioVertices, int inDetailLevel)
Helper function that creates an open cylinder of half height 1 and radius 1.
Definition: GetTrianglesContext.h:89
Holds a 4x4 matrix of floats, but supports also operations on the 3x3 upper left part of the matrix.
Definition: Mat44.h:13
Definition: PhysicsMaterial.h:23
Definition: Quat.h:33
static constexpr int cGetTrianglesMinTrianglesRequested
This is the minimum amount of triangles that should be requested through GetTrianglesNext.
Definition: Shape.h:339
Simple variable length array backed by a fixed size buffer.
Definition: StaticArray.h:12
void push_back(const T &inElement)
Add element to the back of the array.
Definition: StaticArray.h:59
size_type size() const
Returns amount of elements in the array.
Definition: StaticArray.h:87
Definition: Vec3.h:16
static JPH_INLINE Vec3 sAxisX()
Vectors with the principal axis.
Definition: Vec3.h:52
static JPH_INLINE Vec3 sAxisY()
Definition: Vec3.h:53
static JPH_INLINE Vec3 sAxisZ()
Definition: Vec3.h:54
Helper functions to get properties of a scaling vector.
Definition: ScaleHelpers.h:13
An opaque buffer that holds shape specific information during GetTrianglesStart/Next.
Definition: Shape.h:336