@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
@@ -1,308 +0,0 @@
1
- import { Isometry } from "../math/isometry";
2
- import { Mat3 } from "../math/mat3";
3
- import { Vec3 } from "../math/vec3";
4
- import { Face } from "../physics/manifold/Face";
5
- import { Aabb } from "../shape/Aabb";
6
- import { ConvexRadiusObject, SupportMode } from "../shape/Convex";
7
- import { ConvexShape } from "../shape/Shape";
8
- import { Triangle } from "../shape/Triangle";
9
- import { fixNormal } from "./activeEdge";
10
- import { PenetrationDepth, PenetrationDepthModule } from "./gjk/PenetrationDepthModule";
11
- import {
12
- ActiveEdgeMode,
13
- BackFaceMode,
14
- CollisionCollector,
15
- CollisionResult,
16
- CollisionSettings,
17
- CollisionStatus,
18
- } from "./collide/collide";
19
- import { Body } from "../physics/Body";
20
-
21
- const result = /*@__PURE__*/ CollisionResult.create({
22
- faceA: {
23
- numVertices: 0,
24
- buffer: { pool: new Vec3.Pool(32), maxLength: 32 },
25
- },
26
- faceB: {
27
- numVertices: 0,
28
- buffer: { pool: new Vec3.Pool(32), maxLength: 32 },
29
- },
30
- });
31
- const isometryBToA = /*@__PURE__*/ Isometry.create();
32
- const localBoundsA = /*@__PURE__*/ Aabb.create();
33
- const shapeB = /*@__PURE__*/ Triangle.create();
34
- const convexA = /*@__PURE__*/ ConvexRadiusObject.create();
35
- const convexB = /*@__PURE__*/ ConvexRadiusObject.create();
36
- const rotationMatrixA = /*@__PURE__*/ Mat3.create();
37
- const positionA = /*@__PURE__*/ Vec3.create();
38
- const positionB = /*@__PURE__*/ Vec3.create();
39
-
40
- const triangleNormal = /*@__PURE__*/ Vec3.create();
41
- const triangleBounds = /*@__PURE__*/ Aabb.create();
42
- const pointA = /*@__PURE__*/ Vec3.create();
43
- const pointB = /*@__PURE__*/ Vec3.create();
44
- const penetrationAxis = /*@__PURE__*/ Vec3.create();
45
- const gjkResult = /*@__PURE__*/ PenetrationDepth.create();
46
- const pointAB = /*@__PURE__*/ Vec3.create();
47
- const activeEdgeMovementDirectionWorld = /*@__PURE__*/ Vec3.create();
48
- const activeEdgeMovementDirectionLocal = /*@__PURE__*/ Vec3.create();
49
- const contactNormal = /*@__PURE__*/ Vec3.create();
50
- const negatedPenetrationAxis = /*@__PURE__*/ Vec3.create();
51
- const negatedTriangleNormal = /*@__PURE__*/ Vec3.create();
52
- const penetrationAxisWorld = /*@__PURE__*/ Vec3.create();
53
-
54
- export class TriangleCollider {
55
- declare penetrationDepthModule: PenetrationDepthModule;
56
- declare shapeA: ConvexShape;
57
- declare shapeB: Triangle;
58
- declare isometryA: Isometry;
59
- declare isometryB: Isometry;
60
- declare settings: CollisionSettings;
61
- declare collector: CollisionCollector;
62
- declare subShapeAId: number;
63
- bodyA: Body | null = null;
64
- bodyB: Body | null = null;
65
-
66
- initialize(
67
- penetrationDepthModule: PenetrationDepthModule,
68
- shapeA: ConvexShape,
69
- isometryA: Isometry,
70
- isometryB: Isometry,
71
- settings: CollisionSettings,
72
- collector: CollisionCollector,
73
- subShapeAId: number = 0,
74
- bodyA: Body | null = null,
75
- bodyB: Body | null = null
76
- ): void {
77
- this.penetrationDepthModule = penetrationDepthModule;
78
- this.shapeA = shapeA;
79
- this.isometryA = isometryA;
80
- this.isometryB = isometryB;
81
- this.settings = settings;
82
- this.collector = collector;
83
- this.subShapeAId = subShapeAId;
84
- this.bodyA = bodyA;
85
- this.bodyB = bodyB;
86
-
87
- // get the isometry from B to A
88
- isometryBToA.matrix.invertMatrix(isometryA.matrix);
89
- isometryBToA.matrix.multiplyMatrix(isometryB.matrix);
90
-
91
- // get the rotation matrix of A
92
- rotationMatrixA.fromMat4(isometryA.matrix);
93
-
94
- // get the positions
95
- isometryA.matrix.getTranslation(positionA);
96
- isometryB.matrix.getTranslation(positionB);
97
-
98
- // get the local bounds of A
99
- localBoundsA.copy(shapeA.computedAabb);
100
- localBoundsA.expand(settings.maxSeparation);
101
- }
102
-
103
- collide(triangle: Triangle, activeEdges: number, triangleId: number, bodyA?: Body | null, bodyB?: Body | null): void {
104
- result.reset();
105
- // @ts-ignore
106
- result.bodyA = bodyA || this.bodyA;
107
- // @ts-ignore
108
- result.bodyB = bodyB || this.bodyB;
109
- const settings = this.settings;
110
- const shapeA = this.shapeA;
111
- const isometryA = this.isometryA;
112
- const subShapeAId = this.subShapeAId;
113
- const collector = this.collector;
114
- const penetrationDepthModule = this.penetrationDepthModule;
115
-
116
- // get the triangle in A space
117
- shapeB.copy(triangle);
118
- shapeB.transform(isometryBToA.matrix);
119
-
120
- // get the triangle normal
121
-
122
- shapeB.computeNormal(triangleNormal);
123
- // shapeB.getUnnormalizedNormal(triangleNormal);
124
-
125
- // TODO: handle backface mode
126
- const back_facing = triangleNormal.dot(triangle.a) > 0;
127
- if (settings.backFaceMode === BackFaceMode.IgnoreBackFaces && back_facing) {
128
- // console.log("miss: ignoring back-facing triangle");
129
- collector.addMiss();
130
- return;
131
- }
132
-
133
- // get triangle bounds
134
-
135
- shapeB.computeLocalBounds(triangleBounds);
136
-
137
- // collide bounds
138
- if (localBoundsA.intersectsAabb(triangleBounds) === false) {
139
- // console.log("miss: bounds do not intersect");
140
- collector.addMiss();
141
- return;
142
- }
143
-
144
- // get the support shapes
145
- const supportA = shapeA.computeSupportShape(SupportMode.ExcludeConvexRadius, 1);
146
- const supportB = shapeB.computeSupportShape(SupportMode.ExcludeConvexRadius, 1);
147
-
148
- // get convex radii, including the max separation distance
149
- const convexRadiusA = supportA.getConvexRadius() + settings.maxSeparation;
150
- const convexRadiusB = supportB.getConvexRadius();
151
-
152
- // init the pass-through results
153
-
154
- // init the penetration axis as the triangle normal
155
- penetrationAxis.negateVector(triangleNormal);
156
-
157
- // init the gjk result
158
-
159
- // run gjk
160
- penetrationDepthModule.getPenetrationDepthStepGjk(
161
- gjkResult,
162
- supportA,
163
- supportB,
164
- convexRadiusA,
165
- convexRadiusB,
166
- penetrationAxis,
167
- settings.collisionTolerance
168
- );
169
-
170
- switch (gjkResult.status) {
171
- case CollisionStatus.Colliding: {
172
- // pass through the results
173
- pointA.copy(gjkResult.pointA);
174
- pointB.copy(gjkResult.pointB);
175
- penetrationAxis.copy(gjkResult.penetrationAxis);
176
- break;
177
- }
178
-
179
- case CollisionStatus.NotColliding: {
180
- // definitive no penetration
181
- result.hasContact = false;
182
- // console.log("miss: no hit from gjk");
183
- collector.addMiss();
184
- return;
185
- }
186
-
187
- case CollisionStatus.Indeterminate: {
188
- // need to run IMP
189
-
190
- // get the support shapes
191
- const supportA = shapeA.computeSupportShape(SupportMode.IncludeConvexRadius, 1);
192
- const supportB = shapeB.computeSupportShape(SupportMode.IncludeConvexRadius, 1);
193
-
194
- // // get the convex shapes
195
- // convexA.object = supportA;
196
- // convexA.radius = settings.maxSeparation;
197
-
198
- // convexB.object = supportB;
199
- // convexB.radius = 0;
200
- convexA.setData(settings.maxSeparation, supportA);
201
- convexB.setData(0, supportB);
202
-
203
- // init the imp result
204
-
205
- const hitFound = penetrationDepthModule.getPenetrationDepthStepEPA(
206
- convexA,
207
- convexB,
208
- settings.collisionTolerance,
209
- penetrationAxis,
210
- pointA,
211
- pointB
212
- );
213
-
214
- if (!hitFound) {
215
- // console.log("miss: no hit from EPA");
216
- result.hasContact = false;
217
- collector.addMiss();
218
- return;
219
- }
220
- }
221
- }
222
-
223
- // we have a collision
224
-
225
- // get the penetration depth
226
-
227
- // check if penetration is bigger than early out fraction
228
- pointAB.subtractVectors(pointB, pointA);
229
- const penetrationDepth = pointAB.length() - settings.maxSeparation;
230
- if (-penetrationDepth >= collector.getEarlyOutFraction()) {
231
- result.hasContact = false;
232
- collector.addMiss();
233
- return;
234
- }
235
-
236
- // reduce pointA by the max separation distance along the penetration axis
237
- const penetrationAxisLength = penetrationAxis.length();
238
- if (penetrationAxisLength > 0) {
239
- pointA.addScaled(penetrationAxis, -(settings.maxSeparation / penetrationAxisLength));
240
- }
241
-
242
- // TODO: handle active edge detection
243
- if (settings.activeEdgeMode === ActiveEdgeMode.CollideOnlyWithActive && activeEdges !== 0b111) {
244
- activeEdgeMovementDirectionWorld.x = settings.activeEdgeMovementDirectionX;
245
- activeEdgeMovementDirectionWorld.y = settings.activeEdgeMovementDirectionY;
246
- activeEdgeMovementDirectionWorld.z = settings.activeEdgeMovementDirectionZ;
247
-
248
- // convert the active edge velocity hint to local space
249
- isometryA.matrix.multiply3x3Transposed(activeEdgeMovementDirectionLocal, activeEdgeMovementDirectionWorld);
250
-
251
- // update the penetration axis to account for active edges
252
- // note that we flip the triangle normal as the penetration axis is pointing towards the triangle instead of away
253
- negatedPenetrationAxis.negateVector(penetrationAxis);
254
- negatedTriangleNormal.negateVector(triangleNormal);
255
-
256
- fixNormal(
257
- contactNormal,
258
- shapeB.a,
259
- shapeB.b,
260
- shapeB.c,
261
- // back_facing ? triangleNormal : negatedTriangleNormal,
262
- // triangleNormal,
263
- negatedTriangleNormal,
264
- activeEdges,
265
- pointB,
266
- penetrationAxis,
267
- activeEdgeMovementDirectionLocal
268
- );
269
-
270
- // update the penetration axis
271
- penetrationAxis.copy(contactNormal);
272
- }
273
-
274
- // convert results from A space to world space
275
- result.hasContact = true;
276
- result.subShapeIdA = subShapeAId;
277
- result.subShapeIdB = triangleId;
278
- result.isBackFace = back_facing;
279
-
280
- // convert to world space
281
- pointA.transformByMat4(isometryA.matrix);
282
- pointB.transformByMat4(isometryA.matrix);
283
- isometryA.matrix.multiply3x3(penetrationAxisWorld, penetrationAxis);
284
-
285
- result.contactPointA.copy(pointA);
286
- result.contactPointB.copy(pointB);
287
-
288
- // get the normal in world space
289
- result.normalA.copy(penetrationAxisWorld);
290
- result.normalB.negateVector(result.normalA);
291
-
292
- result.penetration = penetrationDepth;
293
- result.hasContact = true;
294
-
295
- // add the world space surface normal of the triangle
296
- result.surfaceNormalA.zero();
297
- result.surfaceNormalB.transformVectorFromMat3(triangleNormal, rotationMatrixA);
298
-
299
- // normalize the normals
300
- result.normalA.normalize();
301
- result.normalB.normalize();
302
-
303
- // console.log("hit: triangle collider hit");
304
-
305
- // add the hit
306
- collector.addHit(result);
307
- }
308
- }
@@ -1,379 +0,0 @@
1
- import { Isometry } from "../math/isometry";
2
- import { Mat3 } from "../math/mat3";
3
- import { Vec3 } from "../math/vec3";
4
- import { Face } from "../physics/manifold/Face";
5
- import { Aabb } from "../shape/Aabb";
6
- import { ConvexRadiusObject, SupportMode } from "../shape/Convex";
7
- import { ConvexShape } from "../shape/Shape";
8
- import { Triangle } from "../shape/Triangle";
9
- import { fixNormal } from "./activeEdge";
10
- import { PenetrationDepth, PenetrationDepthModule } from "./gjk/PenetrationDepthModule";
11
- import {
12
- ActiveEdgeMode,
13
- BackFaceMode,
14
- CollectFacesMode,
15
- CollisionCollector,
16
- CollisionResult,
17
- CollisionSettings,
18
- CollisionStatus,
19
- } from "./collide/collide";
20
- import { Body } from "../physics/Body";
21
-
22
- const result = /*@__PURE__*/ CollisionResult.create({
23
- faceA: {
24
- numVertices: 0,
25
- buffer: { pool: new Vec3.Pool(32), maxLength: 32 },
26
- },
27
- faceB: {
28
- numVertices: 0,
29
- buffer: { pool: new Vec3.Pool(32), maxLength: 32 },
30
- },
31
- });
32
- const isometryBToA = /*@__PURE__*/ Isometry.create();
33
- const localBoundsA = /*@__PURE__*/ Aabb.create();
34
- const shapeB = /*@__PURE__*/ Triangle.create();
35
- const convexA = /*@__PURE__*/ ConvexRadiusObject.create();
36
- const convexB = /*@__PURE__*/ ConvexRadiusObject.create();
37
- const rotationMatrixA = /*@__PURE__*/ Mat3.create();
38
- const positionA = /*@__PURE__*/ Vec3.create();
39
- const positionB = /*@__PURE__*/ Vec3.create();
40
-
41
- const centerA = /*@__PURE__*/ Vec3.create();
42
- const centerB = /*@__PURE__*/ Vec3.create();
43
-
44
- const triangleNormal = /*@__PURE__*/ Vec3.create();
45
- const triangleBounds = /*@__PURE__*/ Aabb.create();
46
- const pointA = /*@__PURE__*/ Vec3.create();
47
- const pointB = /*@__PURE__*/ Vec3.create();
48
- const penetrationAxis = /*@__PURE__*/ Vec3.create();
49
- const gjkResult = /*@__PURE__*/ PenetrationDepth.create();
50
- const pointAB = /*@__PURE__*/ Vec3.create();
51
- const activeEdgeMovementDirectionWorld = /*@__PURE__*/ Vec3.create();
52
- const activeEdgeMovementDirectionLocal = /*@__PURE__*/ Vec3.create();
53
- const contactNormal = /*@__PURE__*/ Vec3.create();
54
- const negatedPenetrationAxis = /*@__PURE__*/ Vec3.create();
55
- const negatedTriangleNormal = /*@__PURE__*/ Vec3.create();
56
- const penetrationAxisWorld = /*@__PURE__*/ Vec3.create();
57
-
58
- export class TriangleCollider2 {
59
- declare penetrationDepthModule: PenetrationDepthModule;
60
- declare shapeA: ConvexShape;
61
- declare shapeB: Triangle;
62
- declare isometryA: Isometry;
63
- declare isometryB: Isometry;
64
- declare settings: CollisionSettings;
65
- declare collector: CollisionCollector;
66
- declare subShapeAId: number;
67
- bodyA: Body | null = null;
68
- bodyB: Body | null = null;
69
-
70
- initialize(
71
- penetrationDepthModule: PenetrationDepthModule,
72
- shapeA: ConvexShape,
73
- isometryA: Isometry,
74
- isometryB: Isometry,
75
- settings: CollisionSettings,
76
- collector: CollisionCollector,
77
- subShapeAId: number = 0,
78
- bodyA: Body | null = null,
79
- bodyB: Body | null = null
80
- ): void {
81
- this.penetrationDepthModule = penetrationDepthModule;
82
- this.shapeA = shapeA;
83
- this.isometryA = isometryA;
84
- this.isometryB = isometryB;
85
- this.settings = settings;
86
- this.collector = collector;
87
- this.subShapeAId = subShapeAId;
88
- this.bodyA = bodyA;
89
- this.bodyB = bodyB;
90
-
91
- // console.log(isometryA.matrix.toObject());
92
- // console.log(isometryB.matrix.toObject());
93
- // console.log(settings);
94
- // console.log(subShapeAId);
95
-
96
- // get the isometry from B to A
97
- isometryBToA.matrix.invertMatrix(isometryA.matrix);
98
- isometryBToA.matrix.multiplyMatrices(isometryBToA.matrix, isometryB.matrix);
99
- // isometryBToA.matrix.log("isometryBToA");
100
-
101
- // get the rotation matrix of A
102
- rotationMatrixA.fromMat4(isometryA.matrix);
103
-
104
- // get the positions
105
- isometryA.matrix.getTranslation(positionA);
106
- isometryB.matrix.getTranslation(positionB);
107
-
108
- // get the local bounds of A
109
- localBoundsA.copy(shapeA.computedAabb);
110
- localBoundsA.expand(settings.maxSeparation);
111
- }
112
-
113
- collide(
114
- triangle: Triangle,
115
- activeEdges: number,
116
- triangleId: number,
117
- bodyA: Body | null = null,
118
- bodyB: Body | null = null,
119
- swapResults: boolean = false
120
- ): void {
121
- result.reset();
122
- // @ts-ignore
123
- result.bodyA = bodyA || this.bodyA;
124
- // @ts-ignore
125
- result.bodyB = bodyB || this.bodyB;
126
- const settings = this.settings;
127
- const shapeA = this.shapeA;
128
- const isometryA = this.isometryA;
129
- const subShapeAId = this.subShapeAId;
130
- const collector = this.collector;
131
- const penetrationDepthModule = this.penetrationDepthModule;
132
-
133
- // get the triangle in A space
134
- shapeB.copy(triangle);
135
- shapeB.transform(isometryBToA.matrix);
136
- // console.log(triangleId, triangle.toObject(), shapeB.toObject());
137
-
138
- // get the triangle normal
139
- shapeB.computeUnnormalizedNormal(triangleNormal);
140
- // shapeB.getNormal(triangleNormal);
141
-
142
- // TODO: handle backface mode
143
- // const back_facing = triangleNormal.dot(triangle.a) > 0;
144
- const back_facing = triangleNormal.dot(shapeB.a) > 0;
145
- if (settings.backFaceMode === BackFaceMode.IgnoreBackFaces && back_facing) {
146
- // this.world.debug && console.log("triangle miss, ignore back faces", triangleId);
147
- // console.log("miss: ignoring back-facing triangle");
148
- collector.addMiss();
149
- return;
150
- }
151
-
152
- // get triangle bounds
153
- shapeB.computeLocalBounds(triangleBounds);
154
-
155
- // collide bounds
156
- if (localBoundsA.intersectsAabb(triangleBounds) === false) {
157
- // this.world.debug && console.log("triangle miss, bounds not intersecting", triangleId);
158
- // console.log("miss: bounds do not intersect");
159
- collector.addMiss();
160
- // console.log("exit because bounds don't overlap");
161
- return;
162
- }
163
-
164
- // get the support shapes
165
- const supportA = shapeA.computeSupportShape(SupportMode.ExcludeConvexRadius, 1);
166
- const supportB = shapeB.computeSupportShape(SupportMode.ExcludeConvexRadius, 1);
167
-
168
- // init the pass-through results
169
- // init the penetration axis as the triangle normal
170
- // vec3.negate(penetrationAxis, triangleNormal);
171
-
172
- // penetrationAxis.set([0, +1, 0]);
173
-
174
- isometryA.matrix.getTranslation(centerA);
175
- shapeB.computeCentroid(centerB);
176
- penetrationAxis.subtractVectors(centerB, centerA);
177
-
178
- penetrationAxis.normalize();
179
-
180
- // init the gjk result
181
- // run gjk
182
- // if (this.world.debug) {
183
- // debugger;
184
- // }
185
- penetrationDepthModule.getPenetrationDepthStepGjk(
186
- gjkResult,
187
- supportA,
188
- supportB,
189
- supportA.getConvexRadius() + settings.maxSeparation,
190
- supportB.getConvexRadius(),
191
- penetrationAxis,
192
- settings.collisionTolerance
193
- );
194
-
195
- switch (gjkResult.status) {
196
- case CollisionStatus.Colliding: {
197
- // pass through the results
198
- pointA.copy(gjkResult.pointA);
199
- pointB.copy(gjkResult.pointB);
200
- penetrationAxis.copy(gjkResult.penetrationAxis);
201
- // console.log("found collision with gjk");
202
- break;
203
- }
204
-
205
- case CollisionStatus.NotColliding: {
206
- // this.world.debug && console.log("triangle miss, not colliding via gjk", triangleId);
207
- // definitive no penetration
208
- // console.log("miss: no hit from gjk");
209
- collector.addMiss();
210
- // console.log("exit because gjk says not colliding");
211
- return;
212
- }
213
-
214
- case CollisionStatus.Indeterminate: {
215
- // console.log("starting imp");
216
- // need to run IMP
217
-
218
- // get the support shapes
219
- const supportA = shapeA.computeSupportShape(SupportMode.IncludeConvexRadius, 1);
220
- const supportB = shapeB.computeSupportShape(SupportMode.IncludeConvexRadius, 1);
221
-
222
- // get the convex shapes
223
- // const convexA = this.convexA;
224
- // convexA.object = supportA;
225
- // convexA.radius = settings.maxSeparation;
226
-
227
- // const convexB = this.convexB;
228
- // convexB.object = supportB;
229
- // convexB.radius = 0;
230
-
231
- convexA.setData(settings.maxSeparation, supportA);
232
- convexB.setData(0, supportB);
233
-
234
- const hitFound = penetrationDepthModule.getPenetrationDepthStepEPA(
235
- convexA,
236
- convexB,
237
- settings.collisionTolerance,
238
- penetrationAxis,
239
- pointA,
240
- pointB
241
- );
242
-
243
- if (!hitFound) {
244
- result.hasContact = false;
245
- collector.addMiss();
246
- return;
247
- }
248
- }
249
- }
250
-
251
- // we have a collision
252
-
253
- // // check if penetration axis is similar to triangle normal, if it is, negate it to make it consistent whether back-facing or not
254
- // if (penetrationAxis.dot(triangleNormal) > 0) {
255
- // vec3.negate(penetrationAxis, penetrationAxis);
256
- // }
257
-
258
- // if (this.world.debugger) {
259
- // this.world.debugger.drawShape({
260
- // type: "arrow",
261
- // group: "foo",
262
- // origin: pointA,
263
- // direction: penetrationAxis,
264
- // length: 10,
265
- // radius: 0.1,
266
- // color: "black",
267
- // });
268
- // }
269
-
270
- // check if penetration is bigger than early out fraction
271
- pointAB.subtractVectors(pointB, pointA);
272
- const penetrationDepth = pointAB.length() - settings.maxSeparation;
273
- if (-penetrationDepth >= collector.getEarlyOutFraction()) {
274
- result.hasContact = false;
275
- collector.addMiss();
276
- return;
277
- }
278
-
279
- // reduce pointA by the max separation distance along the penetration axis
280
- const penetrationAxisLength = penetrationAxis.length();
281
- if (penetrationAxisLength > 0) {
282
- pointA.addScaled(penetrationAxis, -(settings.maxSeparation / penetrationAxisLength));
283
- }
284
-
285
- // TODO: handle active edge detection
286
- if (settings.activeEdgeMode === ActiveEdgeMode.CollideOnlyWithActive && activeEdges !== 0b111) {
287
- activeEdgeMovementDirectionWorld.x = settings.activeEdgeMovementDirectionX;
288
- activeEdgeMovementDirectionWorld.y = settings.activeEdgeMovementDirectionY;
289
- activeEdgeMovementDirectionWorld.z = settings.activeEdgeMovementDirectionZ;
290
-
291
- // convert the active edge velocity hint to local space
292
- isometryA.matrix.multiply3x3Transposed(activeEdgeMovementDirectionLocal, activeEdgeMovementDirectionWorld);
293
-
294
- // update the penetration axis to account for active edges
295
- // note that we flip the triangle normal as the penetration axis is pointing towards the triangle instead of away
296
- negatedPenetrationAxis.negateVector(penetrationAxis);
297
- negatedTriangleNormal.negateVector(triangleNormal);
298
-
299
- fixNormal(
300
- contactNormal,
301
- shapeB.a,
302
- shapeB.b,
303
- shapeB.c,
304
- // back_facing ? triangleNormal : negatedTriangleNormal,
305
- // triangleNormal,
306
- negatedTriangleNormal,
307
- activeEdges,
308
- pointB,
309
- penetrationAxis,
310
- activeEdgeMovementDirectionLocal
311
- );
312
-
313
- // update the penetration axis
314
- penetrationAxis.copy(contactNormal);
315
- }
316
-
317
- // convert results from A space to world space
318
- result.hasContact = true;
319
- result.subShapeIdA = subShapeAId;
320
- result.subShapeIdB = triangleId;
321
- result.isBackFace = back_facing;
322
-
323
- // this.faceA.clear();
324
- // this.faceB.clear();
325
- // result.faceA = this.faceA;
326
- // result.faceB = this.faceB;
327
-
328
- // if (settings.collectFacesMode === CollectFacesMode.CollectFaces) {
329
- // // const negatedPenetrationAxis = Vec3.global(
330
- // // this.world,
331
- // // "CollideConvexAndTriangles2.collide.negatedPenetrationAxis"
332
- // // );
333
- // negatedPenetrationAxis.negateVector(penetrationAxis);
334
- // shapeA.computeSupportingFace(result.faceA, subShapeAId, negatedPenetrationAxis, 1, isometryA.matrix);
335
- // shapeB.computeSupportingFace(result.faceB, triangleId, negatedPenetrationAxis, 1, isometryA.matrix);
336
- // }
337
-
338
- // convert to world space
339
- pointA.transformByMat4(isometryA.matrix);
340
- pointB.transformByMat4(isometryA.matrix);
341
- isometryA.matrix.multiply3x3(penetrationAxisWorld, penetrationAxis);
342
-
343
- result.contactPointA.copy(pointA);
344
- result.contactPointB.copy(pointB);
345
-
346
- // get the normal in world space
347
- result.normalA.copy(penetrationAxisWorld);
348
- result.normalB.negateVector(result.normalA);
349
-
350
- result.penetration = penetrationDepth;
351
- result.hasContact = true;
352
-
353
- // add the world space surface normal of the triangle
354
- result.surfaceNormalA.zero();
355
- result.surfaceNormalB.transformVectorFromMat3(triangleNormal, rotationMatrixA);
356
-
357
- // normalize the normals
358
- result.normalA.normalize();
359
- result.normalB.normalize();
360
-
361
- // console.log("collision found: processed results");
362
- // console.log("result.contactPointA", result.contactPointA.toArray());
363
- // console.log("result.contactPointB", result.contactPointB.toArray());
364
- // console.log("result.normalA", result.normalA.toArray());
365
- // console.log("result.penetration", result.penetration);
366
- // result.faceA.log("result.faceA");
367
- // result.faceB.log("result.faceB");
368
-
369
- if (swapResults) {
370
- result.swap();
371
- }
372
-
373
- // console.log("hit: triangle collider hit");
374
-
375
- // add the hit
376
- // this.world.debug && console.log("triangle hit", triangleId);
377
- collector.addHit(result);
378
- }
379
- }