@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
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Apply the world-frame inverse inertia tensor of a rigid body to a world-space
|
|
3
3
|
* vector and write the result.
|
|
4
4
|
*
|
|
5
|
-
* Body-frame inverse inertia is
|
|
6
|
-
* (
|
|
5
|
+
* Body-frame inverse inertia is supplied as a diagonal in principal axes
|
|
6
|
+
* (a Vector3-like with `.x .y .z`). World inverse inertia is
|
|
7
7
|
* `I_w⁻¹ = R · diag · R^T` where `R` is the body's orientation. We compute
|
|
8
8
|
* `result = R · diag · R^T · v` without materialising the full 3x3 matrix:
|
|
9
9
|
*
|
|
@@ -17,21 +17,26 @@
|
|
|
17
17
|
* Sphere short-circuit: if the inverse inertia is isotropic (ix === iy === iz),
|
|
18
18
|
* the rotation cancels and `result = ix * v`. Skip the trig and save the work.
|
|
19
19
|
*
|
|
20
|
+
* Decoupled from RigidBody / Transform on purpose — callers pass only what
|
|
21
|
+
* is actually read. Lets `compute_penetration` and other standalone
|
|
22
|
+
* geometry helpers reuse this without manufacturing a body.
|
|
23
|
+
*
|
|
20
24
|
* @param {number[]|Float64Array} result length >= 3
|
|
21
25
|
* @param {number} result_offset
|
|
22
|
-
* @param {
|
|
23
|
-
*
|
|
26
|
+
* @param {{x: number, y: number, z: number}} inv_inertia_local
|
|
27
|
+
* Body-frame inverse inertia diagonal (typically `rb.inverseInertiaLocal`).
|
|
28
|
+
* @param {{x: number, y: number, z: number, w: number}} rotation
|
|
29
|
+
* Body orientation as a unit quaternion (typically `transform.rotation`).
|
|
24
30
|
* @param {number} vx
|
|
25
31
|
* @param {number} vy
|
|
26
32
|
* @param {number} vz
|
|
27
33
|
*/
|
|
28
34
|
export function world_inverse_inertia_apply(
|
|
29
35
|
result, result_offset,
|
|
30
|
-
|
|
36
|
+
inv_inertia_local, rotation,
|
|
31
37
|
vx, vy, vz
|
|
32
38
|
) {
|
|
33
|
-
const
|
|
34
|
-
const ix = ii.x, iy = ii.y, iz = ii.z;
|
|
39
|
+
const ix = inv_inertia_local.x, iy = inv_inertia_local.y, iz = inv_inertia_local.z;
|
|
35
40
|
|
|
36
41
|
if (ix === iy && iy === iz) {
|
|
37
42
|
// Isotropic — rotation cancels.
|
|
@@ -41,39 +46,32 @@ export function world_inverse_inertia_apply(
|
|
|
41
46
|
return;
|
|
42
47
|
}
|
|
43
48
|
|
|
44
|
-
const
|
|
45
|
-
const qx = q.x, qy = q.y, qz = q.z, qw = q.w;
|
|
49
|
+
const qx = rotation.x, qy = rotation.y, qz = rotation.z, qw = rotation.w;
|
|
46
50
|
|
|
47
51
|
// Step 1: v_body = R^T · v. R^T corresponds to applying the conjugate
|
|
48
|
-
// quaternion (-qx, -qy, -qz, qw).
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const tw = -cx * vx - cy * vy - cz * vz;
|
|
60
|
-
// v_body = t · (c*) where c* = (qx, qy, qz, qw)
|
|
61
|
-
const vbx = tx * qw + tw * qx + ty * qz - tz * qy;
|
|
62
|
-
const vby = ty * qw + tw * qy + tz * qx - tx * qz;
|
|
63
|
-
const vbz = tz * qw + tw * qz + tx * qy - ty * qx;
|
|
52
|
+
// quaternion (-qx, -qy, -qz, qw). Inlined for V8 inliner — see
|
|
53
|
+
// PosedShape.support and core/geom/vec3/v3_quat3_apply_inverse.js
|
|
54
|
+
// for the canonical form.
|
|
55
|
+
const cx = -qx, cy = -qy, cz = -qz;
|
|
56
|
+
const tx = qw * vx + cy * vz - cz * vy;
|
|
57
|
+
const ty = qw * vy + cz * vx - cx * vz;
|
|
58
|
+
const tz = qw * vz + cx * vy - cy * vx;
|
|
59
|
+
const tw = -cx * vx - cy * vy - cz * vz;
|
|
60
|
+
const vbx = tx * qw + tw * qx + ty * qz - tz * qy;
|
|
61
|
+
const vby = ty * qw + tw * qy + tz * qx - tx * qz;
|
|
62
|
+
const vbz = tz * qw + tw * qz + tx * qy - ty * qx;
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
// Step 2: scale by the principal-frame diagonal.
|
|
65
|
+
const sx = vbx * ix;
|
|
66
|
+
const sy = vby * iy;
|
|
67
|
+
const sz = vbz * iz;
|
|
69
68
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
69
|
+
// Step 3: result = R · scaled = q · scaled · q*. Inlined likewise.
|
|
70
|
+
const ux = qw * sx + qy * sz - qz * sy;
|
|
71
|
+
const uy = qw * sy + qz * sx - qx * sz;
|
|
72
|
+
const uz = qw * sz + qx * sy - qy * sx;
|
|
73
|
+
const uw = -qx * sx - qy * sy - qz * sz;
|
|
74
|
+
result[result_offset] = ux * qw + uw * (-qx) + uy * (-qz) - uz * (-qy);
|
|
75
|
+
result[result_offset + 1] = uy * qw + uw * (-qy) + uz * (-qx) - ux * (-qz);
|
|
76
|
+
result[result_offset + 2] = uz * qw + uw * (-qz) + ux * (-qy) - uy * (-qx);
|
|
79
77
|
}
|
|
@@ -1,16 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Integrate `transform.position` and `transform.rotation` from the body's
|
|
3
|
-
* current linear and angular velocity over a step `dt`. Static bodies are
|
|
4
|
-
* touched.
|
|
3
|
+
* current linear and angular velocity over a step `dt`. Static bodies are
|
|
4
|
+
* not touched.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* The trailing six arguments are the body's *pseudo-velocity*: the
|
|
7
|
+
* position-pass output from the constraint solver (Catto split-impulse).
|
|
8
|
+
* Pseudo-velocity exists only inside the step — it's folded into the
|
|
9
|
+
* integration so the position update reflects depth correction, then
|
|
10
|
+
* implicitly discarded. The body's persistent `linearVelocity` /
|
|
11
|
+
* `angularVelocity` (which carry restitution + warm-start across steps)
|
|
12
|
+
* are never contaminated by it.
|
|
13
|
+
*
|
|
14
|
+
* Callers with no position-pass output should pass zeros for the six
|
|
15
|
+
* pseudo arguments — folding zero is free (one add per axis).
|
|
16
|
+
*
|
|
17
|
+
* KinematicPosition bodies are treated like Dynamic for the position
|
|
18
|
+
* update — if the gameplay code is driving them, their velocity is
|
|
19
|
+
* whatever the user wrote (typically zero); the step is effectively a
|
|
20
|
+
* no-op in that case. KinematicVelocity bodies advance under their
|
|
21
|
+
* user-set velocity.
|
|
10
22
|
*
|
|
11
23
|
* @param {RigidBody} rb
|
|
12
24
|
* @param {Transform} transform
|
|
13
25
|
* @param {number} dt
|
|
26
|
+
* @param {number} ps_lin_x pseudo-linear-velocity x (0 when no contacts)
|
|
27
|
+
* @param {number} ps_lin_y
|
|
28
|
+
* @param {number} ps_lin_z
|
|
29
|
+
* @param {number} ps_ang_x pseudo-angular-velocity x (0 when no contacts)
|
|
30
|
+
* @param {number} ps_ang_y
|
|
31
|
+
* @param {number} ps_ang_z
|
|
14
32
|
*/
|
|
15
|
-
export function integrate_position(rb: RigidBody, transform: Transform, dt: number): void;
|
|
33
|
+
export function integrate_position(rb: RigidBody, transform: Transform, dt: number, ps_lin_x: number, ps_lin_y: number, ps_lin_z: number, ps_ang_x: number, ps_ang_y: number, ps_ang_z: number): void;
|
|
16
34
|
//# sourceMappingURL=integrate_position.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integrate_position.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/integration/integrate_position.js"],"names":[],"mappings":"AAKA
|
|
1
|
+
{"version":3,"file":"integrate_position.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/integration/integrate_position.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,4EARW,MAAM,YACN,MAAM,YACN,MAAM,YACN,MAAM,YACN,MAAM,YACN,MAAM,YACN,MAAM,QA2ChB"}
|
|
@@ -5,19 +5,41 @@ const scratch_q = new Float64Array(4);
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Integrate `transform.position` and `transform.rotation` from the body's
|
|
8
|
-
* current linear and angular velocity over a step `dt`. Static bodies are
|
|
9
|
-
* touched.
|
|
8
|
+
* current linear and angular velocity over a step `dt`. Static bodies are
|
|
9
|
+
* not touched.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* The trailing six arguments are the body's *pseudo-velocity*: the
|
|
12
|
+
* position-pass output from the constraint solver (Catto split-impulse).
|
|
13
|
+
* Pseudo-velocity exists only inside the step — it's folded into the
|
|
14
|
+
* integration so the position update reflects depth correction, then
|
|
15
|
+
* implicitly discarded. The body's persistent `linearVelocity` /
|
|
16
|
+
* `angularVelocity` (which carry restitution + warm-start across steps)
|
|
17
|
+
* are never contaminated by it.
|
|
18
|
+
*
|
|
19
|
+
* Callers with no position-pass output should pass zeros for the six
|
|
20
|
+
* pseudo arguments — folding zero is free (one add per axis).
|
|
21
|
+
*
|
|
22
|
+
* KinematicPosition bodies are treated like Dynamic for the position
|
|
23
|
+
* update — if the gameplay code is driving them, their velocity is
|
|
24
|
+
* whatever the user wrote (typically zero); the step is effectively a
|
|
25
|
+
* no-op in that case. KinematicVelocity bodies advance under their
|
|
26
|
+
* user-set velocity.
|
|
15
27
|
*
|
|
16
28
|
* @param {RigidBody} rb
|
|
17
29
|
* @param {Transform} transform
|
|
18
30
|
* @param {number} dt
|
|
31
|
+
* @param {number} ps_lin_x pseudo-linear-velocity x (0 when no contacts)
|
|
32
|
+
* @param {number} ps_lin_y
|
|
33
|
+
* @param {number} ps_lin_z
|
|
34
|
+
* @param {number} ps_ang_x pseudo-angular-velocity x (0 when no contacts)
|
|
35
|
+
* @param {number} ps_ang_y
|
|
36
|
+
* @param {number} ps_ang_z
|
|
19
37
|
*/
|
|
20
|
-
export function integrate_position(
|
|
38
|
+
export function integrate_position(
|
|
39
|
+
rb, transform, dt,
|
|
40
|
+
ps_lin_x, ps_lin_y, ps_lin_z,
|
|
41
|
+
ps_ang_x, ps_ang_y, ps_ang_z,
|
|
42
|
+
) {
|
|
21
43
|
if (rb.kind === BodyKind.Static) {
|
|
22
44
|
return;
|
|
23
45
|
}
|
|
@@ -25,22 +47,31 @@ export function integrate_position(rb, transform, dt) {
|
|
|
25
47
|
const lv = rb.linearVelocity;
|
|
26
48
|
const p = transform.position;
|
|
27
49
|
|
|
50
|
+
// Combined integration velocity: persistent + pseudo. The pseudo
|
|
51
|
+
// contribution exists only for this step and never lands in `lv`.
|
|
52
|
+
const vx = lv[0] + ps_lin_x;
|
|
53
|
+
const vy = lv[1] + ps_lin_y;
|
|
54
|
+
const vz = lv[2] + ps_lin_z;
|
|
55
|
+
|
|
28
56
|
// Direct reads via typed-array index; the write goes through .set() so
|
|
29
57
|
// Transform's onChanged subscribers (matrix recompose, parent/child sync,
|
|
30
58
|
// viewport position, fog-of-war reveal) fire once per body per step.
|
|
31
59
|
p.set(
|
|
32
|
-
p[0] +
|
|
33
|
-
p[1] +
|
|
34
|
-
p[2] +
|
|
60
|
+
p[0] + vx * dt,
|
|
61
|
+
p[1] + vy * dt,
|
|
62
|
+
p[2] + vz * dt
|
|
35
63
|
);
|
|
36
64
|
|
|
37
65
|
const av = rb.angularVelocity;
|
|
38
|
-
|
|
66
|
+
const wx = av[0] + ps_ang_x;
|
|
67
|
+
const wy = av[1] + ps_ang_y;
|
|
68
|
+
const wz = av[2] + ps_ang_z;
|
|
69
|
+
if (wx !== 0 || wy !== 0 || wz !== 0) {
|
|
39
70
|
const q = transform.rotation;
|
|
40
71
|
quat_integrate(
|
|
41
72
|
scratch_q,
|
|
42
73
|
q[0], q[1], q[2], q[3],
|
|
43
|
-
|
|
74
|
+
wx, wy, wz,
|
|
44
75
|
dt
|
|
45
76
|
);
|
|
46
77
|
q.set(scratch_q[0], scratch_q[1], scratch_q[2], scratch_q[3]);
|
|
@@ -22,4 +22,34 @@
|
|
|
22
22
|
* @param {number} dt step size in seconds
|
|
23
23
|
*/
|
|
24
24
|
export function integrate_velocity(rb: RigidBody, transform: Transform, gx: number, gy: number, gz: number, dt: number): void;
|
|
25
|
+
/**
|
|
26
|
+
* Apply the accumulated force / torque to velocity over a step `dt`, then
|
|
27
|
+
* zero the accumulators. Gravity and damping are NOT applied here.
|
|
28
|
+
*
|
|
29
|
+
* The "once per outer step" half of the TGS integrator: a user force is a
|
|
30
|
+
* per-frame budget that must land in full exactly once, independent of
|
|
31
|
+
* substep count. Gravity is the continuous field re-applied every substep
|
|
32
|
+
* by {@link integrate_velocity_gravity}.
|
|
33
|
+
*
|
|
34
|
+
* @param {RigidBody} rb
|
|
35
|
+
* @param {Transform} transform used to rotate body-frame inertia into world
|
|
36
|
+
* @param {number} dt full outer-step size in seconds
|
|
37
|
+
*/
|
|
38
|
+
export function integrate_velocity_forces(rb: RigidBody, transform: Transform, dt: number): void;
|
|
39
|
+
/**
|
|
40
|
+
* Apply gravity and velocity damping over a (sub)step `dt`. Does NOT touch
|
|
41
|
+
* the force / torque accumulators (consumed once by
|
|
42
|
+
* {@link integrate_velocity_forces}).
|
|
43
|
+
*
|
|
44
|
+
* The "every substep" half of the TGS integrator. Per substep the body sees
|
|
45
|
+
* only `g·h` of gravity, which the per-substep contact warm-start + solve
|
|
46
|
+
* cancels exactly — keeping a resting stack at zero velocity. Damping is the
|
|
47
|
+
* stable implicit decay `v *= 1/(1 + d·dt)` applied at the substep `dt`.
|
|
48
|
+
*
|
|
49
|
+
* @param {RigidBody} rb
|
|
50
|
+
* @param {Transform} transform (unused; signature symmetry with the family)
|
|
51
|
+
* @param {number} gx @param {number} gy @param {number} gz world gravity
|
|
52
|
+
* @param {number} dt sub-step size in seconds
|
|
53
|
+
*/
|
|
54
|
+
export function integrate_velocity_gravity(rb: RigidBody, transform: Transform, gx: number, gy: number, gz: number, dt: number): void;
|
|
25
55
|
//# sourceMappingURL=integrate_velocity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integrate_velocity.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/integration/integrate_velocity.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,4EALW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAoDhB"}
|
|
1
|
+
{"version":3,"file":"integrate_velocity.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/integration/integrate_velocity.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,4EALW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAoDhB;AAED;;;;;;;;;;;;GAYG;AACH,mFAFW,MAAM,QA6BhB;AAED;;;;;;;;;;;;;;GAcG;AACH,oFAHW,MAAM,MAAa,MAAM,MAAa,MAAM,MAC5C,MAAM,QAwBhB"}
|
|
@@ -60,7 +60,7 @@ export function integrate_velocity(rb, transform, gx, gy, gz, dt) {
|
|
|
60
60
|
let avy = av[1];
|
|
61
61
|
let avz = av[2];
|
|
62
62
|
if (at[0] !== 0 || at[1] !== 0 || at[2] !== 0) {
|
|
63
|
-
world_inverse_inertia_apply(scratch_angular, 0, rb, transform, at[0], at[1], at[2]);
|
|
63
|
+
world_inverse_inertia_apply(scratch_angular, 0, rb.inverseInertiaLocal, transform.rotation, at[0], at[1], at[2]);
|
|
64
64
|
avx += scratch_angular[0] * dt;
|
|
65
65
|
avy += scratch_angular[1] * dt;
|
|
66
66
|
avz += scratch_angular[2] * dt;
|
|
@@ -77,3 +77,84 @@ export function integrate_velocity(rb, transform, gx, gy, gz, dt) {
|
|
|
77
77
|
af[0] = 0; af[1] = 0; af[2] = 0;
|
|
78
78
|
at[0] = 0; at[1] = 0; at[2] = 0;
|
|
79
79
|
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Apply the accumulated force / torque to velocity over a step `dt`, then
|
|
83
|
+
* zero the accumulators. Gravity and damping are NOT applied here.
|
|
84
|
+
*
|
|
85
|
+
* The "once per outer step" half of the TGS integrator: a user force is a
|
|
86
|
+
* per-frame budget that must land in full exactly once, independent of
|
|
87
|
+
* substep count. Gravity is the continuous field re-applied every substep
|
|
88
|
+
* by {@link integrate_velocity_gravity}.
|
|
89
|
+
*
|
|
90
|
+
* @param {RigidBody} rb
|
|
91
|
+
* @param {Transform} transform used to rotate body-frame inertia into world
|
|
92
|
+
* @param {number} dt full outer-step size in seconds
|
|
93
|
+
*/
|
|
94
|
+
export function integrate_velocity_forces(rb, transform, dt) {
|
|
95
|
+
const af = rb.accumulatedForce;
|
|
96
|
+
const at = rb.accumulatedTorque;
|
|
97
|
+
|
|
98
|
+
if (rb.kind !== BodyKind.Dynamic) {
|
|
99
|
+
af[0] = 0; af[1] = 0; af[2] = 0;
|
|
100
|
+
at[0] = 0; at[1] = 0; at[2] = 0;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const inv_m = rb.mass > 0 ? 1 / rb.mass : 0;
|
|
105
|
+
|
|
106
|
+
const lv = rb.linearVelocity;
|
|
107
|
+
lv[0] += af[0] * inv_m * dt;
|
|
108
|
+
lv[1] += af[1] * inv_m * dt;
|
|
109
|
+
lv[2] += af[2] * inv_m * dt;
|
|
110
|
+
|
|
111
|
+
if (at[0] !== 0 || at[1] !== 0 || at[2] !== 0) {
|
|
112
|
+
world_inverse_inertia_apply(scratch_angular, 0, rb.inverseInertiaLocal, transform.rotation, at[0], at[1], at[2]);
|
|
113
|
+
const av = rb.angularVelocity;
|
|
114
|
+
av[0] += scratch_angular[0] * dt;
|
|
115
|
+
av[1] += scratch_angular[1] * dt;
|
|
116
|
+
av[2] += scratch_angular[2] * dt;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
af[0] = 0; af[1] = 0; af[2] = 0;
|
|
120
|
+
at[0] = 0; at[1] = 0; at[2] = 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Apply gravity and velocity damping over a (sub)step `dt`. Does NOT touch
|
|
125
|
+
* the force / torque accumulators (consumed once by
|
|
126
|
+
* {@link integrate_velocity_forces}).
|
|
127
|
+
*
|
|
128
|
+
* The "every substep" half of the TGS integrator. Per substep the body sees
|
|
129
|
+
* only `g·h` of gravity, which the per-substep contact warm-start + solve
|
|
130
|
+
* cancels exactly — keeping a resting stack at zero velocity. Damping is the
|
|
131
|
+
* stable implicit decay `v *= 1/(1 + d·dt)` applied at the substep `dt`.
|
|
132
|
+
*
|
|
133
|
+
* @param {RigidBody} rb
|
|
134
|
+
* @param {Transform} transform (unused; signature symmetry with the family)
|
|
135
|
+
* @param {number} gx @param {number} gy @param {number} gz world gravity
|
|
136
|
+
* @param {number} dt sub-step size in seconds
|
|
137
|
+
*/
|
|
138
|
+
export function integrate_velocity_gravity(rb, transform, gx, gy, gz, dt) {
|
|
139
|
+
if (rb.kind !== BodyKind.Dynamic) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const gs = rb.gravityScale;
|
|
144
|
+
const lv = rb.linearVelocity;
|
|
145
|
+
let lvx = lv[0] + gx * gs * dt;
|
|
146
|
+
let lvy = lv[1] + gy * gs * dt;
|
|
147
|
+
let lvz = lv[2] + gz * gs * dt;
|
|
148
|
+
|
|
149
|
+
if (rb.linearDamping > 0) {
|
|
150
|
+
const k = 1 / (1 + rb.linearDamping * dt);
|
|
151
|
+
lvx *= k; lvy *= k; lvz *= k;
|
|
152
|
+
}
|
|
153
|
+
lv[0] = lvx; lv[1] = lvy; lv[2] = lvz;
|
|
154
|
+
|
|
155
|
+
if (rb.angularDamping > 0) {
|
|
156
|
+
const av = rb.angularVelocity;
|
|
157
|
+
const k = 1 / (1 + rb.angularDamping * dt);
|
|
158
|
+
av[0] *= k; av[1] *= k; av[2] *= k;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -117,8 +117,11 @@ export class IslandBuilder {
|
|
|
117
117
|
* @param {ManifoldStore} manifolds
|
|
118
118
|
* @param {RigidBody[]} bodies sparse, indexed by body index
|
|
119
119
|
* @param {Array[]} body_collider_lists sparse, indexed by body index
|
|
120
|
+
* @param {Joint[]} joints live joints (sparse). Jointed dynamic-dynamic
|
|
121
|
+
* bodies are unioned into the same island so a chain / ragdoll sleeps
|
|
122
|
+
* and wakes as a unit. Callers with no joints pass an empty array.
|
|
120
123
|
*/
|
|
121
|
-
build(storage: BodyStorage, manifolds: ManifoldStore, bodies: RigidBody[], body_collider_lists: any[][]): void;
|
|
124
|
+
build(storage: BodyStorage, manifolds: ManifoldStore, bodies: RigidBody[], body_collider_lists: any[][], joints: Joint[]): void;
|
|
122
125
|
/**
|
|
123
126
|
* Fill `body_offsets` + `body_data` with awake dynamic bodies grouped
|
|
124
127
|
* by island, sorted ascending within each island.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IslandBuilder.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/island/IslandBuilder.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"IslandBuilder.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/island/IslandBuilder.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH;IAyFI;;;;;OAKG;IACH,gCAUC;IAtGG;;;;;OAKG;IACH,QAFU,WAAW,CAEY;IAEjC;;;;OAIG;IACH,gBAFU,UAAU,CAEoB;IAExC;;;OAGG;IACH,cAFU,MAAM,CAEK;IAErB;;;;OAIG;IACH,cAFU,WAAW,CAEiB;IAEtC;;;;OAIG;IACH,WAFU,WAAW,CAEe;IAEpC;;;OAGG;IACH,YAFU,MAAM,CAEG;IAEnB;;;;;OAKG;IACH,iBAFU,WAAW,CAEoB;IAEzC;;;;OAIG;IACH,cAFU,WAAW,CAEkB;IAEvC;;;OAGG;IACH,eAFU,MAAM,CAEM;IAEtB;;;;;OAKG;IACH,yBAA0C;IAE1C;;;;;OAKG;IACH,wBAA0C;IAE1C;;;;OAIG;IACH,kBAAmC;IAqBvC;;;;;;;;;;;OAWG;IACH,8DANW,WAAW,uBACX,OAAO,UACP,OAAO,QAgGjB;IAED;;;;OAIG;IACH,yBA+CC;IAED;;;;;;OAMG;IACH,4BAwCC;IAED;;;;;;;;OAQG;IACH,yBAcC;IAID;;;OAGG;IACH,+BAQC;IAED;;;OAGG;IACH,uCAOC;IAED;;;OAGG;IACH,oCAIC;IAED;;;OAGG;IACH,uCAIC;CACJ"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { ceilPowerOfTwo } from "../../../core/binary/operations/ceilPowerOfTwo.js";
|
|
1
2
|
import { body_id_index } from "../body/BodyStorage.js";
|
|
2
3
|
import { BodyKind } from "../ecs/BodyKind.js";
|
|
3
4
|
import { ColliderFlags } from "../ecs/ColliderFlags.js";
|
|
5
|
+
import { JOINT_WORLD } from "../ecs/Joint.js";
|
|
4
6
|
import { RigidBodyFlags } from "../ecs/RigidBodyFlags.js";
|
|
5
7
|
import { uf_find, uf_init, uf_union } from "./union_find.js";
|
|
6
8
|
|
|
@@ -149,8 +151,11 @@ export class IslandBuilder {
|
|
|
149
151
|
* @param {ManifoldStore} manifolds
|
|
150
152
|
* @param {RigidBody[]} bodies sparse, indexed by body index
|
|
151
153
|
* @param {Array[]} body_collider_lists sparse, indexed by body index
|
|
154
|
+
* @param {Joint[]} joints live joints (sparse). Jointed dynamic-dynamic
|
|
155
|
+
* bodies are unioned into the same island so a chain / ragdoll sleeps
|
|
156
|
+
* and wakes as a unit. Callers with no joints pass an empty array.
|
|
152
157
|
*/
|
|
153
|
-
build(storage, manifolds, bodies, body_collider_lists) {
|
|
158
|
+
build(storage, manifolds, bodies, body_collider_lists, joints) {
|
|
154
159
|
const hwm = storage.high_water_mark;
|
|
155
160
|
this.__ensure_body_capacity(hwm);
|
|
156
161
|
|
|
@@ -174,6 +179,29 @@ export class IslandBuilder {
|
|
|
174
179
|
}
|
|
175
180
|
}
|
|
176
181
|
|
|
182
|
+
// --- Pass 1b: union dynamic-dynamic bodies connected by a joint, so a
|
|
183
|
+
// chain / ragdoll forms one island (and so sleeps/wakes as a unit).
|
|
184
|
+
// Joint-to-world and joint-to-static/kinematic anchor the island
|
|
185
|
+
// without enlarging it — same rule as a static contact. Stale joint
|
|
186
|
+
// references (body unlinked / slot reused) are filtered by the
|
|
187
|
+
// generation-checked `is_valid`. (Empty when the caller has no
|
|
188
|
+
// joints — the loop is then a no-op.)
|
|
189
|
+
const jn = joints.length;
|
|
190
|
+
for (let i = 0; i < jn; i++) {
|
|
191
|
+
const joint = joints[i];
|
|
192
|
+
if (joint === undefined || joint === null) continue;
|
|
193
|
+
if (joint._bodyIdB === JOINT_WORLD) continue;
|
|
194
|
+
if (!storage.is_valid(joint._bodyIdA) || !storage.is_valid(joint._bodyIdB)) continue;
|
|
195
|
+
const idxA = body_id_index(joint._bodyIdA);
|
|
196
|
+
const idxB = body_id_index(joint._bodyIdB);
|
|
197
|
+
const rbA = bodies[idxA];
|
|
198
|
+
const rbB = bodies[idxB];
|
|
199
|
+
if (rbA === undefined || rbB === undefined) continue;
|
|
200
|
+
if (rbA.kind === BodyKind.Dynamic && rbB.kind === BodyKind.Dynamic) {
|
|
201
|
+
uf_union(parent, idxA, idxB);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
177
205
|
// --- Pass 2: collect distinct roots over awake dynamic bodies.
|
|
178
206
|
const island_of_body = this.island_of_body;
|
|
179
207
|
// Cheap reset: only the indices we may write are below hwm.
|
|
@@ -357,7 +385,7 @@ export class IslandBuilder {
|
|
|
357
385
|
*/
|
|
358
386
|
__ensure_body_capacity(n) {
|
|
359
387
|
if (this.parent.length < n) {
|
|
360
|
-
const cap =
|
|
388
|
+
const cap = ceilPowerOfTwo(n);
|
|
361
389
|
this.parent = new Uint32Array(cap);
|
|
362
390
|
this.island_of_body = new Int32Array(cap);
|
|
363
391
|
this.__root_to_island = new Int32Array(cap);
|
|
@@ -371,7 +399,7 @@ export class IslandBuilder {
|
|
|
371
399
|
*/
|
|
372
400
|
__ensure_island_count_capacity(n) {
|
|
373
401
|
if (this.body_offsets.length < n + 1) {
|
|
374
|
-
const cap =
|
|
402
|
+
const cap = ceilPowerOfTwo(n + 1);
|
|
375
403
|
this.body_offsets = new Uint32Array(cap);
|
|
376
404
|
this.contact_offsets = new Uint32Array(cap);
|
|
377
405
|
this.__cursors = new Uint32Array(cap);
|
|
@@ -384,7 +412,7 @@ export class IslandBuilder {
|
|
|
384
412
|
*/
|
|
385
413
|
__ensure_body_data_capacity(n) {
|
|
386
414
|
if (this.body_data.length < n) {
|
|
387
|
-
this.body_data = new Uint32Array(
|
|
415
|
+
this.body_data = new Uint32Array(ceilPowerOfTwo(n));
|
|
388
416
|
}
|
|
389
417
|
}
|
|
390
418
|
|
|
@@ -394,18 +422,7 @@ export class IslandBuilder {
|
|
|
394
422
|
*/
|
|
395
423
|
__ensure_contact_data_capacity(n) {
|
|
396
424
|
if (this.contact_data.length < n) {
|
|
397
|
-
this.contact_data = new Uint32Array(
|
|
425
|
+
this.contact_data = new Uint32Array(ceilPowerOfTwo(n));
|
|
398
426
|
}
|
|
399
427
|
}
|
|
400
428
|
}
|
|
401
|
-
|
|
402
|
-
/**
|
|
403
|
-
* @param {number} n
|
|
404
|
-
* @returns {number}
|
|
405
|
-
*/
|
|
406
|
-
function next_pow2(n) {
|
|
407
|
-
if (n <= 1) return 1;
|
|
408
|
-
let p = 1;
|
|
409
|
-
while (p < n) p <<= 1;
|
|
410
|
-
return p;
|
|
411
|
-
}
|
|
@@ -45,14 +45,6 @@ export class PosedShape extends AbstractShape3D {
|
|
|
45
45
|
z: number;
|
|
46
46
|
w: number;
|
|
47
47
|
}): void;
|
|
48
|
-
/**
|
|
49
|
-
* @param {number[]|Float32Array|Float64Array} result
|
|
50
|
-
* @param {number} result_offset
|
|
51
|
-
* @param {number} dx world-space query direction x (unit)
|
|
52
|
-
* @param {number} dy world-space query direction y
|
|
53
|
-
* @param {number} dz world-space query direction z
|
|
54
|
-
*/
|
|
55
|
-
support(result: number[] | Float32Array | Float64Array, result_offset: number, dx: number, dy: number, dz: number): void;
|
|
56
48
|
compute_bounding_box(result: any): void;
|
|
57
49
|
}
|
|
58
50
|
import { AbstractShape3D } from "../../../core/geom/3d/shape/AbstractShape3D.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PosedShape.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/narrowphase/PosedShape.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;GAkBG;AACH;IAKQ,mCAAmC;IACnC,OADW,eAAe,GAAC,IAAI,CACd;IAEjB,WAAW;IAAE,WAAW;IAAE,WAAW;IACrC,WAAW;IAAE,WAAW;IAAE,WAAW;IAAE,WAAW;IAGtD;;;;;;;OAOG;IACH,aAJW,eAAe,YACf,UAAQ;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,YACpC,aAAW;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,QAM1D;
|
|
1
|
+
{"version":3,"file":"PosedShape.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/narrowphase/PosedShape.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;GAkBG;AACH;IAKQ,mCAAmC;IACnC,OADW,eAAe,GAAC,IAAI,CACd;IAEjB,WAAW;IAAE,WAAW;IAAE,WAAW;IACrC,WAAW;IAAE,WAAW;IAAE,WAAW;IAAE,WAAW;IAGtD;;;;;;;OAOG;IACH,aAJW,eAAe,YACf,UAAQ;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,YACpC,aAAW;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,QAM1D;IAgDD,wCASC;CACJ;gCA1G+B,gDAAgD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { aabb3_transform_oriented } from "../../../core/geom/3d/aabb/aabb3_transform_oriented.js";
|
|
1
2
|
import { AbstractShape3D } from "../../../core/geom/3d/shape/AbstractShape3D.js";
|
|
2
|
-
import { aabb_transform_oriented } from "../broadphase/aabb_transform_oriented.js";
|
|
3
3
|
|
|
4
4
|
const scratch_local = new Float64Array(3);
|
|
5
5
|
const scratch_local_aabb = new Float64Array(6);
|
|
@@ -57,49 +57,47 @@ export class PosedShape extends AbstractShape3D {
|
|
|
57
57
|
* @param {number} dz world-space query direction z
|
|
58
58
|
*/
|
|
59
59
|
support(result, result_offset, dx, dy, dz) {
|
|
60
|
-
//
|
|
61
|
-
//
|
|
60
|
+
// Inline q·v·q* math: PosedShape.support is the hottest GJK call
|
|
61
|
+
// (twice per iteration of the body-level fallback, once per
|
|
62
|
+
// triangle for concave dispatch). V8 declines to inline
|
|
63
|
+
// v3_quat3_apply at 9-arg call sites, so the math is repeated
|
|
64
|
+
// inline here at the cost of ~7 extra lines per direction.
|
|
65
|
+
// See core/geom/vec3/v3_quat3_apply.js for the canonical form
|
|
66
|
+
// — this is a literal expansion of it.
|
|
62
67
|
const qx = this.qx, qy = this.qy, qz = this.qz, qw = this.qw;
|
|
63
68
|
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
|
|
69
|
+
// Rotate world direction into body frame via the conjugate
|
|
70
|
+
// quaternion: v_local = q* · v_world · q. Conjugate xyz are
|
|
71
|
+
// negated (cx, cy, cz below).
|
|
72
|
+
const tdx = qw * dx - qy * dz + qz * dy;
|
|
73
|
+
const tdy = qw * dy - qz * dx + qx * dz;
|
|
74
|
+
const tdz = qw * dz - qx * dy + qy * dx;
|
|
75
|
+
const tdw = qx * dx + qy * dy + qz * dz;
|
|
67
76
|
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
const tz = qw * dz + cx * dy - cy * dx;
|
|
72
|
-
const tw = -cx * dx - cy * dy - cz * dz;
|
|
73
|
-
|
|
74
|
-
// result_local = t · c^-1; conjugate of c is (-cx,-cy,-cz,qw) = (qx,qy,qz,qw) = original q
|
|
75
|
-
const ldx = tx * qw + tw * (-cx) + ty * (-cz) - tz * (-cy);
|
|
76
|
-
const ldy = ty * qw + tw * (-cy) + tz * (-cx) - tx * (-cz);
|
|
77
|
-
const ldz = tz * qw + tw * (-cz) + tx * (-cy) - ty * (-cx);
|
|
77
|
+
const ldx = tdx * qw + tdw * qx + tdy * qz - tdz * qy;
|
|
78
|
+
const ldy = tdy * qw + tdw * qy + tdz * qx - tdx * qz;
|
|
79
|
+
const ldz = tdz * qw + tdw * qz + tdx * qy - tdy * qx;
|
|
78
80
|
|
|
79
81
|
// Ask the local shape for its support point in body-local space.
|
|
80
82
|
this.shape.support(scratch_local, 0, ldx, ldy, ldz);
|
|
81
83
|
|
|
82
|
-
// Rotate
|
|
84
|
+
// Rotate the body-local support point back to world: v_world =
|
|
85
|
+
// q · v_local · q*.
|
|
83
86
|
const lsx = scratch_local[0], lsy = scratch_local[1], lsz = scratch_local[2];
|
|
84
87
|
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
const iw = -qx * lsx - qy * lsy - qz * lsz;
|
|
90
|
-
|
|
91
|
-
const wx = ix * qw + iw * (-qx) + iy * (-qz) - iz * (-qy);
|
|
92
|
-
const wy = iy * qw + iw * (-qy) + iz * (-qx) - ix * (-qz);
|
|
93
|
-
const wz = iz * qw + iw * (-qz) + ix * (-qy) - iy * (-qx);
|
|
88
|
+
const tsx = qw * lsx + qy * lsz - qz * lsy;
|
|
89
|
+
const tsy = qw * lsy + qz * lsx - qx * lsz;
|
|
90
|
+
const tsz = qw * lsz + qx * lsy - qy * lsx;
|
|
91
|
+
const tsw = -qx * lsx - qy * lsy - qz * lsz;
|
|
94
92
|
|
|
95
|
-
result[result_offset]
|
|
96
|
-
result[result_offset + 1] =
|
|
97
|
-
result[result_offset + 2] =
|
|
93
|
+
result[result_offset] = tsx * qw - tsw * qx - tsy * qz + tsz * qy + this.px;
|
|
94
|
+
result[result_offset + 1] = tsy * qw - tsw * qy - tsz * qx + tsx * qz + this.py;
|
|
95
|
+
result[result_offset + 2] = tsz * qw - tsw * qz - tsx * qy + tsy * qx + this.pz;
|
|
98
96
|
}
|
|
99
97
|
|
|
100
98
|
compute_bounding_box(result) {
|
|
101
99
|
this.shape.compute_bounding_box(scratch_local_aabb);
|
|
102
|
-
|
|
100
|
+
aabb3_transform_oriented(
|
|
103
101
|
result, 0,
|
|
104
102
|
scratch_local_aabb[0], scratch_local_aabb[1], scratch_local_aabb[2],
|
|
105
103
|
scratch_local_aabb[3], scratch_local_aabb[4], scratch_local_aabb[5],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"box_box_manifold.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/narrowphase/box_box_manifold.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"box_box_manifold.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/narrowphase/box_box_manifold.js"],"names":[],"mappings":"AAqJA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,sCAvBW,MAAM,EAAE,GAAC,YAAY,MACrB,MAAM,MACN,MAAM,MACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,GACJ,OAAO,CA8anB;AA3hBD;;;GAGG;AACH,iCAFU,MAAM,CAEoD"}
|