@perplexdotgg/bounce 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
@@ -1,493 +0,0 @@
|
|
|
1
|
-
import { createClass, MonomorphType, NumberType, PropertyDefinitionMap } from "monomorph";
|
|
2
|
-
import { Vec3 } from "../../math/vec3";
|
|
3
|
-
import { GjkCastShapeResult, GjkClosestPoints, GjkModule } from "./GjkModule";
|
|
4
|
-
import { degreesToRadians, squared } from "../../math/scalar";
|
|
5
|
-
import { Isometry } from "../../math/isometry";
|
|
6
|
-
import { ConvexRadiusObject, SupportShape, TransformedConvexObject } from "../../shape/Convex";
|
|
7
|
-
import { EpaConvexHullBuilder, EpaConvexHullBuilderSettings } from "../epa/EpaConvexHullBuilder";
|
|
8
|
-
import { assert } from "../../helpers";
|
|
9
|
-
import { SupportPoints } from "./SupportPoints";
|
|
10
|
-
import { Mat4 } from "../../math/mat4";
|
|
11
|
-
import { NewTriangles } from "../epa/arrays";
|
|
12
|
-
import { Triangle } from "../epa/structs";
|
|
13
|
-
|
|
14
|
-
const d1 = /*@__PURE__*/ Vec3.create({ x: 0, y: 1, z: 0 });
|
|
15
|
-
const d2 = /*@__PURE__*/ Vec3.create({ x: -1, y: -1, z: -1 });
|
|
16
|
-
const d3 = /*@__PURE__*/ Vec3.create({ x: 1, y: -1, z: -1 });
|
|
17
|
-
const d4 = /*@__PURE__*/ Vec3.create({ x: 0, y: -1, z: 1 });
|
|
18
|
-
const axis = /*@__PURE__*/ Vec3.create();
|
|
19
|
-
const rotation = /*@__PURE__*/ Mat4.create();
|
|
20
|
-
const dir1 = /*@__PURE__*/ Vec3.create();
|
|
21
|
-
const dir2 = /*@__PURE__*/ Vec3.create();
|
|
22
|
-
const dir3 = /*@__PURE__*/ Vec3.create();
|
|
23
|
-
const p2 = /*@__PURE__*/ Vec3.create();
|
|
24
|
-
const q2 = /*@__PURE__*/ Vec3.create();
|
|
25
|
-
const w2 = /*@__PURE__*/ Vec3.create();
|
|
26
|
-
const negatedNormal = /*@__PURE__*/ Vec3.create();
|
|
27
|
-
const p01 = /*@__PURE__*/ Vec3.create();
|
|
28
|
-
const p02 = /*@__PURE__*/ Vec3.create();
|
|
29
|
-
const q01 = /*@__PURE__*/ Vec3.create();
|
|
30
|
-
const q02 = /*@__PURE__*/ Vec3.create();
|
|
31
|
-
const p10 = /*@__PURE__*/ Vec3.create();
|
|
32
|
-
const p12 = /*@__PURE__*/ Vec3.create();
|
|
33
|
-
const q10 = /*@__PURE__*/ Vec3.create();
|
|
34
|
-
const q12 = /*@__PURE__*/ Vec3.create();
|
|
35
|
-
export const enum PenetrationDepthStatus {
|
|
36
|
-
NotColliding,
|
|
37
|
-
Colliding,
|
|
38
|
-
Indeterminate,
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const penetrationDepthProps = {
|
|
42
|
-
status: NumberType(0),
|
|
43
|
-
penetrationAxis: MonomorphType(Vec3),
|
|
44
|
-
pointA: MonomorphType(Vec3),
|
|
45
|
-
pointB: MonomorphType(Vec3),
|
|
46
|
-
} as const satisfies PropertyDefinitionMap;
|
|
47
|
-
|
|
48
|
-
export class PenetrationDepth extends createClass<PenetrationDepth, typeof penetrationDepthProps>(
|
|
49
|
-
penetrationDepthProps
|
|
50
|
-
) {}
|
|
51
|
-
|
|
52
|
-
const transformed_a = /*@__PURE__*/ new TransformedConvexObject();
|
|
53
|
-
const closest = /*@__PURE__*/ GjkClosestPoints.create();
|
|
54
|
-
const add_convex_a = /*@__PURE__*/ ConvexRadiusObject.create();
|
|
55
|
-
const add_convex_b = /*@__PURE__*/ ConvexRadiusObject.create();
|
|
56
|
-
|
|
57
|
-
export class PenetrationDepthModule {
|
|
58
|
-
gjkModule: GjkModule;
|
|
59
|
-
hull: EpaConvexHullBuilder;
|
|
60
|
-
supportPoints: SupportPoints;
|
|
61
|
-
newTriangles: NewTriangles;
|
|
62
|
-
maxPointsToIncludeOriginInHull: number;
|
|
63
|
-
|
|
64
|
-
constructor(
|
|
65
|
-
gjk: GjkModule,
|
|
66
|
-
hullBuilderSettings: Partial<EpaConvexHullBuilderSettings> = {},
|
|
67
|
-
maxPointsToIncludeOriginInHull: number = 32
|
|
68
|
-
) {
|
|
69
|
-
this.hull = new EpaConvexHullBuilder(hullBuilderSettings);
|
|
70
|
-
// #v-ifdef DEV
|
|
71
|
-
assert(
|
|
72
|
-
maxPointsToIncludeOriginInHull < this.hull.settings.maxPoints,
|
|
73
|
-
"maxPointsToIncludeOriginInHull must be less than maxPoints in hull builder settings"
|
|
74
|
-
);
|
|
75
|
-
// #v-endif
|
|
76
|
-
this.maxPointsToIncludeOriginInHull = maxPointsToIncludeOriginInHull;
|
|
77
|
-
this.gjkModule = gjk;
|
|
78
|
-
this.supportPoints = new SupportPoints(this.hull.settings.maxPoints);
|
|
79
|
-
this.hull.positions = this.supportPoints.mY;
|
|
80
|
-
this.newTriangles = new NewTriangles(this.hull.settings.maxEdgeLength);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
getPenetrationDepthStepGjk(
|
|
84
|
-
result: PenetrationDepth,
|
|
85
|
-
inAExcludingConvexRadius: SupportShape,
|
|
86
|
-
inBExcludingConvexRadius: SupportShape,
|
|
87
|
-
inConvexRadiusA: number,
|
|
88
|
-
inConvexRadiusB: number,
|
|
89
|
-
inDirection: Vec3,
|
|
90
|
-
inTolerance: number
|
|
91
|
-
): void {
|
|
92
|
-
// #v-ifdef DEV
|
|
93
|
-
// Don't supply a zero ioV, we only want to get points on the hull of the Minkowsky sum and not internal points
|
|
94
|
-
if (inDirection.isNearZero()) {
|
|
95
|
-
throw new Error("inDirection cannot be zero");
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// #v-endif
|
|
99
|
-
// Get closest points
|
|
100
|
-
const combinedRadius = inConvexRadiusA + inConvexRadiusB;
|
|
101
|
-
const combinedRadiusSquared = squared(combinedRadius);
|
|
102
|
-
|
|
103
|
-
this.gjkModule.getClosestPoints(
|
|
104
|
-
closest,
|
|
105
|
-
inAExcludingConvexRadius,
|
|
106
|
-
inBExcludingConvexRadius,
|
|
107
|
-
inTolerance,
|
|
108
|
-
combinedRadiusSquared,
|
|
109
|
-
inDirection
|
|
110
|
-
);
|
|
111
|
-
result.pointA.copy(closest.pointA);
|
|
112
|
-
result.pointB.copy(closest.pointB);
|
|
113
|
-
result.penetrationAxis.copy(closest.penetrationAxis);
|
|
114
|
-
|
|
115
|
-
if (closest.squaredDistance > combinedRadiusSquared) {
|
|
116
|
-
// No collision
|
|
117
|
-
result.status = PenetrationDepthStatus.NotColliding;
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (closest.squaredDistance > 0.0) {
|
|
122
|
-
// Collision within convex radius, adjust points for convex radius
|
|
123
|
-
const vLength = Math.sqrt(closest.squaredDistance); // GetClosestPoints function returns |ioV|^2 when return value < FLT_MAX
|
|
124
|
-
result.pointA.addScaled(result.penetrationAxis, inConvexRadiusA / vLength);
|
|
125
|
-
result.pointB.addScaled(result.penetrationAxis, -inConvexRadiusB / vLength);
|
|
126
|
-
result.status = PenetrationDepthStatus.Colliding;
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
result.status = PenetrationDepthStatus.Indeterminate;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// TODO: fix usage of inPenetrationTolerance
|
|
134
|
-
castShape(
|
|
135
|
-
result: GjkCastShapeResult,
|
|
136
|
-
inStart: Isometry,
|
|
137
|
-
inDirection: Vec3,
|
|
138
|
-
inCollisionTolerance: number,
|
|
139
|
-
inPenetrationTolerance: number,
|
|
140
|
-
inA: SupportShape,
|
|
141
|
-
inB: SupportShape,
|
|
142
|
-
inConvexRadiusA: number,
|
|
143
|
-
inConvexRadiusB: number,
|
|
144
|
-
inReturnDeepestPoint: boolean
|
|
145
|
-
): void {
|
|
146
|
-
// First determine if there's a collision at all
|
|
147
|
-
this.gjkModule.castShape(
|
|
148
|
-
result,
|
|
149
|
-
inStart,
|
|
150
|
-
inDirection,
|
|
151
|
-
inCollisionTolerance,
|
|
152
|
-
inA,
|
|
153
|
-
inB,
|
|
154
|
-
inConvexRadiusA,
|
|
155
|
-
inConvexRadiusB
|
|
156
|
-
);
|
|
157
|
-
// ioCollector.addGjkCastShapeResult(result);
|
|
158
|
-
if (result.isHitFound === false) {
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// When our contact normal is too small, we don't have an accurate result
|
|
163
|
-
const contact_normal_invalid = result.separatingAxis.isNearZero(squared(inCollisionTolerance));
|
|
164
|
-
|
|
165
|
-
if (
|
|
166
|
-
inReturnDeepestPoint &&
|
|
167
|
-
result.lambda === 0.0 && // Only when lambda = 0 we can have the bodies overlap
|
|
168
|
-
(inConvexRadiusA + inConvexRadiusB === 0.0 || // When no convex radius was provided we can never trust contact points at lambda = 0
|
|
169
|
-
contact_normal_invalid)
|
|
170
|
-
) {
|
|
171
|
-
// If we're initially intersecting, we need to run the EPA algorithm in order to find the deepest contact point
|
|
172
|
-
add_convex_a.setData(inConvexRadiusA, inA);
|
|
173
|
-
add_convex_b.setData(inConvexRadiusB, inB);
|
|
174
|
-
transformed_a.setData(inStart, add_convex_a);
|
|
175
|
-
|
|
176
|
-
// TODO: replace epa for imp
|
|
177
|
-
// if (!GetPenetrationDepthStepEPA(transformed_a, add_convex_b, inPenetrationTolerance, outContactNormal, outPointA, outPointB))
|
|
178
|
-
// return false;
|
|
179
|
-
result.isHitFound = false;
|
|
180
|
-
return;
|
|
181
|
-
} else if (contact_normal_invalid) {
|
|
182
|
-
// If we weren't able to calculate a contact normal, use the cast direction instead
|
|
183
|
-
result.separatingAxis.copy(inDirection);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// vec3.normalize(result.separatingAxis, result.separatingAxis);
|
|
187
|
-
|
|
188
|
-
result.isHitFound = true;
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
getPenetrationDepthStepEPA(
|
|
193
|
-
inAIncludingConvexRadius: SupportShape,
|
|
194
|
-
inBIncludingConvexRadius: SupportShape,
|
|
195
|
-
inTolerance: number,
|
|
196
|
-
outV: Vec3,
|
|
197
|
-
outPointA: Vec3,
|
|
198
|
-
outPointB: Vec3
|
|
199
|
-
): boolean {
|
|
200
|
-
// #v-ifdef DEV
|
|
201
|
-
assert(inTolerance >= Number.EPSILON, "inTolerance must be greater than or equal to FLT_EPSILON");
|
|
202
|
-
// #v-endif
|
|
203
|
-
|
|
204
|
-
// fetch the simplex from the gjk algorithm
|
|
205
|
-
const support_points = this.supportPoints;
|
|
206
|
-
support_points.clear();
|
|
207
|
-
this.gjkModule.getClosestPointsSimplex(support_points);
|
|
208
|
-
|
|
209
|
-
// Fill up the amount of support points to 4
|
|
210
|
-
switch (support_points.mY.size()) {
|
|
211
|
-
case 1: {
|
|
212
|
-
// #v-ifdef DEV
|
|
213
|
-
// 1 vertex, which must be at the origin, which is useless for our purpose
|
|
214
|
-
assert(
|
|
215
|
-
support_points.mY.values[0].isNearZero(squared(this.gjkModule.tolerance)),
|
|
216
|
-
"only support point Y[0] must not be near zero"
|
|
217
|
-
);
|
|
218
|
-
// #v-endif
|
|
219
|
-
support_points.popBack();
|
|
220
|
-
|
|
221
|
-
const p1 = support_points.add(inAIncludingConvexRadius, inBIncludingConvexRadius, d1);
|
|
222
|
-
const p2 = support_points.add(inAIncludingConvexRadius, inBIncludingConvexRadius, d2);
|
|
223
|
-
const p3 = support_points.add(inAIncludingConvexRadius, inBIncludingConvexRadius, d3);
|
|
224
|
-
const p4 = support_points.add(inAIncludingConvexRadius, inBIncludingConvexRadius, d4);
|
|
225
|
-
|
|
226
|
-
// #v-ifdef DEV
|
|
227
|
-
assert(p1 === 0, "support point index 0 must be added first");
|
|
228
|
-
assert(p2 === 1, "support point index 1 must be added second");
|
|
229
|
-
assert(p3 === 2, "support point index 2 must be added third");
|
|
230
|
-
assert(p4 === 3, "support point index 3 must be added fourth");
|
|
231
|
-
// #v-endif
|
|
232
|
-
break;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
case 2: {
|
|
236
|
-
// Two vertices, create 3 extra by taking perpendicular axis and rotating it around in 120 degree increments
|
|
237
|
-
|
|
238
|
-
axis.subtractVectors(support_points.mY.values[1], support_points.mY.values[0]).normalize();
|
|
239
|
-
|
|
240
|
-
rotation.fromAxisAngle(axis, degreesToRadians(120.0));
|
|
241
|
-
|
|
242
|
-
dir1.computeNormalizedPerpendicular(axis);
|
|
243
|
-
rotation.multiply3x3(dir2, dir1);
|
|
244
|
-
rotation.multiply3x3(dir3, dir2);
|
|
245
|
-
|
|
246
|
-
const p1 = support_points.add(inAIncludingConvexRadius, inBIncludingConvexRadius, dir1);
|
|
247
|
-
const p2 = support_points.add(inAIncludingConvexRadius, inBIncludingConvexRadius, dir2);
|
|
248
|
-
const p3 = support_points.add(inAIncludingConvexRadius, inBIncludingConvexRadius, dir3);
|
|
249
|
-
|
|
250
|
-
// #v-ifdef DEV
|
|
251
|
-
assert(p1 === 2, "support point index 2 must be added first");
|
|
252
|
-
assert(p2 === 3, "support point index 3 must be added second");
|
|
253
|
-
assert(p3 === 4, "support point index 4 must be added third");
|
|
254
|
-
// #v-endif
|
|
255
|
-
break;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
case 3:
|
|
259
|
-
case 4: {
|
|
260
|
-
// We already have enough points
|
|
261
|
-
break;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// Create hull out of the initial points
|
|
266
|
-
// #v-ifdef DEV
|
|
267
|
-
assert(support_points.mY.size() >= 3, "support points must have at least 3 points");
|
|
268
|
-
// #v-endif
|
|
269
|
-
const hull = this.hull;
|
|
270
|
-
hull.initialize(0, 1, 2);
|
|
271
|
-
for (let i = 3; i < support_points.mY.size(); ++i) {
|
|
272
|
-
const distSq: { value: number } = { value: -1 };
|
|
273
|
-
const t = hull.findFacingTriangle(support_points.mY.values[i], distSq);
|
|
274
|
-
if (t !== null) {
|
|
275
|
-
const newTriangles = this.newTriangles;
|
|
276
|
-
newTriangles.clear();
|
|
277
|
-
|
|
278
|
-
if (!hull.addPoint(t, i, Number.MAX_VALUE, newTriangles)) {
|
|
279
|
-
// We can't recover from a failure to add a point to the hull because the old triangles have been unlinked already.
|
|
280
|
-
// Assume no collision. This can happen if the shapes touch in 1 point (or plane) in which case the hull is degenerate.
|
|
281
|
-
return false;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// Loop until we are sure that the origin is inside the hull
|
|
287
|
-
while (true) {
|
|
288
|
-
// Get the next closest triangle
|
|
289
|
-
const t = hull.peekClosestTriangleInQueue();
|
|
290
|
-
|
|
291
|
-
// #v-ifdef DEV
|
|
292
|
-
// assert
|
|
293
|
-
if (!t) {
|
|
294
|
-
throw new Error("t must not be null");
|
|
295
|
-
}
|
|
296
|
-
// #v-endif
|
|
297
|
-
|
|
298
|
-
// Don't process removed triangles, just free them (because they're in a heap we don't remove them earlier since we would have to rebuild the sorted heap)
|
|
299
|
-
if (t.removed) {
|
|
300
|
-
hull.popClosestTriangleFromQueue();
|
|
301
|
-
|
|
302
|
-
// If we run out of triangles, we couldn't include the origin in the hull so there must be very little penetration and we report no collision.
|
|
303
|
-
if (!hull.hasNextTriangle()) {
|
|
304
|
-
return false;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
hull.freeTriangle(t);
|
|
308
|
-
continue;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// If the closest to the triangle is zero or positive, the origin is in the hull and we can proceed to the main algorithm
|
|
312
|
-
if (t.closestLengthSq >= 0.0) {
|
|
313
|
-
break;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
// Remove the triangle from the queue before we start adding new ones (which may result in a new closest triangle at the front of the queue)
|
|
317
|
-
hull.popClosestTriangleFromQueue();
|
|
318
|
-
|
|
319
|
-
// Add a support point to get the origin inside the hull
|
|
320
|
-
const newIndex = support_points.add(inAIncludingConvexRadius, inBIncludingConvexRadius, t.normal);
|
|
321
|
-
const w = support_points.mY.values[newIndex];
|
|
322
|
-
|
|
323
|
-
// Add the point to the hull, if we fail we terminate and report no collision
|
|
324
|
-
const newTriangles = this.newTriangles;
|
|
325
|
-
newTriangles.clear();
|
|
326
|
-
if (!t.isFacing(w) || !hull.addPoint(t, newIndex, Number.MAX_VALUE, newTriangles)) {
|
|
327
|
-
return false;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// The triangle is facing the support point "w" and can now be safely removed
|
|
331
|
-
// #v-ifdef DEV
|
|
332
|
-
assert(t.removed, "triangle must be removed after adding a new point");
|
|
333
|
-
// #v-endif
|
|
334
|
-
hull.freeTriangle(t);
|
|
335
|
-
|
|
336
|
-
// If we run out of triangles or points, we couldn't include the origin in the hull so there must be very little penetration and we report no collision.
|
|
337
|
-
if (!hull.hasNextTriangle() || support_points.mY.size() >= this.maxPointsToIncludeOriginInHull) {
|
|
338
|
-
return false;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// Current closest distance to origin
|
|
343
|
-
let closestDistSq = Number.MAX_VALUE;
|
|
344
|
-
|
|
345
|
-
// Remember last good triangle
|
|
346
|
-
let last: Triangle | null = null;
|
|
347
|
-
|
|
348
|
-
// If we want to flip the penetration depth
|
|
349
|
-
let flipVSign = false;
|
|
350
|
-
|
|
351
|
-
// Loop until closest point found
|
|
352
|
-
do {
|
|
353
|
-
// Get closest triangle to the origin
|
|
354
|
-
const t = hull.popClosestTriangleFromQueue();
|
|
355
|
-
|
|
356
|
-
// #v-ifdef DEV
|
|
357
|
-
// assert
|
|
358
|
-
if (!t) {
|
|
359
|
-
throw new Error("t must not be null");
|
|
360
|
-
}
|
|
361
|
-
// #v-endif
|
|
362
|
-
|
|
363
|
-
// Don't process removed triangles, just free them (because they're in a heap we don't remove them earlier since we would have to rebuild the sorted heap)
|
|
364
|
-
if (t.removed) {
|
|
365
|
-
hull.freeTriangle(t);
|
|
366
|
-
continue;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
// Check if next triangle is further away than closest point, we've found the closest point
|
|
370
|
-
if (t.closestLengthSq >= closestDistSq) {
|
|
371
|
-
break;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// Replace last good with this triangle
|
|
375
|
-
if (last !== null) {
|
|
376
|
-
hull.freeTriangle(last);
|
|
377
|
-
}
|
|
378
|
-
last = t;
|
|
379
|
-
|
|
380
|
-
// Add support point in direction of normal of the plane
|
|
381
|
-
// Note that the article uses the closest point between the origin and plane, but this always has the exact same direction as the normal (if the origin is behind the plane)
|
|
382
|
-
// and this way we do less calculations and lose less precision
|
|
383
|
-
const newIndex = support_points.add(inAIncludingConvexRadius, inBIncludingConvexRadius, t.normal);
|
|
384
|
-
const w = support_points.mY.values[newIndex];
|
|
385
|
-
|
|
386
|
-
// Project w onto the triangle normal
|
|
387
|
-
const dot = t.normal.dot(w);
|
|
388
|
-
|
|
389
|
-
// Check if we just found a separating axis. This can happen if the shape shrunk by convex radius and then expanded by
|
|
390
|
-
// convex radius is bigger then the original shape due to inaccuracies in the shrinking process.
|
|
391
|
-
if (dot < 0.0) {
|
|
392
|
-
return false;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// Get the distance squared (along normal) to the support point
|
|
396
|
-
const distSq = squared(dot) / t.normal.squaredLength();
|
|
397
|
-
|
|
398
|
-
// If the error became small enough, we've converged
|
|
399
|
-
if (distSq - t.closestLengthSq < t.closestLengthSq * inTolerance) {
|
|
400
|
-
break;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// Keep track of the minimum distance
|
|
404
|
-
closestDistSq = Math.min(closestDistSq, distSq);
|
|
405
|
-
|
|
406
|
-
// If the triangle thinks this point is not front facing, we've reached numerical precision and we're done
|
|
407
|
-
if (!t.isFacing(w)) {
|
|
408
|
-
break;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// Add point to hull
|
|
412
|
-
const newTriangles = this.newTriangles;
|
|
413
|
-
newTriangles.clear();
|
|
414
|
-
if (!hull.addPoint(t, newIndex, closestDistSq, newTriangles)) {
|
|
415
|
-
break;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
// If the hull is starting to form defects then we're reaching numerical precision and we have to stop
|
|
419
|
-
let hasDefect = false;
|
|
420
|
-
for (const nt of newTriangles) {
|
|
421
|
-
if (nt && nt.isFacingOrigin()) {
|
|
422
|
-
hasDefect = true;
|
|
423
|
-
break;
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
if (hasDefect) {
|
|
428
|
-
// When the hull has defects it is possible that the origin has been classified on the wrong side of the triangle
|
|
429
|
-
// so we do an additional check to see if the penetration in the -triangle normal direction is smaller than
|
|
430
|
-
// the penetration in the triangle normal direction. If so we must flip the sign of the penetration depth.
|
|
431
|
-
|
|
432
|
-
negatedNormal.negateVector(t.normal);
|
|
433
|
-
inAIncludingConvexRadius.computeSupport(p2, negatedNormal);
|
|
434
|
-
inBIncludingConvexRadius.computeSupport(q2, t.normal);
|
|
435
|
-
w2.subtractVectors(p2, q2);
|
|
436
|
-
const dot2 = negatedNormal.dot(w2);
|
|
437
|
-
if (dot2 < dot) {
|
|
438
|
-
// Flip the sign of the penetration depth
|
|
439
|
-
flipVSign = !flipVSign;
|
|
440
|
-
}
|
|
441
|
-
break;
|
|
442
|
-
}
|
|
443
|
-
} while (hull.hasNextTriangle() && support_points.mY.size() < this.hull.settings.maxPoints);
|
|
444
|
-
|
|
445
|
-
// Determine closest points, if last == null it means the hull was a plane so there's no penetration
|
|
446
|
-
if (last === null) {
|
|
447
|
-
return false;
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
// Calculate penetration by getting the vector from the origin to the closest point on the triangle:
|
|
451
|
-
// distance = (centroid - origin) . normal / |normal|, closest = origin + distance * normal / |normal|
|
|
452
|
-
outV.copy(last.normal).scale(last.centroid.dot(last.normal) / last.normal.squaredLength());
|
|
453
|
-
|
|
454
|
-
// If penetration is near zero, treat this as a non collision since we cannot find a good normal
|
|
455
|
-
if (outV.isNearZero()) {
|
|
456
|
-
return false;
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// Check if we have to flip the sign of the penetration depth
|
|
460
|
-
if (flipVSign) {
|
|
461
|
-
outV.negate();
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
// Use the barycentric coordinates for the closest point to the origin to find the contact points on A and B
|
|
465
|
-
const xp0 = support_points.mP.values[last.edge[0].startIndex];
|
|
466
|
-
const xp1 = support_points.mP.values[last.edge[1].startIndex];
|
|
467
|
-
const xp2 = support_points.mP.values[last.edge[2].startIndex];
|
|
468
|
-
|
|
469
|
-
const xq0 = support_points.mQ.values[last.edge[0].startIndex];
|
|
470
|
-
const xq1 = support_points.mQ.values[last.edge[1].startIndex];
|
|
471
|
-
const xq2 = support_points.mQ.values[last.edge[2].startIndex];
|
|
472
|
-
|
|
473
|
-
if (last.lambdaRelativeTo0) {
|
|
474
|
-
p01.subtractVectors(xp1, xp0);
|
|
475
|
-
p02.subtractVectors(xp2, xp0);
|
|
476
|
-
q01.subtractVectors(xq1, xq0);
|
|
477
|
-
q02.subtractVectors(xq2, xq0);
|
|
478
|
-
|
|
479
|
-
outPointA.copy(xp0).addScaled(p01, last.lambda[0]).addScaled(p02, last.lambda[1]);
|
|
480
|
-
outPointB.copy(xq0).addScaled(q01, last.lambda[0]).addScaled(q02, last.lambda[1]);
|
|
481
|
-
} else {
|
|
482
|
-
p10.subtractVectors(xp0, xp1);
|
|
483
|
-
p12.subtractVectors(xp2, xp1);
|
|
484
|
-
q10.subtractVectors(xq0, xq1);
|
|
485
|
-
q12.subtractVectors(xq2, xq1);
|
|
486
|
-
|
|
487
|
-
outPointA.copy(xp1).addScaled(p10, last.lambda[0]).addScaled(p12, last.lambda[1]);
|
|
488
|
-
outPointB.copy(xq1).addScaled(q10, last.lambda[0]).addScaled(q12, last.lambda[1]);
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
return true;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Vec3 } from "../../math/vec3";
|
|
2
|
-
import { SupportShape } from "../../shape/Convex";
|
|
3
|
-
import { Points } from "../epa/arrays";
|
|
4
|
-
|
|
5
|
-
const negatedDirection = /*@__PURE__*/ Vec3.create();
|
|
6
|
-
|
|
7
|
-
const p = /*@__PURE__*/ Vec3.create();
|
|
8
|
-
const q = /*@__PURE__*/ Vec3.create();
|
|
9
|
-
const y = /*@__PURE__*/ Vec3.create();
|
|
10
|
-
|
|
11
|
-
export class SupportPoints {
|
|
12
|
-
mY: Points;
|
|
13
|
-
mP: Points;
|
|
14
|
-
mQ: Points;
|
|
15
|
-
|
|
16
|
-
constructor(capacity: number) {
|
|
17
|
-
this.mY = new Points(capacity);
|
|
18
|
-
this.mP = new Points(capacity);
|
|
19
|
-
this.mQ = new Points(capacity);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
clear() {
|
|
23
|
-
this.mY.clear();
|
|
24
|
-
this.mP.clear();
|
|
25
|
-
this.mQ.clear();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Calculate and add new support point to the list of points
|
|
29
|
-
add(inA: SupportShape, inB: SupportShape, inDirection: Vec3) {
|
|
30
|
-
negatedDirection.negateVector(inDirection);
|
|
31
|
-
|
|
32
|
-
inA.computeSupport(p, inDirection);
|
|
33
|
-
inB.computeSupport(q, negatedDirection);
|
|
34
|
-
y.subtractVectors(p, q);
|
|
35
|
-
|
|
36
|
-
// Store new point
|
|
37
|
-
this.mY.pushBackCopy(y);
|
|
38
|
-
this.mP.pushBackCopy(p);
|
|
39
|
-
this.mQ.pushBackCopy(q);
|
|
40
|
-
|
|
41
|
-
// return the index of the new point
|
|
42
|
-
return this.mY.size() - 1;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
popBack() {
|
|
46
|
-
this.mY.popBack();
|
|
47
|
-
this.mP.popBack();
|
|
48
|
-
this.mQ.popBack();
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { createClass, MonomorphType, PropertyDefinitionMap } from "monomorph";
|
|
2
|
-
import { Vec3 } from "../../math/vec3";
|
|
3
|
-
import { SupportShape } from "../../shape/Convex";
|
|
4
|
-
|
|
5
|
-
const directionA = /*@__PURE__*/ Vec3.create();
|
|
6
|
-
const directionB = /*@__PURE__*/ Vec3.create();
|
|
7
|
-
const supportPointA = /*@__PURE__*/ Vec3.create();
|
|
8
|
-
const supportPointB = /*@__PURE__*/ Vec3.create();
|
|
9
|
-
|
|
10
|
-
const minkowskiDifferenceProps = {
|
|
11
|
-
direction: MonomorphType(Vec3),
|
|
12
|
-
point: MonomorphType(Vec3),
|
|
13
|
-
pointA: MonomorphType(Vec3),
|
|
14
|
-
pointB: MonomorphType(Vec3),
|
|
15
|
-
} as const satisfies PropertyDefinitionMap;
|
|
16
|
-
|
|
17
|
-
export class MinkowskiDifference extends createClass<MinkowskiDifference, typeof minkowskiDifferenceProps>(
|
|
18
|
-
minkowskiDifferenceProps
|
|
19
|
-
) {
|
|
20
|
-
get isOriginBeyondSupportPoint(): boolean {
|
|
21
|
-
return this.point.dot(this.direction) < 0;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
getSupportPointOnMinkowskiDifference(shapeA: SupportShape, shapeB: SupportShape, direction: Vec3): void {
|
|
25
|
-
directionA.copy(direction);
|
|
26
|
-
directionB.negateVector(direction);
|
|
27
|
-
|
|
28
|
-
shapeA.computeSupport(supportPointA, directionA);
|
|
29
|
-
shapeB.computeSupport(supportPointB, directionB);
|
|
30
|
-
|
|
31
|
-
this.direction.copy(direction);
|
|
32
|
-
this.point.subtractVectors(supportPointA, supportPointB);
|
|
33
|
-
this.pointA.copy(supportPointA);
|
|
34
|
-
this.pointB.copy(supportPointB);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { assert } from "../../helpers";
|
|
2
|
-
import { Vec3 } from "../../math/vec3";
|
|
3
|
-
|
|
4
|
-
const d = /*@__PURE__*/ Vec3.create();
|
|
5
|
-
|
|
6
|
-
export function computeExploredDistanceLowerUpperBound(
|
|
7
|
-
result: [number, number],
|
|
8
|
-
ray_direction: Vec3,
|
|
9
|
-
v1: Vec3,
|
|
10
|
-
v2: Vec3,
|
|
11
|
-
v3: Vec3,
|
|
12
|
-
v123_normal: Vec3,
|
|
13
|
-
o_to_v1_dot_v123_normal: number,
|
|
14
|
-
o_to_v4_dot_v_123_normal: number
|
|
15
|
-
): void {
|
|
16
|
-
d.copy(ray_direction);
|
|
17
|
-
// #v-ifdef DEV
|
|
18
|
-
assert(d.isUnitVector(), "d must be a unit vector");
|
|
19
|
-
assert(v123_normal.isUnitVector(), "v123_normal must be a unit vector");
|
|
20
|
-
// #v-endif
|
|
21
|
-
const v123_normal_dot_d = v123_normal.dot(d);
|
|
22
|
-
if (Math.abs(v123_normal_dot_d) <= 0) {
|
|
23
|
-
const o_to_v1_dot_d = v1.dot(d);
|
|
24
|
-
const o_to_v2_dot_d = v2.dot(d);
|
|
25
|
-
const o_to_v3_dot_d = v3.dot(d);
|
|
26
|
-
result[0] = Math.max(o_to_v1_dot_d, o_to_v2_dot_d, o_to_v3_dot_d);
|
|
27
|
-
result[1] = result[0];
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// The case we can make a division
|
|
32
|
-
result[0] = o_to_v1_dot_v123_normal / v123_normal_dot_d;
|
|
33
|
-
result[1] = o_to_v4_dot_v_123_normal / v123_normal_dot_d;
|
|
34
|
-
// #v-ifdef DEV
|
|
35
|
-
// assert(
|
|
36
|
-
// result[1] >= result[0],
|
|
37
|
-
// `upper_bound must be >= lower_bound, got lower bound ${result[0]} and upper bound ${result[1]} instead`
|
|
38
|
-
// );
|
|
39
|
-
// #v-endif
|
|
40
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { assert } from "../../helpers";
|
|
2
|
-
import { Vec3 } from "../../math/vec3";
|
|
3
|
-
import { SupportShape } from "../../shape/Convex";
|
|
4
|
-
import { MinkowskiDifference } from "./MinkowskiDifference";
|
|
5
|
-
import { ImpResult } from "./imp";
|
|
6
|
-
|
|
7
|
-
const d = /*@__PURE__*/ Vec3.create();
|
|
8
|
-
const support1 = /*@__PURE__*/ MinkowskiDifference.create();
|
|
9
|
-
const support2 = /*@__PURE__*/ MinkowskiDifference.create();
|
|
10
|
-
const support3 = /*@__PURE__*/ MinkowskiDifference.create();
|
|
11
|
-
const o_projected = /*@__PURE__*/ Vec3.create();
|
|
12
|
-
const v1_to_v2 = /*@__PURE__*/ Vec3.create();
|
|
13
|
-
const v1_to_v3 = /*@__PURE__*/ Vec3.create();
|
|
14
|
-
const s1s2s3_plane_normal = /*@__PURE__*/ Vec3.create();
|
|
15
|
-
const o_projected_to_v1 = /*@__PURE__*/ Vec3.create();
|
|
16
|
-
const cross_v1_to_v3_o_projected_to_v1 = /*@__PURE__*/ Vec3.create();
|
|
17
|
-
const cross_v1_to_v2_o_projected_to_v1 = /*@__PURE__*/ Vec3.create();
|
|
18
|
-
|
|
19
|
-
export function finalizeImpResult(
|
|
20
|
-
penetration_data: ImpResult,
|
|
21
|
-
shapeA: SupportShape,
|
|
22
|
-
shapeB: SupportShape,
|
|
23
|
-
ray_direction: Vec3,
|
|
24
|
-
v1: Vec3,
|
|
25
|
-
v2: Vec3,
|
|
26
|
-
v3: Vec3,
|
|
27
|
-
v1_dir: Vec3,
|
|
28
|
-
v2_dir: Vec3,
|
|
29
|
-
v3_dir: Vec3,
|
|
30
|
-
v123_normal: Vec3,
|
|
31
|
-
[distance_lb, distance_ub]: [number, number]
|
|
32
|
-
): void {
|
|
33
|
-
support1.getSupportPointOnMinkowskiDifference(shapeA, shapeB, v1_dir);
|
|
34
|
-
support2.getSupportPointOnMinkowskiDifference(shapeA, shapeB, v2_dir);
|
|
35
|
-
support3.getSupportPointOnMinkowskiDifference(shapeA, shapeB, v3_dir);
|
|
36
|
-
v1.copy(support1.point);
|
|
37
|
-
v2.copy(support2.point);
|
|
38
|
-
v3.copy(support3.point);
|
|
39
|
-
|
|
40
|
-
d.copy(ray_direction);
|
|
41
|
-
penetration_data.minimum_penetration = distance_ub;
|
|
42
|
-
penetration_data.penetration_direction.copy(d);
|
|
43
|
-
|
|
44
|
-
// Point in triangle distance is just lb
|
|
45
|
-
// #v-ifdef DEV
|
|
46
|
-
assert(Math.abs(d.dot(v123_normal)) > 0, "d and v123_normal must be in same direction");
|
|
47
|
-
// #v-endif
|
|
48
|
-
o_projected.scaleVector(d, distance_lb);
|
|
49
|
-
v1_to_v2.subtractVectors(v2, v1);
|
|
50
|
-
v1_to_v3.subtractVectors(v3, v1);
|
|
51
|
-
s1s2s3_plane_normal.crossVectors(v1_to_v2, v1_to_v3);
|
|
52
|
-
const area = s1s2s3_plane_normal.length();
|
|
53
|
-
o_projected_to_v1.subtractVectors(v1, o_projected);
|
|
54
|
-
cross_v1_to_v3_o_projected_to_v1.crossVectors(v1_to_v3, o_projected_to_v1);
|
|
55
|
-
cross_v1_to_v2_o_projected_to_v1.crossVectors(v1_to_v2, o_projected_to_v1);
|
|
56
|
-
const s2_weight = cross_v1_to_v3_o_projected_to_v1.length() / area;
|
|
57
|
-
const s3_weight = cross_v1_to_v2_o_projected_to_v1.length() / area;
|
|
58
|
-
const s1_weight = 1 - s2_weight - s3_weight;
|
|
59
|
-
|
|
60
|
-
penetration_data.worldContactPointA.zero();
|
|
61
|
-
penetration_data.worldContactPointA.addScaled(support1.pointA, s1_weight);
|
|
62
|
-
penetration_data.worldContactPointA.addScaled(support2.pointA, s2_weight);
|
|
63
|
-
penetration_data.worldContactPointA.addScaled(support3.pointA, s3_weight);
|
|
64
|
-
|
|
65
|
-
penetration_data.worldContactPointB.zero();
|
|
66
|
-
penetration_data.worldContactPointB.addScaled(support1.pointB, s1_weight);
|
|
67
|
-
penetration_data.worldContactPointB.addScaled(support2.pointB, s2_weight);
|
|
68
|
-
penetration_data.worldContactPointB.addScaled(support3.pointB, s3_weight);
|
|
69
|
-
}
|