@perplexdotgg/bounce 1.0.0 → 1.0.2

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 (138) 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
  135. package/tests/BodyPairsModule.test.ts +0 -71
  136. package/tests/BvhTree.test.ts +0 -406
  137. package/tests/test.md +0 -642
  138. package/tests/vec3.test.ts +0 -12
package/src/shape/Aabb.ts DELETED
@@ -1,400 +0,0 @@
1
- import { createClass, MonomorphType, PropertyDefinitionMap } from "monomorph";
2
- import { Vec3 } from "../math/vec3";
3
- import { Face } from "../physics/manifold/Face";
4
- import { Isometry } from "../math/isometry";
5
- import { Segment } from "./Segment";
6
- import { Ray } from "./Ray";
7
- import { Quat } from "../math/quat";
8
-
9
- const epsilon = 1e-7;
10
- const newMin = /*@__PURE__*/ Vec3.create();
11
- const newMax = /*@__PURE__*/ Vec3.create();
12
- const col = /*@__PURE__*/ Vec3.create();
13
- const a = /*@__PURE__*/ Vec3.create();
14
- const b = /*@__PURE__*/ Vec3.create();
15
-
16
- interface Vec3Like {
17
- x: number;
18
- y: number;
19
- z: number;
20
- }
21
-
22
- const aabbProps = {
23
- min: MonomorphType(Vec3),
24
- max: MonomorphType(Vec3),
25
- centroid: MonomorphType(Vec3, undefined, true),
26
- } as const satisfies PropertyDefinitionMap;
27
-
28
- export class Aabb extends createClass<Aabb, typeof aabbProps>(aabbProps) {
29
- computeSupport(out: Vec3, direction: Vec3) {
30
- out.x = direction.x < 0 ? this.min.x : this.max.x;
31
- out.y = direction.y < 0 ? this.min.y : this.max.y;
32
- out.z = direction.z < 0 ? this.min.z : this.max.z;
33
- }
34
-
35
- computeSupportingFace(out: Face, inDirection: Vec3): void {
36
- const absX = Math.abs(inDirection.x);
37
- const absY = Math.abs(inDirection.y);
38
- const absZ = Math.abs(inDirection.z);
39
-
40
- const axis = absX > absY ? (absX > absZ ? 0 : 2) : absY > absZ ? 1 : 2;
41
- const component = inDirection.getComponentAtIndex(axis);
42
- if (component < 0) {
43
- switch (axis) {
44
- case 0: {
45
- out.pushVertexValues(this.max.x, this.min.y, this.min.z);
46
- out.pushVertexValues(this.max.x, this.max.y, this.min.z);
47
- out.pushVertexValues(this.max.x, this.max.y, this.max.z);
48
- out.pushVertexValues(this.max.x, this.min.y, this.max.z);
49
- break;
50
- }
51
-
52
- case 1: {
53
- out.pushVertexValues(this.min.x, this.max.y, this.min.z);
54
- out.pushVertexValues(this.min.x, this.max.y, this.max.z);
55
- out.pushVertexValues(this.max.x, this.max.y, this.max.z);
56
- out.pushVertexValues(this.max.x, this.max.y, this.min.z);
57
- break;
58
- }
59
-
60
- case 2: {
61
- out.pushVertexValues(this.min.x, this.min.y, this.max.z);
62
- out.pushVertexValues(this.max.x, this.min.y, this.max.z);
63
- out.pushVertexValues(this.max.x, this.max.y, this.max.z);
64
- out.pushVertexValues(this.min.x, this.max.y, this.max.z);
65
- break;
66
- }
67
- }
68
- } else {
69
- switch (axis) {
70
- case 0: {
71
- out.pushVertexValues(this.min.x, this.min.y, this.min.z);
72
- out.pushVertexValues(this.min.x, this.min.y, this.max.z);
73
- out.pushVertexValues(this.min.x, this.max.y, this.max.z);
74
- out.pushVertexValues(this.min.x, this.max.y, this.min.z);
75
- break;
76
- }
77
-
78
- case 1: {
79
- out.pushVertexValues(this.min.x, this.min.y, this.min.z);
80
- out.pushVertexValues(this.max.x, this.min.y, this.min.z);
81
- out.pushVertexValues(this.max.x, this.min.y, this.max.z);
82
- out.pushVertexValues(this.min.x, this.min.y, this.max.z);
83
- break;
84
- }
85
-
86
- case 2: {
87
- out.pushVertexValues(this.min.x, this.min.y, this.min.z);
88
- out.pushVertexValues(this.min.x, this.max.y, this.min.z);
89
- out.pushVertexValues(this.max.x, this.max.y, this.min.z);
90
- out.pushVertexValues(this.max.x, this.min.y, this.min.z);
91
- break;
92
- }
93
- }
94
- }
95
- }
96
-
97
- translate(translation: Vec3): void {
98
- this.min.addVector(translation);
99
- this.max.addVector(translation);
100
- this.computeCentroid(this.centroid);
101
- }
102
-
103
- translateAabb(aabb: Aabb, translation: Vec3): Aabb {
104
- this.min.addVectors(aabb.min, translation);
105
- this.max.addVectors(aabb.max, translation);
106
- this.computeCentroid(this.centroid);
107
- return this;
108
- }
109
-
110
- transform(transform: Isometry) {
111
- // start with the translation of the matrix
112
- transform.matrix.getTranslation(newMin);
113
- transform.matrix.getTranslation(newMax);
114
-
115
- // mow find the extreme points by considering the product of the min and max with each column of inMatrix
116
- for (let c = 0; c < 3; ++c) {
117
- transform.matrix.getColumn3(col, c);
118
-
119
- const minComponent = this.min.getComponentAtIndex(c);
120
- const maxComponent = this.max.getComponentAtIndex(c);
121
-
122
- a.scaleVector(col, minComponent);
123
- b.scaleVector(col, maxComponent);
124
-
125
- newMin.x += Math.min(a.x, b.x);
126
- newMin.y += Math.min(a.y, b.y);
127
- newMin.z += Math.min(a.z, b.z);
128
-
129
- newMax.x += Math.max(a.x, b.x);
130
- newMax.y += Math.max(a.y, b.y);
131
- newMax.z += Math.max(a.z, b.z);
132
- }
133
-
134
- // set the new bounding box
135
- this.min.copy(newMin);
136
- this.max.copy(newMax);
137
- this.computeCentroid(this.centroid);
138
-
139
- return this;
140
- }
141
-
142
- transformAabb(aabb: Aabb, transform: Isometry) {
143
- // start with the translation of the matrix
144
- transform.matrix.getTranslation(newMin);
145
- transform.matrix.getTranslation(newMax);
146
-
147
- // now find the extreme points by considering the product of the min and max with each column of inMatrix
148
- for (let c = 0; c < 3; ++c) {
149
- transform.matrix.getColumn3(col, c);
150
-
151
- const minComponent = aabb.min.getComponentAtIndex(c);
152
- const maxComponent = aabb.max.getComponentAtIndex(c);
153
-
154
- a.scaleVector(col, minComponent);
155
- b.scaleVector(col, maxComponent);
156
-
157
- newMin.x += Math.min(a.x, b.x);
158
- newMin.y += Math.min(a.y, b.y);
159
- newMin.z += Math.min(a.z, b.z);
160
-
161
- newMax.x += Math.max(a.x, b.x);
162
- newMax.y += Math.max(a.y, b.y);
163
- newMax.z += Math.max(a.z, b.z);
164
- }
165
-
166
- // set the new bounding box
167
- this.min.copy(newMin);
168
- this.max.copy(newMax);
169
- this.computeCentroid(this.centroid);
170
-
171
- return this;
172
- }
173
-
174
- intersectsAabb(aabb: Aabb) {
175
- return (
176
- this.min.x <= aabb.max.x &&
177
- this.max.x >= aabb.min.x &&
178
- this.min.y <= aabb.max.y &&
179
- this.max.y >= aabb.min.y &&
180
- this.min.z <= aabb.max.z &&
181
- this.max.z >= aabb.min.z
182
- );
183
- }
184
-
185
- unionAabb(aabb: Aabb) {
186
- this.min.minVectors(this.min, aabb.min);
187
- this.max.maxVectors(this.max, aabb.max);
188
- this.computeCentroid(this.centroid);
189
- return this;
190
- }
191
-
192
- unionAabbs(boxA: Aabb, boxB: Aabb) {
193
- this.min.minVectors(boxA.min, boxB.min);
194
- this.max.maxVectors(boxA.max, boxB.max);
195
- this.computeCentroid(this.centroid);
196
- }
197
-
198
- expand(value: number) {
199
- this.min.x -= value;
200
- this.min.y -= value;
201
- this.min.z -= value;
202
- this.max.x += value;
203
- this.max.y += value;
204
- this.max.z += value;
205
- this.computeCentroid(this.centroid);
206
- }
207
-
208
- expandAabb(aabb: Aabb, value: number) {
209
- this.min.x = aabb.min.x - value;
210
- this.min.y = aabb.min.y - value;
211
- this.min.z = aabb.min.z - value;
212
- this.max.x = aabb.max.x + value;
213
- this.max.y = aabb.max.y + value;
214
- this.max.z = aabb.max.z + value;
215
- this.computeCentroid(this.centroid);
216
- return this;
217
- }
218
-
219
- setExtents(min: Vec3Like, max: Vec3Like) {
220
- this.min.set(min);
221
- this.max.set(max);
222
- this.computeCentroid(this.centroid);
223
- return this;
224
- }
225
-
226
- computeSurfaceArea() {
227
- const dx = this.max.x - this.min.x;
228
- const dy = this.max.y - this.min.y;
229
- const dz = this.max.z - this.min.z;
230
- return 2 * (dx * dy + dy * dz + dz * dx);
231
- }
232
-
233
- computeExtents(out: Vec3) {
234
- out.x = this.max.x - this.min.x;
235
- out.y = this.max.y - this.min.y;
236
- out.z = this.max.z - this.min.z;
237
- }
238
-
239
- computeLargestAxis() {
240
- const dx = this.max.x - this.min.x;
241
- const dy = this.max.y - this.min.y;
242
- const dz = this.max.z - this.min.z;
243
-
244
- if (dx >= dy && dx >= dz) {
245
- return 0;
246
- }
247
-
248
- if (dy >= dx && dy >= dz) {
249
- return 1;
250
- }
251
-
252
- return 2;
253
- }
254
-
255
- computeLargestComponent() {
256
- const dx = this.max.x - this.min.x;
257
- const dy = this.max.y - this.min.y;
258
- const dz = this.max.z - this.min.z;
259
-
260
- if (dx >= dy && dx >= dz) {
261
- return "x";
262
- }
263
-
264
- if (dy >= dx && dy >= dz) {
265
- return "y";
266
- }
267
-
268
- return "z";
269
- }
270
-
271
- computeCentroid(out: Vec3) {
272
- out.x = (this.min.x + this.max.x) * 0.5;
273
- out.y = (this.min.y + this.max.y) * 0.5;
274
- out.z = (this.min.z + this.max.z) * 0.5;
275
- return out;
276
- }
277
-
278
- computeHalfExtents(out: Vec3) {
279
- out.subtractVectors(this.max, this.min);
280
- out.scaleVector(out, 0.5);
281
- }
282
-
283
- expandToPoint(point: Vec3) {
284
- this.min.minVector(point);
285
- this.max.maxVector(point);
286
- return this;
287
- }
288
-
289
- enclosesAabb(aabb: Aabb) {
290
- return (
291
- this.min.x < aabb.min.x &&
292
- this.max.x > aabb.max.x &&
293
- this.min.y < aabb.min.y &&
294
- this.max.y > aabb.max.y &&
295
- this.min.z < aabb.min.z &&
296
- this.max.z > aabb.max.z
297
- );
298
- }
299
-
300
- expandByVector(vector: Vec3) {
301
- this.min.x -= vector.x;
302
- this.min.y -= vector.y;
303
- this.min.z -= vector.z;
304
- this.max.x += vector.x;
305
- this.max.y += vector.y;
306
- this.max.z += vector.z;
307
- }
308
-
309
- toString() {
310
- return `Aabb(min: ${[this.min.x, this.min.y, this.min.z].join(", ")}, max: ${[
311
- this.max.x,
312
- this.max.y,
313
- this.max.z,
314
- ].join(", ")})`;
315
- }
316
-
317
- intersectsRay(ray: Ray) {
318
- segment.setFromRay(ray);
319
- return this.intersectsSegment(segment);
320
- }
321
-
322
- /**
323
- * from Christer Ericson's book "Real-Time Collision Detection", "5.3.3 Intersecting Ray or Segment Against Box"
324
- */
325
- intersectsSegment(segment: Segment) {
326
- this.computeCentroid(aabbCenter);
327
- this.computeHalfExtents(aabbHalfExtents);
328
-
329
- segment.computeCenter(segmentCenter);
330
- segment.computeHalfExtents(segmentHalfExtents);
331
-
332
- // translate the segment to the aabb space
333
- segmentCenter.subtractVectors(segmentCenter, aabbCenter);
334
-
335
- // test the 6 separating axes
336
-
337
- // try the aabb axes first
338
-
339
- // for any given axis, if the projection of the segment center onto the axis is greater than the sum of the half extents of the aabb and the segment, then the aabb and the segment do not intersect
340
- let adx = Math.abs(segmentHalfExtents.x);
341
- if (Math.abs(segmentCenter.x) > aabbHalfExtents.x + adx) {
342
- return false;
343
- }
344
-
345
- let ady = Math.abs(segmentHalfExtents.y);
346
- if (Math.abs(segmentCenter.y) > aabbHalfExtents.y + ady) {
347
- return false;
348
- }
349
-
350
- let adz = Math.abs(segmentHalfExtents.z);
351
- if (Math.abs(segmentCenter.z) > aabbHalfExtents.z + adz) {
352
- return false;
353
- }
354
-
355
- // try the segment cross aabb axes next
356
-
357
- // an epsilon is added to the half extents to counteract floating point errors when segment is near parallel to an axis
358
- adx += epsilon;
359
- ady += epsilon;
360
- adz += epsilon;
361
-
362
- if (
363
- Math.abs(segmentCenter.y * segmentHalfExtents.z - segmentCenter.z * segmentHalfExtents.y) >
364
- aabbHalfExtents.y * adz + aabbHalfExtents.z * ady
365
- ) {
366
- return false;
367
- }
368
-
369
- if (
370
- Math.abs(segmentCenter.z * segmentHalfExtents.x - segmentCenter.x * segmentHalfExtents.z) >
371
- aabbHalfExtents.x * adz + aabbHalfExtents.z * adx
372
- ) {
373
- return false;
374
- }
375
-
376
- if (
377
- Math.abs(segmentCenter.x * segmentHalfExtents.y - segmentCenter.y * segmentHalfExtents.x) >
378
- aabbHalfExtents.x * ady + aabbHalfExtents.y * adx
379
- ) {
380
- return false;
381
- }
382
-
383
- // if the segment passes all the tests, then it intersects the aabb
384
-
385
- return true;
386
- }
387
-
388
- toObject() {
389
- return {
390
- min: this.min.toObject(),
391
- max: this.max.toObject(),
392
- };
393
- }
394
- }
395
-
396
- const segment = /*@__PURE__*/ Segment.create();
397
- const aabbCenter = /*@__PURE__*/ Vec3.create();
398
- const aabbHalfExtents = /*@__PURE__*/ Vec3.create();
399
- const segmentCenter = /*@__PURE__*/ Vec3.create();
400
- const segmentHalfExtents = /*@__PURE__*/ Vec3.create();
package/src/shape/Box.ts DELETED
@@ -1,231 +0,0 @@
1
- import {
2
- createClass,
3
- LazyReferenceType,
4
- MonomorphType,
5
- NumberType,
6
- PropertyDefinitionMap,
7
- PropertyDefinitionReference,
8
- } from "monomorph";
9
- import { Vec3 } from "../math/vec3";
10
- import { ConvexShapeInterface, ShapeType } from "./Shape";
11
- import { Quat } from "../math/quat";
12
- import { Aabb } from "./Aabb";
13
- import { Face } from "../physics/manifold/Face";
14
- import { Mat4 } from "../math/mat4";
15
- import { Mat3 } from "../math/mat3";
16
- import { Isometry } from "../math/isometry";
17
- import { SupportMode, SupportShapeWithConvexRadius } from "./Convex";
18
- import type { World } from "../world";
19
-
20
- const scaledHalfExtent = /*@__PURE__*/ Vec3.create();
21
- const halfExtent = /*@__PURE__*/ Vec3.create();
22
- const convexRadiusVector = /*@__PURE__*/ Vec3.create();
23
- const reducedHalfExtent = /*@__PURE__*/ Vec3.create();
24
- const negatedScaledHalfExtent = /*@__PURE__*/ Vec3.create();
25
- const box = /*@__PURE__*/ Aabb.create();
26
-
27
- const isometry = /*@__PURE__*/ Isometry.create();
28
-
29
- const absLocalSurfacePosition = /*@__PURE__*/ Vec3.create();
30
- const tempVector = /*@__PURE__*/ Vec3.create();
31
-
32
- const defaultConvexRadius = 0.05; // Default convex radius for box shapes
33
-
34
- const boxSupportProps = {
35
- convexRadius: NumberType(0.0),
36
- // TODO: cannot used undefined default for this, possibly due to it being used as a deeply nested prop
37
- computedAabb: MonomorphType(Aabb, {}, true),
38
- } as const satisfies PropertyDefinitionMap;
39
-
40
- export class BoxSupport extends createClass<BoxSupport, typeof boxSupportProps>(boxSupportProps) {
41
- computeSupport(out: Vec3, direction: Vec3): void {
42
- this.computedAabb.computeSupport(out, direction);
43
- }
44
-
45
- getConvexRadius(): number {
46
- return this.convexRadius;
47
- }
48
- }
49
-
50
- const boxProps = {
51
- computedCenterOfMass: MonomorphType(Vec3, undefined, true),
52
- computedVolume: NumberType(0.0, true),
53
- computedAabb: MonomorphType(Aabb, undefined, true),
54
- convexRadius: NumberType(0.0),
55
- width: NumberType(0.0),
56
- height: NumberType(0.0),
57
- depth: NumberType(0.0),
58
- boxSupport: MonomorphType(BoxSupport, undefined, true),
59
- copyForDiff: LazyReferenceType((() => Box) as () => never) as PropertyDefinitionReference<Box | null, true>,
60
- } as const satisfies PropertyDefinitionMap;
61
-
62
- const afterConstructorCode = `
63
- this.world = null;
64
- `;
65
-
66
- export class Box
67
- extends createClass<Box, typeof boxProps>(boxProps, { afterConstructorCode })
68
- implements ConvexShapeInterface
69
- {
70
- type: ShapeType.box = ShapeType.box;
71
-
72
- declare world: World | null;
73
-
74
- computeSupportShape(mode: SupportMode, scale: number): SupportShapeWithConvexRadius {
75
- // Scale our half extents
76
- halfExtent.x = this.width * 0.5;
77
- halfExtent.y = this.height * 0.5;
78
- halfExtent.z = this.depth * 0.5;
79
- scaledHalfExtent.scaleVector(halfExtent, scale);
80
-
81
- switch (mode) {
82
- case SupportMode.IncludeConvexRadius: {
83
- // Make box out of our half extents
84
- const out = this.boxSupport;
85
- out.computedAabb.min.negateVector(scaledHalfExtent);
86
- out.computedAabb.max.copy(scaledHalfExtent);
87
- out.convexRadius = 0;
88
- return out;
89
- }
90
-
91
- case SupportMode.ExcludeConvexRadius: {
92
- // Reduce the box by our convex radius
93
- // TODO: could this be a bug in their code? this never lets convex radius grow past the default
94
- const convexRadius = Math.min(this.convexRadius * Math.abs(scale), defaultConvexRadius);
95
- convexRadiusVector.replicate(convexRadius);
96
- reducedHalfExtent.subtractVectors(scaledHalfExtent, convexRadiusVector);
97
-
98
- const out = this.boxSupport;
99
- out.computedAabb.min.negateVector(reducedHalfExtent);
100
- out.computedAabb.max.copy(reducedHalfExtent);
101
- out.convexRadius = convexRadius;
102
- return out;
103
- }
104
-
105
- default: {
106
- throw new Error(`Invalid support mode: ${mode}`);
107
- }
108
- }
109
- }
110
-
111
- computeSupportingFace(
112
- out: Face,
113
- subShapeID: number,
114
- direction: Vec3,
115
- scale: number,
116
- centerOfMassTransform: Mat4
117
- ): void {
118
- scale = Math.abs(scale);
119
-
120
- halfExtent.set({ x: this.width * 0.5, y: this.height * 0.5, z: this.depth * 0.5 });
121
-
122
- scaledHalfExtent.scaleVector(halfExtent, scale);
123
-
124
- negatedScaledHalfExtent.negateVector(scaledHalfExtent);
125
-
126
- box.set({ min: negatedScaledHalfExtent, max: scaledHalfExtent });
127
- box.computeSupportingFace(out, direction);
128
-
129
- if (out.numVertices > 4) {
130
- throw new Error("Box face has more than 4 vertices");
131
- }
132
-
133
- // transform to world space
134
- out.transform(centerOfMassTransform);
135
- }
136
-
137
- computeInertiaTensor(out: Mat3, mass: number): void {
138
- const widthSquared = this.width * this.width;
139
- const heightSquared = this.height * this.height;
140
- const depthSquared = this.depth * this.depth;
141
-
142
- out.fromArray([
143
- (mass * (heightSquared + depthSquared)) / 12,
144
- 0,
145
- 0,
146
- 0,
147
- (mass * (widthSquared + depthSquared)) / 12,
148
- 0,
149
- 0,
150
- 0,
151
- (mass * (widthSquared + heightSquared)) / 12,
152
- ]);
153
- }
154
-
155
- computeInverseInertiaTensor(out: Mat3, mass: number): void {
156
- this.computeInertiaTensor(out, mass);
157
- out.invert();
158
- }
159
-
160
- computeWorldBounds(out: Aabb, translation: Vec3, rotation: Quat): void {
161
- // TODO: apply rotation if shape's center of mass is not at the origin?
162
- isometry.fromRotationAndTranslation(rotation, translation);
163
- out.transformAabb(this.computedAabb, isometry);
164
- }
165
-
166
- hasChanged() {
167
- return (
168
- this.copyForDiff !== null &&
169
- (this.width !== this.copyForDiff.width ||
170
- this.height !== this.copyForDiff.height ||
171
- this.depth !== this.copyForDiff.depth)
172
- );
173
- }
174
-
175
- commitChanges() {
176
- if (this.hasChanged()) {
177
- updateShape(this);
178
- // this.world?.updateBodyProperties();
179
- }
180
- }
181
-
182
- computeSurfaceNormal(out: Vec3, inLocalSurfacePosition: Vec3): void {
183
- // Get component that is closest to the surface of the box
184
-
185
- absLocalSurfacePosition.absVector(inLocalSurfacePosition);
186
- halfExtent.set({ x: this.width * 0.5, y: this.height * 0.5, z: this.depth * 0.5 });
187
- tempVector.subtractVectors(absLocalSurfacePosition, halfExtent);
188
- tempVector.absVector(tempVector);
189
- const index = tempVector.computeLowestComponentIndex();
190
-
191
- // Calculate normal
192
- out.zero();
193
- const component = inLocalSurfacePosition.getComponentAtIndex(index);
194
- out.setComponentAtIndex(index, component > 0 ? 1 : -1);
195
- }
196
- }
197
-
198
- const oldCreate = Box.create;
199
- Box.create = function () {
200
- const shape = oldCreate.apply(this, arguments as any);
201
- updateShape(shape);
202
- return shape;
203
- };
204
-
205
- function updateCopyForDiff(shape: Box) {
206
- if (shape.copyForDiff) {
207
- shape.copyForDiff.copy(shape);
208
- shape.copyForDiff.copyForDiff = null;
209
- }
210
- }
211
-
212
- function updateCenterOfMass(shape: Box) {
213
- shape.computedCenterOfMass.zero();
214
- }
215
-
216
- function updateVolume(shape: Box) {
217
- shape.computedVolume = shape.width * shape.height * shape.depth;
218
- }
219
-
220
- function updateLocalBounds(shape: Box) {
221
- halfExtent.set({ x: shape.width * 0.5, y: shape.height * 0.5, z: shape.depth * 0.5 });
222
- shape.computedAabb.min.negateVector(halfExtent);
223
- shape.computedAabb.max.copy(halfExtent);
224
- }
225
-
226
- function updateShape(shape: Box) {
227
- updateCopyForDiff(shape);
228
- updateCenterOfMass(shape);
229
- updateVolume(shape);
230
- updateLocalBounds(shape);
231
- }