reze-engine 0.30.2 → 0.31.2

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.
@@ -15,6 +15,13 @@ function wrapAngle(a) {
15
15
  }
16
16
  export class LocomotionController {
17
17
  constructor(model, clips, options) {
18
+ this.lastEntries = null;
19
+ this.turning = null;
20
+ this.runTurning = null;
21
+ /** An interrupted authored clip fading out OVER resumed locomotion, so breaking
22
+ * out of a stop is instantly responsive without a pose pop. */
23
+ this.exitGhost = null;
24
+ this.stopping = null;
18
25
  this.inputX = 0;
19
26
  this.inputY = 0;
20
27
  this.inputSprint = false;
@@ -23,6 +30,10 @@ export class LocomotionController {
23
30
  this.inputForward = 0;
24
31
  this.inputSteer = 0;
25
32
  this.speedLevel = 0;
33
+ /** Peak-hold of speedLevel (decays ~1.5/s): reversal triggers read this, because
34
+ * keyboard direction flips pass through a dead moment (W+S cancel, key gap) that
35
+ * dips the instantaneous level right when the reversal input lands. */
36
+ this.recentSpeed = 0;
26
37
  this.yaw = 0;
27
38
  // Movement direction = the INPUT heading, not the body yaw. The body turns
28
39
  // cosmetically toward it; translating along the (sweeping) body yaw instead
@@ -40,8 +51,17 @@ export class LocomotionController {
40
51
  this.runSpeed = options?.runSpeed ?? 67;
41
52
  this.sprintSpeed = options?.sprintSpeed ?? 92;
42
53
  this.speedResponse = options?.speedResponse ?? 5;
54
+ this.autoApply = options?.autoApply ?? true;
43
55
  this.turnResponse = options?.turnResponse ?? 10;
44
56
  this.cosTurnThreshold = Math.cos(options?.turnInPlaceThreshold ?? Math.PI / 4);
57
+ this.turnClipMinAngle = options?.turnClipMinAngle ?? (100 * Math.PI) / 180;
58
+ this.turnTimeScale = options?.turnTimeScale ?? 1.4;
59
+ this.stopTimeScale = options?.stopTimeScale ?? 1.25;
60
+ this.turnEntries = [
61
+ { name: clips.idle, time: 0, weight: 0 },
62
+ { name: clips.idle, time: 0, weight: 1 },
63
+ { name: clips.idle, time: 0, weight: 0 },
64
+ ];
45
65
  this.steerRate = options?.steerRate ?? 2.5;
46
66
  this.backpedalScale = options?.backpedalScale ?? 0.5;
47
67
  this.yawOffset = options?.yawOffset ?? Math.PI;
@@ -49,6 +69,7 @@ export class LocomotionController {
49
69
  { name: clips.idle, time: 0, weight: 1 },
50
70
  { name: clips.run, time: 0, weight: 0 },
51
71
  { name: clips.sprint ?? clips.run, time: 0, weight: 0 },
72
+ { name: clips.idle, time: 0, weight: 0 }, // fading ghost of an interrupted clip
52
73
  ];
53
74
  const byAngle = (a, b) => a.angle - b.angle;
54
75
  this.strafeRun = clips.strafeRun ? [...clips.strafeRun].sort(byAngle) : null;
@@ -97,7 +118,19 @@ export class LocomotionController {
97
118
  }
98
119
  /** Stop driving the model's pose (the blend is cleared; the single-clip player resumes). */
99
120
  detach() {
100
- this.model.clearBlendPose();
121
+ this.lastEntries = null;
122
+ if (this.autoApply)
123
+ this.model.clearBlendPose();
124
+ }
125
+ /** The most recent update()'s blend entries (null before the first update or
126
+ * after detach). The array is reused between frames — read, don't hold. */
127
+ getBlendEntries() {
128
+ return this.lastEntries;
129
+ }
130
+ emit(entries) {
131
+ this.lastEntries = entries;
132
+ if (this.autoApply)
133
+ this.model.setBlendPose(entries);
101
134
  }
102
135
  clipDuration(name) {
103
136
  const frames = this.model.getClip(name)?.frameCount ?? 0;
@@ -111,6 +144,15 @@ export class LocomotionController {
111
144
  if (this.facingYaw !== null && this.strafeRun !== null && !this.tankMode) {
112
145
  return this.updateStrafe(dt);
113
146
  }
147
+ if (this.turning !== null) {
148
+ return this.updateTurnClip(dt);
149
+ }
150
+ if (this.runTurning !== null) {
151
+ return this.updateRunTurn(dt);
152
+ }
153
+ if (this.stopping !== null) {
154
+ return this.updateStop(dt);
155
+ }
114
156
  const hasSprint = this.clips.sprint !== undefined;
115
157
  let moving;
116
158
  let align = 1;
@@ -131,12 +173,99 @@ export class LocomotionController {
131
173
  else {
132
174
  const m = Math.hypot(this.inputX, this.inputY);
133
175
  moving = m > 0.05;
176
+ this.recentSpeed = Math.max(this.speedLevel, this.recentSpeed - dt * 1.5);
177
+ // Release at speed: play the authored stop instead of blending to idle.
178
+ const stops = this.clips.stop;
179
+ // Gate on the peak-hold speed: the release decay (throttle/analog) drains the
180
+ // instantaneous level below any threshold before `moving` goes false. The
181
+ // small floor on the actual level keeps standstill taps from faking a skid.
182
+ if (!moving && stops && stops.length > 0 && this.recentSpeed >= 0.7 && this.speedLevel >= 0.35) {
183
+ const gear = this.recentSpeed > 1.4 ? "sprint" : "run";
184
+ const foot = this.gaitPhase < 0.5 ? "L" : "R";
185
+ // Gear must match exactly: supplying stops for only one gear means the
186
+ // other gear keeps the default quick blend-to-idle.
187
+ let best = null;
188
+ let bestScore = -1;
189
+ for (const e of stops) {
190
+ if (e.gear !== gear)
191
+ continue;
192
+ const score = e.foot === foot ? 1 : 0;
193
+ if (score > bestScore) {
194
+ best = e;
195
+ bestScore = score;
196
+ }
197
+ }
198
+ if (best) {
199
+ const fromClip = gear === "sprint" && this.clips.sprint ? this.clips.sprint : this.clips.run;
200
+ this.stopping = {
201
+ entry: best,
202
+ time: 0,
203
+ startX: this.position.x,
204
+ startZ: this.position.z,
205
+ dirX: this.dirX,
206
+ dirZ: this.dirZ,
207
+ startLevel: Math.min(this.recentSpeed, 2),
208
+ fromIdleW: Math.max(0, 1 - this.speedLevel),
209
+ fromClip,
210
+ fromTime: this.gaitPhase * this.clipDuration(fromClip),
211
+ };
212
+ return this.updateStop(dt);
213
+ }
214
+ }
134
215
  // Yaw eases toward the input heading only while there is one. Turns are strictly
135
216
  // in place: zero translation outside the threshold cone, ramping smoothly to full
136
217
  // speed as the body aligns — so direction reversals (L-R-L) cannot drift.
137
218
  if (moving) {
138
219
  const desired = Math.atan2(this.inputX, this.inputY);
139
220
  const err = wrapAngle(desired - this.yaw);
221
+ // Running reversal: while moving fast with a reversal-class error, play the
222
+ // authored plant-and-turn for the current gear and gait foot.
223
+ const runTurns = this.clips.runTurn;
224
+ if (runTurns && runTurns.length > 0 && this.recentSpeed >= 0.6 && Math.abs(err) >= (130 * Math.PI) / 180) {
225
+ const gear = this.recentSpeed > 1.4 ? "sprint" : "run";
226
+ const foot = this.gaitPhase < 0.5 ? "L" : "R";
227
+ const side = err < 0 ? -1 : 1;
228
+ let best = null;
229
+ let bestScore = -1;
230
+ for (const e of runTurns) {
231
+ if (Math.sign(e.angle) !== side)
232
+ continue;
233
+ const score = (e.gear === gear ? 2 : 0) + (e.foot === foot ? 1 : 0);
234
+ if (score > bestScore) {
235
+ best = e;
236
+ bestScore = score;
237
+ }
238
+ }
239
+ if (best) {
240
+ // Restore the pre-dip speed so she runs OUT of the turn at pace.
241
+ this.speedLevel = Math.max(this.speedLevel, Math.min(this.recentSpeed, 2));
242
+ this.runTurning = {
243
+ entry: best,
244
+ time: 0,
245
+ startX: this.position.x,
246
+ startZ: this.position.z,
247
+ dirX: Math.sin(this.yaw),
248
+ dirZ: Math.cos(this.yaw),
249
+ };
250
+ return this.updateRunTurn(dt);
251
+ }
252
+ }
253
+ // Reversal-class turn from near-standstill: play the authored turn clip
254
+ // whose angle is nearest the error instead of the eased pivot.
255
+ const turnClips = this.clips.turnInPlace;
256
+ if (turnClips && turnClips.length > 0 && this.speedLevel < 0.3 && Math.abs(err) >= this.turnClipMinAngle) {
257
+ let best = turnClips[0];
258
+ let bestD = Math.abs(wrapAngle(err - best.angle));
259
+ for (const e of turnClips) {
260
+ const d = Math.abs(wrapAngle(err - e.angle));
261
+ if (d < bestD) {
262
+ best = e;
263
+ bestD = d;
264
+ }
265
+ }
266
+ this.turning = { entry: best, time: 0 };
267
+ return this.updateTurnClip(dt);
268
+ }
140
269
  this.yaw = wrapAngle(this.yaw + err * Math.min(1, this.turnResponse * dt));
141
270
  align = Math.max(0, (Math.cos(err) - this.cosTurnThreshold) / (1 - this.cosTurnThreshold));
142
271
  this.dirX = this.inputX / m;
@@ -186,7 +315,28 @@ export class LocomotionController {
186
315
  this.entries[1].weight = wRun;
187
316
  this.entries[2].time = this.gaitPhase * sprintDur;
188
317
  this.entries[2].weight = wSprint;
189
- this.model.setBlendPose(this.entries);
318
+ const GHOST_FADE = 0.25;
319
+ if (this.exitGhost) {
320
+ const g = this.exitGhost;
321
+ g.elapsed += dt;
322
+ const wGhost = Math.max(0, 1 - g.elapsed / GHOST_FADE);
323
+ if (wGhost <= 0) {
324
+ this.exitGhost = null;
325
+ this.entries[3].weight = 0;
326
+ }
327
+ else {
328
+ this.entries[0].weight *= 1 - wGhost;
329
+ this.entries[1].weight *= 1 - wGhost;
330
+ this.entries[2].weight *= 1 - wGhost;
331
+ this.entries[3].name = g.clip;
332
+ this.entries[3].time = g.clipTime + g.elapsed; // the clip's real tail keeps playing
333
+ this.entries[3].weight = wGhost;
334
+ }
335
+ }
336
+ else {
337
+ this.entries[3].weight = 0;
338
+ }
339
+ this.emit(this.entries);
190
340
  const ry = this.yaw + this.yawOffset;
191
341
  const half = ry * 0.5;
192
342
  this.rotation.setXYZW(0, Math.sin(half), 0, Math.cos(half));
@@ -286,7 +436,7 @@ export class LocomotionController {
286
436
  e[4].name = sprintB.clip;
287
437
  e[4].time = this.gaitPhase * sprintDur;
288
438
  e[4].weight = wSprint * sprintT;
289
- this.model.setBlendPose(e);
439
+ this.emit(e);
290
440
  const ry = this.yaw + this.yawOffset;
291
441
  const half = ry * 0.5;
292
442
  this.rotation.setXYZW(0, Math.sin(half), 0, Math.cos(half));
@@ -294,4 +444,183 @@ export class LocomotionController {
294
444
  this.pose.speedLevel = level;
295
445
  return this.pose;
296
446
  }
447
+ /** Authored turn-in-place frame: the clip rotates the body through its bones while
448
+ * the root yaw stays frozen; at exitTime the measured angle transfers to the root
449
+ * in the same instant the pose hands back to idle — the same orientation expressed
450
+ * two ways, so the cut is seamless. No translation during the turn. */
451
+ updateTurnClip(dt) {
452
+ const t = this.turning;
453
+ t.time += dt * this.turnTimeScale;
454
+ // Speed level settles toward 0 while turning (we were near-standstill already).
455
+ const maxStep = this.speedResponse * dt;
456
+ this.speedLevel += Math.abs(-this.speedLevel) <= maxStep ? -this.speedLevel : -Math.sign(this.speedLevel) * maxStep;
457
+ const idleDur = this.clipDuration(this.clips.idle);
458
+ this.idleTime = (this.idleTime + dt) % idleDur;
459
+ if (t.time >= t.entry.exitTime) {
460
+ // Transfer the angle to the root and hand the pose to idle IN THE SAME frame —
461
+ // leaving the previous blend up would double the rotation for one frame.
462
+ this.yaw = wrapAngle(this.yaw + t.entry.angle);
463
+ this.turning = null;
464
+ const e = this.turnEntries;
465
+ e[0].weight = 0;
466
+ e[1].name = this.clips.idle;
467
+ e[1].time = this.idleTime;
468
+ e[1].weight = 1;
469
+ e[2].weight = 0;
470
+ this.emit(e);
471
+ }
472
+ else {
473
+ // Fade the turn clip over idle at the edges so entry doesn't pop.
474
+ const w = Math.min(1, t.time / 0.12);
475
+ const e = this.turnEntries;
476
+ e[0].name = t.entry.clip;
477
+ e[0].time = Math.min(t.time, t.entry.exitTime);
478
+ e[0].weight = w;
479
+ e[1].name = this.clips.idle;
480
+ e[1].time = this.idleTime;
481
+ e[1].weight = 1 - w;
482
+ e[2].weight = 0;
483
+ this.emit(e);
484
+ }
485
+ const ry = this.yaw + this.yawOffset;
486
+ const half = ry * 0.5;
487
+ this.rotation.setXYZW(0, Math.sin(half), 0, Math.cos(half));
488
+ this.pose.yaw = this.yaw;
489
+ this.pose.speedLevel = this.speedLevel;
490
+ return this.pose;
491
+ }
492
+ /** Authored-stop frame: root follows the clip's measured skid profile along the
493
+ * release heading; input returning interrupts and resumes locomotion at a level
494
+ * proportional to how much of the stop remains. */
495
+ updateStop(dt) {
496
+ const t = this.stopping;
497
+ const entry = t.entry;
498
+ // Interrupt: input came back — locomotion resumes instantly from a LOW level
499
+ // (a stop is committed; breaking out is a fresh walk-up, never a drift), while
500
+ // the stop pose fades out as a ghost instead of hard-cutting.
501
+ if (Math.hypot(this.inputX, this.inputY) > 0.05) {
502
+ this.speedLevel = Math.min(t.startLevel * (1 - Math.min(1, t.time / entry.exitTime)), 0.3);
503
+ this.recentSpeed = this.speedLevel;
504
+ this.exitGhost = { clip: entry.clip, clipTime: Math.min(t.time, entry.exitTime), elapsed: 0 };
505
+ this.stopping = null;
506
+ return this.update(dt);
507
+ }
508
+ t.time += dt * this.stopTimeScale;
509
+ const clipT = Math.min(t.time, entry.exitTime);
510
+ const fwd = LocomotionController.profileAt(entry.forward, clipT / entry.exitTime);
511
+ this.position.x = t.startX + t.dirX * fwd;
512
+ this.position.z = t.startZ + t.dirZ * fwd;
513
+ this.speedLevel = t.startLevel * Math.max(0, 1 - t.time / entry.exitTime);
514
+ const idleDur = this.clipDuration(this.clips.idle);
515
+ this.idleTime = (this.idleTime + dt) % idleDur;
516
+ const FADE_OUT = 0.35;
517
+ if (t.time >= entry.exitTime + FADE_OUT) {
518
+ this.stopping = null;
519
+ this.speedLevel = 0;
520
+ this.gaitPhase = 0;
521
+ const e = this.turnEntries;
522
+ e[0].weight = 0;
523
+ e[1].name = this.clips.idle;
524
+ e[1].time = this.idleTime;
525
+ e[1].weight = 1;
526
+ e[2].weight = 0;
527
+ this.emit(e);
528
+ }
529
+ else if (t.time >= entry.exitTime) {
530
+ // Settle tail: the root is already still, so keep playing the clip's own
531
+ // recovery (it exists past exitTime) while fading to idle — no hard cut.
532
+ const wOut = (t.time - entry.exitTime) / FADE_OUT;
533
+ const e = this.turnEntries;
534
+ e[0].name = entry.clip;
535
+ e[0].time = t.time; // real tail frames beyond exitTime
536
+ e[0].weight = 1 - wOut;
537
+ e[1].name = this.clips.idle;
538
+ e[1].time = this.idleTime;
539
+ e[1].weight = wOut;
540
+ e[2].weight = 0;
541
+ this.emit(e);
542
+ }
543
+ else {
544
+ const fromDur = this.clipDuration(t.fromClip);
545
+ t.fromTime = (t.fromTime + dt) % fromDur;
546
+ const w = Math.min(1, t.time / 0.25);
547
+ const e = this.turnEntries;
548
+ e[0].name = entry.clip;
549
+ e[0].time = clipT;
550
+ e[0].weight = w;
551
+ e[1].name = t.fromClip;
552
+ e[1].time = t.fromTime;
553
+ e[1].weight = (1 - w) * (1 - t.fromIdleW);
554
+ e[2].name = this.clips.idle;
555
+ e[2].time = this.idleTime;
556
+ e[2].weight = (1 - w) * t.fromIdleW;
557
+ this.emit(e);
558
+ }
559
+ const ry = this.yaw + this.yawOffset;
560
+ const half = ry * 0.5;
561
+ this.rotation.setXYZW(0, Math.sin(half), 0, Math.cos(half));
562
+ this.pose.yaw = this.yaw;
563
+ this.pose.speedLevel = this.speedLevel;
564
+ return this.pose;
565
+ }
566
+ /** Linear interpolation over a uniformly sampled profile at t in [0, 1]. */
567
+ static profileAt(samples, t) {
568
+ const n = samples.length - 1;
569
+ if (n <= 0)
570
+ return 0;
571
+ const x = Math.min(Math.max(t, 0), 1) * n;
572
+ const i = Math.min(n - 1, Math.floor(x));
573
+ return samples[i] + (samples[i + 1] - samples[i]) * (x - i);
574
+ }
575
+ /** Running-reversal frame: bones carry the turn while the root travels the clip's
576
+ * AUTHORED forward profile along the trigger heading (overrun, plant, return) —
577
+ * no fabricated motion, so the feet stay glued. At exitTime the yaw transfers
578
+ * and the normal path runs her out along the new heading. */
579
+ updateRunTurn(dt) {
580
+ const t = this.runTurning;
581
+ t.time += dt;
582
+ const entry = t.entry;
583
+ const clipT = Math.min(t.time, entry.exitTime);
584
+ const fwd = LocomotionController.profileAt(entry.forward, clipT / entry.exitTime);
585
+ this.position.x = t.startX + t.dirX * fwd;
586
+ this.position.z = t.startZ + t.dirZ * fwd;
587
+ const idleDur = this.clipDuration(this.clips.idle);
588
+ this.idleTime = (this.idleTime + dt) % idleDur;
589
+ if (t.time >= entry.exitTime) {
590
+ this.yaw = wrapAngle(this.yaw + entry.angle);
591
+ this.runTurning = null;
592
+ // She exits mid-stride: keep the speed level, restart the gait cleanly, and
593
+ // point the travel direction along the new heading so the next frame runs out.
594
+ this.gaitPhase = 0;
595
+ this.dirX = Math.sin(this.yaw);
596
+ this.dirZ = Math.cos(this.yaw);
597
+ const e = this.turnEntries;
598
+ e[0].name = this.clips.run;
599
+ e[0].time = 0;
600
+ e[0].weight = Math.min(1, this.speedLevel);
601
+ e[1].name = this.clips.idle;
602
+ e[1].time = this.idleTime;
603
+ e[1].weight = 1 - Math.min(1, this.speedLevel);
604
+ e[2].weight = 0;
605
+ this.emit(e);
606
+ }
607
+ else {
608
+ const w = Math.min(1, t.time / 0.1);
609
+ const e = this.turnEntries;
610
+ e[0].name = entry.clip;
611
+ e[0].time = clipT;
612
+ e[0].weight = w;
613
+ e[1].name = this.clips.run;
614
+ e[1].time = this.gaitPhase * this.clipDuration(this.clips.run);
615
+ e[1].weight = 1 - w;
616
+ e[2].weight = 0;
617
+ this.emit(e);
618
+ }
619
+ const ry = this.yaw + this.yawOffset;
620
+ const half = ry * 0.5;
621
+ this.rotation.setXYZW(0, Math.sin(half), 0, Math.cos(half));
622
+ this.pose.yaw = this.yaw;
623
+ this.pose.speedLevel = this.speedLevel;
624
+ return this.pose;
625
+ }
297
626
  }
package/dist/model.d.ts CHANGED
@@ -2,6 +2,13 @@ import { Mat4, Quat, Vec3 } from "./math";
2
2
  import { type AssetReader } from "./asset-reader";
3
3
  import { Rigidbody, Joint } from "./physics";
4
4
  import { AnimationClip, AnimationPlayOptions, AnimationProgress, BlendEntry } from "./animation";
5
+ export interface ClipEventInfo {
6
+ clip: string;
7
+ /** The registered event time, seconds. */
8
+ time: number;
9
+ /** The clip's blend weight at the moment of firing. */
10
+ weight: number;
11
+ }
5
12
  export interface Texture {
6
13
  path: string;
7
14
  name: string;
@@ -157,6 +164,10 @@ export declare class Model {
157
164
  private lastAppliedClip;
158
165
  private oneShot;
159
166
  private readonly oneShotEntries;
167
+ /** Time-triggered clip callbacks (footsteps, skill timing). Fired by every
168
+ * playback path when a clip's cursor crosses the event time with weight. */
169
+ private readonly clipEvents;
170
+ private readonly entryEventPrev;
160
171
  private blendEntries;
161
172
  private crossfade;
162
173
  private readonly blendBoneCursors;
@@ -253,6 +264,18 @@ export declare class Model {
253
264
  cancelOneShot(fadeOut?: number): void;
254
265
  /** Name of the active one-shot, or null. */
255
266
  getOneShot(): string | null;
267
+ /** Fire `callback` whenever `clip`'s playback crosses `time` (seconds) with at
268
+ * least `minWeight` influence (default 0.1) — on any path: blend entries,
269
+ * one-shots, crossfades, or plain play. Loop wraps fire correctly; hard cursor
270
+ * jumps may occasionally fire or skip (events are for sfx-grade timing, not
271
+ * logic). Returns an unsubscribe function. */
272
+ addClipEvent(clip: string, time: number, callback: (e: ClipEventInfo) => void, options?: {
273
+ minWeight?: number;
274
+ }): () => void;
275
+ private fireClipEvents;
276
+ /** Per-entry cursor memory for event crossing detection; keyed on entry object
277
+ * identity (controllers reuse their arrays, so this stays warm). */
278
+ private trackEntryEvents;
256
279
  /** Fade from the currently playing clip (or from the rest pose when nothing plays)
257
280
  * into `name` over `seconds`. The target starts at frame 0 and becomes the current
258
281
  * clip immediately — progress, looping and the camera clock report the target for
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
package/dist/model.js CHANGED
@@ -106,6 +106,10 @@ export class Model {
106
106
  // envelopes — the background keeps advancing and is what the fade-out returns to.
107
107
  this.oneShot = null;
108
108
  this.oneShotEntries = [];
109
+ /** Time-triggered clip callbacks (footsteps, skill timing). Fired by every
110
+ * playback path when a clip's cursor crosses the event time with weight. */
111
+ this.clipEvents = new Map();
112
+ this.entryEventPrev = new WeakMap();
109
113
  // Blended pose: declarative N-clip mix (setBlendPose) or a running crossfade.
110
114
  // Cursor caches are per clip so sampling several clips in one frame doesn't
111
115
  // thrash the single-clip caches above; WeakMap so removed clips can collect.
@@ -1079,6 +1083,52 @@ export class Model {
1079
1083
  getOneShot() {
1080
1084
  return this.oneShot?.name ?? null;
1081
1085
  }
1086
+ /** Fire `callback` whenever `clip`'s playback crosses `time` (seconds) with at
1087
+ * least `minWeight` influence (default 0.1) — on any path: blend entries,
1088
+ * one-shots, crossfades, or plain play. Loop wraps fire correctly; hard cursor
1089
+ * jumps may occasionally fire or skip (events are for sfx-grade timing, not
1090
+ * logic). Returns an unsubscribe function. */
1091
+ addClipEvent(clip, time, callback, options) {
1092
+ let list = this.clipEvents.get(clip);
1093
+ if (!list) {
1094
+ list = [];
1095
+ this.clipEvents.set(clip, list);
1096
+ }
1097
+ const def = { time, minWeight: options?.minWeight ?? 0.1, callback };
1098
+ list.push(def);
1099
+ return () => {
1100
+ const i = list.indexOf(def);
1101
+ if (i >= 0)
1102
+ list.splice(i, 1);
1103
+ };
1104
+ }
1105
+ fireClipEvents(name, prev, now, weight) {
1106
+ const evs = this.clipEvents.get(name);
1107
+ if (!evs || evs.length === 0)
1108
+ return;
1109
+ const wrapped = now < prev;
1110
+ for (let i = 0; i < evs.length; i++) {
1111
+ const ev = evs[i];
1112
+ if (weight < ev.minWeight)
1113
+ continue;
1114
+ const hit = wrapped ? ev.time > prev || ev.time <= now : ev.time > prev && ev.time <= now;
1115
+ if (hit)
1116
+ ev.callback({ clip: name, time: ev.time, weight });
1117
+ }
1118
+ }
1119
+ /** Per-entry cursor memory for event crossing detection; keyed on entry object
1120
+ * identity (controllers reuse their arrays, so this stays warm). */
1121
+ trackEntryEvents(e) {
1122
+ const prev = this.entryEventPrev.get(e);
1123
+ if (prev === undefined) {
1124
+ this.entryEventPrev.set(e, { name: e.name, time: e.time });
1125
+ return;
1126
+ }
1127
+ if (prev.name === e.name && prev.time !== e.time)
1128
+ this.fireClipEvents(e.name, prev.time, e.time, e.weight);
1129
+ prev.name = e.name;
1130
+ prev.time = e.time;
1131
+ }
1082
1132
  /** Fade from the currently playing clip (or from the rest pose when nothing plays)
1083
1133
  * into `name` over `seconds`. The target starts at frame 0 and becomes the current
1084
1134
  * clip immediately — progress, looping and the camera clock report the target for
@@ -1335,6 +1385,8 @@ export class Model {
1335
1385
  continue;
1336
1386
  const w = e.weight * norm;
1337
1387
  const frame = e.time * FPS;
1388
+ if (this.clipEvents.size > 0)
1389
+ this.trackEntryEvents(e);
1338
1390
  let cursors = this.blendBoneCursors.get(clip);
1339
1391
  if (!cursors) {
1340
1392
  cursors = new Map();
@@ -1526,6 +1578,8 @@ export class Model {
1526
1578
  this.tweenTimeMs += deltaTime * 1000;
1527
1579
  // Update all active tweens (rotations, translations, morphs)
1528
1580
  const tweensChangedMorphs = this.updateTweens();
1581
+ const evWatch = this.clipEvents.size > 0 ? this.animationState.getCurrentAnimation() : null;
1582
+ const evPrevFrame = evWatch !== null ? this.animationState.getCurrentFrame() : 0;
1529
1583
  this.animationState.update(deltaTime);
1530
1584
  if (!this.clipApplySuspended) {
1531
1585
  if (this.oneShot !== null) {
@@ -1539,8 +1593,12 @@ export class Model {
1539
1593
  }
1540
1594
  else {
1541
1595
  const clip = this.animationState.getCurrentClip();
1542
- if (clip !== null)
1596
+ if (clip !== null) {
1543
1597
  this.applyPoseFromClip(clip, this.animationState.getCurrentFrame());
1598
+ if (evWatch !== null && evWatch === this.animationState.getCurrentAnimation()) {
1599
+ this.fireClipEvents(evWatch, evPrevFrame / FPS, this.animationState.getCurrentFrame() / FPS, 1);
1600
+ }
1601
+ }
1544
1602
  }
1545
1603
  }
1546
1604
  // Constant per-bone offsets compose after every pose source, before the
@@ -0,0 +1,64 @@
1
+ import type { Model } from "./model";
2
+ import type { BlendEntry } from "./animation";
3
+ export interface AnimStateDef {
4
+ /** Clip name previously loaded on the model. Mutually exclusive with `entries`. */
5
+ clip?: string;
6
+ /** Loop the clip (default true). Non-loop states hold their last frame. */
7
+ loop?: boolean;
8
+ /** Clip playback speed multiplier (default 1). */
9
+ speed?: number;
10
+ /** Delegate pose producer — return this frame's blend entries (e.g. a
11
+ * LocomotionController with autoApply: false). Return null to contribute
12
+ * nothing (the pose relaxes toward rest per setBlendPose semantics). */
13
+ entries?: (dt: number) => BlendEntry[] | null;
14
+ onEnter?: (from: string | null) => void;
15
+ onExit?: (to: string) => void;
16
+ }
17
+ export interface AnimTransitionDef {
18
+ /** Source state name, or "*" for any state (never fires into itself). */
19
+ from: string | "*";
20
+ to: string;
21
+ /** Condition, checked every update. Omitted = unconditional. */
22
+ when?: () => boolean;
23
+ /** Fire only once the state has been active this many seconds. On a clip
24
+ * state with NO `when` and NO `exitTime`, the transition fires when the
25
+ * (non-looping) clip approaches its end — the "skill finished, back to
26
+ * locomotion" pattern. */
27
+ exitTime?: number;
28
+ /** Crossfade seconds (default: machine's defaultFade). */
29
+ fade?: number;
30
+ }
31
+ export interface StateMachineOptions {
32
+ initial: string;
33
+ /** Crossfade used when a transition does not specify one (default 0.25). */
34
+ defaultFade?: number;
35
+ }
36
+ export declare class AnimationStateMachine {
37
+ private readonly model;
38
+ private readonly states;
39
+ private readonly transitions;
40
+ private readonly defaultFade;
41
+ private current;
42
+ /** Outgoing state during a crossfade — keeps playing while it fades. */
43
+ private fading;
44
+ private readonly merged;
45
+ constructor(model: Model, states: Record<string, AnimStateDef>, transitions: AnimTransitionDef[], options: StateMachineOptions);
46
+ get state(): string;
47
+ /** Seconds the current state has been active. */
48
+ get stateTime(): number;
49
+ /** Force a transition now, regardless of the transition table. */
50
+ go(to: string, fade?: number): void;
51
+ update(dt: number): void;
52
+ private transitionReady;
53
+ private begin;
54
+ /** This frame's entries for a state: clip states own a one-entry pose;
55
+ * delegate states produce their own. Returns null for "no pose". */
56
+ private produce;
57
+ private readonly inScratch;
58
+ private readonly outScratch;
59
+ /** Merge up to two entry lists scaled by their group weights into the stable
60
+ * scratch array and hand it to the model. */
61
+ private apply;
62
+ private clipDuration;
63
+ }
64
+ //# sourceMappingURL=state-machine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-machine.d.ts","sourceRoot":"","sources":["../src/state-machine.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAK7C,MAAM,WAAW,YAAY;IAC3B,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2EAA2E;IAC3E,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;6EAEyE;IACzE,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,UAAU,EAAE,GAAG,IAAI,CAAA;IAC7C,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;IACvC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,yEAAyE;IACzE,IAAI,EAAE,MAAM,GAAG,GAAG,CAAA;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,OAAO,CAAA;IACpB;;;+BAG2B;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAQD,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAO;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;IACrD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IAEpC,OAAO,CAAC,OAAO,CAAa;IAC5B,wEAAwE;IACxE,OAAO,CAAC,MAAM,CAAyE;IAIvF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;gBAE9B,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,WAAW,EAAE,iBAAiB,EAAE,EAAE,OAAO,EAAE,mBAAmB;IAW9H,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,iDAAiD;IACjD,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,kEAAkE;IAClE,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAInC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAgCxB,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,KAAK;IAYb;yEACqE;IACrE,OAAO,CAAC,OAAO;IAaf,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmD;IAC7E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmD;IAE9E;kDAC8C;IAC9C,OAAO,CAAC,KAAK;IAyBb,OAAO,CAAC,YAAY;CAIrB"}