@perplexdotgg/bounce 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/build/bounce.d.ts +39501 -0
  2. package/build/bounce.js +17166 -0
  3. package/package.json +1 -1
  4. package/src/builders/ConvexHullBuilder.ts +0 -437
  5. package/src/builders/ConvexHullBuilder2d.ts +0 -344
  6. package/src/builders/ConvexHullBuilder3d.ts +0 -1689
  7. package/src/builders/HeightMapBuilder.ts +0 -414
  8. package/src/builders/TriangleMeshBuilder.ts +0 -92
  9. package/src/collision/CastShapesModule.ts +0 -184
  10. package/src/collision/CollideShapesModule.ts +0 -152
  11. package/src/collision/HeightMapCaster.ts +0 -38
  12. package/src/collision/HeightMapCollider.ts +0 -33
  13. package/src/collision/TriangleCaster.ts +0 -249
  14. package/src/collision/TriangleCollider.ts +0 -308
  15. package/src/collision/TriangleCollider2.ts +0 -379
  16. package/src/collision/activeEdge.ts +0 -146
  17. package/src/collision/cast/cast.ts +0 -139
  18. package/src/collision/cast/castCompoundVsCompound.ts +0 -59
  19. package/src/collision/cast/castCompoundVsConvex.ts +0 -116
  20. package/src/collision/cast/castConvexVsCompound.ts +0 -123
  21. package/src/collision/cast/castConvexVsConvex.ts +0 -213
  22. package/src/collision/cast/castConvexVsHeightMap.ts +0 -73
  23. package/src/collision/cast/castConvexVsTriangleMesh.ts +0 -56
  24. package/src/collision/cast/castRayVsCompound.ts +0 -44
  25. package/src/collision/cast/castRayVsConvex.ts +0 -45
  26. package/src/collision/cast/castRayVsHeightMap.ts +0 -58
  27. package/src/collision/cast/castRayVsTriangleMesh.ts +0 -58
  28. package/src/collision/closestPoints/closestPoints.ts +0 -23
  29. package/src/collision/closestPoints/computeBarycentricCoordinates2d.ts +0 -32
  30. package/src/collision/closestPoints/computeBarycentricCoordinates3d.ts +0 -81
  31. package/src/collision/closestPoints/computeClosestPointOnLine.ts +0 -30
  32. package/src/collision/closestPoints/computeClosestPointOnTetrahedron.ts +0 -96
  33. package/src/collision/closestPoints/computeClosestPointOnTriangle.ts +0 -195
  34. package/src/collision/closestPoints/isOriginOutsideOfPlane.ts +0 -25
  35. package/src/collision/closestPoints/isOriginOutsideOfTrianglePlanes.ts +0 -72
  36. package/src/collision/collide/collide.ts +0 -146
  37. package/src/collision/collide/collideCompoundVsCompound.ts +0 -60
  38. package/src/collision/collide/collideCompoundVsConvex.ts +0 -59
  39. package/src/collision/collide/collideCompoundVsHeightMap.ts +0 -73
  40. package/src/collision/collide/collideCompoundVsTriangleMesh.ts +0 -56
  41. package/src/collision/collide/collideConvexVsCompound.ts +0 -57
  42. package/src/collision/collide/collideConvexVsConvex.ts +0 -225
  43. package/src/collision/collide/collideConvexVsConvexImp.ts +0 -236
  44. package/src/collision/collide/collideConvexVsHeightMap.ts +0 -53
  45. package/src/collision/collide/collideConvexVsTriangleMesh.ts +0 -58
  46. package/src/collision/collide/collideHeightMapVsCompound.ts +0 -69
  47. package/src/collision/collide/collideHeightMapVsConvex.ts +0 -53
  48. package/src/collision/collide/collideSphereVsSphere.ts +0 -81
  49. package/src/collision/collide/collideTriangleMeshVsCompound.ts +0 -58
  50. package/src/collision/collide/collideTriangleMeshVsConvex.ts +0 -58
  51. package/src/collision/epa/EpaConvexHullBuilder.ts +0 -397
  52. package/src/collision/epa/StaticArray.ts +0 -154
  53. package/src/collision/epa/TriangleFactory.ts +0 -32
  54. package/src/collision/epa/arrays.ts +0 -99
  55. package/src/collision/epa/binaryHeap.ts +0 -82
  56. package/src/collision/epa/structs.ts +0 -227
  57. package/src/collision/gjk/GjkModule.ts +0 -864
  58. package/src/collision/gjk/PenetrationDepthModule.ts +0 -493
  59. package/src/collision/gjk/SupportPoints.ts +0 -50
  60. package/src/collision/imp/MinkowskiDifference.ts +0 -36
  61. package/src/collision/imp/computeExploredDistanceLowerUpperBound.ts +0 -40
  62. package/src/collision/imp/finalizeImpResult.ts +0 -69
  63. package/src/collision/imp/findContactImp.ts +0 -196
  64. package/src/collision/imp/imp.ts +0 -28
  65. package/src/collision/imp/incrementalMinimumDistanceExploreDirection.ts +0 -207
  66. package/src/collision/mpr/findPortal.ts +0 -152
  67. package/src/collision/mpr/mpr.ts +0 -29
  68. package/src/collision/mpr/updatePortal.ts +0 -52
  69. package/src/constraints/BaseConstraint.ts +0 -50
  70. package/src/constraints/ConstraintOptions.ts +0 -22
  71. package/src/constraints/ConstraintSolver.ts +0 -119
  72. package/src/constraints/DistanceConstraint.ts +0 -229
  73. package/src/constraints/FixedConstraint.ts +0 -203
  74. package/src/constraints/HingeConstraint.ts +0 -460
  75. package/src/constraints/PointConstraint.ts +0 -108
  76. package/src/constraints/components/AngleComponent.ts +0 -226
  77. package/src/constraints/components/AxisComponent.ts +0 -263
  78. package/src/constraints/components/HingeComponent.ts +0 -215
  79. package/src/constraints/components/Motor.ts +0 -36
  80. package/src/constraints/components/PointConstraintComponent.ts +0 -179
  81. package/src/constraints/components/RotationEulerComponent.ts +0 -139
  82. package/src/constraints/components/Spring.ts +0 -30
  83. package/src/constraints/components/SpringComponent.ts +0 -71
  84. package/src/constraints/types.ts +0 -6
  85. package/src/helpers.ts +0 -147
  86. package/src/index.ts +0 -50
  87. package/src/math/BasicTransform.ts +0 -19
  88. package/src/math/NumberValue.ts +0 -13
  89. package/src/math/isometry.ts +0 -64
  90. package/src/math/mat3.ts +0 -529
  91. package/src/math/mat4.ts +0 -588
  92. package/src/math/quat.ts +0 -193
  93. package/src/math/scalar.ts +0 -81
  94. package/src/math/tensor.ts +0 -17
  95. package/src/math/vec3.ts +0 -589
  96. package/src/math/vec4.ts +0 -10
  97. package/src/physics/Body.ts +0 -581
  98. package/src/physics/CollisionFilter.ts +0 -52
  99. package/src/physics/SleepModule.ts +0 -163
  100. package/src/physics/broadphase/BodyPairsModule.ts +0 -363
  101. package/src/physics/broadphase/BvhModule.ts +0 -237
  102. package/src/physics/broadphase/BvhTree.ts +0 -803
  103. package/src/physics/broadphase/ConstraintPairsModule.ts +0 -385
  104. package/src/physics/broadphase/TriangleMeshBvhTree.ts +0 -379
  105. package/src/physics/manifold/ContactManifold.ts +0 -227
  106. package/src/physics/manifold/ContactManifoldModule.ts +0 -623
  107. package/src/physics/manifold/Face.ts +0 -119
  108. package/src/physics/manifold/ManifoldCache.ts +0 -116
  109. package/src/physics/manifold/clipping/clipPolyVsEdge.ts +0 -131
  110. package/src/physics/manifold/clipping/clipPolyVsPlane.ts +0 -73
  111. package/src/physics/manifold/clipping/clipPolyVsPoly.ts +0 -72
  112. package/src/physics/narrowphase/CollideBodiesModule.ts +0 -755
  113. package/src/physics/solver/ContactConstraintModule.ts +0 -659
  114. package/src/physics/solver/ManifoldConstraint.ts +0 -420
  115. package/src/physics/solver/estimateCollisionResponse.ts +0 -146
  116. package/src/shape/Aabb.ts +0 -400
  117. package/src/shape/Box.ts +0 -231
  118. package/src/shape/Capsule.ts +0 -332
  119. package/src/shape/CompoundShape.ts +0 -288
  120. package/src/shape/Convex.ts +0 -130
  121. package/src/shape/ConvexHull.ts +0 -423
  122. package/src/shape/Cylinder.ts +0 -313
  123. package/src/shape/HeightMap.ts +0 -511
  124. package/src/shape/Line.ts +0 -14
  125. package/src/shape/Plane.ts +0 -116
  126. package/src/shape/Ray.ts +0 -81
  127. package/src/shape/Segment.ts +0 -25
  128. package/src/shape/Shape.ts +0 -77
  129. package/src/shape/Sphere.ts +0 -181
  130. package/src/shape/TransformedShape.ts +0 -51
  131. package/src/shape/Triangle.ts +0 -122
  132. package/src/shape/TriangleMesh.ts +0 -186
  133. package/src/types.ts +0 -1
  134. package/src/world.ts +0 -1335
@@ -1,414 +0,0 @@
1
- import { InputType } from "monomorph";
2
- import { computeClosestPowersOfTwo, degreesToRadians, isPowerOf2 } from "../math/scalar";
3
- import { Vec3 } from "../math/vec3";
4
- import {
5
- computeCornerIndicesInGrid,
6
- computeNumberOfCells,
7
- computeNumberOfLevels,
8
- HeightMap,
9
- updateShape,
10
- } from "../shape/HeightMap";
11
- import { Triangle } from "../shape/Triangle";
12
- import { Tuple4 } from "../types";
13
- import { isEdgeActive } from "../collision/activeEdge";
14
-
15
- const cos5Degrees = Math.cos(degreesToRadians(5));
16
-
17
- const a1 = /*@__PURE__*/ Vec3.create();
18
- const b1 = /*@__PURE__*/ Vec3.create();
19
- const c1 = /*@__PURE__*/ Vec3.create();
20
- const a2 = /*@__PURE__*/ Vec3.create();
21
- const b2 = /*@__PURE__*/ Vec3.create();
22
- const c2 = /*@__PURE__*/ Vec3.create();
23
- const triangleLeftOfEdge = /*@__PURE__*/ Triangle.create();
24
- const triangleRightOfEdge = /*@__PURE__*/ Triangle.create();
25
- const normalLeftOfEdge = /*@__PURE__*/ Vec3.create();
26
- const normalRightOfEdge = /*@__PURE__*/ Vec3.create();
27
- const edge = /*@__PURE__*/ Vec3.create();
28
-
29
- export class HeightMapBuilder {
30
- buildHeightMapQuadtree(heightMap: HeightMap): void {
31
- const numberOfSubdivisions = heightMap.subdivisionsCount;
32
-
33
- // #v-ifdef DEV
34
- // assert that number of subdivisions is a power of 2
35
- if (isPowerOf2(numberOfSubdivisions) === false) {
36
- throw new Error(`expected number of subdivisions to be a power of 2, got ${numberOfSubdivisions} instead`);
37
- }
38
- // #v-endif
39
-
40
- const index: Tuple4<number> = [0, 0, 0, 0];
41
-
42
- // walk through each layer starting from the bottom, aggregating min and max heights for each cell
43
- let currentNumberOfSubdivisions = heightMap.subdivisionsCount;
44
- while (currentNumberOfSubdivisions >= 1) {
45
- // get the level of the current layer
46
- const level = Math.log2(currentNumberOfSubdivisions);
47
-
48
- // get offset for the current layer
49
- const offset = computeNumberOfCells(currentNumberOfSubdivisions / 2);
50
-
51
- // case: we're in the bottom layer, the 4 "children" heights are queried from the heightMap data itself
52
- if (currentNumberOfSubdivisions === heightMap.subdivisionsCount) {
53
- // for each cell in the current layer
54
- for (let x = 0; x < currentNumberOfSubdivisions; x++) {
55
- for (let z = 0; z < currentNumberOfSubdivisions; z++) {
56
- // get the current level corner vertex indices
57
- computeCornerIndicesInGrid(index, x, z, currentNumberOfSubdivisions + 1);
58
-
59
- const blHeight = heightMap.heights[index[0]];
60
- const brHeight = heightMap.heights[index[1]];
61
- const tlHeight = heightMap.heights[index[2]];
62
- const trHeight = heightMap.heights[index[3]];
63
-
64
- const minHeight = Math.min(blHeight, brHeight, tlHeight, trHeight);
65
- const maxHeight = Math.max(blHeight, brHeight, tlHeight, trHeight);
66
-
67
- const flatIndex = z + x * currentNumberOfSubdivisions;
68
- heightMap.minHeights[offset + flatIndex] = minHeight;
69
- heightMap.maxHeights[offset + flatIndex] = maxHeight;
70
- heightMap.levels[offset + flatIndex] = level;
71
- }
72
- }
73
- }
74
- // case: we're in a higher layer, the 4 "children" heights are queried from the lower layer
75
- else {
76
- // get the lower level offset
77
- const lowerOffset = computeNumberOfCells(currentNumberOfSubdivisions);
78
-
79
- for (let x = 0; x < currentNumberOfSubdivisions; x++) {
80
- for (let z = 0; z < currentNumberOfSubdivisions; z++) {
81
- // get the lower level corner block indices
82
- computeCornerIndicesInGrid(index, x * 2, z * 2, currentNumberOfSubdivisions * 2);
83
-
84
- const blMinHeight = heightMap.minHeights[lowerOffset + index[0]];
85
- const brMinHeight = heightMap.minHeights[lowerOffset + index[1]];
86
- const tlMinHeight = heightMap.minHeights[lowerOffset + index[2]];
87
- const trMinHeight = heightMap.minHeights[lowerOffset + index[3]];
88
-
89
- const blMaxHeight = heightMap.maxHeights[lowerOffset + index[0]];
90
- const brMaxHeight = heightMap.maxHeights[lowerOffset + index[1]];
91
- const tlMaxHeight = heightMap.maxHeights[lowerOffset + index[2]];
92
- const trMaxHeight = heightMap.maxHeights[lowerOffset + index[3]];
93
-
94
- const minHeight = Math.min(blMinHeight, brMinHeight, tlMinHeight, trMinHeight);
95
- const maxHeight = Math.max(blMaxHeight, brMaxHeight, tlMaxHeight, trMaxHeight);
96
-
97
- const flatIndex = z + x * currentNumberOfSubdivisions;
98
- heightMap.minHeights[offset + flatIndex] = minHeight;
99
- heightMap.maxHeights[offset + flatIndex] = maxHeight;
100
- heightMap.levels[offset + flatIndex] = level;
101
- }
102
- }
103
- }
104
-
105
- currentNumberOfSubdivisions /= 2;
106
- }
107
- }
108
-
109
- buildActiveEdges(heightMap: HeightMap): void {
110
- // TODO: this can be cleaned up to avoid repetition of logic
111
-
112
- // we store 1 uint32 per triangle, using the first 3 bits to represent the active edges
113
-
114
- // for each quad
115
-
116
- let activeEdge = 0b000;
117
- let result = 0b000;
118
-
119
- for (let row = 0; row < heightMap.subdivisionsCount; row++) {
120
- for (let col = 0; col < heightMap.subdivisionsCount; col++) {
121
- // compute flat index
122
- const index = col + row * heightMap.subdivisionsCount;
123
-
124
- // outer edge flags
125
- const isFirstRow = row === 0;
126
- const isLastRow = row === heightMap.subdivisionsCount - 1;
127
- const isFirstColumn = col === 0;
128
- const isLastColumn = col === heightMap.subdivisionsCount - 1;
129
-
130
- // triangle indices
131
- const firstTriangleIndex = index * 2 + 0;
132
- const secondTriangleIndex = index * 2 + 1;
133
-
134
- // TRIANGLE ABC
135
- activeEdge = 0b000;
136
- result = 0b000;
137
-
138
- // check if edge 0 is active (AB)
139
-
140
- // if edge is an outer edge, it is active
141
- if (isFirstRow) {
142
- activeEdge |= 0b001;
143
- }
144
- // if edge is an interior edge, get both triangles on either side of the edge
145
- else {
146
- // get triangles
147
- heightMap.computeVertex(a1, col + 0, row + 0);
148
- heightMap.computeVertex(b1, col + 1, row + 0);
149
- heightMap.computeVertex(c1, col + 0, row + 1);
150
- triangleLeftOfEdge.set({ a: a1, b: b1, c: c1 });
151
-
152
- heightMap.computeVertex(a2, col + 1, row + 0);
153
- heightMap.computeVertex(b2, col + 0, row + 0);
154
- heightMap.computeVertex(c2, col + 1, row - 1);
155
- triangleRightOfEdge.set({ a: a2, b: b2, c: c2 });
156
-
157
- // get normals
158
- triangleLeftOfEdge.computeNormal(normalLeftOfEdge);
159
- triangleRightOfEdge.computeNormal(normalRightOfEdge);
160
-
161
- // get edge direction
162
- edge.subtractVectors(b1, a1);
163
- edge.normalize();
164
-
165
- // check if edge is active
166
- result = isEdgeActive(normalLeftOfEdge, normalRightOfEdge, edge, cos5Degrees) ? 0b001 : 0b000;
167
- activeEdge |= result;
168
- }
169
-
170
- // check if edge 1 is active (BC)
171
-
172
- // this edge is always interior, get both triangles on either side of the edge
173
-
174
- // get triangles, left is ABC, right is BDC
175
- heightMap.computeVertex(a1, col + 1, row + 0);
176
- heightMap.computeVertex(b1, col + 0, row + 1);
177
- heightMap.computeVertex(c1, col + 0, row + 0);
178
- triangleLeftOfEdge.set({ a: a1, b: b1, c: c1 });
179
-
180
- heightMap.computeVertex(a2, col + 1, row + 0);
181
- heightMap.computeVertex(b2, col + 1, row + 1);
182
- heightMap.computeVertex(c2, col + 0, row + 1);
183
- triangleRightOfEdge.set({ a: a2, b: b2, c: c2 });
184
-
185
- // get normals
186
- triangleLeftOfEdge.computeNormal(normalLeftOfEdge);
187
- triangleRightOfEdge.computeNormal(normalRightOfEdge);
188
-
189
- // get edge direction
190
- edge.subtractVectors(b1, a1);
191
- edge.normalize();
192
-
193
- // check if edge is active
194
- result = isEdgeActive(normalLeftOfEdge, normalRightOfEdge, edge, cos5Degrees) ? 0b010 : 0b000;
195
- activeEdge |= result;
196
-
197
- // check if edge 2 is active (CA)
198
-
199
- // if edge is an outer edge, it is active
200
- if (isFirstColumn) {
201
- activeEdge |= 0b100;
202
- }
203
-
204
- // if edge is an interior edge, get both triangles on either side of the edge
205
- else {
206
- // get triangles
207
- heightMap.computeVertex(a1, col + 0, row + 1);
208
- heightMap.computeVertex(b1, col + 0, row + 0);
209
- heightMap.computeVertex(c1, col + 1, row + 0);
210
- triangleLeftOfEdge.set({ a: a1, b: b1, c: c1 });
211
-
212
- heightMap.computeVertex(a2, col + 0, row + 1);
213
- heightMap.computeVertex(b2, col - 1, row + 1);
214
- heightMap.computeVertex(c2, col + 0, row + 0);
215
- triangleRightOfEdge.set({ a: a2, b: b2, c: c2 });
216
-
217
- // get normals
218
- triangleLeftOfEdge.computeNormal(normalLeftOfEdge);
219
- triangleRightOfEdge.computeNormal(normalRightOfEdge);
220
-
221
- // get edge direction
222
- edge.subtractVectors(b1, a1);
223
- edge.normalize();
224
-
225
- // check if edge is active
226
- result = isEdgeActive(normalLeftOfEdge, normalRightOfEdge, edge, cos5Degrees) ? 0b100 : 0b000;
227
- activeEdge |= result;
228
- }
229
-
230
- // set active edges for triangle ABC
231
- heightMap.activeEdges[firstTriangleIndex] = activeEdge;
232
-
233
- // TRIANGLE DCB
234
-
235
- activeEdge = 0b000;
236
- result = 0b000;
237
-
238
- // check if edge 0 is active (DC)
239
-
240
- // if edge is an outer edge, it is active
241
- if (isLastRow) {
242
- activeEdge |= 0b001;
243
- }
244
-
245
- // if edge is an interior edge, get both triangles on either side of the edge
246
- else {
247
- // get triangles
248
- heightMap.computeVertex(a1, col + 1, row + 1);
249
- heightMap.computeVertex(b1, col + 0, row + 1);
250
- heightMap.computeVertex(c1, col + 1, row + 0);
251
- triangleLeftOfEdge.set({ a: a1, b: b1, c: c1 });
252
-
253
- heightMap.computeVertex(a2, col + 1, row + 1);
254
- heightMap.computeVertex(b2, col + 0, row + 2);
255
- heightMap.computeVertex(c2, col + 0, row + 1);
256
- triangleRightOfEdge.set({ a: a2, b: b2, c: c2 });
257
-
258
- // get normals
259
- triangleLeftOfEdge.computeNormal(normalLeftOfEdge);
260
- triangleRightOfEdge.computeNormal(normalRightOfEdge);
261
-
262
- // get edge direction
263
- edge.subtractVectors(b1, a1);
264
- edge.normalize();
265
-
266
- // check if edge is active
267
- result = isEdgeActive(normalLeftOfEdge, normalRightOfEdge, edge, cos5Degrees) ? 0b001 : 0b000;
268
- activeEdge |= result;
269
- }
270
-
271
- // check if edge 1 is active (CB)
272
-
273
- // this edge is always interior, get both triangles on either side of the edge
274
-
275
- // get triangles
276
- heightMap.computeVertex(a1, col + 0, row + 1);
277
- heightMap.computeVertex(b1, col + 1, row + 0);
278
- heightMap.computeVertex(c1, col + 1, row + 1);
279
- triangleLeftOfEdge.set({ a: a1, b: b1, c: c1 });
280
-
281
- heightMap.computeVertex(a2, col + 0, row + 1);
282
- heightMap.computeVertex(b2, col + 0, row + 0);
283
- heightMap.computeVertex(c2, col + 1, row + 0);
284
- triangleRightOfEdge.set({ a: a2, b: b2, c: c2 });
285
-
286
- // get normals
287
- triangleLeftOfEdge.computeNormal(normalLeftOfEdge);
288
- triangleRightOfEdge.computeNormal(normalRightOfEdge);
289
-
290
- // get edge direction
291
- edge.subtractVectors(b1, a1);
292
- edge.normalize();
293
-
294
- // check if edge is active
295
- result = isEdgeActive(normalLeftOfEdge, normalRightOfEdge, edge, cos5Degrees) ? 0b010 : 0b000;
296
- activeEdge |= result;
297
-
298
- // check if edge 2 is active (BD)
299
-
300
- // if edge is an outer edge, it is active
301
- if (isLastColumn) {
302
- activeEdge |= 0b100;
303
- }
304
-
305
- // if edge is an interior edge, get both triangles on either side of the edge
306
- else {
307
- // get triangles
308
- heightMap.computeVertex(a1, col + 1, row + 0);
309
- heightMap.computeVertex(b1, col + 1, row + 1);
310
- heightMap.computeVertex(c1, col + 0, row + 1);
311
- triangleLeftOfEdge.set({ a: a1, b: b1, c: c1 });
312
-
313
- heightMap.computeVertex(a2, col + 1, row + 0);
314
- heightMap.computeVertex(b2, col + 2, row + 0);
315
- heightMap.computeVertex(c2, col + 1, row + 1);
316
- triangleRightOfEdge.set({ a: a2, b: b2, c: c2 });
317
-
318
- // get normals
319
- triangleLeftOfEdge.computeNormal(normalLeftOfEdge);
320
- triangleRightOfEdge.computeNormal(normalRightOfEdge);
321
-
322
- // get edge direction
323
- edge.subtractVectors(b1, a1);
324
- edge.normalize();
325
-
326
- // check if edge is active
327
- result = isEdgeActive(normalLeftOfEdge, normalRightOfEdge, edge, cos5Degrees) ? 0b100 : 0b000;
328
- activeEdge |= result;
329
- }
330
-
331
- // set active edges for triangle DCB
332
- heightMap.activeEdges[secondTriangleIndex] = activeEdge;
333
- }
334
- }
335
- }
336
-
337
- buildHeightMap(
338
- vertexCount: { width: number; depth: number },
339
- extents: InputType<Vec3>,
340
- heights: Float32Array | Float64Array | number[],
341
- heightMapPool?: typeof HeightMap.Pool
342
- ): HeightMap {
343
- if (vertexCount.width < 2 || vertexCount.depth < 2) {
344
- throw new Error(`vertexCount must be at least 2x2: ${vertexCount.width}x${vertexCount.depth}`);
345
- }
346
-
347
- if (vertexCount.width !== vertexCount.depth) {
348
- throw new Error(`non-square heightmaps are not yet supported: ${vertexCount.width}x${vertexCount.depth}`);
349
- }
350
-
351
- const subdivisionsCount = vertexCount.width - 1; // number of subdivisions is one less than the number of vertices
352
- if (!isPowerOf2(subdivisionsCount)) {
353
- const { previous, next } = computeClosestPowersOfTwo(subdivisionsCount);
354
- throw new Error(
355
- `non-power-of-two sub-divisions are not yet supported. the closest valid vertex counts are: [${previous + 1}, ${
356
- next + 1
357
- }]`
358
- );
359
- }
360
-
361
- if (heights.length !== vertexCount.width * vertexCount.depth) {
362
- throw new Error(
363
- `heights length must match vertex count: ${vertexCount.width * vertexCount.depth}, got ${
364
- heights.length
365
- } instead`
366
- );
367
- }
368
-
369
- for (let i = 0; i < heights.length; i++) {
370
- const height = heights[i];
371
- if (height < 0.0 || height > 1.0) {
372
- throw new Error(`heights must be normalized to the range [0, 1], got ${height} at index ${i} instead`);
373
- }
374
- }
375
-
376
- const numberOfQuads = subdivisionsCount ** 2;
377
- const numberOfTriangles = numberOfQuads * 2;
378
- const numberOfCells = computeNumberOfCells(subdivisionsCount);
379
-
380
- actualExtents.fromArray([1, 1, 1]);
381
- actualExtents.set(extents);
382
-
383
- scale.x = actualExtents.x / subdivisionsCount;
384
- scale.y = actualExtents.y;
385
- scale.z = actualExtents.z / subdivisionsCount;
386
-
387
- positionOffset.x = -actualExtents.x * 0.5;
388
- positionOffset.y = 0.0;
389
- positionOffset.z = -actualExtents.z * 0.5;
390
-
391
- // 2. allocate the heightMap
392
- const heightMap = HeightMap.create({
393
- subdivisionsCount: subdivisionsCount,
394
- scale: scale,
395
- positionOffset: positionOffset,
396
- }, heightMapPool);
397
- heightMap.heights = Array.from(heights);
398
- heightMap.activeEdges = new Array(numberOfTriangles).fill(0);
399
- heightMap.minHeights = new Array(numberOfCells).fill(Number.POSITIVE_INFINITY);
400
- heightMap.maxHeights = new Array(numberOfCells).fill(Number.NEGATIVE_INFINITY);
401
- heightMap.levels = new Array(numberOfCells).fill(0);
402
-
403
- // 3. build the quadtree and active edges
404
- this.buildActiveEdges(heightMap);
405
- this.buildHeightMapQuadtree(heightMap);
406
-
407
- updateShape(heightMap);
408
- return heightMap;
409
- }
410
- }
411
-
412
- const scale = /*@__PURE__*/ Vec3.create();
413
- const positionOffset = /*@__PURE__*/ Vec3.create();
414
- const actualExtents = /*@__PURE__*/ Vec3.create();
@@ -1,92 +0,0 @@
1
- import { Vec3 } from "../math/vec3";
2
- import { TriangleMeshBvhTreeOptions, TriangleMeshBvhTree, TriangleMeshBvhNode } from "../physics/broadphase/TriangleMeshBvhTree";
3
- import { Triangle } from "../shape/Triangle";
4
- import { TriangleMesh, updateShape } from "../shape/TriangleMesh";
5
- import { ConvexHullBuilder } from "./ConvexHullBuilder";
6
-
7
- export interface BuildTriangleMeshParams {
8
- vertexPositions: Float32Array;
9
- faceIndices: Uint32Array;
10
- bvhOptions: TriangleMeshBvhTreeOptions;
11
- }
12
-
13
- export class TriangleMeshBuilder {
14
- convexHullBuilder: ConvexHullBuilder;
15
-
16
- constructor() {
17
- this.convexHullBuilder = new ConvexHullBuilder();
18
- }
19
-
20
- build(
21
- params: BuildTriangleMeshParams,
22
- triangleMeshPool?: typeof TriangleMesh.Pool,
23
- bvhNodePool?: typeof TriangleMeshBvhNode.Pool,
24
- bvhTreePool?: typeof TriangleMeshBvhTree.Pool,
25
- vertexPositionPool?: typeof Vec3.Pool,
26
- faceIndexPool?: typeof Vec3.Pool,
27
- trianglePool?: typeof Triangle.Pool
28
- ) {
29
- const vertexPositions = vertexPositionPool || new Vec3.Pool(params.vertexPositions.length / 3);
30
- const faceIndices = faceIndexPool || new Vec3.Pool(params.faceIndices.length / 3);
31
- const triangles = trianglePool || new Triangle.Pool(params.faceIndices.length / 3);
32
- const mesh = TriangleMesh.create({
33
- vertexPositions: { pool: vertexPositions },
34
- faceIndices: { pool: faceIndices },
35
- triangles: { pool: triangles },
36
- }, triangleMeshPool);
37
-
38
- for (let i = 0; i < params.vertexPositions.length; i += 3) {
39
- mesh.vertexPositions.create(
40
- {
41
- x: params.vertexPositions[i + 0],
42
- y: params.vertexPositions[i + 1],
43
- z: params.vertexPositions[i + 2],
44
- },
45
- );
46
- }
47
-
48
- for (let i = 0; i < params.faceIndices.length; i += 3) {
49
- mesh.faceIndices.create(
50
- {
51
- x: params.faceIndices[i + 0],
52
- y: params.faceIndices[i + 1],
53
- z: params.faceIndices[i + 2],
54
- },
55
- );
56
- }
57
-
58
- let subShapeId = 0;
59
- for (const face of mesh.faceIndices!) {
60
- const triangle = mesh.triangles.create(
61
- {
62
- a: mesh.vertexPositions.getAtIndex(face.x)!,
63
- b: mesh.vertexPositions.getAtIndex(face.y)!,
64
- c: mesh.vertexPositions.getAtIndex(face.z)!,
65
- },
66
- );
67
- triangle.computeLocalBounds(triangle.computedBounds);
68
- triangle.computeNormal(triangle.normal);
69
- triangle.subShapeId = subShapeId++;
70
- triangle.activeEdges = 0b111;
71
- }
72
-
73
- updateShape(mesh);
74
-
75
- const nodes = bvhNodePool || new TriangleMeshBvhNode.Pool();
76
- bvhTreePool = bvhTreePool || new TriangleMeshBvhTree.Pool();
77
- mesh.bvh = TriangleMeshBvhTree.create({
78
- nodes: { pool: nodes },
79
- }, bvhTreePool);
80
-
81
- mesh.bvh.build({
82
- mesh: mesh,
83
- bvhTreeOptions: params.bvhOptions,
84
- }, triangles);
85
-
86
- const hull = this.convexHullBuilder.buildFromPoints(params.vertexPositions, 0.0, 1e-3);
87
- mesh.computedVolume = hull.computedVolume;
88
- mesh.inertia.copy(hull.inertia);
89
-
90
- return mesh;
91
- }
92
- }
@@ -1,184 +0,0 @@
1
- import { Isometry } from "../math/isometry";
2
- import { Shape, ShapeType } from "../shape/Shape";
3
- import { Vec3 } from "../math/vec3";
4
- import { castConvexVsConvex } from "./cast/castConvexVsConvex";
5
- import { PenetrationDepthModule } from "./gjk/PenetrationDepthModule";
6
- import { castCompoundVsConvex } from "./cast/castCompoundVsConvex";
7
- import { castConvexVsCompound } from "./cast/castConvexVsCompound";
8
- import { CastCollector, CastSettings, RayCastSettings } from "./cast/cast";
9
- import { Body } from "../physics/Body";
10
- import { castConvexVsHeightMap } from "./cast/castConvexVsHeightMap";
11
- import { castConvexVsTriangleMesh } from "./cast/castConvexVsTriangleMesh";
12
- import { Ray } from "../shape/Ray";
13
- import { castRayVsConvex } from "./cast/castRayVsConvex";
14
- import { castRayVsCompound } from "./cast/castRayVsCompound";
15
- import { castRayVsTriangleMesh } from "./cast/castRayVsTriangleMesh";
16
- import { castRayVsHeightMap } from "./cast/castRayVsHeightMap";
17
-
18
- const castShapesFns = {
19
- [ShapeType.sphere]: {
20
- [ShapeType.box]: castConvexVsConvex,
21
- [ShapeType.capsule]: castConvexVsConvex,
22
- [ShapeType.compoundShape]: castConvexVsCompound,
23
- [ShapeType.convexHull]: castConvexVsConvex,
24
- [ShapeType.cylinder]: castConvexVsConvex,
25
- [ShapeType.heightMap]: castConvexVsHeightMap,
26
- [ShapeType.sphere]: castConvexVsConvex,
27
- [ShapeType.triangleMesh]: castConvexVsTriangleMesh,
28
- },
29
- [ShapeType.box]: {
30
- [ShapeType.box]: castConvexVsConvex,
31
- [ShapeType.capsule]: castConvexVsConvex,
32
- [ShapeType.compoundShape]: castConvexVsCompound,
33
- [ShapeType.convexHull]: castConvexVsConvex,
34
- [ShapeType.cylinder]: castConvexVsConvex,
35
- [ShapeType.heightMap]: castConvexVsHeightMap,
36
- [ShapeType.sphere]: castConvexVsConvex,
37
- [ShapeType.triangleMesh]: castConvexVsTriangleMesh,
38
- },
39
- [ShapeType.capsule]: {
40
- [ShapeType.box]: castConvexVsConvex,
41
- [ShapeType.capsule]: castConvexVsConvex,
42
- [ShapeType.compoundShape]: castConvexVsCompound,
43
- [ShapeType.convexHull]: castConvexVsConvex,
44
- [ShapeType.cylinder]: castConvexVsConvex,
45
- [ShapeType.heightMap]: castConvexVsHeightMap,
46
- [ShapeType.sphere]: castConvexVsConvex,
47
- [ShapeType.triangleMesh]: castConvexVsTriangleMesh,
48
- },
49
- [ShapeType.cylinder]: {
50
- [ShapeType.box]: castConvexVsConvex,
51
- [ShapeType.capsule]: castConvexVsConvex,
52
- [ShapeType.compoundShape]: castConvexVsCompound,
53
- [ShapeType.convexHull]: castConvexVsConvex,
54
- [ShapeType.cylinder]: castConvexVsConvex,
55
- [ShapeType.heightMap]: castConvexVsHeightMap,
56
- [ShapeType.sphere]: castConvexVsConvex,
57
- [ShapeType.triangleMesh]: castConvexVsTriangleMesh,
58
- },
59
- [ShapeType.compoundShape]: {
60
- [ShapeType.box]: castCompoundVsConvex,
61
- [ShapeType.capsule]: castCompoundVsConvex,
62
- // [ShapeType.compoundShape]: castCompoundVsCompound,
63
- [ShapeType.convexHull]: castCompoundVsConvex,
64
- [ShapeType.cylinder]: castCompoundVsConvex,
65
- // [ShapeType.heightMap]: castCompoundVsHeightMap,
66
- [ShapeType.sphere]: castCompoundVsConvex,
67
- // [ShapeType.triangleMesh]: castCompoundVsTriangleMesh,
68
- },
69
- // [ShapeType.heightMap]: {
70
- // [ShapeType.box]: castHeightMapVsConvex,
71
- // [ShapeType.capsule]: castHeightMapVsConvex,
72
- // [ShapeType.compoundShape]: castHeightMapVsCompound,
73
- // [ShapeType.convexHull]: castHeightMapVsConvex,
74
- // [ShapeType.cylinder]: castHeightMapVsConvex,
75
- // [ShapeType.heightMap]: castHeightMapVsHeightMap,
76
- // [ShapeType.sphere]: castHeightMapVsConvex,
77
- // [ShapeType.triangleMesh]: castHeightMapVsTriangleMesh,
78
- // },
79
- // [ShapeType.triangleMesh]: {
80
- // [ShapeType.box]: castTriangleMeshVsConvex,
81
- // [ShapeType.capsule]: castTriangleMeshVsConvex,
82
- // [ShapeType.compoundShape]: castTriangleMeshVsCompound,
83
- // [ShapeType.convexHull]: castTriangleMeshVsConvex,
84
- // [ShapeType.cylinder]: castTriangleMeshVsConvex,
85
- // [ShapeType.heightMap]: castTriangleMeshVsHeightMap,
86
- // [ShapeType.sphere]: castTriangleMeshVsConvex,
87
- // [ShapeType.triangleMesh]: castTriangleMeshVsTriangleMesh,
88
- // },
89
- // [ShapeType.triangle]: {
90
- // [ShapeType.box]: castTriangleVsConvex,
91
- // [ShapeType.sphere]: castTriangleVsConvex,
92
- // },
93
- } as const;
94
-
95
- const raycastFns = {
96
- [ShapeType.sphere]: castRayVsConvex,
97
- [ShapeType.box]: castRayVsConvex,
98
- [ShapeType.capsule]: castRayVsConvex,
99
- [ShapeType.cylinder]: castRayVsConvex,
100
- [ShapeType.compoundShape]: castRayVsCompound, // castRayVsCompound,
101
- [ShapeType.convexHull]: castRayVsConvex,
102
- [ShapeType.heightMap]: castRayVsHeightMap, // castRayVsHeightMap,
103
- [ShapeType.triangleMesh]: castRayVsTriangleMesh, // castRayVsTriangleMesh,
104
- };
105
-
106
- export class CastShapesModule {
107
- penetrationDepthModule: PenetrationDepthModule;
108
-
109
- constructor(penetrationDepthModule: PenetrationDepthModule) {
110
- this.penetrationDepthModule = penetrationDepthModule;
111
- }
112
-
113
- castRay(
114
- collector: CastCollector,
115
- ray: Ray,
116
- shapeB: Shape,
117
- isometryB: Isometry,
118
- scaleB: number,
119
- offset: Vec3,
120
- settings: RayCastSettings,
121
- bodyB: Body | null = null
122
- ) {
123
- const fn = raycastFns[shapeB.type as keyof typeof raycastFns];
124
- if (!fn) {
125
- return;
126
- }
127
- return fn(
128
- this.penetrationDepthModule,
129
- collector,
130
- ray,
131
- // @ts-ignore
132
- shapeB,
133
- isometryB,
134
- scaleB,
135
- offset,
136
- settings,
137
- bodyB
138
- );
139
- }
140
-
141
- // casts two shapes that implement the ShapeWithType interface, using the query map
142
- // the shapes must be in local space
143
- // the isometries must transform the shapes into world space
144
- // the results are in world space
145
- castShapes(
146
- collector: CastCollector,
147
- shapeA: Shape,
148
- isometryA: Isometry,
149
- scaleA: number,
150
- shapeB: Shape,
151
- isometryB: Isometry,
152
- scaleB: number,
153
- displacement: Vec3,
154
- offset: Vec3,
155
- settings: CastSettings,
156
- bodyA: Body | null = null,
157
- bodyB: Body | null = null
158
- ): void {
159
- const keyA = shapeA.type as keyof typeof castShapesFns;
160
- const keyB = shapeB.type as keyof (typeof castShapesFns)[keyof typeof castShapesFns];
161
- const castFunction = castShapesFns[keyA][keyB];
162
- if (!castFunction) {
163
- throw new Error(`no cast function found for shapes with type ${keyA} and ${keyB}`);
164
- }
165
-
166
- return castFunction(
167
- this.penetrationDepthModule,
168
- collector,
169
- // @ts-ignore
170
- shapeA,
171
- shapeB,
172
- isometryA,
173
- isometryB,
174
- scaleA,
175
- scaleB,
176
- displacement,
177
- offset,
178
- settings,
179
- undefined,
180
- bodyA,
181
- bodyB
182
- );
183
- }
184
- }