@woosh/meep-engine 2.139.0 → 2.141.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.
- package/package.json +1 -1
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_aabb.d.ts +3 -3
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_aabb.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_aabb.js +4 -4
- package/src/{engine/physics/broadphase/aabb_transform_oriented.d.ts → core/geom/3d/aabb/aabb3_transform_oriented.d.ts} +2 -2
- package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts.map +1 -0
- package/src/{engine/physics/broadphase/aabb_transform_oriented.js → core/geom/3d/aabb/aabb3_transform_oriented.js} +1 -1
- package/src/core/geom/3d/quaternion/quat3_multiply.d.ts +21 -0
- package/src/core/geom/3d/quaternion/quat3_multiply.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/quat3_multiply.js +25 -0
- package/src/core/geom/3d/quaternion/quat3_to_matrix3.d.ts +54 -0
- package/src/core/geom/3d/quaternion/quat3_to_matrix3.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/quat3_to_matrix3.js +69 -0
- package/src/core/geom/3d/shape/AbstractShape3D.d.ts +24 -2
- package/src/core/geom/3d/shape/AbstractShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/AbstractShape3D.js +24 -1
- package/src/core/geom/3d/shape/HeightMapShape3D.d.ts +148 -0
- package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -0
- package/src/core/geom/3d/shape/HeightMapShape3D.js +451 -0
- package/src/core/geom/3d/shape/MeshShape3D.d.ts +210 -0
- package/src/core/geom/3d/shape/MeshShape3D.d.ts.map +1 -0
- package/src/core/geom/3d/shape/MeshShape3D.js +593 -0
- package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/TransformedShape3D.js +46 -2
- package/src/core/geom/3d/shape/Triangle3D.d.ts +95 -0
- package/src/core/geom/3d/shape/Triangle3D.d.ts.map +1 -0
- package/src/core/geom/3d/shape/Triangle3D.js +318 -0
- package/src/core/geom/3d/shape/UnionShape3D.js +13 -0
- package/src/core/geom/3d/shape/shape_mesh_from_geometry.d.ts +30 -0
- package/src/core/geom/3d/shape/shape_mesh_from_geometry.d.ts.map +1 -0
- package/src/core/geom/3d/shape/shape_mesh_from_geometry.js +64 -0
- package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.js +9 -11
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.d.ts +28 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.js +48 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.d.ts.map +1 -1
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.js +40 -18
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts +9 -5
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts.map +1 -1
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.js +38 -10
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts +14 -5
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts.map +1 -1
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.js +47 -5
- package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts +19 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.js +75 -13
- package/src/core/geom/3d/triangle/v3_compute_triangle_normal.d.ts +2 -2
- package/src/core/geom/3d/triangle/v3_compute_triangle_normal.d.ts.map +1 -1
- package/src/core/geom/3d/triangle/v3_compute_triangle_normal.js +1 -1
- package/src/core/geom/vec3/v3_dot_array_array.d.ts +3 -3
- package/src/core/geom/vec3/v3_dot_array_array.d.ts.map +1 -1
- package/src/core/geom/vec3/v3_dot_array_array.js +2 -2
- package/src/core/geom/vec3/v3_negate_array.d.ts +3 -3
- package/src/core/geom/vec3/v3_negate_array.d.ts.map +1 -1
- package/src/core/geom/vec3/v3_negate_array.js +2 -2
- package/src/core/geom/vec3/v3_quat3_apply.d.ts +29 -0
- package/src/core/geom/vec3/v3_quat3_apply.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_quat3_apply.js +39 -0
- package/src/core/geom/vec3/v3_quat3_apply_inverse.d.ts +30 -0
- package/src/core/geom/vec3/v3_quat3_apply_inverse.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_quat3_apply_inverse.js +41 -0
- package/src/core/geom/vec3/v3_triple_cross_product.d.ts +32 -0
- package/src/core/geom/vec3/v3_triple_cross_product.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_triple_cross_product.js +45 -0
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +16 -3
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerController.js +211 -211
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +72 -8
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +37 -5
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +101 -3
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +1789 -1416
- package/src/engine/control/first-person/TODO.md +173 -127
- package/src/engine/control/first-person/abilities/Slide.d.ts.map +1 -1
- package/src/engine/control/first-person/abilities/Slide.js +9 -1
- package/src/engine/control/first-person/prototype_first_person_controller.js +88 -2
- package/src/engine/control/first-person/test/buildTestPlayer.d.ts.map +1 -1
- package/src/engine/control/first-person/test/buildTestPlayer.js +9 -1
- package/src/engine/graphics/geometry/CapsuleGeometry.d.ts +42 -0
- package/src/engine/graphics/geometry/CapsuleGeometry.d.ts.map +1 -0
- package/src/engine/graphics/geometry/CapsuleGeometry.js +171 -0
- package/src/engine/physics/BULLET_REVIEW.md +945 -0
- package/src/engine/physics/CANNON_REVIEW.md +1300 -0
- package/src/engine/physics/JOLT_REVIEW.md +913 -0
- package/src/engine/physics/PLAN.md +578 -236
- package/src/engine/physics/RAPIER_REVIEW.md +934 -0
- package/src/engine/physics/REVIEW_001_ACTION_PLAN.md +642 -0
- package/src/engine/physics/REVIEW_002.md +151 -0
- package/src/engine/physics/broadphase/compute_fat_world_aabb.js +2 -2
- package/src/engine/physics/constraint/DofMode.d.ts +28 -0
- package/src/engine/physics/constraint/DofMode.d.ts.map +1 -0
- package/src/engine/physics/constraint/DofMode.js +35 -0
- package/src/engine/physics/constraint/solve_constraints.d.ts +16 -0
- package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -0
- package/src/engine/physics/constraint/solve_constraints.js +436 -0
- package/src/engine/physics/contact/ManifoldStore.d.ts +83 -10
- package/src/engine/physics/contact/ManifoldStore.d.ts.map +1 -1
- package/src/engine/physics/contact/ManifoldStore.js +608 -499
- package/src/engine/physics/ecs/ColliderObserverSystem.d.ts +2 -2
- package/src/engine/physics/ecs/ColliderObserverSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/Joint.d.ts +179 -0
- package/src/engine/physics/ecs/Joint.d.ts.map +1 -0
- package/src/engine/physics/ecs/Joint.js +234 -0
- package/src/engine/physics/ecs/PhysicsSystem.d.ts +180 -20
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +1423 -1159
- package/src/engine/physics/fluid/FluidField.d.ts +14 -10
- package/src/engine/physics/fluid/FluidField.d.ts.map +1 -1
- package/src/engine/physics/fluid/FluidField.js +14 -10
- package/src/engine/physics/fluid/FluidSimulator.js +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts +17 -10
- package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.js +18 -11
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts +13 -10
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.js +18 -13
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts +4 -3
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.js +15 -11
- package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts +30 -6
- package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js +44 -18
- package/src/engine/physics/gjk/expanding_polytope_algorithm.d.ts +6 -6
- package/src/engine/physics/gjk/expanding_polytope_algorithm.d.ts.map +1 -1
- package/src/engine/physics/gjk/expanding_polytope_algorithm.js +68 -22
- package/src/engine/physics/gjk/gjk.d.ts +28 -2
- package/src/engine/physics/gjk/gjk.d.ts.map +1 -1
- package/src/engine/physics/gjk/gjk.js +421 -378
- package/src/engine/physics/gjk/minkowski_support.d.ts +37 -0
- package/src/engine/physics/gjk/minkowski_support.d.ts.map +1 -0
- package/src/engine/physics/gjk/minkowski_support.js +75 -0
- package/src/engine/physics/gjk/mpr.d.ts +56 -0
- package/src/engine/physics/gjk/mpr.d.ts.map +1 -0
- package/src/engine/physics/gjk/mpr.js +344 -0
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts +20 -5
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -1
- package/src/engine/physics/inertia/world_inverse_inertia.js +36 -38
- package/src/engine/physics/integration/integrate_position.d.ts +25 -7
- package/src/engine/physics/integration/integrate_position.d.ts.map +1 -1
- package/src/engine/physics/integration/integrate_position.js +43 -12
- package/src/engine/physics/integration/integrate_velocity.d.ts +30 -0
- package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -1
- package/src/engine/physics/integration/integrate_velocity.js +82 -1
- package/src/engine/physics/island/IslandBuilder.d.ts +4 -1
- package/src/engine/physics/island/IslandBuilder.d.ts.map +1 -1
- package/src/engine/physics/island/IslandBuilder.js +33 -16
- package/src/engine/physics/narrowphase/PosedShape.d.ts +0 -8
- package/src/engine/physics/narrowphase/PosedShape.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/PosedShape.js +28 -30
- package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/box_box_manifold.js +140 -18
- package/src/engine/physics/narrowphase/box_triangle_contact.d.ts +30 -0
- package/src/engine/physics/narrowphase/box_triangle_contact.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/box_triangle_contact.js +811 -0
- package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/capsule_contacts.js +10 -56
- package/src/engine/physics/narrowphase/capsule_triangle_contact.d.ts +71 -0
- package/src/engine/physics/narrowphase/capsule_triangle_contact.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/capsule_triangle_contact.js +375 -0
- package/src/engine/physics/narrowphase/compute_penetration.d.ts +91 -0
- package/src/engine/physics/narrowphase/compute_penetration.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/compute_penetration.js +396 -0
- package/src/engine/physics/narrowphase/decomposition/aabb_world_to_local.d.ts +35 -0
- package/src/engine/physics/narrowphase/decomposition/aabb_world_to_local.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/decomposition/aabb_world_to_local.js +80 -0
- package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.d.ts +31 -0
- package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.js +55 -0
- package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts +42 -0
- package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.js +204 -0
- package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts +42 -0
- package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.js +94 -0
- package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.d.ts +37 -0
- package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.js +37 -0
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts +41 -2
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/narrowphase_step.js +1497 -382
- package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/sphere_box_contact.js +16 -23
- package/src/engine/physics/narrowphase/sphere_triangle_contact.d.ts +48 -0
- package/src/engine/physics/narrowphase/sphere_triangle_contact.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/sphere_triangle_contact.js +143 -0
- package/src/engine/physics/queries/overlap_shape.d.ts +51 -0
- package/src/engine/physics/queries/overlap_shape.d.ts.map +1 -0
- package/src/engine/physics/queries/overlap_shape.js +183 -0
- package/src/engine/physics/queries/shape_cast.d.ts +56 -0
- package/src/engine/physics/queries/shape_cast.d.ts.map +1 -0
- package/src/engine/physics/queries/shape_cast.js +387 -0
- package/src/engine/physics/solver/solve_contacts.d.ts +146 -32
- package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -1
- package/src/engine/physics/solver/solve_contacts.js +809 -223
- package/src/engine/physics/broadphase/aabb_transform_oriented.d.ts.map +0 -1
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts +0 -20
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts.map +0 -1
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.js +0 -83
|
@@ -1,378 +1,421 @@
|
|
|
1
|
-
import { v3_dot } from "../../../core/geom/vec3/v3_dot.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
)
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
* GJK
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* @param {number[]|
|
|
62
|
-
* @param {AbstractShape3D} shape_a
|
|
63
|
-
* @param {AbstractShape3D} shape_b
|
|
64
|
-
* @
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
//
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
//
|
|
242
|
-
|
|
243
|
-
const
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
//
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
//
|
|
262
|
-
//
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
//
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
simplex[
|
|
272
|
-
simplex[
|
|
273
|
-
simplex[
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
search_dir
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
*
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
1
|
+
import { v3_dot } from "../../../core/geom/vec3/v3_dot.js";
|
|
2
|
+
import { v3_triple_cross_product } from "../../../core/geom/vec3/v3_triple_cross_product.js";
|
|
3
|
+
import { minkowski_support } from "./minkowski_support.js";
|
|
4
|
+
|
|
5
|
+
const GJK_MAX_ITERATIONS = 64;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Search-direction scratch. The Minkowski-support call uses its own
|
|
9
|
+
* pair of scratch buffers from {@link minkowski_support}; this one is
|
|
10
|
+
* just for the per-iteration search direction the simplex algorithm
|
|
11
|
+
* mutates in place.
|
|
12
|
+
*
|
|
13
|
+
* Float64 — see the precision sweep that converted the rest of the
|
|
14
|
+
* solver-path arrays.
|
|
15
|
+
*/
|
|
16
|
+
const scratch_dir = new Float64Array(3);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* GJK intersection test for two convex shapes.
|
|
20
|
+
*
|
|
21
|
+
* Determines whether two convex shapes overlap by iteratively building a simplex
|
|
22
|
+
* in the Minkowski difference space. If the origin is enclosed by the simplex,
|
|
23
|
+
* the shapes intersect.
|
|
24
|
+
*
|
|
25
|
+
* Adapted from https://github.com/kevinmoran/GJK/blob/master/GJK.h
|
|
26
|
+
*
|
|
27
|
+
* @param {number[]|Float64Array} simplex Working buffer for simplex vertices (4 vec3s). Must have length >= 12.
|
|
28
|
+
* @param {AbstractShape3D} shape_a
|
|
29
|
+
* @param {AbstractShape3D} shape_b
|
|
30
|
+
* @returns {boolean} true if the shapes intersect
|
|
31
|
+
*/
|
|
32
|
+
export function gjk(simplex, shape_a, shape_b) {
|
|
33
|
+
// Default initial search direction (1, 0, 0). gjk_core uses the
|
|
34
|
+
// caller's `dir` buffer as both the seed and the working
|
|
35
|
+
// direction, but for this wrapper the seed is fixed and the
|
|
36
|
+
// final direction is discarded.
|
|
37
|
+
scratch_dir[0] = 1;
|
|
38
|
+
scratch_dir[1] = 0;
|
|
39
|
+
scratch_dir[2] = 0;
|
|
40
|
+
return gjk_core(simplex, shape_a, shape_b, scratch_dir);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Separating-axis-cached variant of {@link gjk}. The 3 floats at
|
|
45
|
+
* `axis_buffer[axis_offset..+2]` are used as the initial search
|
|
46
|
+
* direction (seed) AND are overwritten with the final search direction
|
|
47
|
+
* on exit. The narrowphase keeps a per-manifold-slot cache of these
|
|
48
|
+
* three floats so quiescent contacts converge in 1–2 iterations next
|
|
49
|
+
* frame instead of ~6–10 from a cold `(1, 0, 0)` start (Bullet's
|
|
50
|
+
* `m_cachedSeparatingAxis` and Jolt's `ioV` use the same pattern).
|
|
51
|
+
*
|
|
52
|
+
* The same primitive doubles as a separating-axis cache for the
|
|
53
|
+
* "no-overlap" path: when GJK returns false, the final direction is
|
|
54
|
+
* roughly the separating axis, and next frame's first iteration
|
|
55
|
+
* detects separation immediately.
|
|
56
|
+
*
|
|
57
|
+
* Writeback is automatic — `gjk_core` mutates a `subarray` view of
|
|
58
|
+
* `axis_buffer`, so on return `axis_buffer[axis_offset..+2]` holds the
|
|
59
|
+
* final direction. No try/finally needed.
|
|
60
|
+
*
|
|
61
|
+
* @param {number[]|Float64Array} simplex
|
|
62
|
+
* @param {AbstractShape3D} shape_a
|
|
63
|
+
* @param {AbstractShape3D} shape_b
|
|
64
|
+
* @param {Float64Array} axis_buffer
|
|
65
|
+
* @param {number} axis_offset
|
|
66
|
+
* @returns {boolean}
|
|
67
|
+
*/
|
|
68
|
+
export function gjk_with_axis(simplex, shape_a, shape_b, axis_buffer, axis_offset) {
|
|
69
|
+
// Subarray view: zero-copy in V8 once the JIT realises both views
|
|
70
|
+
// back the same buffer; the in-place writes inside gjk_core
|
|
71
|
+
// propagate to axis_buffer automatically.
|
|
72
|
+
const dir_view = axis_buffer.subarray(axis_offset, axis_offset + 3);
|
|
73
|
+
|
|
74
|
+
// Guard against a stale or degenerate cached axis. A zero vector
|
|
75
|
+
// (first-frame initial state, or a stuck cache) and NaN / Inf
|
|
76
|
+
// would crash the first support-point query; the (1, 0, 0)
|
|
77
|
+
// fallback is the cold-start default.
|
|
78
|
+
const x = dir_view[0], y = dir_view[1], z = dir_view[2];
|
|
79
|
+
if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z)
|
|
80
|
+
|| (x === 0 && y === 0 && z === 0)) {
|
|
81
|
+
dir_view[0] = 1;
|
|
82
|
+
dir_view[1] = 0;
|
|
83
|
+
dir_view[2] = 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return gjk_core(simplex, shape_a, shape_b, dir_view);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Core GJK routine — parameterised on the search-direction buffer.
|
|
91
|
+
* The caller seeds `dir[0..2]` with an initial direction (typically
|
|
92
|
+
* `(1, 0, 0)` for cold starts or a cached separating axis from a
|
|
93
|
+
* previous frame), and on return `dir` holds the FINAL search
|
|
94
|
+
* direction the algorithm settled on. The narrowphase separating-
|
|
95
|
+
* axis cache (P2.1) uses this to thread per-manifold axes through
|
|
96
|
+
* `gjk_with_axis` without a try/finally writeback dance.
|
|
97
|
+
*
|
|
98
|
+
* @param {number[]|Float64Array} simplex
|
|
99
|
+
* @param {AbstractShape3D} shape_a
|
|
100
|
+
* @param {AbstractShape3D} shape_b
|
|
101
|
+
* @param {Float64Array} dir 3 floats; seed direction on entry, final
|
|
102
|
+
* direction on exit. The buffer is mutated throughout the function.
|
|
103
|
+
* @returns {boolean}
|
|
104
|
+
*/
|
|
105
|
+
function gjk_core(simplex, shape_a, shape_b, dir) {
|
|
106
|
+
|
|
107
|
+
// Get initial support point (simplex point C). Uses `dir` (the
|
|
108
|
+
// caller's seed) as the search direction.
|
|
109
|
+
minkowski_support(
|
|
110
|
+
simplex, 6,
|
|
111
|
+
shape_a, shape_b,
|
|
112
|
+
dir[0], dir[1], dir[2]
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
// Search toward the origin from C
|
|
116
|
+
dir[0] = -simplex[6];
|
|
117
|
+
dir[1] = -simplex[7];
|
|
118
|
+
dir[2] = -simplex[8];
|
|
119
|
+
|
|
120
|
+
if (dir[0] === 0 && dir[1] === 0 && dir[2] === 0) {
|
|
121
|
+
// Origin is exactly on the first support point — intersection
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Get second support point (simplex point B)
|
|
126
|
+
minkowski_support(simplex, 3, shape_a, shape_b, dir[0], dir[1], dir[2]);
|
|
127
|
+
|
|
128
|
+
// B didn't pass the origin — no intersection possible
|
|
129
|
+
if (v3_dot(simplex[3], simplex[4], simplex[5], dir[0], dir[1], dir[2]) < 0) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Line case: compute direction perpendicular to line segment BC toward origin
|
|
134
|
+
// CB = C - B
|
|
135
|
+
const cb_x = simplex[6] - simplex[3];
|
|
136
|
+
const cb_y = simplex[7] - simplex[4];
|
|
137
|
+
const cb_z = simplex[8] - simplex[5];
|
|
138
|
+
|
|
139
|
+
// BO = -B (origin - B)
|
|
140
|
+
const bo_x = -simplex[3];
|
|
141
|
+
const bo_y = -simplex[4];
|
|
142
|
+
const bo_z = -simplex[5];
|
|
143
|
+
|
|
144
|
+
// dir = CB × BO × CB (triple cross product)
|
|
145
|
+
v3_triple_cross_product(dir, 0, cb_x, cb_y, cb_z, bo_x, bo_y, bo_z);
|
|
146
|
+
|
|
147
|
+
// Handle degenerate case where origin is on the line segment
|
|
148
|
+
if (dir[0] === 0 && dir[1] === 0 && dir[2] === 0) {
|
|
149
|
+
// Origin is on the line segment — pick any perpendicular direction
|
|
150
|
+
// Use the cross product of CB with an arbitrary axis
|
|
151
|
+
// CB × (1,0,0)
|
|
152
|
+
dir[0] = cb_y;
|
|
153
|
+
dir[1] = -cb_x;
|
|
154
|
+
dir[2] = 0;
|
|
155
|
+
|
|
156
|
+
if (dir[0] === 0 && dir[1] === 0 && dir[2] === 0) {
|
|
157
|
+
// CB is parallel to (1,0,0), use (0,1,0)
|
|
158
|
+
dir[0] = -cb_z;
|
|
159
|
+
dir[1] = 0;
|
|
160
|
+
dir[2] = cb_x;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
let simplex_size = 2; // we have B and C
|
|
165
|
+
|
|
166
|
+
for (let iterations = 0; iterations < GJK_MAX_ITERATIONS; iterations++) {
|
|
167
|
+
// Get new support point A
|
|
168
|
+
minkowski_support(simplex, 0, shape_a, shape_b, dir[0], dir[1], dir[2]);
|
|
169
|
+
|
|
170
|
+
const a_x = simplex[0];
|
|
171
|
+
const a_y = simplex[1];
|
|
172
|
+
const a_z = simplex[2];
|
|
173
|
+
|
|
174
|
+
// Check if A passed the origin
|
|
175
|
+
if (v3_dot(a_x, a_y, a_z, dir[0], dir[1], dir[2]) < 0) {
|
|
176
|
+
return false; // no intersection
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
simplex_size++;
|
|
180
|
+
|
|
181
|
+
if (simplex_size === 3) {
|
|
182
|
+
// Triangle case — may reduce to line (size 2) or keep as
|
|
183
|
+
// triangle (size 3) before shifting slots for the next iter.
|
|
184
|
+
simplex_size = update_simplex_triangle(dir, simplex);
|
|
185
|
+
} else {
|
|
186
|
+
// Tetrahedron case — 0 if origin enclosed, else new size
|
|
187
|
+
// after recursive face reduction.
|
|
188
|
+
const result = update_simplex_tetrahedron(dir, simplex);
|
|
189
|
+
if (result === 0) {
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
simplex_size = result;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Did not converge — assume no intersection
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Update simplex for the triangle case (3 points: A, B, C).
|
|
202
|
+
*
|
|
203
|
+
* Determines the Voronoi region of the origin relative to triangle ABC
|
|
204
|
+
* and updates the search direction accordingly. When the origin is
|
|
205
|
+
* closest to a triangle edge the simplex is reduced to a line (return
|
|
206
|
+
* 2). When the origin is above or below the triangle, the existing
|
|
207
|
+
* vertices are shifted (A → B, B → C, C → D for "above";
|
|
208
|
+
* B → D, A → B for "below") so the next iteration's new support
|
|
209
|
+
* point can be written into slot 0 without losing simplex history,
|
|
210
|
+
* and the function returns 3 — the main loop's `simplex_size++` then
|
|
211
|
+
* promotes it to 4 (tetrahedron case) on the next pass.
|
|
212
|
+
*
|
|
213
|
+
* simplex layout: [A(0-2), B(3-5), C(6-8), D(9-11)]
|
|
214
|
+
*
|
|
215
|
+
* @param {number[]|Float64Array} search_dir output: next search direction
|
|
216
|
+
* @param {Float64Array} simplex
|
|
217
|
+
* @returns {number} new simplex size — 2 if reduced to a line,
|
|
218
|
+
* 3 if a triangle was retained (with vertices shifted toward higher
|
|
219
|
+
* slots so the next iteration grows into a tetrahedron)
|
|
220
|
+
*/
|
|
221
|
+
function update_simplex_triangle(search_dir, simplex) {
|
|
222
|
+
const a_x = simplex[0], a_y = simplex[1], a_z = simplex[2];
|
|
223
|
+
const b_x = simplex[3], b_y = simplex[4], b_z = simplex[5];
|
|
224
|
+
const c_x = simplex[6], c_y = simplex[7], c_z = simplex[8];
|
|
225
|
+
|
|
226
|
+
// AB = B - A
|
|
227
|
+
const ab_x = b_x - a_x;
|
|
228
|
+
const ab_y = b_y - a_y;
|
|
229
|
+
const ab_z = b_z - a_z;
|
|
230
|
+
|
|
231
|
+
// AC = C - A
|
|
232
|
+
const ac_x = c_x - a_x;
|
|
233
|
+
const ac_y = c_y - a_y;
|
|
234
|
+
const ac_z = c_z - a_z;
|
|
235
|
+
|
|
236
|
+
// AO = -A (origin - A)
|
|
237
|
+
const ao_x = -a_x;
|
|
238
|
+
const ao_y = -a_y;
|
|
239
|
+
const ao_z = -a_z;
|
|
240
|
+
|
|
241
|
+
// Normal of triangle ABC
|
|
242
|
+
const abc_x = ab_y * ac_z - ab_z * ac_y;
|
|
243
|
+
const abc_y = ab_z * ac_x - ab_x * ac_z;
|
|
244
|
+
const abc_z = ab_x * ac_y - ab_y * ac_x;
|
|
245
|
+
|
|
246
|
+
// Test edge AC
|
|
247
|
+
// ABC × AC
|
|
248
|
+
const abc_cross_ac_x = abc_y * ac_z - abc_z * ac_y;
|
|
249
|
+
const abc_cross_ac_y = abc_z * ac_x - abc_x * ac_z;
|
|
250
|
+
const abc_cross_ac_z = abc_x * ac_y - abc_y * ac_x;
|
|
251
|
+
|
|
252
|
+
if (v3_dot(abc_cross_ac_x, abc_cross_ac_y, abc_cross_ac_z, ao_x, ao_y, ao_z) > 0) {
|
|
253
|
+
// Origin is on the AC side — reduce to line {A, C}, drop B.
|
|
254
|
+
//
|
|
255
|
+
// Slot management note: every main-loop iteration writes the
|
|
256
|
+
// newest support point into simplex[0..2] (the A slot),
|
|
257
|
+
// OVERWRITING the previous A. For "old A" to survive into the
|
|
258
|
+
// next iteration's triangle, it must be moved into another
|
|
259
|
+
// slot here. Kevin Moran's reference does `b = a;` — A's value
|
|
260
|
+
// is copied into the B slot. C stays where it is. Next iter's
|
|
261
|
+
// new A lands at slot 0; the simplex is then {new A, old A
|
|
262
|
+
// (in B slot), C} — a valid 3-vertex triangle.
|
|
263
|
+
//
|
|
264
|
+
// The previous implementation here wrote `simplex[3..5] = C`,
|
|
265
|
+
// which both duplicated C and discarded old A. Combined with
|
|
266
|
+
// the missing simplex-size accounting that kept the main loop
|
|
267
|
+
// calling `update_simplex_tetrahedron` with a stale D slot,
|
|
268
|
+
// this produced false-positive overlap for sphere-vs-sphere
|
|
269
|
+
// configurations placed off-axis. See `gjk.spec.js`'s
|
|
270
|
+
// documented regression block.
|
|
271
|
+
simplex[3] = a_x;
|
|
272
|
+
simplex[4] = a_y;
|
|
273
|
+
simplex[5] = a_z;
|
|
274
|
+
|
|
275
|
+
// New direction: AC × AO × AC
|
|
276
|
+
v3_triple_cross_product(search_dir, 0, ac_x, ac_y, ac_z, ao_x, ao_y, ao_z);
|
|
277
|
+
return 2;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Test edge AB
|
|
281
|
+
// AB × ABC
|
|
282
|
+
const ab_cross_abc_x = ab_y * abc_z - ab_z * abc_y;
|
|
283
|
+
const ab_cross_abc_y = ab_z * abc_x - ab_x * abc_z;
|
|
284
|
+
const ab_cross_abc_z = ab_x * abc_y - ab_y * abc_x;
|
|
285
|
+
|
|
286
|
+
if (v3_dot(ab_cross_abc_x, ab_cross_abc_y, ab_cross_abc_z, ao_x, ao_y, ao_z) > 0) {
|
|
287
|
+
// Origin is on the AB side — reduce to line {A, B}, drop C.
|
|
288
|
+
// Kevin Moran: `c = a;` — A's value into C slot. B stays.
|
|
289
|
+
simplex[6] = a_x;
|
|
290
|
+
simplex[7] = a_y;
|
|
291
|
+
simplex[8] = a_z;
|
|
292
|
+
|
|
293
|
+
// New direction: AB × AO × AB
|
|
294
|
+
v3_triple_cross_product(search_dir, 0, ab_x, ab_y, ab_z, ao_x, ao_y, ao_z);
|
|
295
|
+
return 2;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Origin is above or below the triangle. We're growing to a
|
|
299
|
+
// tetrahedron next iteration, so shift the existing vertices out
|
|
300
|
+
// of slot 0 to make room for the next minkowski_support.
|
|
301
|
+
if (v3_dot(abc_x, abc_y, abc_z, ao_x, ao_y, ao_z) > 0) {
|
|
302
|
+
// Origin above — `d = c; c = b; b = a;` (Kevin Moran). The
|
|
303
|
+
// next iteration writes new A at slot 0; the tetrahedron then
|
|
304
|
+
// has all four vertices populated with valid simplex history.
|
|
305
|
+
simplex[9] = simplex[6]; simplex[10] = simplex[7]; simplex[11] = simplex[8];
|
|
306
|
+
simplex[6] = simplex[3]; simplex[7] = simplex[4]; simplex[8] = simplex[5];
|
|
307
|
+
simplex[3] = simplex[0]; simplex[4] = simplex[1]; simplex[5] = simplex[2];
|
|
308
|
+
search_dir[0] = abc_x;
|
|
309
|
+
search_dir[1] = abc_y;
|
|
310
|
+
search_dir[2] = abc_z;
|
|
311
|
+
} else {
|
|
312
|
+
// Origin below — `d = b; b = a;` (C stays). Inverted-winding
|
|
313
|
+
// tetrahedron; the face tests in `update_simplex_tetrahedron`
|
|
314
|
+
// multiply face_test by face_d_side and compare against 0, so
|
|
315
|
+
// they're winding-agnostic.
|
|
316
|
+
simplex[9] = simplex[3]; simplex[10] = simplex[4]; simplex[11] = simplex[5];
|
|
317
|
+
simplex[3] = simplex[0]; simplex[4] = simplex[1]; simplex[5] = simplex[2];
|
|
318
|
+
search_dir[0] = -abc_x;
|
|
319
|
+
search_dir[1] = -abc_y;
|
|
320
|
+
search_dir[2] = -abc_z;
|
|
321
|
+
}
|
|
322
|
+
return 3;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Update simplex for the tetrahedron case (4 points: A, B, C, D).
|
|
327
|
+
*
|
|
328
|
+
* Tests which face of the tetrahedron is closest to the origin and
|
|
329
|
+
* reduces the simplex accordingly. Returns 0 if the origin is inside
|
|
330
|
+
* the tetrahedron, otherwise returns the new simplex size (2 = line,
|
|
331
|
+
* 3 = triangle) so the main loop can dispatch the next iteration
|
|
332
|
+
* correctly. The size after reduction is determined by the recursive
|
|
333
|
+
* `update_simplex_triangle` call on the surviving face.
|
|
334
|
+
*
|
|
335
|
+
* simplex layout: [A(0-2), B(3-5), C(6-8), D(9-11)]
|
|
336
|
+
*
|
|
337
|
+
* @param {number[]|Float64Array} search_dir output: next search direction (only written on non-enclosure)
|
|
338
|
+
* @param {Float64Array} simplex
|
|
339
|
+
* @returns {number} 0 if origin is inside, else new simplex size (2 or 3)
|
|
340
|
+
*/
|
|
341
|
+
function update_simplex_tetrahedron(search_dir, simplex) {
|
|
342
|
+
const a_x = simplex[0], a_y = simplex[1], a_z = simplex[2];
|
|
343
|
+
const b_x = simplex[3], b_y = simplex[4], b_z = simplex[5];
|
|
344
|
+
const c_x = simplex[6], c_y = simplex[7], c_z = simplex[8];
|
|
345
|
+
const d_x = simplex[9], d_y = simplex[10], d_z = simplex[11];
|
|
346
|
+
|
|
347
|
+
// AB, AC, AD vectors
|
|
348
|
+
const ab_x = b_x - a_x, ab_y = b_y - a_y, ab_z = b_z - a_z;
|
|
349
|
+
const ac_x = c_x - a_x, ac_y = c_y - a_y, ac_z = c_z - a_z;
|
|
350
|
+
const ad_x = d_x - a_x, ad_y = d_y - a_y, ad_z = d_z - a_z;
|
|
351
|
+
|
|
352
|
+
// AO = origin - A = -A
|
|
353
|
+
const ao_x = -a_x, ao_y = -a_y, ao_z = -a_z;
|
|
354
|
+
|
|
355
|
+
// Face normals (outward-facing from A's perspective)
|
|
356
|
+
// ABC normal
|
|
357
|
+
const abc_x = ab_y * ac_z - ab_z * ac_y;
|
|
358
|
+
const abc_y = ab_z * ac_x - ab_x * ac_z;
|
|
359
|
+
const abc_z = ab_x * ac_y - ab_y * ac_x;
|
|
360
|
+
|
|
361
|
+
// ACD normal
|
|
362
|
+
const acd_x = ac_y * ad_z - ac_z * ad_y;
|
|
363
|
+
const acd_y = ac_z * ad_x - ac_x * ad_z;
|
|
364
|
+
const acd_z = ac_x * ad_y - ac_y * ad_x;
|
|
365
|
+
|
|
366
|
+
// ADB normal
|
|
367
|
+
const adb_x = ad_y * ab_z - ad_z * ab_y;
|
|
368
|
+
const adb_y = ad_z * ab_x - ad_x * ab_z;
|
|
369
|
+
const adb_z = ad_x * ab_y - ad_y * ab_x;
|
|
370
|
+
|
|
371
|
+
// Test each face to see if the origin is on the outside
|
|
372
|
+
|
|
373
|
+
// Check face ABC (opposite to D)
|
|
374
|
+
const abc_test = v3_dot(abc_x, abc_y, abc_z, ao_x, ao_y, ao_z);
|
|
375
|
+
// Make sure normal points away from D
|
|
376
|
+
const abc_d_side = v3_dot(abc_x, abc_y, abc_z, ad_x, ad_y, ad_z);
|
|
377
|
+
|
|
378
|
+
if (abc_test * abc_d_side < 0) {
|
|
379
|
+
// Origin is on the opposite side of ABC from D
|
|
380
|
+
// Reduce to triangle ABC: D is dropped
|
|
381
|
+
// simplex = [A, B, C] — A(0), B(3), C(6) already in place
|
|
382
|
+
return update_simplex_triangle(search_dir, simplex);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Check face ACD (opposite to B)
|
|
386
|
+
const acd_test = v3_dot(acd_x, acd_y, acd_z, ao_x, ao_y, ao_z);
|
|
387
|
+
const acd_b_side = v3_dot(acd_x, acd_y, acd_z, ab_x, ab_y, ab_z);
|
|
388
|
+
|
|
389
|
+
if (acd_test * acd_b_side < 0) {
|
|
390
|
+
// Origin is outside face ACD
|
|
391
|
+
// Reduce to triangle ACD: replace B with D
|
|
392
|
+
simplex[3] = c_x;
|
|
393
|
+
simplex[4] = c_y;
|
|
394
|
+
simplex[5] = c_z;
|
|
395
|
+
simplex[6] = d_x;
|
|
396
|
+
simplex[7] = d_y;
|
|
397
|
+
simplex[8] = d_z;
|
|
398
|
+
|
|
399
|
+
return update_simplex_triangle(search_dir, simplex);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Check face ADB (opposite to C)
|
|
403
|
+
const adb_test = v3_dot(adb_x, adb_y, adb_z, ao_x, ao_y, ao_z);
|
|
404
|
+
const adb_c_side = v3_dot(adb_x, adb_y, adb_z, ac_x, ac_y, ac_z);
|
|
405
|
+
|
|
406
|
+
if (adb_test * adb_c_side < 0) {
|
|
407
|
+
// Origin is outside face ADB
|
|
408
|
+
// Reduce to triangle ADB: replace C with B, B with D
|
|
409
|
+
simplex[6] = b_x;
|
|
410
|
+
simplex[7] = b_y;
|
|
411
|
+
simplex[8] = b_z;
|
|
412
|
+
simplex[3] = d_x;
|
|
413
|
+
simplex[4] = d_y;
|
|
414
|
+
simplex[5] = d_z;
|
|
415
|
+
|
|
416
|
+
return update_simplex_triangle(search_dir, simplex);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// Origin is inside the tetrahedron
|
|
420
|
+
return 0;
|
|
421
|
+
}
|