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 template <class A>
72 static void sCreateHalfUnitSphereTop(A &ioVertices, int inDetailLevel)
73 {
74 sCreateUnitSphereHelper(ioVertices, Vec3::sAxisX(), Vec3::sAxisY(), Vec3::sAxisZ(), inDetailLevel);
75 sCreateUnitSphereHelper(ioVertices, Vec3::sAxisY(), -Vec3::sAxisX(), Vec3::sAxisZ(), inDetailLevel);
76 sCreateUnitSphereHelper(ioVertices, Vec3::sAxisY(), Vec3::sAxisX(), -Vec3::sAxisZ(), inDetailLevel);
77 sCreateUnitSphereHelper(ioVertices, -Vec3::sAxisX(), Vec3::sAxisY(), -Vec3::sAxisZ(), inDetailLevel);
78 }
79
81 template <class A>
82 static void sCreateHalfUnitSphereBottom(A &ioVertices, int inDetailLevel)
83 {
84 sCreateUnitSphereHelper(ioVertices, -Vec3::sAxisX(), -Vec3::sAxisY(), Vec3::sAxisZ(), inDetailLevel);
85 sCreateUnitSphereHelper(ioVertices, -Vec3::sAxisY(), Vec3::sAxisX(), Vec3::sAxisZ(), inDetailLevel);
86 sCreateUnitSphereHelper(ioVertices, Vec3::sAxisX(), -Vec3::sAxisY(), -Vec3::sAxisZ(), inDetailLevel);
87 sCreateUnitSphereHelper(ioVertices, -Vec3::sAxisY(), -Vec3::sAxisX(), -Vec3::sAxisZ(), inDetailLevel);
88 }
89
91 template <class A>
92 static void sCreateUnitOpenCylinder(A &ioVertices, int inDetailLevel)
93 {
94 const Vec3 bottom_offset(0.0f, -2.0f, 0.0f);
95 int num_verts = 4 * (1 << inDetailLevel);
96 for (int i = 0; i < num_verts; ++i)
97 {
98 float angle1 = 2.0f * JPH_PI * (float(i) / num_verts);
99 float angle2 = 2.0f * JPH_PI * (float(i + 1) / num_verts);
100
101 Vec3 t1(Sin(angle1), 1.0f, Cos(angle1));
102 Vec3 t2(Sin(angle2), 1.0f, Cos(angle2));
103 Vec3 b1 = t1 + bottom_offset;
104 Vec3 b2 = t2 + bottom_offset;
105
106 ioVertices.push_back(t1);
107 ioVertices.push_back(b1);
108 ioVertices.push_back(t2);
109
110 ioVertices.push_back(t2);
111 ioVertices.push_back(b1);
112 ioVertices.push_back(b2);
113 }
114 }
115
116private:
118 template <class A>
119 static void sCreateUnitSphereHelper(A &ioVertices, Vec3Arg inV1, Vec3Arg inV2, Vec3Arg inV3, int inLevel)
120 {
121 Vec3 center1 = (inV1 + inV2).Normalized();
122 Vec3 center2 = (inV2 + inV3).Normalized();
123 Vec3 center3 = (inV3 + inV1).Normalized();
124
125 if (inLevel > 0)
126 {
127 int new_level = inLevel - 1;
128 sCreateUnitSphereHelper(ioVertices, inV1, center1, center3, new_level);
129 sCreateUnitSphereHelper(ioVertices, center1, center2, center3, new_level);
130 sCreateUnitSphereHelper(ioVertices, center1, inV2, center2, new_level);
131 sCreateUnitSphereHelper(ioVertices, center3, center2, inV3, new_level);
132 }
133 else
134 {
135 ioVertices.push_back(inV1);
136 ioVertices.push_back(inV2);
137 ioVertices.push_back(inV3);
138 }
139 }
140
141 Mat44 mLocalToWorld;
142 const Vec3 * mTriangleVertices;
143 size_t mNumTriangleVertices;
144 size_t mCurrentVertex = 0;
145 const PhysicsMaterial * mMaterial;
146 bool mIsInsideOut;
147};
148
151{
152public:
154 GetTrianglesContextMultiVertexList(bool inIsInsideOut, const PhysicsMaterial *inMaterial) :
155 mMaterial(inMaterial),
156 mIsInsideOut(inIsInsideOut)
157 {
158 static_assert(sizeof(GetTrianglesContextMultiVertexList) <= sizeof(Shape::GetTrianglesContext), "GetTrianglesContext too small");
160 }
161
163 void AddPart(Mat44Arg inLocalToWorld, const Vec3 *inTriangleVertices, size_t inNumTriangleVertices)
164 {
165 JPH_ASSERT(inNumTriangleVertices % 3 == 0);
166
167 mParts.push_back({ inLocalToWorld, inTriangleVertices, inNumTriangleVertices });
168 }
169
171 int GetTrianglesNext(int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials)
172 {
173 JPH_ASSERT(inMaxTrianglesRequested >= Shape::cGetTrianglesMinTrianglesRequested);
174
175 int total_num_vertices = 0;
176 int max_vertices_requested = inMaxTrianglesRequested * 3;
177
178 // Loop over parts
179 for (; mCurrentPart < mParts.size(); ++mCurrentPart)
180 {
181 const Part &part = mParts[mCurrentPart];
182
183 // Calculate how many vertices to take from this part
184 int part_num_vertices = min(max_vertices_requested, int(part.mNumTriangleVertices - mCurrentVertex));
185 if (part_num_vertices == 0)
186 break;
187
188 max_vertices_requested -= part_num_vertices;
189 total_num_vertices += part_num_vertices;
190
191 if (mIsInsideOut)
192 {
193 // Store triangles flipped
194 for (const Vec3 *v = part.mTriangleVertices + mCurrentVertex, *v_end = v + part_num_vertices; v < v_end; v += 3)
195 {
196 (part.mLocalToWorld * v[0]).StoreFloat3(outTriangleVertices++);
197 (part.mLocalToWorld * v[2]).StoreFloat3(outTriangleVertices++);
198 (part.mLocalToWorld * v[1]).StoreFloat3(outTriangleVertices++);
199 }
200 }
201 else
202 {
203 // Store triangles
204 for (const Vec3 *v = part.mTriangleVertices + mCurrentVertex, *v_end = v + part_num_vertices; v < v_end; v += 3)
205 {
206 (part.mLocalToWorld * v[0]).StoreFloat3(outTriangleVertices++);
207 (part.mLocalToWorld * v[1]).StoreFloat3(outTriangleVertices++);
208 (part.mLocalToWorld * v[2]).StoreFloat3(outTriangleVertices++);
209 }
210 }
211
212 // Update the current vertex to point to the next vertex to get
213 mCurrentVertex += part_num_vertices;
214
215 // Check if we completed this part
216 if (mCurrentVertex < part.mNumTriangleVertices)
217 break;
218
219 // Reset current vertex for the next part
220 mCurrentVertex = 0;
221 }
222
223 int total_num_triangles = total_num_vertices / 3;
224
225 // Store materials
226 if (outMaterials != nullptr)
227 for (const PhysicsMaterial **m = outMaterials, **m_end = outMaterials + total_num_triangles; m < m_end; ++m)
228 *m = mMaterial;
229
230 return total_num_triangles;
231 }
232
233private:
234 struct Part
235 {
236 Mat44 mLocalToWorld;
237 const Vec3 * mTriangleVertices;
238 size_t mNumTriangleVertices;
239 };
240
242 uint mCurrentPart = 0;
243 size_t mCurrentVertex = 0;
244 const PhysicsMaterial * mMaterial;
245 bool mIsInsideOut;
246};
247
unsigned int uint
Definition: Core.h:452
#define JPH_NAMESPACE_END
Definition: Core.h:378
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:372
#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:151
void AddPart(Mat44Arg inLocalToWorld, const Vec3 *inTriangleVertices, size_t inNumTriangleVertices)
Add a mesh part and its transform.
Definition: GetTrianglesContext.h:163
GetTrianglesContextMultiVertexList(bool inIsInsideOut, const PhysicsMaterial *inMaterial)
Constructor, to be called in GetTrianglesStart.
Definition: GetTrianglesContext.h:154
int GetTrianglesNext(int inMaxTrianglesRequested, Float3 *outTriangleVertices, const PhysicsMaterial **outMaterials)
Definition: GetTrianglesContext.h:171
Implementation of GetTrianglesStart/Next that uses a fixed list of vertices for the triangles....
Definition: GetTrianglesContext.h:15
static void sCreateHalfUnitSphereBottom(A &ioVertices, int inDetailLevel)
Helper function that creates a vertex list of a half unit sphere (bottom part)
Definition: GetTrianglesContext.h:82
static void sCreateUnitOpenCylinder(A &ioVertices, int inDetailLevel)
Helper function that creates an open cylinder of half height 1 and radius 1.
Definition: GetTrianglesContext.h:92
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 sCreateHalfUnitSphereTop(A &ioVertices, int inDetailLevel)
Helper function that creates a vertex list of a half unit sphere (top part)
Definition: GetTrianglesContext.h:72
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:351
Simple variable length array backed by a fixed size buffer.
Definition: StaticArray.h:14
void push_back(const T &inElement)
Add element to the back of the array.
Definition: StaticArray.h:61
size_type size() const
Returns amount of elements in the array.
Definition: StaticArray.h:89
Definition: Vec3.h:17
static JPH_INLINE Vec3 sAxisX()
Vectors with the principal axis.
Definition: Vec3.h:53
static JPH_INLINE Vec3 sAxisY()
Definition: Vec3.h:54
static JPH_INLINE Vec3 sAxisZ()
Definition: Vec3.h:55
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:348