@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.
- package/build/bounce.d.ts +39501 -0
- package/build/bounce.js +17166 -0
- package/package.json +1 -1
- package/src/builders/ConvexHullBuilder.ts +0 -437
- package/src/builders/ConvexHullBuilder2d.ts +0 -344
- package/src/builders/ConvexHullBuilder3d.ts +0 -1689
- package/src/builders/HeightMapBuilder.ts +0 -414
- package/src/builders/TriangleMeshBuilder.ts +0 -92
- package/src/collision/CastShapesModule.ts +0 -184
- package/src/collision/CollideShapesModule.ts +0 -152
- package/src/collision/HeightMapCaster.ts +0 -38
- package/src/collision/HeightMapCollider.ts +0 -33
- package/src/collision/TriangleCaster.ts +0 -249
- package/src/collision/TriangleCollider.ts +0 -308
- package/src/collision/TriangleCollider2.ts +0 -379
- package/src/collision/activeEdge.ts +0 -146
- package/src/collision/cast/cast.ts +0 -139
- package/src/collision/cast/castCompoundVsCompound.ts +0 -59
- package/src/collision/cast/castCompoundVsConvex.ts +0 -116
- package/src/collision/cast/castConvexVsCompound.ts +0 -123
- package/src/collision/cast/castConvexVsConvex.ts +0 -213
- package/src/collision/cast/castConvexVsHeightMap.ts +0 -73
- package/src/collision/cast/castConvexVsTriangleMesh.ts +0 -56
- package/src/collision/cast/castRayVsCompound.ts +0 -44
- package/src/collision/cast/castRayVsConvex.ts +0 -45
- package/src/collision/cast/castRayVsHeightMap.ts +0 -58
- package/src/collision/cast/castRayVsTriangleMesh.ts +0 -58
- package/src/collision/closestPoints/closestPoints.ts +0 -23
- package/src/collision/closestPoints/computeBarycentricCoordinates2d.ts +0 -32
- package/src/collision/closestPoints/computeBarycentricCoordinates3d.ts +0 -81
- package/src/collision/closestPoints/computeClosestPointOnLine.ts +0 -30
- package/src/collision/closestPoints/computeClosestPointOnTetrahedron.ts +0 -96
- package/src/collision/closestPoints/computeClosestPointOnTriangle.ts +0 -195
- package/src/collision/closestPoints/isOriginOutsideOfPlane.ts +0 -25
- package/src/collision/closestPoints/isOriginOutsideOfTrianglePlanes.ts +0 -72
- package/src/collision/collide/collide.ts +0 -146
- package/src/collision/collide/collideCompoundVsCompound.ts +0 -60
- package/src/collision/collide/collideCompoundVsConvex.ts +0 -59
- package/src/collision/collide/collideCompoundVsHeightMap.ts +0 -73
- package/src/collision/collide/collideCompoundVsTriangleMesh.ts +0 -56
- package/src/collision/collide/collideConvexVsCompound.ts +0 -57
- package/src/collision/collide/collideConvexVsConvex.ts +0 -225
- package/src/collision/collide/collideConvexVsConvexImp.ts +0 -236
- package/src/collision/collide/collideConvexVsHeightMap.ts +0 -53
- package/src/collision/collide/collideConvexVsTriangleMesh.ts +0 -58
- package/src/collision/collide/collideHeightMapVsCompound.ts +0 -69
- package/src/collision/collide/collideHeightMapVsConvex.ts +0 -53
- package/src/collision/collide/collideSphereVsSphere.ts +0 -81
- package/src/collision/collide/collideTriangleMeshVsCompound.ts +0 -58
- package/src/collision/collide/collideTriangleMeshVsConvex.ts +0 -58
- package/src/collision/epa/EpaConvexHullBuilder.ts +0 -397
- package/src/collision/epa/StaticArray.ts +0 -154
- package/src/collision/epa/TriangleFactory.ts +0 -32
- package/src/collision/epa/arrays.ts +0 -99
- package/src/collision/epa/binaryHeap.ts +0 -82
- package/src/collision/epa/structs.ts +0 -227
- package/src/collision/gjk/GjkModule.ts +0 -864
- package/src/collision/gjk/PenetrationDepthModule.ts +0 -493
- package/src/collision/gjk/SupportPoints.ts +0 -50
- package/src/collision/imp/MinkowskiDifference.ts +0 -36
- package/src/collision/imp/computeExploredDistanceLowerUpperBound.ts +0 -40
- package/src/collision/imp/finalizeImpResult.ts +0 -69
- package/src/collision/imp/findContactImp.ts +0 -196
- package/src/collision/imp/imp.ts +0 -28
- package/src/collision/imp/incrementalMinimumDistanceExploreDirection.ts +0 -207
- package/src/collision/mpr/findPortal.ts +0 -152
- package/src/collision/mpr/mpr.ts +0 -29
- package/src/collision/mpr/updatePortal.ts +0 -52
- package/src/constraints/BaseConstraint.ts +0 -50
- package/src/constraints/ConstraintOptions.ts +0 -22
- package/src/constraints/ConstraintSolver.ts +0 -119
- package/src/constraints/DistanceConstraint.ts +0 -229
- package/src/constraints/FixedConstraint.ts +0 -203
- package/src/constraints/HingeConstraint.ts +0 -460
- package/src/constraints/PointConstraint.ts +0 -108
- package/src/constraints/components/AngleComponent.ts +0 -226
- package/src/constraints/components/AxisComponent.ts +0 -263
- package/src/constraints/components/HingeComponent.ts +0 -215
- package/src/constraints/components/Motor.ts +0 -36
- package/src/constraints/components/PointConstraintComponent.ts +0 -179
- package/src/constraints/components/RotationEulerComponent.ts +0 -139
- package/src/constraints/components/Spring.ts +0 -30
- package/src/constraints/components/SpringComponent.ts +0 -71
- package/src/constraints/types.ts +0 -6
- package/src/helpers.ts +0 -147
- package/src/index.ts +0 -50
- package/src/math/BasicTransform.ts +0 -19
- package/src/math/NumberValue.ts +0 -13
- package/src/math/isometry.ts +0 -64
- package/src/math/mat3.ts +0 -529
- package/src/math/mat4.ts +0 -588
- package/src/math/quat.ts +0 -193
- package/src/math/scalar.ts +0 -81
- package/src/math/tensor.ts +0 -17
- package/src/math/vec3.ts +0 -589
- package/src/math/vec4.ts +0 -10
- package/src/physics/Body.ts +0 -581
- package/src/physics/CollisionFilter.ts +0 -52
- package/src/physics/SleepModule.ts +0 -163
- package/src/physics/broadphase/BodyPairsModule.ts +0 -363
- package/src/physics/broadphase/BvhModule.ts +0 -237
- package/src/physics/broadphase/BvhTree.ts +0 -803
- package/src/physics/broadphase/ConstraintPairsModule.ts +0 -385
- package/src/physics/broadphase/TriangleMeshBvhTree.ts +0 -379
- package/src/physics/manifold/ContactManifold.ts +0 -227
- package/src/physics/manifold/ContactManifoldModule.ts +0 -623
- package/src/physics/manifold/Face.ts +0 -119
- package/src/physics/manifold/ManifoldCache.ts +0 -116
- package/src/physics/manifold/clipping/clipPolyVsEdge.ts +0 -131
- package/src/physics/manifold/clipping/clipPolyVsPlane.ts +0 -73
- package/src/physics/manifold/clipping/clipPolyVsPoly.ts +0 -72
- package/src/physics/narrowphase/CollideBodiesModule.ts +0 -755
- package/src/physics/solver/ContactConstraintModule.ts +0 -659
- package/src/physics/solver/ManifoldConstraint.ts +0 -420
- package/src/physics/solver/estimateCollisionResponse.ts +0 -146
- package/src/shape/Aabb.ts +0 -400
- package/src/shape/Box.ts +0 -231
- package/src/shape/Capsule.ts +0 -332
- package/src/shape/CompoundShape.ts +0 -288
- package/src/shape/Convex.ts +0 -130
- package/src/shape/ConvexHull.ts +0 -423
- package/src/shape/Cylinder.ts +0 -313
- package/src/shape/HeightMap.ts +0 -511
- package/src/shape/Line.ts +0 -14
- package/src/shape/Plane.ts +0 -116
- package/src/shape/Ray.ts +0 -81
- package/src/shape/Segment.ts +0 -25
- package/src/shape/Shape.ts +0 -77
- package/src/shape/Sphere.ts +0 -181
- package/src/shape/TransformedShape.ts +0 -51
- package/src/shape/Triangle.ts +0 -122
- package/src/shape/TriangleMesh.ts +0 -186
- package/src/types.ts +0 -1
- package/src/world.ts +0 -1335
- package/tests/BodyPairsModule.test.ts +0 -71
- package/tests/BvhTree.test.ts +0 -406
- package/tests/test.md +0 -642
- 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
|
-
}
|