@perplexdotgg/bounce 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +30 -0
  3. package/package.json +32 -0
  4. package/src/builders/ConvexHullBuilder.ts +437 -0
  5. package/src/builders/ConvexHullBuilder2d.ts +344 -0
  6. package/src/builders/ConvexHullBuilder3d.ts +1689 -0
  7. package/src/builders/HeightMapBuilder.ts +414 -0
  8. package/src/builders/TriangleMeshBuilder.ts +92 -0
  9. package/src/collision/CastShapesModule.ts +184 -0
  10. package/src/collision/CollideShapesModule.ts +152 -0
  11. package/src/collision/HeightMapCaster.ts +38 -0
  12. package/src/collision/HeightMapCollider.ts +33 -0
  13. package/src/collision/TriangleCaster.ts +249 -0
  14. package/src/collision/TriangleCollider.ts +308 -0
  15. package/src/collision/TriangleCollider2.ts +379 -0
  16. package/src/collision/activeEdge.ts +146 -0
  17. package/src/collision/cast/cast.ts +139 -0
  18. package/src/collision/cast/castCompoundVsCompound.ts +59 -0
  19. package/src/collision/cast/castCompoundVsConvex.ts +116 -0
  20. package/src/collision/cast/castConvexVsCompound.ts +123 -0
  21. package/src/collision/cast/castConvexVsConvex.ts +213 -0
  22. package/src/collision/cast/castConvexVsHeightMap.ts +73 -0
  23. package/src/collision/cast/castConvexVsTriangleMesh.ts +56 -0
  24. package/src/collision/cast/castRayVsCompound.ts +44 -0
  25. package/src/collision/cast/castRayVsConvex.ts +45 -0
  26. package/src/collision/cast/castRayVsHeightMap.ts +58 -0
  27. package/src/collision/cast/castRayVsTriangleMesh.ts +58 -0
  28. package/src/collision/closestPoints/closestPoints.ts +23 -0
  29. package/src/collision/closestPoints/computeBarycentricCoordinates2d.ts +32 -0
  30. package/src/collision/closestPoints/computeBarycentricCoordinates3d.ts +81 -0
  31. package/src/collision/closestPoints/computeClosestPointOnLine.ts +30 -0
  32. package/src/collision/closestPoints/computeClosestPointOnTetrahedron.ts +96 -0
  33. package/src/collision/closestPoints/computeClosestPointOnTriangle.ts +195 -0
  34. package/src/collision/closestPoints/isOriginOutsideOfPlane.ts +25 -0
  35. package/src/collision/closestPoints/isOriginOutsideOfTrianglePlanes.ts +72 -0
  36. package/src/collision/collide/collide.ts +146 -0
  37. package/src/collision/collide/collideCompoundVsCompound.ts +60 -0
  38. package/src/collision/collide/collideCompoundVsConvex.ts +59 -0
  39. package/src/collision/collide/collideCompoundVsHeightMap.ts +73 -0
  40. package/src/collision/collide/collideCompoundVsTriangleMesh.ts +56 -0
  41. package/src/collision/collide/collideConvexVsCompound.ts +57 -0
  42. package/src/collision/collide/collideConvexVsConvex.ts +225 -0
  43. package/src/collision/collide/collideConvexVsConvexImp.ts +236 -0
  44. package/src/collision/collide/collideConvexVsHeightMap.ts +53 -0
  45. package/src/collision/collide/collideConvexVsTriangleMesh.ts +58 -0
  46. package/src/collision/collide/collideHeightMapVsCompound.ts +69 -0
  47. package/src/collision/collide/collideHeightMapVsConvex.ts +53 -0
  48. package/src/collision/collide/collideSphereVsSphere.ts +81 -0
  49. package/src/collision/collide/collideTriangleMeshVsCompound.ts +58 -0
  50. package/src/collision/collide/collideTriangleMeshVsConvex.ts +58 -0
  51. package/src/collision/epa/EpaConvexHullBuilder.ts +397 -0
  52. package/src/collision/epa/StaticArray.ts +154 -0
  53. package/src/collision/epa/TriangleFactory.ts +32 -0
  54. package/src/collision/epa/arrays.ts +99 -0
  55. package/src/collision/epa/binaryHeap.ts +82 -0
  56. package/src/collision/epa/structs.ts +227 -0
  57. package/src/collision/gjk/GjkModule.ts +864 -0
  58. package/src/collision/gjk/PenetrationDepthModule.ts +493 -0
  59. package/src/collision/gjk/SupportPoints.ts +50 -0
  60. package/src/collision/imp/MinkowskiDifference.ts +36 -0
  61. package/src/collision/imp/computeExploredDistanceLowerUpperBound.ts +40 -0
  62. package/src/collision/imp/finalizeImpResult.ts +69 -0
  63. package/src/collision/imp/findContactImp.ts +196 -0
  64. package/src/collision/imp/imp.ts +28 -0
  65. package/src/collision/imp/incrementalMinimumDistanceExploreDirection.ts +207 -0
  66. package/src/collision/mpr/findPortal.ts +152 -0
  67. package/src/collision/mpr/mpr.ts +29 -0
  68. package/src/collision/mpr/updatePortal.ts +52 -0
  69. package/src/constraints/BaseConstraint.ts +50 -0
  70. package/src/constraints/ConstraintOptions.ts +22 -0
  71. package/src/constraints/ConstraintSolver.ts +119 -0
  72. package/src/constraints/DistanceConstraint.ts +229 -0
  73. package/src/constraints/FixedConstraint.ts +203 -0
  74. package/src/constraints/HingeConstraint.ts +460 -0
  75. package/src/constraints/PointConstraint.ts +108 -0
  76. package/src/constraints/components/AngleComponent.ts +226 -0
  77. package/src/constraints/components/AxisComponent.ts +263 -0
  78. package/src/constraints/components/HingeComponent.ts +215 -0
  79. package/src/constraints/components/Motor.ts +36 -0
  80. package/src/constraints/components/PointConstraintComponent.ts +179 -0
  81. package/src/constraints/components/RotationEulerComponent.ts +139 -0
  82. package/src/constraints/components/Spring.ts +30 -0
  83. package/src/constraints/components/SpringComponent.ts +71 -0
  84. package/src/constraints/types.ts +6 -0
  85. package/src/helpers.ts +147 -0
  86. package/src/index.ts +50 -0
  87. package/src/math/BasicTransform.ts +19 -0
  88. package/src/math/NumberValue.ts +13 -0
  89. package/src/math/isometry.ts +64 -0
  90. package/src/math/mat3.ts +529 -0
  91. package/src/math/mat4.ts +588 -0
  92. package/src/math/quat.ts +193 -0
  93. package/src/math/scalar.ts +81 -0
  94. package/src/math/tensor.ts +17 -0
  95. package/src/math/vec3.ts +589 -0
  96. package/src/math/vec4.ts +10 -0
  97. package/src/physics/Body.ts +581 -0
  98. package/src/physics/CollisionFilter.ts +52 -0
  99. package/src/physics/SleepModule.ts +163 -0
  100. package/src/physics/broadphase/BodyPairsModule.ts +363 -0
  101. package/src/physics/broadphase/BvhModule.ts +237 -0
  102. package/src/physics/broadphase/BvhTree.ts +803 -0
  103. package/src/physics/broadphase/ConstraintPairsModule.ts +385 -0
  104. package/src/physics/broadphase/TriangleMeshBvhTree.ts +379 -0
  105. package/src/physics/manifold/ContactManifold.ts +227 -0
  106. package/src/physics/manifold/ContactManifoldModule.ts +623 -0
  107. package/src/physics/manifold/Face.ts +119 -0
  108. package/src/physics/manifold/ManifoldCache.ts +116 -0
  109. package/src/physics/manifold/clipping/clipPolyVsEdge.ts +131 -0
  110. package/src/physics/manifold/clipping/clipPolyVsPlane.ts +73 -0
  111. package/src/physics/manifold/clipping/clipPolyVsPoly.ts +72 -0
  112. package/src/physics/narrowphase/CollideBodiesModule.ts +755 -0
  113. package/src/physics/solver/ContactConstraintModule.ts +659 -0
  114. package/src/physics/solver/ManifoldConstraint.ts +420 -0
  115. package/src/physics/solver/estimateCollisionResponse.ts +146 -0
  116. package/src/shape/Aabb.ts +400 -0
  117. package/src/shape/Box.ts +231 -0
  118. package/src/shape/Capsule.ts +332 -0
  119. package/src/shape/CompoundShape.ts +288 -0
  120. package/src/shape/Convex.ts +130 -0
  121. package/src/shape/ConvexHull.ts +423 -0
  122. package/src/shape/Cylinder.ts +313 -0
  123. package/src/shape/HeightMap.ts +511 -0
  124. package/src/shape/Line.ts +14 -0
  125. package/src/shape/Plane.ts +116 -0
  126. package/src/shape/Ray.ts +81 -0
  127. package/src/shape/Segment.ts +25 -0
  128. package/src/shape/Shape.ts +77 -0
  129. package/src/shape/Sphere.ts +181 -0
  130. package/src/shape/TransformedShape.ts +51 -0
  131. package/src/shape/Triangle.ts +122 -0
  132. package/src/shape/TriangleMesh.ts +186 -0
  133. package/src/types.ts +1 -0
  134. package/src/world.ts +1335 -0
  135. package/tests/BodyPairsModule.test.ts +71 -0
  136. package/tests/BvhTree.test.ts +406 -0
  137. package/tests/test.md +642 -0
  138. package/tests/vec3.test.ts +12 -0
  139. package/tsconfig.json +20 -0
  140. package/vite.config.js +40 -0
@@ -0,0 +1,146 @@
1
+ // activeEdges (uint8bit): 0 = edge AB active, bit 1 = edge BC active, bit 2 = edge CA active
2
+
3
+ import { degreesToRadians } from "../math/scalar";
4
+ import { Vec3 } from "../math/vec3";
5
+ import { BarycentricCoordinatesResult } from "./closestPoints/closestPoints";
6
+ import { computeBarycentricCoordinates3d } from "./closestPoints/computeBarycentricCoordinates3d";
7
+
8
+ const cos1degree = Math.cos(degreesToRadians(1));
9
+ const cos179degrees = Math.cos(degreesToRadians(179));
10
+ const epsilon = 1e-4;
11
+ const oneMinusEpsilon = 1 - epsilon;
12
+
13
+ const result = /*@__PURE__*/ BarycentricCoordinatesResult.create();
14
+ const crossNormal1Normal2 = /*@__PURE__*/ Vec3.create();
15
+ const pa = /*@__PURE__*/ Vec3.create();
16
+ const pb = /*@__PURE__*/ Vec3.create();
17
+ const pc = /*@__PURE__*/ Vec3.create();
18
+
19
+ export function isEdgeActive(
20
+ inNormal1: Vec3,
21
+ inNormal2: Vec3,
22
+ inEdgeDirection: Vec3,
23
+ inCosThresholdAngle: number
24
+ ): boolean {
25
+ // If normals are opposite the edges are active (the triangles are back to back)
26
+ const cosAngleBetweenNormals = inNormal1.dot(inNormal2);
27
+
28
+ // case: triangles are back to back -> edge is active
29
+ if (cosAngleBetweenNormals < cos179degrees) {
30
+ return true;
31
+ }
32
+
33
+ crossNormal1Normal2.crossVectors(inNormal1, inNormal2);
34
+
35
+ // case: concave edge -> edge is inactive
36
+ if (crossNormal1Normal2.dot(inEdgeDirection) < 0) {
37
+ return false;
38
+ }
39
+
40
+ // case: convex edge -> edge is active when angle between normals is bigger than threshold
41
+ return cosAngleBetweenNormals < inCosThresholdAngle;
42
+ }
43
+
44
+ export function fixNormal(
45
+ out: Vec3,
46
+ inV0: Vec3,
47
+ inV1: Vec3,
48
+ inV2: Vec3,
49
+ inTriangleNormal: Vec3,
50
+ inActiveEdges: number,
51
+ inPoint: Vec3,
52
+ inNormal: Vec3,
53
+ inMovementDirection: Vec3
54
+ ): void {
55
+ // #v-ifdef DEV
56
+ // TODO: assert that not all edges are active, else we already have the correct normal
57
+ if (inActiveEdges === 0b111) {
58
+ throw new Error("All edges are active, no need to fix normal");
59
+ }
60
+ // #v-endif
61
+
62
+ // If inNormal would affect movement less than inTriangleNormal use inNormal
63
+ // This is done since it is really hard to make a distinction between sliding over a horizontal triangulated grid and hitting an edge (in this case you want to use the triangle normal)
64
+ // and sliding over a triangulated grid and grazing a vertical triangle with an inactive edge (in this case using the triangle normal will cause the object to bounce back so we want to use the calculated normal).
65
+ // To solve this we take a movement hint to give an indication of what direction our object is moving. If the edge normal results in less motion difference than the triangle normal we use the edge normal.
66
+ const normal_length = inNormal.length();
67
+ const triangle_normal_length = inTriangleNormal.length();
68
+ if (
69
+ inMovementDirection.dot(inNormal) * triangle_normal_length <
70
+ inMovementDirection.dot(inTriangleNormal) * normal_length
71
+ ) {
72
+ out.copy(inNormal);
73
+ return;
74
+ }
75
+
76
+ // Check: None of the edges are active, we need to use the triangle normal
77
+ if (inActiveEdges === 0) {
78
+ out.copy(inTriangleNormal);
79
+ return;
80
+ }
81
+
82
+ // Some edges are active.
83
+ // If normal is parallel to the triangle normal we don't need to check the active edges.
84
+ if (inTriangleNormal.dot(inNormal) > cos1degree * normal_length * triangle_normal_length) {
85
+ out.copy(inNormal);
86
+ return;
87
+ }
88
+
89
+ let collidingEdge: number;
90
+
91
+ // Test where the contact point is in the triangle
92
+ result.u;
93
+ result.v;
94
+ result.w;
95
+
96
+ pa.subtractVectors(inV0, inPoint);
97
+ pb.subtractVectors(inV1, inPoint);
98
+ pc.subtractVectors(inV2, inPoint);
99
+
100
+ computeBarycentricCoordinates3d(result, pa, pb, pc);
101
+
102
+ // Colliding with v0, edge 0 or 2 needs to be active
103
+ if (result.u > oneMinusEpsilon) {
104
+ collidingEdge = 0b101;
105
+ }
106
+
107
+ // Colliding with v1, edge 0 or 1 needs to be active
108
+ else if (result.v > oneMinusEpsilon) {
109
+ collidingEdge = 0b011;
110
+ }
111
+
112
+ // Colliding with v2, edge 1 or 2 needs to be active
113
+ else if (result.w > oneMinusEpsilon) {
114
+ collidingEdge = 0b110;
115
+ }
116
+
117
+ // Colliding with edge v1, v2, edge 1 needs to be active
118
+ else if (result.u < epsilon) {
119
+ collidingEdge = 0b010;
120
+ }
121
+
122
+ // Colliding with edge v0, v2, edge 2 needs to be active
123
+ else if (result.v < epsilon) {
124
+ collidingEdge = 0b100;
125
+ }
126
+
127
+ // Colliding with edge v0, v1, edge 0 needs to be active
128
+ else if (result.w < epsilon) {
129
+ collidingEdge = 0b001;
130
+ }
131
+
132
+ // Interior hit
133
+ else {
134
+ out.copy(inTriangleNormal);
135
+ return;
136
+ }
137
+
138
+ // If this edge is active, use the provided normal
139
+ if ((inActiveEdges & collidingEdge) !== 0) {
140
+ out.copy(inNormal);
141
+ return;
142
+ }
143
+
144
+ // if this edge is not active, use the triangle normal
145
+ out.copy(inTriangleNormal);
146
+ }
@@ -0,0 +1,139 @@
1
+ import {
2
+ BooleanType,
3
+ createClass,
4
+ LazyReferenceType,
5
+ MonomorphType,
6
+ NumberType,
7
+ PropertyDefinitionMap,
8
+ PropertyDefinitionReference,
9
+ } from "monomorph";
10
+ import { Vec3 } from "../../math/vec3";
11
+ import { Face } from "../../physics/manifold/Face";
12
+ import { BackFaceMode, CollisionSettings, createDefaultCollisionSettings } from "../collide/collide";
13
+ import { Body } from "../../physics/Body";
14
+
15
+ export const enum CastStatus {
16
+ NotColliding,
17
+ Colliding,
18
+ Indeterminate,
19
+ }
20
+
21
+ const castResultProps = {
22
+ status: NumberType(0),
23
+ hasContact: BooleanType(false),
24
+ penetration: NumberType(0.0),
25
+ contactPointA: MonomorphType(Vec3),
26
+ contactPointB: MonomorphType(Vec3),
27
+ normalA: MonomorphType(Vec3),
28
+ normalB: MonomorphType(Vec3),
29
+ momentArmA: MonomorphType(Vec3),
30
+ momentArmB: MonomorphType(Vec3),
31
+ surfaceNormalA: MonomorphType(Vec3),
32
+ surfaceNormalB: MonomorphType(Vec3),
33
+ bodyA: LazyReferenceType((() => Body) as () => never) as PropertyDefinitionReference<Body | null, true>,
34
+ bodyB: LazyReferenceType((() => Body) as () => never) as PropertyDefinitionReference<Body | null, true>,
35
+ subShapeIdA: NumberType(0),
36
+ subShapeIdB: NumberType(0),
37
+ isBackFace: BooleanType(false),
38
+ faceA: MonomorphType(Face),
39
+ faceB: MonomorphType(Face),
40
+ fraction: NumberType(0.0),
41
+ isBackFaceHit: BooleanType(false),
42
+ } as const satisfies PropertyDefinitionMap;
43
+
44
+ export class CastResult extends createClass<CastResult, typeof castResultProps>(castResultProps) {
45
+ reset() {
46
+ this.status = CastStatus.Indeterminate;
47
+ this.hasContact = false;
48
+ this.penetration = 0;
49
+ this.bodyA = null;
50
+ this.bodyB = null;
51
+ this.subShapeIdA = 0;
52
+ this.subShapeIdB = 0;
53
+ this.isBackFace = false;
54
+ this.faceA.clear();
55
+ this.faceB.clear();
56
+ }
57
+
58
+ /**
59
+ * swaps the A and B data
60
+ */
61
+ swap() {
62
+ this.contactPointA.swap(this.contactPointB);
63
+ this.normalA.swap(this.normalB);
64
+ this.momentArmA.swap(this.momentArmB);
65
+ this.surfaceNormalA.swap(this.surfaceNormalB);
66
+
67
+ const tempBody = this.bodyA;
68
+ this.bodyA = this.bodyB;
69
+ this.bodyB = tempBody;
70
+
71
+ const tempSubShapeId = this.subShapeIdA;
72
+ this.subShapeIdA = this.subShapeIdB;
73
+ this.subShapeIdB = tempSubShapeId;
74
+
75
+ this.faceA.swap(this.faceB);
76
+ }
77
+
78
+ getEarlyOutFraction(): number {
79
+ return this.fraction > 0.0 ? this.fraction : -this.penetration;
80
+ }
81
+ }
82
+
83
+ export class CastCollector {
84
+ static initialEarlyOutFraction: number = 1.0 + 1e-4;
85
+ static shouldEarlyOutFraction: number = -Infinity;
86
+ earlyOutFraction: number = CastCollector.initialEarlyOutFraction;
87
+ body2: Body | null = null;
88
+
89
+ getEarlyOutFraction(): number {
90
+ return this.earlyOutFraction;
91
+ }
92
+
93
+ getPositiveEarlyOutFraction(): number {
94
+ return Math.max(Number.MIN_VALUE, this.earlyOutFraction);
95
+ }
96
+
97
+ reset() {
98
+ this.earlyOutFraction = CastCollector.initialEarlyOutFraction;
99
+ this.body2 = null;
100
+
101
+ return this;
102
+ }
103
+
104
+ updateEarlyOutFraction(inFraction: number): void {
105
+ if (inFraction <= this.earlyOutFraction) {
106
+ this.earlyOutFraction = inFraction;
107
+ }
108
+ }
109
+
110
+ addHit(result: CastResult): void {}
111
+
112
+ addMiss(): void {}
113
+ }
114
+
115
+ export interface CastSettings extends CollisionSettings {
116
+ backFaceModeConvex: BackFaceMode;
117
+ backFaceModeTriangles: BackFaceMode;
118
+ useShrunkenShapeAndConvexRadius: boolean;
119
+ returnDeepestPoint: boolean;
120
+ }
121
+ export const enum QueryPrecision {
122
+ approximate,
123
+ precise,
124
+ preciseWithContacts,
125
+ }
126
+ export interface RayCastSettings {
127
+ precision?: QueryPrecision;
128
+ returnClosestOnly?: boolean;
129
+ }
130
+
131
+ export function createDefaultCastSettings() {
132
+ return {
133
+ ...createDefaultCollisionSettings(),
134
+ backFaceModeConvex: BackFaceMode.IgnoreBackFaces,
135
+ backFaceModeTriangles: BackFaceMode.IgnoreBackFaces,
136
+ useShrunkenShapeAndConvexRadius: false,
137
+ returnDeepestPoint: false,
138
+ } satisfies CastSettings;
139
+ }
@@ -0,0 +1,59 @@
1
+ // import { Isometry } from "../../math/isometry";
2
+ // import { Vec3 } from "../../math/vec3";
3
+ // import { CompoundShape } from "../../shape/CompoundShape";
4
+ // import { ConvexWithcomputeSupportShape } from "../../shape/Convex";
5
+ // import { PenetrationDepthModule } from "../gjk/PenetrationDepthModule";
6
+ // import { CastCollector, CastSettings } from "./cast";
7
+ // import { castConvexVsConvex } from "./castConvexVsConvex";
8
+
9
+ // const negatedOffset = /*@__PURE__*/ Vec3.create();
10
+ // const offsetIsometryA = /*@__PURE__*/ Isometry.create();
11
+ // const offsetIsometryB = /*@__PURE__*/ Isometry.create();
12
+ // const inverseOffsetIsometryB = /*@__PURE__*/ Isometry.create();
13
+ // const offsetIsometryAToB = /*@__PURE__*/ Isometry.create();
14
+ // const displacementInB = /*@__PURE__*/ Vec3.create();
15
+
16
+ // export function castCompoundVsCompound(
17
+ // penetrationDepthModule: PenetrationDepthModule,
18
+ // ioCollector: CastCollector,
19
+ // inShapeA: CompoundShape,
20
+ // inShapeB: CompoundShape,
21
+ // isometryA: Isometry,
22
+ // isometryB: Isometry,
23
+ // inScaleA: number,
24
+ // inScaleB: number,
25
+ // displacement: Vec3,
26
+ // offset: Vec3,
27
+ // inSettings: CastSettings,
28
+ // preferredNormalBDirection?: Vec3,
29
+ // bodyIdA: number = 0,
30
+ // bodyIdB: number = 0
31
+ // ): void {
32
+ // // translate A and B by the offset, for example to move them both to origin
33
+ // negatedOffset.negateVector(offset);
34
+ // offsetIsometryA.matrix.postTranslatedMatrix(isometryA.matrix, negatedOffset);
35
+ // offsetIsometryB.matrix.postTranslatedMatrix(isometryB.matrix, negatedOffset);
36
+
37
+ // // get a transformA in the space of B
38
+ // inverseOffsetIsometryB.matrix.invertMat4(offsetIsometryB.matrix);
39
+ // offsetIsometryAToB.matrix.multiplyMatrices(inverseOffsetIsometryB.matrix, offsetIsometryA.matrix);
40
+
41
+ // // get displacement in the space of B
42
+ // inverseOffsetIsometryB.matrix.multiply3x3(displacementInB, displacement);
43
+
44
+ // castConvexVsConvex(
45
+ // penetrationDepthModule,
46
+ // ioCollector,
47
+ // inShapeA,
48
+ // inShapeB,
49
+ // offsetIsometryAToB,
50
+ // offsetIsometryB,
51
+ // inScaleA,
52
+ // inScaleB,
53
+ // displacementInB,
54
+ // inSettings,
55
+ // preferredNormalBDirection,
56
+ // bodyIdA,
57
+ // bodyIdB
58
+ // );
59
+ // }
@@ -0,0 +1,116 @@
1
+ import { BasicTransform } from "../../math/BasicTransform";
2
+ import { Isometry } from "../../math/isometry";
3
+ import { Vec3 } from "../../math/vec3";
4
+ import { Body } from "../../physics/Body";
5
+ import { CompoundShape } from "../../shape/CompoundShape";
6
+ import { ConvexWithcomputeSupportShape } from "../../shape/Convex";
7
+ import { ConvexShape } from "../../shape/Shape";
8
+ import { PenetrationDepthModule } from "../gjk/PenetrationDepthModule";
9
+ import { CastCollector, CastSettings } from "./cast";
10
+ import { castConvexVsConvexLocal } from "./castConvexVsConvex";
11
+
12
+ const negatedOffset = /*@__PURE__*/ Vec3.create();
13
+ const offsetIsometryA = /*@__PURE__*/ Isometry.create();
14
+ const offsetIsometryB = /*@__PURE__*/ Isometry.create();
15
+ const inverseOffsetIsometryB = /*@__PURE__*/ Isometry.create();
16
+ const offsetIsometryAToB = /*@__PURE__*/ Isometry.create();
17
+ const displacementInB = /*@__PURE__*/ Vec3.create();
18
+
19
+ export function castCompoundVsConvex(
20
+ penetrationDepthModule: PenetrationDepthModule,
21
+ ioCollector: CastCollector,
22
+ inShapeA: CompoundShape,
23
+ inShapeB: ConvexWithcomputeSupportShape,
24
+ isometryA: Isometry,
25
+ isometryB: Isometry,
26
+ inScaleA: number,
27
+ inScaleB: number,
28
+ displacement: Vec3,
29
+ offset: Vec3,
30
+ inSettings: CastSettings,
31
+ preferredNormalBDirection?: Vec3,
32
+ bodyA: Body | null = null,
33
+ bodyB: Body | null = null
34
+ ): void {
35
+ // translate A and B by the offset, for example to move them both to origin
36
+ negatedOffset.negateVector(offset);
37
+ offsetIsometryA.matrix.postTranslatedMatrix(isometryA.matrix, negatedOffset);
38
+ offsetIsometryB.matrix.postTranslatedMatrix(isometryB.matrix, negatedOffset);
39
+
40
+ // get a transformA in the space of B
41
+ inverseOffsetIsometryB.matrix.invertMatrix(offsetIsometryB.matrix);
42
+ offsetIsometryAToB.matrix.multiplyMatrices(inverseOffsetIsometryB.matrix, offsetIsometryA.matrix);
43
+
44
+ // get displacement in the space of B
45
+ inverseOffsetIsometryB.matrix.multiply3x3(displacementInB, displacement);
46
+
47
+ castCompoundVsConvexLocal(
48
+ penetrationDepthModule,
49
+ ioCollector,
50
+ inShapeA,
51
+ inShapeB,
52
+ offsetIsometryAToB,
53
+ offsetIsometryB,
54
+ inScaleA,
55
+ inScaleB,
56
+ displacementInB,
57
+ inSettings,
58
+ preferredNormalBDirection,
59
+ bodyA,
60
+ bodyB
61
+ );
62
+ }
63
+
64
+ const transformSubShapeToA = /*@__PURE__*/ Isometry.create();
65
+ const transformSubShapeToB = /*@__PURE__*/ Isometry.create();
66
+
67
+ export function castCompoundVsConvexLocal(
68
+ penetrationDepthModule: PenetrationDepthModule,
69
+ ioCollector: CastCollector,
70
+ inShapeA: CompoundShape,
71
+ inShapeB: ConvexWithcomputeSupportShape,
72
+ isometryAToB: Isometry,
73
+ isometryB: Isometry,
74
+ inScaleA: number,
75
+ inScaleB: number,
76
+ displacementInB: Vec3,
77
+ inShapeCastSettings: CastSettings,
78
+ preferredNormalBDirection?: Vec3,
79
+ bodyA: Body | null = null,
80
+ bodyB: Body | null = null
81
+ ): void {
82
+ // debugger;
83
+ // for (let i = 0; i < inShapeA.shapeIds.itemMaxCount; i++) {
84
+ let index = 0;
85
+ for (const shapeObj of inShapeA.shapes) {
86
+ const shape = shapeObj.shape as ConvexShape;
87
+ const transform = shapeObj.transform as BasicTransform;
88
+ const translation = transform.position;
89
+ const rotation = transform.rotation;
90
+
91
+ // set the isometries
92
+ transformSubShapeToA.fromRotationAndTranslation(rotation, translation);
93
+ transformSubShapeToB.matrix.multiplyMatrices(isometryAToB.matrix, transformSubShapeToA.matrix);
94
+
95
+ // cast the shapes
96
+ castConvexVsConvexLocal(
97
+ penetrationDepthModule,
98
+ ioCollector,
99
+ shape,
100
+ inShapeB,
101
+ transformSubShapeToB,
102
+ isometryB,
103
+ inScaleA,
104
+ inScaleB,
105
+ displacementInB,
106
+ inShapeCastSettings,
107
+ preferredNormalBDirection,
108
+ bodyA,
109
+ bodyB,
110
+ index,
111
+ 0
112
+ );
113
+
114
+ index++;
115
+ }
116
+ }
@@ -0,0 +1,123 @@
1
+ import { BasicTransform, ConvexShape } from "../..";
2
+ import { Isometry } from "../../math/isometry";
3
+ import { Vec3 } from "../../math/vec3";
4
+ import { Body } from "../../physics/Body";
5
+ import { CompoundShape } from "../../shape/CompoundShape";
6
+ import { ConvexWithcomputeSupportShape } from "../../shape/Convex";
7
+ import { PenetrationDepthModule } from "../gjk/PenetrationDepthModule";
8
+ import { CastCollector, CastSettings } from "./cast";
9
+ import { castConvexVsConvexLocal } from "./castConvexVsConvex";
10
+
11
+ const negatedOffset = /*@__PURE__*/ Vec3.create();
12
+ const offsetIsometryA = /*@__PURE__*/ Isometry.create();
13
+ const offsetIsometryB = /*@__PURE__*/ Isometry.create();
14
+ const inverseOffsetIsometryB = /*@__PURE__*/ Isometry.create();
15
+ const offsetIsometryAToB = /*@__PURE__*/ Isometry.create();
16
+ const displacementInB = /*@__PURE__*/ Vec3.create();
17
+
18
+ export function castConvexVsCompound(
19
+ penetrationDepthModule: PenetrationDepthModule,
20
+ ioCollector: CastCollector,
21
+ inShapeA: ConvexWithcomputeSupportShape,
22
+ inShapeB: CompoundShape,
23
+ isometryA: Isometry,
24
+ isometryB: Isometry,
25
+ inScaleA: number,
26
+ inScaleB: number,
27
+ displacement: Vec3,
28
+ offset: Vec3,
29
+ inSettings: CastSettings,
30
+ preferredNormalBDirection?: Vec3,
31
+ bodyA: Body | null = null,
32
+ bodyB: Body | null = null
33
+ ) {
34
+ // translate A and B by the offset, for example to move them both to origin
35
+ negatedOffset.negateVector(offset);
36
+ offsetIsometryA.matrix.postTranslatedMatrix(isometryA.matrix, negatedOffset);
37
+ offsetIsometryB.matrix.postTranslatedMatrix(isometryB.matrix, negatedOffset);
38
+
39
+ // get a transformA in the space of B
40
+ inverseOffsetIsometryB.matrix.invertMatrix(offsetIsometryB.matrix);
41
+ offsetIsometryAToB.matrix.multiplyMatrices(inverseOffsetIsometryB.matrix, offsetIsometryA.matrix);
42
+
43
+ // get displacement in the space of B
44
+ inverseOffsetIsometryB.matrix.multiply3x3(displacementInB, displacement);
45
+
46
+ castConvexVsCompoundLocal(
47
+ penetrationDepthModule,
48
+ ioCollector,
49
+ inShapeA,
50
+ inShapeB,
51
+ offsetIsometryAToB,
52
+ offsetIsometryB,
53
+ inScaleA,
54
+ inScaleB,
55
+ displacementInB,
56
+ inSettings,
57
+ preferredNormalBDirection,
58
+ bodyA,
59
+ bodyB
60
+ );
61
+ }
62
+
63
+ const transformSubShapeToB = /*@__PURE__*/ Isometry.create();
64
+ const transformBToSubShape = /*@__PURE__*/ Isometry.create();
65
+ const transformAToSubShape = /*@__PURE__*/ Isometry.create();
66
+ const transformSubShapeToWorld = /*@__PURE__*/ Isometry.create();
67
+ const displacementInSubShape = /*@__PURE__*/ Vec3.create();
68
+
69
+ export function castConvexVsCompoundLocal(
70
+ penetrationDepthModule: PenetrationDepthModule,
71
+ ioCollector: CastCollector,
72
+ inShapeA: ConvexWithcomputeSupportShape,
73
+ inShapeB: CompoundShape,
74
+ isometryAToB: Isometry,
75
+ isometryB: Isometry,
76
+ inScaleA: number,
77
+ inScaleB: number,
78
+ displacementInB: Vec3,
79
+ inShapeCastSettings: CastSettings,
80
+ preferredNormalBDirection?: Vec3,
81
+ bodyA: Body | null = null,
82
+ bodyB: Body | null = null
83
+ ): void {
84
+ let index = 0;
85
+ for (const shapeObj of inShapeB.shapes) {
86
+ const shape = shapeObj.shape as ConvexShape;
87
+ const transform = shapeObj.transform as BasicTransform;
88
+ const translation = transform.position;
89
+ const rotation = transform.rotation;
90
+
91
+ // set the isometries
92
+ transformSubShapeToB.fromRotationAndTranslation(rotation, translation);
93
+ transformBToSubShape.fromInverseRotationAndTranslation(rotation, translation);
94
+ transformAToSubShape.matrix.multiplyMatrices(transformBToSubShape.matrix, isometryAToB.matrix);
95
+
96
+ // set the displacement
97
+ transformBToSubShape.matrix.multiply3x3(displacementInSubShape, displacementInB);
98
+
99
+ // subshape to world transform to transform results back to world space
100
+ transformSubShapeToWorld.matrix.multiplyMatrices(isometryB.matrix, transformSubShapeToB.matrix);
101
+
102
+ // cast the shapes
103
+ castConvexVsConvexLocal(
104
+ penetrationDepthModule,
105
+ ioCollector,
106
+ inShapeA,
107
+ shape,
108
+ transformAToSubShape,
109
+ transformSubShapeToWorld,
110
+ inScaleA,
111
+ inScaleB,
112
+ displacementInSubShape,
113
+ inShapeCastSettings,
114
+ preferredNormalBDirection,
115
+ bodyA,
116
+ bodyB,
117
+ 0,
118
+ index
119
+ );
120
+
121
+ index++;
122
+ }
123
+ }