@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.
- package/package.json +1 -1
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts +4 -4
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.js +48 -52
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts +23 -21
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.js +41 -406
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts +5 -4
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js +400 -395
- package/src/engine/physics/body/SolverBodyState.d.ts +142 -0
- package/src/engine/physics/body/SolverBodyState.d.ts.map +1 -0
- package/src/engine/physics/body/SolverBodyState.js +251 -0
- package/src/engine/physics/broadphase/generate_pairs.d.ts +2 -1
- package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -1
- package/src/engine/physics/broadphase/generate_pairs.js +5 -3
- package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
- package/src/engine/physics/constraint/solve_constraints.js +691 -673
- package/src/engine/physics/ecs/PhysicsSystem.d.ts +21 -18
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +223 -91
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts +23 -0
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -1
- package/src/engine/physics/inertia/world_inverse_inertia.js +116 -77
- package/src/engine/physics/integration/integrate_position.d.ts +11 -1
- package/src/engine/physics/integration/integrate_position.d.ts.map +1 -1
- package/src/engine/physics/integration/integrate_position.js +97 -79
- package/src/engine/physics/integration/integrate_velocity.d.ts +12 -3
- package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -1
- package/src/engine/physics/integration/integrate_velocity.js +201 -160
- package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/box_box_manifold.js +750 -665
- package/src/engine/physics/narrowphase/box_triangle_contact.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/box_triangle_contact.js +4 -34
- package/src/engine/physics/narrowphase/clip_against_axis_uv.d.ts +16 -0
- package/src/engine/physics/narrowphase/clip_against_axis_uv.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/clip_against_axis_uv.js +49 -0
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/narrowphase_step.js +24 -3
- package/src/engine/physics/queries/raycast.d.ts.map +1 -1
- package/src/engine/physics/queries/raycast.js +7 -4
- package/src/engine/physics/solver/solve_contacts.d.ts +2 -2
- package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -1
- package/src/engine/physics/solver/solve_contacts.js +1341 -1173
|
@@ -1,160 +1,201 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* `
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* @param {
|
|
24
|
-
* @param {
|
|
25
|
-
* @param {number}
|
|
26
|
-
* @param {number}
|
|
27
|
-
* @param {number}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
let
|
|
47
|
-
let
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
let
|
|
61
|
-
let
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* per
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* @param {
|
|
92
|
-
* @param {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const
|
|
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
|
-
|
|
1
|
+
import { SBS_AV_X, SBS_AV_Y, SBS_AV_Z, SBS_LV_X, SBS_LV_Y, SBS_LV_Z, } from "../body/SolverBodyState.js";
|
|
2
|
+
import { BodyKind } from "../ecs/BodyKind.js";
|
|
3
|
+
import { world_inverse_inertia_apply } from "../inertia/world_inverse_inertia.js";
|
|
4
|
+
|
|
5
|
+
const scratch_angular = new Float64Array(3);
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Semi-implicit Euler velocity integration for a single rigid body.
|
|
9
|
+
*
|
|
10
|
+
* For Dynamic bodies:
|
|
11
|
+
* - gravity (scaled by `gravityScale`) and the accumulated force are converted
|
|
12
|
+
* to a velocity delta via `1/mass`,
|
|
13
|
+
* - accumulated torque is converted to angular acceleration via the
|
|
14
|
+
* world-frame inverse inertia (R · diag(I_local) · R^T applied to τ),
|
|
15
|
+
* - linear and angular damping are applied as a stable implicit decay
|
|
16
|
+
* `v *= 1 / (1 + d·dt)` (Box2D / Bullet recipe — never goes negative, no
|
|
17
|
+
* `exp()` call on the hot path),
|
|
18
|
+
* - the force / torque accumulators are zeroed afterwards.
|
|
19
|
+
*
|
|
20
|
+
* Kinematic and Static bodies are skipped — their velocity is the
|
|
21
|
+
* user / animation system's responsibility.
|
|
22
|
+
*
|
|
23
|
+
* @param {RigidBody} rb
|
|
24
|
+
* @param {Transform} transform used to rotate body-frame inertia into world
|
|
25
|
+
* @param {number} gx world gravity x
|
|
26
|
+
* @param {number} gy world gravity y
|
|
27
|
+
* @param {number} gz world gravity z
|
|
28
|
+
* @param {number} dt step size in seconds
|
|
29
|
+
*/
|
|
30
|
+
export function integrate_velocity(rb, transform, gx, gy, gz, dt) {
|
|
31
|
+
const af = rb.accumulatedForce;
|
|
32
|
+
const at = rb.accumulatedTorque;
|
|
33
|
+
|
|
34
|
+
if (rb.kind !== BodyKind.Dynamic) {
|
|
35
|
+
// Direct indexing — no observer listens to body-internal accumulators.
|
|
36
|
+
af[0] = 0; af[1] = 0; af[2] = 0;
|
|
37
|
+
at[0] = 0; at[1] = 0; at[2] = 0;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const inv_m = rb.mass > 0 ? 1 / rb.mass : 0;
|
|
42
|
+
const gs = rb.gravityScale;
|
|
43
|
+
|
|
44
|
+
// Linear velocity update: v += (F * invM + g * gravityScale) * dt
|
|
45
|
+
const lv = rb.linearVelocity;
|
|
46
|
+
let lvx = lv[0] + (af[0] * inv_m + gx * gs) * dt;
|
|
47
|
+
let lvy = lv[1] + (af[1] * inv_m + gy * gs) * dt;
|
|
48
|
+
let lvz = lv[2] + (af[2] * inv_m + gz * gs) * dt;
|
|
49
|
+
|
|
50
|
+
if (rb.linearDamping > 0) {
|
|
51
|
+
const k = 1 / (1 + rb.linearDamping * dt);
|
|
52
|
+
lvx *= k;
|
|
53
|
+
lvy *= k;
|
|
54
|
+
lvz *= k;
|
|
55
|
+
}
|
|
56
|
+
lv[0] = lvx; lv[1] = lvy; lv[2] = lvz;
|
|
57
|
+
|
|
58
|
+
// Angular velocity update: ω += I_world⁻¹ · τ · dt
|
|
59
|
+
const av = rb.angularVelocity;
|
|
60
|
+
let avx = av[0];
|
|
61
|
+
let avy = av[1];
|
|
62
|
+
let avz = av[2];
|
|
63
|
+
if (at[0] !== 0 || at[1] !== 0 || at[2] !== 0) {
|
|
64
|
+
world_inverse_inertia_apply(scratch_angular, 0, rb.inverseInertiaLocal, transform.rotation, at[0], at[1], at[2]);
|
|
65
|
+
avx += scratch_angular[0] * dt;
|
|
66
|
+
avy += scratch_angular[1] * dt;
|
|
67
|
+
avz += scratch_angular[2] * dt;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (rb.angularDamping > 0) {
|
|
71
|
+
const k = 1 / (1 + rb.angularDamping * dt);
|
|
72
|
+
avx *= k;
|
|
73
|
+
avy *= k;
|
|
74
|
+
avz *= k;
|
|
75
|
+
}
|
|
76
|
+
av[0] = avx; av[1] = avy; av[2] = avz;
|
|
77
|
+
|
|
78
|
+
af[0] = 0; af[1] = 0; af[2] = 0;
|
|
79
|
+
at[0] = 0; at[1] = 0; at[2] = 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Apply the accumulated force / torque to velocity over a step `dt`, then
|
|
84
|
+
* zero the accumulators. Gravity and damping are NOT applied here.
|
|
85
|
+
*
|
|
86
|
+
* The "once per outer step" half of the TGS integrator: a user force is a
|
|
87
|
+
* per-frame budget that must land in full exactly once, independent of
|
|
88
|
+
* substep count. Gravity is the continuous field re-applied every substep
|
|
89
|
+
* by {@link integrate_velocity_gravity}.
|
|
90
|
+
*
|
|
91
|
+
* @param {RigidBody} rb
|
|
92
|
+
* @param {Transform} transform used to rotate body-frame inertia into world
|
|
93
|
+
* @param {number} dt full outer-step size in seconds
|
|
94
|
+
*/
|
|
95
|
+
export function integrate_velocity_forces(rb, transform, dt) {
|
|
96
|
+
const af = rb.accumulatedForce;
|
|
97
|
+
const at = rb.accumulatedTorque;
|
|
98
|
+
|
|
99
|
+
if (rb.kind !== BodyKind.Dynamic) {
|
|
100
|
+
|
|
101
|
+
af[0] = 0;
|
|
102
|
+
af[1] = 0;
|
|
103
|
+
af[2] = 0;
|
|
104
|
+
|
|
105
|
+
at[0] = 0;
|
|
106
|
+
at[1] = 0;
|
|
107
|
+
at[2] = 0;
|
|
108
|
+
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const inv_m = rb.mass > 0 ? 1 / rb.mass : 0;
|
|
113
|
+
|
|
114
|
+
const lv = rb.linearVelocity;
|
|
115
|
+
lv[0] += af[0] * inv_m * dt;
|
|
116
|
+
lv[1] += af[1] * inv_m * dt;
|
|
117
|
+
lv[2] += af[2] * inv_m * dt;
|
|
118
|
+
|
|
119
|
+
if (at[0] !== 0 || at[1] !== 0 || at[2] !== 0) {
|
|
120
|
+
|
|
121
|
+
world_inverse_inertia_apply(
|
|
122
|
+
scratch_angular, 0,
|
|
123
|
+
rb.inverseInertiaLocal, transform.rotation,
|
|
124
|
+
at[0],
|
|
125
|
+
at[1],
|
|
126
|
+
at[2]
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
const av = rb.angularVelocity;
|
|
130
|
+
|
|
131
|
+
av[0] += scratch_angular[0] * dt;
|
|
132
|
+
av[1] += scratch_angular[1] * dt;
|
|
133
|
+
av[2] += scratch_angular[2] * dt;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
af[0] = 0;
|
|
137
|
+
af[1] = 0;
|
|
138
|
+
af[2] = 0;
|
|
139
|
+
|
|
140
|
+
at[0] = 0;
|
|
141
|
+
at[1] = 0;
|
|
142
|
+
at[2] = 0;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Apply gravity and velocity damping over a (sub)step `dt`. Does NOT touch
|
|
147
|
+
* the force / torque accumulators (consumed once by
|
|
148
|
+
* {@link integrate_velocity_forces}).
|
|
149
|
+
*
|
|
150
|
+
* The "every substep" half of the TGS integrator. Per substep the body sees
|
|
151
|
+
* only `g·h` of gravity, which the per-substep contact warm-start + solve
|
|
152
|
+
* cancels exactly — keeping a resting stack at zero velocity. Damping is the
|
|
153
|
+
* stable implicit decay `v *= 1/(1 + d·dt)` applied at the substep `dt`.
|
|
154
|
+
*
|
|
155
|
+
* Velocity (and the damping it applies) lives in the data-oriented
|
|
156
|
+
* {@link SolverBodyState} for the duration of the substep loop; this reads and
|
|
157
|
+
* writes that span by `base`. The body's configuration (kind / gravityScale /
|
|
158
|
+
* damping coefficients) is still read from the `RigidBody` — cheap, once per
|
|
159
|
+
* body per substep, and unchanged across the step.
|
|
160
|
+
*
|
|
161
|
+
* @param {Float64Array} ss solver-body-state data array
|
|
162
|
+
* @param {number} base `body_index * SBS_STRIDE`
|
|
163
|
+
* @param {RigidBody} rb
|
|
164
|
+
* @param {number} gx
|
|
165
|
+
* @param {number} gy
|
|
166
|
+
* @param {number} gz world gravity
|
|
167
|
+
* @param {number} dt sub-step size in seconds
|
|
168
|
+
*/
|
|
169
|
+
export function integrate_velocity_gravity(ss, base, rb, gx, gy, gz, dt) {
|
|
170
|
+
if (rb.kind !== BodyKind.Dynamic) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const gs = rb.gravityScale;
|
|
175
|
+
|
|
176
|
+
let lvx = ss[base + SBS_LV_X] + gx * gs * dt;
|
|
177
|
+
let lvy = ss[base + SBS_LV_Y] + gy * gs * dt;
|
|
178
|
+
let lvz = ss[base + SBS_LV_Z] + gz * gs * dt;
|
|
179
|
+
|
|
180
|
+
if (rb.linearDamping > 0) {
|
|
181
|
+
const k = 1 / (1 + rb.linearDamping * dt);
|
|
182
|
+
|
|
183
|
+
lvx *= k;
|
|
184
|
+
lvy *= k;
|
|
185
|
+
lvz *= k;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
ss[base + SBS_LV_X] = lvx;
|
|
189
|
+
ss[base + SBS_LV_Y] = lvy;
|
|
190
|
+
ss[base + SBS_LV_Z] = lvz;
|
|
191
|
+
|
|
192
|
+
if (rb.angularDamping > 0) {
|
|
193
|
+
|
|
194
|
+
const k = 1 / (1 + rb.angularDamping * dt);
|
|
195
|
+
|
|
196
|
+
ss[base + SBS_AV_X] *= k;
|
|
197
|
+
ss[base + SBS_AV_Y] *= k;
|
|
198
|
+
ss[base + SBS_AV_Z] *= k;
|
|
199
|
+
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -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":"AAgHA;;;;;;;;;;;;;;;;;;;;;;;;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,CAghBnB;AArlBD;;;GAGG;AACH,iCAFU,MAAM,CAEoD"}
|