@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,119 +0,0 @@
|
|
|
1
|
-
import { createClass, LazyReferenceListType, MonomorphInstance, NumberType, PropertyDefinitionMap, PropertyDefinitionReferenceList, ReferenceListType } from "monomorph";
|
|
2
|
-
import { Vec3 } from "../../math/vec3";
|
|
3
|
-
import { Mat4 } from "../../math/mat4";
|
|
4
|
-
import { Triangle } from "../../shape/Triangle";
|
|
5
|
-
|
|
6
|
-
const faceProps = {
|
|
7
|
-
numVertices: NumberType(0),
|
|
8
|
-
buffer: LazyReferenceListType(((() => Vec3) as () => never)) as PropertyDefinitionReferenceList<Vec3, Vec3 extends MonomorphInstance<infer P, infer I> ? P : never, Vec3 extends MonomorphInstance<infer P, infer I> ? I : never>,
|
|
9
|
-
} as const satisfies PropertyDefinitionMap;
|
|
10
|
-
|
|
11
|
-
const triangle = /*@__PURE__*/ Triangle.create();
|
|
12
|
-
const tempVertex = /*@__PURE__*/ Vec3.create();
|
|
13
|
-
|
|
14
|
-
export class Face extends createClass<Face, typeof faceProps>(faceProps) {
|
|
15
|
-
clear(): void {
|
|
16
|
-
this.numVertices = 0;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
isEmpty(): boolean {
|
|
20
|
-
return this.numVertices === 0;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
isFull(): boolean {
|
|
24
|
-
return this.numVertices === this.buffer!.maxLength;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
getVertex(out: Vec3, index: number): void {
|
|
28
|
-
// #v-ifdef DEV
|
|
29
|
-
// assert that index is within bounds
|
|
30
|
-
if (index < 0 || index >= this.buffer!.maxLength) {
|
|
31
|
-
throw new Error("index out of bounds");
|
|
32
|
-
}
|
|
33
|
-
// #v-endif
|
|
34
|
-
|
|
35
|
-
out.copy(this.buffer!.getAtIndex(index)!);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
pushVertex(value: Vec3): void {
|
|
39
|
-
if (this.numVertices >= this.buffer!.maxLength) {
|
|
40
|
-
throw new Error("Face is full");
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
this.buffer!.getAtIndex(this.numVertices)!.copy(value);
|
|
44
|
-
this.numVertices++;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
pushVertexValues(x: number, y: number, z: number): void {
|
|
48
|
-
if (this.numVertices >= this.buffer!.maxLength) {
|
|
49
|
-
throw new Error("Face is full");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const vertex = this.buffer!.getAtIndex(this.numVertices)!;
|
|
53
|
-
vertex.x = x;
|
|
54
|
-
vertex.y = y;
|
|
55
|
-
vertex.z = z;
|
|
56
|
-
this.numVertices++;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
transform(isometry: Mat4): void {
|
|
60
|
-
for (let i = 0; i < this.numVertices; i++) {
|
|
61
|
-
this.buffer!.getAtIndex(i)!.transformByMat4(isometry);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
getCentroid(out: Vec3): void {
|
|
66
|
-
out.zero();
|
|
67
|
-
for (let i = 0; i < this.numVertices; i++) {
|
|
68
|
-
out.addVector(this.buffer!.getAtIndex(i)!);
|
|
69
|
-
}
|
|
70
|
-
out.scale(1 / this.numVertices);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
getNormal(out: Vec3): void {
|
|
74
|
-
switch (this.numVertices) {
|
|
75
|
-
case 0:
|
|
76
|
-
case 1:
|
|
77
|
-
case 2: {
|
|
78
|
-
out.zero();
|
|
79
|
-
break;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
default: {
|
|
83
|
-
triangle.a.copy(this.buffer!.getAtIndex(0)!);
|
|
84
|
-
triangle.b.copy(this.buffer!.getAtIndex(1)!);
|
|
85
|
-
triangle.c.copy(this.buffer!.getAtIndex(2)!);
|
|
86
|
-
triangle.computeNormal(out);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
translate(translation: Vec3): void {
|
|
92
|
-
for (let i = 0; i < this.numVertices; i++) {
|
|
93
|
-
this.buffer!.getAtIndex(i)!.addVector(translation);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
swap(other: Face): void {
|
|
98
|
-
if (this.numVertices !== other.numVertices) {
|
|
99
|
-
throw new Error("Cannot swap faces of different sizes");
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
for (let i = 0; i < this.numVertices; i++) {
|
|
103
|
-
tempVertex.copy(this.buffer!.getAtIndex(i)!);
|
|
104
|
-
this.buffer!.getAtIndex(i)!.copy(other.buffer!.getAtIndex(i)!);
|
|
105
|
-
other.buffer!.getAtIndex(i)!.copy(tempVertex);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const oldCreate = Face.create;
|
|
111
|
-
Face.create = function () {
|
|
112
|
-
const face = oldCreate.apply(this, arguments as any);
|
|
113
|
-
if (isFinite(face.buffer.maxLength)) {
|
|
114
|
-
for (let i = 0; i < face.buffer.maxLength; i++) {
|
|
115
|
-
face.buffer.create();
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return face;
|
|
119
|
-
};
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { PoolClass, type NumberArray } from "monomorph";
|
|
2
|
-
import { ContactManifold, ContactManifoldPool } from "./ContactManifold";
|
|
3
|
-
import { ContactPair } from "./ContactManifold";
|
|
4
|
-
import { destroyAllInstancesInPool } from "../../helpers";
|
|
5
|
-
import { Body } from "../Body";
|
|
6
|
-
|
|
7
|
-
export interface ManifoldCacheOptions {
|
|
8
|
-
maxContactManifolds: number;
|
|
9
|
-
maxContactPairs: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export class ManifoldCache {
|
|
13
|
-
options: ManifoldCacheOptions;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* the allocation of contact manifolds
|
|
17
|
-
*/
|
|
18
|
-
manifolds: ContactManifoldPool;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* the key is a string of the form (BodyIdA|SubShapeIdA,BodyIdB|SubShapeIdB), where BodyIdA < BodyIdB. if no SubShape is involved for a Body, the SubShapeId is 0
|
|
22
|
-
* the value is the structId of the ContactManifold
|
|
23
|
-
*/
|
|
24
|
-
manifoldMap: Map<string, ContactManifold>;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* the allocation of contact pairs
|
|
28
|
-
*/
|
|
29
|
-
pairs: PoolClass<ContactPair>;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* the key is a string of the form (BodyIdA,BodyIdB), where BodyIdA < BodyIdB.
|
|
33
|
-
* the value is the structId of the ContactPair, which points to the first contact manifold in the linked list of contact manifolds for that pair of bodies
|
|
34
|
-
*/
|
|
35
|
-
pairMap: Map<string, ContactPair>;
|
|
36
|
-
|
|
37
|
-
constructor(options?: Partial<ManifoldCacheOptions>) {
|
|
38
|
-
this.options = {
|
|
39
|
-
maxContactManifolds: 1024,
|
|
40
|
-
maxContactPairs: 1024,
|
|
41
|
-
...(options ?? {}),
|
|
42
|
-
};
|
|
43
|
-
this.manifolds = new ContactManifoldPool(this.options.maxContactManifolds, 4);
|
|
44
|
-
this.manifoldMap = new Map();
|
|
45
|
-
|
|
46
|
-
this.pairs = new ContactPair.Pool(this.options.maxContactPairs);
|
|
47
|
-
this.pairMap = new Map();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
toArray(array: NumberArray, startOffset: number): number {
|
|
51
|
-
startOffset = this.manifolds.vec3Pool.toArray(array, startOffset);
|
|
52
|
-
startOffset = this.manifolds.contactManifoldPool.toArray(array, startOffset);
|
|
53
|
-
startOffset = this.pairs.toArray(array, startOffset);
|
|
54
|
-
return startOffset;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
fromArray(
|
|
58
|
-
array: NumberArray,
|
|
59
|
-
references: {
|
|
60
|
-
body: PoolClass<Body>;
|
|
61
|
-
},
|
|
62
|
-
startOffset: number,
|
|
63
|
-
): number {
|
|
64
|
-
startOffset = this.manifolds.vec3Pool.fromArray(array, startOffset);
|
|
65
|
-
// startOffset not advanced until following line, since there are circular references
|
|
66
|
-
this.manifolds.contactManifoldPool.fromArrayNoReferences(array, startOffset);
|
|
67
|
-
startOffset = this.manifolds.contactManifoldPool.fromArrayOnlyReferences(array, {
|
|
68
|
-
bodyA: references.body,
|
|
69
|
-
bodyB: references.body,
|
|
70
|
-
contactPointsA: this.manifolds.vec3Pool,
|
|
71
|
-
contactPointsB: this.manifolds.vec3Pool,
|
|
72
|
-
lambdas: this.manifolds.vec3Pool,
|
|
73
|
-
nextContactManifold: this.manifolds.contactManifoldPool,
|
|
74
|
-
}, startOffset);
|
|
75
|
-
startOffset = this.pairs.fromArray(array, {
|
|
76
|
-
bodyA: references.body,
|
|
77
|
-
bodyB: references.body,
|
|
78
|
-
firstContactManifold: this.manifolds.contactManifoldPool,
|
|
79
|
-
}, startOffset);
|
|
80
|
-
this.rebuildMaps();
|
|
81
|
-
return startOffset;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* this method exists to support the History class
|
|
86
|
-
* see StructModule.rebuildMaps for reference on how to achieve this in general
|
|
87
|
-
* this should happen AFTER the world has rebuilt its base maps, to ensure that the manifold and pair struct data is accessible
|
|
88
|
-
*/
|
|
89
|
-
rebuildMaps(): void {
|
|
90
|
-
// 1. rebuild the manifoldMap
|
|
91
|
-
this.manifoldMap.clear();
|
|
92
|
-
for (const manifold of this.manifolds.contactManifoldPool) {
|
|
93
|
-
if (manifold) {
|
|
94
|
-
this.manifoldMap.set(manifold.key, manifold);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// 2. rebuild the pairMap
|
|
99
|
-
this.pairMap.clear();
|
|
100
|
-
for (const pair of this.pairs) {
|
|
101
|
-
if (pair) {
|
|
102
|
-
this.pairMap.set(pair.key, pair);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
clear(): void {
|
|
108
|
-
// 1. clear the manifolds
|
|
109
|
-
this.manifoldMap.clear();
|
|
110
|
-
destroyAllInstancesInPool(this.manifolds.contactManifoldPool);
|
|
111
|
-
|
|
112
|
-
// 2. clear the pairs
|
|
113
|
-
this.pairMap.clear();
|
|
114
|
-
destroyAllInstancesInPool(this.pairs);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { Vec3 } from "../../../math/vec3";
|
|
2
|
-
import { Face } from "../../../physics/manifold/Face";
|
|
3
|
-
|
|
4
|
-
const edge = /*@__PURE__*/ Vec3.create();
|
|
5
|
-
const edgeNormal = /*@__PURE__*/ Vec3.create();
|
|
6
|
-
const polygonNormal = /*@__PURE__*/ Vec3.create();
|
|
7
|
-
const vertex0 = /*@__PURE__*/ Vec3.create();
|
|
8
|
-
const vertex1 = /*@__PURE__*/ Vec3.create();
|
|
9
|
-
const vertex2 = /*@__PURE__*/ Vec3.create();
|
|
10
|
-
const vector01 = /*@__PURE__*/ Vec3.create();
|
|
11
|
-
const vector02 = /*@__PURE__*/ Vec3.create();
|
|
12
|
-
const edge10 = /*@__PURE__*/ Vec3.create();
|
|
13
|
-
const edge20 = /*@__PURE__*/ Vec3.create();
|
|
14
|
-
const v1 = /*@__PURE__*/ Vec3.create();
|
|
15
|
-
const v2 = /*@__PURE__*/ Vec3.create();
|
|
16
|
-
const v12 = /*@__PURE__*/ Vec3.create();
|
|
17
|
-
const e1 = /*@__PURE__*/ Vec3.create();
|
|
18
|
-
const vecE1ToEdgeVertex1 = /*@__PURE__*/ Vec3.create();
|
|
19
|
-
const e2 = /*@__PURE__*/ Vec3.create();
|
|
20
|
-
const vecE2ToEdgeVertex1 = /*@__PURE__*/ Vec3.create();
|
|
21
|
-
const e12 = /*@__PURE__*/ Vec3.create();
|
|
22
|
-
const clippedPoint = /*@__PURE__*/ Vec3.create();
|
|
23
|
-
const v1ToClippedPoint = /*@__PURE__*/ Vec3.create();
|
|
24
|
-
|
|
25
|
-
export function clipPolyVsEdge(
|
|
26
|
-
out: Face,
|
|
27
|
-
inPolygonToClip: Face,
|
|
28
|
-
inEdgeVertex1: Vec3,
|
|
29
|
-
inEdgeVertex2: Vec3,
|
|
30
|
-
inClippingEdgeNormal: Vec3
|
|
31
|
-
): void {
|
|
32
|
-
// #v-ifdef DEV
|
|
33
|
-
// assert that face to clip is a polygon (3 or more vertices)
|
|
34
|
-
if (inPolygonToClip.numVertices < 3) {
|
|
35
|
-
throw new Error("ContactManifoldModule.clipFaceAgainstEdge: faceToClip must have 3 or more vertices");
|
|
36
|
-
}
|
|
37
|
-
// #v-endif
|
|
38
|
-
|
|
39
|
-
// #v-ifdef DEV
|
|
40
|
-
// assert that out face is empty
|
|
41
|
-
if (out.numVertices > 0) {
|
|
42
|
-
throw new Error("ContactManifoldModule.clipFaceAgainstEdge: out face must be empty");
|
|
43
|
-
}
|
|
44
|
-
// #v-endif
|
|
45
|
-
|
|
46
|
-
// Get normal that is perpendicular to the edge and the clipping edge normal
|
|
47
|
-
|
|
48
|
-
edge.subtractVectors(inEdgeVertex2, inEdgeVertex1);
|
|
49
|
-
|
|
50
|
-
edgeNormal.crossVectors(inClippingEdgeNormal, edge);
|
|
51
|
-
|
|
52
|
-
// Project vertices of edge on inPolygonToClip
|
|
53
|
-
|
|
54
|
-
// get polygon normal
|
|
55
|
-
|
|
56
|
-
inPolygonToClip.getVertex(vertex0, 0);
|
|
57
|
-
|
|
58
|
-
inPolygonToClip.getVertex(vertex1, 1);
|
|
59
|
-
|
|
60
|
-
inPolygonToClip.getVertex(vertex2, 2);
|
|
61
|
-
|
|
62
|
-
vector01.subtractVectors(vertex1, vertex0);
|
|
63
|
-
|
|
64
|
-
vector02.subtractVectors(vertex2, vertex0);
|
|
65
|
-
|
|
66
|
-
polygonNormal.crossVectors(vector01, vector02);
|
|
67
|
-
|
|
68
|
-
const polygonNormalLenSquared = polygonNormal.squaredLength();
|
|
69
|
-
|
|
70
|
-
edge10.subtractVectors(vertex0, inEdgeVertex1);
|
|
71
|
-
|
|
72
|
-
edge20.subtractVectors(vertex0, inEdgeVertex2);
|
|
73
|
-
|
|
74
|
-
v1.addScaledToVector(inEdgeVertex1, polygonNormal, polygonNormal.dot(edge10) / polygonNormalLenSquared);
|
|
75
|
-
|
|
76
|
-
v2.addScaledToVector(inEdgeVertex2, polygonNormal, polygonNormal.dot(edge20) / polygonNormalLenSquared);
|
|
77
|
-
|
|
78
|
-
v12.subtractVectors(v2, v1);
|
|
79
|
-
|
|
80
|
-
const v12LenSquared = v12.squaredLength();
|
|
81
|
-
|
|
82
|
-
// Determine state of last point
|
|
83
|
-
|
|
84
|
-
inPolygonToClip.getVertex(e1, inPolygonToClip.numVertices - 1);
|
|
85
|
-
|
|
86
|
-
vecE1ToEdgeVertex1.subtractVectors(inEdgeVertex1, e1);
|
|
87
|
-
|
|
88
|
-
let prevNum = vecE1ToEdgeVertex1.dot(edgeNormal);
|
|
89
|
-
let prevInside = prevNum < 0;
|
|
90
|
-
|
|
91
|
-
// Loop through all vertices
|
|
92
|
-
|
|
93
|
-
for (let j = 0; j < inPolygonToClip.numVertices; j++) {
|
|
94
|
-
// Check if second point is inside
|
|
95
|
-
inPolygonToClip.getVertex(e2, j);
|
|
96
|
-
|
|
97
|
-
vecE2ToEdgeVertex1.subtractVectors(inEdgeVertex1, e2);
|
|
98
|
-
|
|
99
|
-
const num = vecE2ToEdgeVertex1.dot(edgeNormal);
|
|
100
|
-
const curInside = num < 0;
|
|
101
|
-
|
|
102
|
-
// In -> Out or Out -> In: Add point on clipping plane
|
|
103
|
-
if (curInside !== prevInside) {
|
|
104
|
-
// Solve: (X - inPlaneOrigin) . inPlaneNormal = 0 and X = e1 + t * (e2 - e1) for X
|
|
105
|
-
|
|
106
|
-
e12.subtractVectors(e2, e1);
|
|
107
|
-
|
|
108
|
-
const denom = e12.dot(edgeNormal);
|
|
109
|
-
|
|
110
|
-
clippedPoint.addScaledToVector(e1, e12, prevNum / denom);
|
|
111
|
-
|
|
112
|
-
// Project point on line segment v1, v2 so see if it falls outside if the edge
|
|
113
|
-
|
|
114
|
-
v1ToClippedPoint.subtractVectors(clippedPoint, v1);
|
|
115
|
-
|
|
116
|
-
const projection = v1ToClippedPoint.dot(v12);
|
|
117
|
-
if (projection < 0) {
|
|
118
|
-
out.pushVertex(v1);
|
|
119
|
-
} else if (projection > v12LenSquared) {
|
|
120
|
-
out.pushVertex(v2);
|
|
121
|
-
} else {
|
|
122
|
-
out.pushVertex(clippedPoint);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Update previous state
|
|
127
|
-
prevNum = num;
|
|
128
|
-
prevInside = curInside;
|
|
129
|
-
e1.copy(e2);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { Vec3 } from "../../../math/vec3";
|
|
2
|
-
import { Face } from "../Face";
|
|
3
|
-
|
|
4
|
-
const e1 = /*@__PURE__*/ Vec3.create();
|
|
5
|
-
const e1ToPlaneOrigin = /*@__PURE__*/ Vec3.create();
|
|
6
|
-
const e2 = /*@__PURE__*/ Vec3.create();
|
|
7
|
-
const e2ToPlaneOrigin = /*@__PURE__*/ Vec3.create();
|
|
8
|
-
const e12 = /*@__PURE__*/ Vec3.create();
|
|
9
|
-
const clippedPoint = /*@__PURE__*/ Vec3.create();
|
|
10
|
-
|
|
11
|
-
export function clipPolyVsPlane(out: Face, inPolygonToClip: Face, inPlaneOrigin: Vec3, inPlaneNormal: Vec3) {
|
|
12
|
-
// #v-ifdef DEV
|
|
13
|
-
// assert that face to clip is a polygon (3 or more vertices)
|
|
14
|
-
if (inPolygonToClip.numVertices < 3) {
|
|
15
|
-
throw new Error("ContactManifoldModule.clipPolyVsPlane: faceToClip must have 3 or more vertices");
|
|
16
|
-
}
|
|
17
|
-
// #v-endif
|
|
18
|
-
|
|
19
|
-
// #v-ifdef DEV
|
|
20
|
-
// assert that out face is empty
|
|
21
|
-
if (out.numVertices > 0) {
|
|
22
|
-
throw new Error("ContactManifoldModule.clipPolyVsPlane: out face must be empty");
|
|
23
|
-
}
|
|
24
|
-
// #v-endif
|
|
25
|
-
|
|
26
|
-
// determine state of last point
|
|
27
|
-
|
|
28
|
-
inPolygonToClip.getVertex(e1, inPolygonToClip.numVertices - 1);
|
|
29
|
-
|
|
30
|
-
e1ToPlaneOrigin.subtractVectors(inPlaneOrigin, e1);
|
|
31
|
-
|
|
32
|
-
let prevNum = e1ToPlaneOrigin.dot(inPlaneNormal);
|
|
33
|
-
let prevInside = prevNum < 0;
|
|
34
|
-
|
|
35
|
-
// loop through all vertices
|
|
36
|
-
|
|
37
|
-
for (let j = 0; j < inPolygonToClip.numVertices; j++) {
|
|
38
|
-
// check if second point is inside
|
|
39
|
-
inPolygonToClip.getVertex(e2, j);
|
|
40
|
-
|
|
41
|
-
e2ToPlaneOrigin.subtractVectors(inPlaneOrigin, e2);
|
|
42
|
-
|
|
43
|
-
const num = e2ToPlaneOrigin.dot(inPlaneNormal);
|
|
44
|
-
let curInside = num < 0;
|
|
45
|
-
|
|
46
|
-
// in -> out or out -> in: add point on clipping plane
|
|
47
|
-
if (curInside !== prevInside) {
|
|
48
|
-
// Solve: (X - inPlaneOrigin) . inPlaneNormal = 0 and X = e1 + t * (e2 - e1) for X
|
|
49
|
-
|
|
50
|
-
e12.subtractVectors(e2, e1);
|
|
51
|
-
|
|
52
|
-
const denom = e12.dot(inPlaneNormal);
|
|
53
|
-
|
|
54
|
-
if (denom !== 0) {
|
|
55
|
-
clippedPoint.addScaledToVector(e1, e12, prevNum / denom);
|
|
56
|
-
out.pushVertex(clippedPoint);
|
|
57
|
-
} else {
|
|
58
|
-
// Edge is parallel to plane, treat point as if it were on the same side as the last point
|
|
59
|
-
curInside = prevInside;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Point is inside, so we keep it
|
|
64
|
-
if (curInside) {
|
|
65
|
-
out.pushVertex(e2);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Update previous state
|
|
69
|
-
prevNum = num;
|
|
70
|
-
prevInside = curInside;
|
|
71
|
-
e1.copy(e2);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { Vec3 } from "../../../math/vec3";
|
|
2
|
-
import { Face } from "../Face";
|
|
3
|
-
import { clipPolyVsPlane } from "./clipPolyVsPlane";
|
|
4
|
-
|
|
5
|
-
const clipE1 = /*@__PURE__*/ Vec3.create();
|
|
6
|
-
const clipE2 = /*@__PURE__*/ Vec3.create();
|
|
7
|
-
const clipE1ToE2 = /*@__PURE__*/ Vec3.create();
|
|
8
|
-
const clipNormal = /*@__PURE__*/ Vec3.create();
|
|
9
|
-
|
|
10
|
-
const tempFace0 = /*@__PURE__*/ Face.create({
|
|
11
|
-
numVertices: 0,
|
|
12
|
-
buffer: { pool: new Vec3.Pool(32), maxLength: 32 },
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
const tempFace1 = /*@__PURE__*/ Face.create({
|
|
16
|
-
numVertices: 0,
|
|
17
|
-
buffer: { pool: new Vec3.Pool(32), maxLength: 32 },
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
export function clipPolyVsPoly(
|
|
21
|
-
out: Face,
|
|
22
|
-
inPolygonToClip: Face,
|
|
23
|
-
inClippingPolygon: Face,
|
|
24
|
-
inClippingPolygonNormal: Vec3
|
|
25
|
-
) {
|
|
26
|
-
// #v-ifdef DEV
|
|
27
|
-
// assert that face to clip is a polygon (3 or more vertices)
|
|
28
|
-
if (inPolygonToClip.numVertices < 3) {
|
|
29
|
-
throw new Error("ContactManifoldModule.clipPolyVsPoly: faceToClip must have 3 or more vertices");
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// #v-endif
|
|
33
|
-
// #v-ifdef DEV
|
|
34
|
-
// assert that clipping polygon is a polygon (3 or more vertices)
|
|
35
|
-
if (inClippingPolygon.numVertices < 3) {
|
|
36
|
-
throw new Error("ContactManifoldModule.clipPolyVsPoly: clippingPolygon must have 3 or more vertices");
|
|
37
|
-
}
|
|
38
|
-
// #v-endif
|
|
39
|
-
|
|
40
|
-
tempFace0.clear();
|
|
41
|
-
tempFace1.clear();
|
|
42
|
-
const tmpVertices = [tempFace0, tempFace1];
|
|
43
|
-
let tmpVerticesIdx = 0;
|
|
44
|
-
|
|
45
|
-
for (let i = 0; i < inClippingPolygon.numVertices; i++) {
|
|
46
|
-
// get edge to clip against
|
|
47
|
-
|
|
48
|
-
inClippingPolygon.getVertex(clipE1, i);
|
|
49
|
-
|
|
50
|
-
inClippingPolygon.getVertex(clipE2, (i + 1) % inClippingPolygon.numVertices);
|
|
51
|
-
|
|
52
|
-
clipE1ToE2.subtractVectors(clipE2, clipE1);
|
|
53
|
-
|
|
54
|
-
clipNormal.crossVectors(inClippingPolygonNormal, clipE1ToE2); // pointing inward to the clipping polygon
|
|
55
|
-
|
|
56
|
-
// get source and target polygon
|
|
57
|
-
const sourcePolygon = i === 0 ? inPolygonToClip : tmpVertices[tmpVerticesIdx];
|
|
58
|
-
tmpVerticesIdx ^= 1;
|
|
59
|
-
|
|
60
|
-
const targetPolygon = i === inClippingPolygon.numVertices - 1 ? out : tmpVertices[tmpVerticesIdx];
|
|
61
|
-
targetPolygon.clear();
|
|
62
|
-
|
|
63
|
-
// clip against the edge
|
|
64
|
-
clipPolyVsPlane(targetPolygon, sourcePolygon, clipE1, clipNormal);
|
|
65
|
-
|
|
66
|
-
// break out if no polygon left
|
|
67
|
-
if (targetPolygon.numVertices < 3) {
|
|
68
|
-
out.clear();
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|