@woosh/meep-engine 2.147.0 → 2.148.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 (44) hide show
  1. package/package.json +1 -1
  2. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts +4 -4
  3. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts.map +1 -1
  4. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.js +48 -52
  5. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts +23 -21
  6. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts.map +1 -1
  7. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.js +41 -406
  8. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts +5 -4
  9. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts.map +1 -1
  10. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js +400 -395
  11. package/src/engine/physics/body/SolverBodyState.d.ts +142 -0
  12. package/src/engine/physics/body/SolverBodyState.d.ts.map +1 -0
  13. package/src/engine/physics/body/SolverBodyState.js +251 -0
  14. package/src/engine/physics/broadphase/generate_pairs.d.ts +2 -1
  15. package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -1
  16. package/src/engine/physics/broadphase/generate_pairs.js +5 -3
  17. package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
  18. package/src/engine/physics/constraint/solve_constraints.js +691 -673
  19. package/src/engine/physics/ecs/PhysicsSystem.d.ts +21 -18
  20. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  21. package/src/engine/physics/ecs/PhysicsSystem.js +223 -91
  22. package/src/engine/physics/inertia/world_inverse_inertia.d.ts +23 -0
  23. package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -1
  24. package/src/engine/physics/inertia/world_inverse_inertia.js +116 -77
  25. package/src/engine/physics/integration/integrate_position.d.ts +11 -1
  26. package/src/engine/physics/integration/integrate_position.d.ts.map +1 -1
  27. package/src/engine/physics/integration/integrate_position.js +97 -79
  28. package/src/engine/physics/integration/integrate_velocity.d.ts +12 -3
  29. package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -1
  30. package/src/engine/physics/integration/integrate_velocity.js +201 -160
  31. package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -1
  32. package/src/engine/physics/narrowphase/box_box_manifold.js +750 -665
  33. package/src/engine/physics/narrowphase/box_triangle_contact.d.ts.map +1 -1
  34. package/src/engine/physics/narrowphase/box_triangle_contact.js +4 -34
  35. package/src/engine/physics/narrowphase/clip_against_axis_uv.d.ts +16 -0
  36. package/src/engine/physics/narrowphase/clip_against_axis_uv.d.ts.map +1 -0
  37. package/src/engine/physics/narrowphase/clip_against_axis_uv.js +49 -0
  38. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  39. package/src/engine/physics/narrowphase/narrowphase_step.js +24 -3
  40. package/src/engine/physics/queries/raycast.d.ts.map +1 -1
  41. package/src/engine/physics/queries/raycast.js +7 -4
  42. package/src/engine/physics/solver/solve_contacts.d.ts +2 -2
  43. package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -1
  44. package/src/engine/physics/solver/solve_contacts.js +1341 -1173
@@ -1,77 +1,116 @@
1
- /**
2
- * Apply the world-frame inverse inertia tensor of a rigid body to a world-space
3
- * vector and write the result.
4
- *
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
- * `I_w⁻¹ = R · diag · R^T` where `R` is the body's orientation. We compute
8
- * `result = R · diag · R^T · v` without materialising the full 3x3 matrix:
9
- *
10
- * 1. `v_body = R^T · v` (rotate v into body frame)
11
- * 2. scale component-wise by the diagonal
12
- * 3. `result = R · v_body_scaled`
13
- *
14
- * Quaternion-rotate-vector uses the standard `q · v · q*` identity. Inverse
15
- * rotation uses the conjugate quaternion.
16
- *
17
- * Sphere short-circuit: if the inverse inertia is isotropic (ix === iy === iz),
18
- * the rotation cancels and `result = ix * v`. Skip the trig and save the work.
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
- *
24
- * @param {number[]|Float64Array} result length >= 3
25
- * @param {number} result_offset
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`).
30
- * @param {number} vx
31
- * @param {number} vy
32
- * @param {number} vz
33
- */
34
- export function world_inverse_inertia_apply(
35
- result, result_offset,
36
- inv_inertia_local, rotation,
37
- vx, vy, vz
38
- ) {
39
- const ix = inv_inertia_local.x, iy = inv_inertia_local.y, iz = inv_inertia_local.z;
40
-
41
- if (ix === iy && iy === iz) {
42
- // Isotropic rotation cancels.
43
- result[result_offset] = vx * ix;
44
- result[result_offset + 1] = vy * ix;
45
- result[result_offset + 2] = vz * ix;
46
- return;
47
- }
48
-
49
- const qx = rotation.x, qy = rotation.y, qz = rotation.z, qw = rotation.w;
50
-
51
- // Step 1: v_body = R^T · v. R^T corresponds to applying the conjugate
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;
63
-
64
- // Step 2: scale by the principal-frame diagonal.
65
- const sx = vbx * ix;
66
- const sy = vby * iy;
67
- const sz = vbz * iz;
68
-
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);
77
- }
1
+ /**
2
+ * Apply the world-frame inverse inertia tensor of a rigid body to a world-space
3
+ * vector and write the result.
4
+ *
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
+ * `I_w⁻¹ = R · diag · R^T` where `R` is the body's orientation. We compute
8
+ * `result = R · diag · R^T · v` without materialising the full 3x3 matrix:
9
+ *
10
+ * 1. `v_body = R^T · v` (rotate v into body frame)
11
+ * 2. scale component-wise by the diagonal
12
+ * 3. `result = R · v_body_scaled`
13
+ *
14
+ * Quaternion-rotate-vector uses the standard `q · v · q*` identity. Inverse
15
+ * rotation uses the conjugate quaternion.
16
+ *
17
+ * Sphere short-circuit: if the inverse inertia is isotropic (ix === iy === iz),
18
+ * the rotation cancels and `result = ix * v`. Skip the trig and save the work.
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
+ *
24
+ * @param {number[]|Float64Array} result length >= 3
25
+ * @param {number} result_offset
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`).
30
+ * @param {number} vx
31
+ * @param {number} vy
32
+ * @param {number} vz
33
+ */
34
+ export function world_inverse_inertia_apply(
35
+ result, result_offset,
36
+ inv_inertia_local, rotation,
37
+ vx, vy, vz
38
+ ) {
39
+ // Thin object-reading wrapper over the raw-float kernel. Reads the
40
+ // quaternion fields eagerly (harmless in the isotropic short-circuit,
41
+ // where they're ignored) so the kernel is the single source of the math —
42
+ // keeping object callers and the data-oriented (SoA) solver path
43
+ // bit-identical.
44
+ world_inverse_inertia_apply_raw(
45
+ result, result_offset,
46
+ inv_inertia_local.x, inv_inertia_local.y, inv_inertia_local.z,
47
+ rotation.x, rotation.y, rotation.z, rotation.w,
48
+ vx, vy, vz
49
+ );
50
+ }
51
+
52
+ /**
53
+ * Raw-float counterpart of {@link world_inverse_inertia_apply}: the same
54
+ * `I_w⁻¹ = R · diag · R^T` application, with the inverse-inertia diagonal and
55
+ * orientation quaternion passed as scalars rather than read off
56
+ * `{x,y,z}` / `{x,y,z,w}` objects. The data-oriented contact / joint solver
57
+ * reads these straight out of its `SolverBodyState` typed array, avoiding the
58
+ * per-impulse object dereference on the hot path. The arithmetic is identical
59
+ * to the object version (same operation order), so results are bit-identical.
60
+ *
61
+ * @param {number[]|Float64Array} result length >= 3
62
+ * @param {number} result_offset
63
+ * @param {number} ix
64
+ * @param {number} iy
65
+ * @param {number} iz Body-frame inverse inertia diagonal.
66
+ * @param {number} qx
67
+ * @param {number} qy
68
+ * @param {number} qz
69
+ * @param {number} qw Body orientation as a unit quaternion.
70
+ * @param {number} vx
71
+ * @param {number} vy
72
+ * @param {number} vz
73
+ */
74
+ export function world_inverse_inertia_apply_raw(
75
+ result, result_offset,
76
+ ix, iy, iz,
77
+ qx, qy, qz, qw,
78
+ vx, vy, vz
79
+ ) {
80
+
81
+ if (ix === iy && iy === iz) {
82
+ // Isotropic — rotation cancels.
83
+ result[result_offset] = vx * ix;
84
+ result[result_offset + 1] = vy * ix;
85
+ result[result_offset + 2] = vz * ix;
86
+ return;
87
+ }
88
+
89
+ // Step 1: v_body = R^T · v. R^T corresponds to applying the conjugate
90
+ // quaternion (-qx, -qy, -qz, qw). Inlined for V8 inliner — see
91
+ // PosedShape.support and core/geom/vec3/v3_quat3_apply_inverse.js
92
+ // for the canonical form.
93
+ const tx = qw * vx - qy * vz + qz * vy;
94
+ const ty = qw * vy - qz * vx + qx * vz;
95
+ const tz = qw * vz - qx * vy + qy * vx;
96
+ const tw = qx * vx + qy * vy + qz * vz;
97
+
98
+ const vbx = tx * qw + tw * qx + ty * qz - tz * qy;
99
+ const vby = ty * qw + tw * qy + tz * qx - tx * qz;
100
+ const vbz = tz * qw + tw * qz + tx * qy - ty * qx;
101
+
102
+ // Step 2: scale by the principal-frame diagonal.
103
+ const sx = vbx * ix;
104
+ const sy = vby * iy;
105
+ const sz = vbz * iz;
106
+
107
+ // Step 3: result = R · scaled = q · scaled · q*. Inlined likewise.
108
+ const ux = qw * sx + qy * sz - qz * sy;
109
+ const uy = qw * sy + qz * sx - qx * sz;
110
+ const uz = qw * sz + qx * sy - qy * sx;
111
+ const uw = -qx * sx - qy * sy - qz * sz;
112
+
113
+ result[result_offset] = ux * qw - uw * qx - uy * qz + uz * qy;
114
+ result[result_offset + 1] = uy * qw - uw * qy - uz * qx + ux * qz;
115
+ result[result_offset + 2] = uz * qw - uw * qz - ux * qy + uy * qx;
116
+ }
@@ -20,6 +20,16 @@
20
20
  * no-op in that case. KinematicVelocity bodies advance under their
21
21
  * user-set velocity.
22
22
  *
23
+ * Persistent linear / angular velocity is read from the data-oriented
24
+ * {@link SolverBodyState} span (`ss` / `base`); the pose remains authoritative
25
+ * on the `Transform` and is written through `.set()` so its onChanged
26
+ * subscribers and the per-substep concave re-detection keep seeing the moved
27
+ * pose. The integrated orientation is mirrored back into the solver state so
28
+ * the next substep's impulse loop evaluates world inertia against the current
29
+ * frame.
30
+ *
31
+ * @param {Float64Array} ss solver-body-state data array
32
+ * @param {number} base `body_index * SBS_STRIDE`
23
33
  * @param {RigidBody} rb
24
34
  * @param {Transform} transform
25
35
  * @param {number} dt
@@ -30,5 +40,5 @@
30
40
  * @param {number} ps_ang_y
31
41
  * @param {number} ps_ang_z
32
42
  */
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;
43
+ export function integrate_position(ss: Float64Array, base: number, 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;
34
44
  //# 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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,4EARW,MAAM,YACN,MAAM,YACN,MAAM,YACN,MAAM,YACN,MAAM,YACN,MAAM,YACN,MAAM,QA2ChB"}
1
+ {"version":3,"file":"integrate_position.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/integration/integrate_position.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,uCAZW,YAAY,QACZ,MAAM,2CAGN,MAAM,YACN,MAAM,YACN,MAAM,YACN,MAAM,YACN,MAAM,YACN,MAAM,YACN,MAAM,QA8ChB"}
@@ -1,79 +1,97 @@
1
- import { BodyKind } from "../ecs/BodyKind.js";
2
- import { quat_integrate } from "./quat_integrate.js";
3
-
4
- const scratch_q = new Float64Array(4);
5
-
6
- /**
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
- * not touched.
10
- *
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.
27
- *
28
- * @param {RigidBody} rb
29
- * @param {Transform} transform
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
37
- */
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
- ) {
43
- if (rb.kind === BodyKind.Static) {
44
- return;
45
- }
46
-
47
- const lv = rb.linearVelocity;
48
- const p = transform.position;
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
-
56
- // Direct reads via typed-array index; the write goes through .set() so
57
- // Transform's onChanged subscribers (matrix recompose, parent/child sync,
58
- // viewport position, fog-of-war reveal) fire once per body per step.
59
- p.set(
60
- p[0] + vx * dt,
61
- p[1] + vy * dt,
62
- p[2] + vz * dt
63
- );
64
-
65
- const av = rb.angularVelocity;
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) {
70
- const q = transform.rotation;
71
- quat_integrate(
72
- scratch_q,
73
- q[0], q[1], q[2], q[3],
74
- wx, wy, wz,
75
- dt
76
- );
77
- q.set(scratch_q[0], scratch_q[1], scratch_q[2], scratch_q[3]);
78
- }
79
- }
1
+ import { BodyKind } from "../ecs/BodyKind.js";
2
+ import { quat_integrate } from "./quat_integrate.js";
3
+ import {
4
+ SBS_QX, SBS_QY, SBS_QZ, SBS_QW,
5
+ SBS_LV_X, SBS_LV_Y, SBS_LV_Z,
6
+ SBS_AV_X, SBS_AV_Y, SBS_AV_Z,
7
+ } from "../body/SolverBodyState.js";
8
+
9
+ const scratch_q = new Float64Array(4);
10
+
11
+ /**
12
+ * Integrate `transform.position` and `transform.rotation` from the body's
13
+ * current linear and angular velocity over a step `dt`. Static bodies are
14
+ * not touched.
15
+ *
16
+ * The trailing six arguments are the body's *pseudo-velocity*: the
17
+ * position-pass output from the constraint solver (Catto split-impulse).
18
+ * Pseudo-velocity exists only inside the step — it's folded into the
19
+ * integration so the position update reflects depth correction, then
20
+ * implicitly discarded. The body's persistent `linearVelocity` /
21
+ * `angularVelocity` (which carry restitution + warm-start across steps)
22
+ * are never contaminated by it.
23
+ *
24
+ * Callers with no position-pass output should pass zeros for the six
25
+ * pseudo arguments folding zero is free (one add per axis).
26
+ *
27
+ * KinematicPosition bodies are treated like Dynamic for the position
28
+ * update if the gameplay code is driving them, their velocity is
29
+ * whatever the user wrote (typically zero); the step is effectively a
30
+ * no-op in that case. KinematicVelocity bodies advance under their
31
+ * user-set velocity.
32
+ *
33
+ * Persistent linear / angular velocity is read from the data-oriented
34
+ * {@link SolverBodyState} span (`ss` / `base`); the pose remains authoritative
35
+ * on the `Transform` and is written through `.set()` so its onChanged
36
+ * subscribers and the per-substep concave re-detection keep seeing the moved
37
+ * pose. The integrated orientation is mirrored back into the solver state so
38
+ * the next substep's impulse loop evaluates world inertia against the current
39
+ * frame.
40
+ *
41
+ * @param {Float64Array} ss solver-body-state data array
42
+ * @param {number} base `body_index * SBS_STRIDE`
43
+ * @param {RigidBody} rb
44
+ * @param {Transform} transform
45
+ * @param {number} dt
46
+ * @param {number} ps_lin_x pseudo-linear-velocity x (0 when no contacts)
47
+ * @param {number} ps_lin_y
48
+ * @param {number} ps_lin_z
49
+ * @param {number} ps_ang_x pseudo-angular-velocity x (0 when no contacts)
50
+ * @param {number} ps_ang_y
51
+ * @param {number} ps_ang_z
52
+ */
53
+ export function integrate_position(
54
+ ss, base, rb, transform, dt,
55
+ ps_lin_x, ps_lin_y, ps_lin_z,
56
+ ps_ang_x, ps_ang_y, ps_ang_z,
57
+ ) {
58
+ if (rb.kind === BodyKind.Static) {
59
+ return;
60
+ }
61
+
62
+ const p = transform.position;
63
+
64
+ // Combined integration velocity: persistent + pseudo. The pseudo
65
+ // contribution exists only for this step and never lands in the velocity.
66
+ const vx = ss[base + SBS_LV_X] + ps_lin_x;
67
+ const vy = ss[base + SBS_LV_Y] + ps_lin_y;
68
+ const vz = ss[base + SBS_LV_Z] + ps_lin_z;
69
+
70
+ // The write goes through .set() so Transform's onChanged subscribers
71
+ // (matrix recompose, parent/child sync, viewport position, fog-of-war
72
+ // reveal) fire — pose stays authoritative on the Transform.
73
+ p.set(
74
+ p[0] + vx * dt,
75
+ p[1] + vy * dt,
76
+ p[2] + vz * dt
77
+ );
78
+
79
+ const wx = ss[base + SBS_AV_X] + ps_ang_x;
80
+ const wy = ss[base + SBS_AV_Y] + ps_ang_y;
81
+ const wz = ss[base + SBS_AV_Z] + ps_ang_z;
82
+ if (wx !== 0 || wy !== 0 || wz !== 0) {
83
+ const q = transform.rotation;
84
+ quat_integrate(
85
+ scratch_q,
86
+ q[0], q[1], q[2], q[3],
87
+ wx, wy, wz,
88
+ dt
89
+ );
90
+ q.set(scratch_q[0], scratch_q[1], scratch_q[2], scratch_q[3]);
91
+ // Mirror the moved orientation into the solver state.
92
+ ss[base + SBS_QX] = scratch_q[0];
93
+ ss[base + SBS_QY] = scratch_q[1];
94
+ ss[base + SBS_QZ] = scratch_q[2];
95
+ ss[base + SBS_QW] = scratch_q[3];
96
+ }
97
+ }
@@ -46,10 +46,19 @@ export function integrate_velocity_forces(rb: RigidBody, transform: Transform, d
46
46
  * cancels exactly — keeping a resting stack at zero velocity. Damping is the
47
47
  * stable implicit decay `v *= 1/(1 + d·dt)` applied at the substep `dt`.
48
48
  *
49
+ * Velocity (and the damping it applies) lives in the data-oriented
50
+ * {@link SolverBodyState} for the duration of the substep loop; this reads and
51
+ * writes that span by `base`. The body's configuration (kind / gravityScale /
52
+ * damping coefficients) is still read from the `RigidBody` — cheap, once per
53
+ * body per substep, and unchanged across the step.
54
+ *
55
+ * @param {Float64Array} ss solver-body-state data array
56
+ * @param {number} base `body_index * SBS_STRIDE`
49
57
  * @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
58
+ * @param {number} gx
59
+ * @param {number} gy
60
+ * @param {number} gz world gravity
52
61
  * @param {number} dt sub-step size in seconds
53
62
  */
54
- export function integrate_velocity_gravity(rb: RigidBody, transform: Transform, gx: number, gy: number, gz: number, dt: number): void;
63
+ export function integrate_velocity_gravity(ss: Float64Array, base: number, rb: RigidBody, gx: number, gy: number, gz: number, dt: number): void;
55
64
  //# 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;AAED;;;;;;;;;;;;GAYG;AACH,mFAFW,MAAM,QA6BhB;AAED;;;;;;;;;;;;;;GAcG;AACH,oFAHW,MAAM,MAAa,MAAM,MAAa,MAAM,MAC5C,MAAM,QAwBhB"}
1
+ {"version":3,"file":"integrate_velocity.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/integration/integrate_velocity.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,4EALW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAoDhB;AAED;;;;;;;;;;;;GAYG;AACH,mFAFW,MAAM,QAkDhB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,+CARW,YAAY,QACZ,MAAM,qBAEN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAkChB"}