rig-play 1.11.0 → 1.11.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.
@@ -1 +1 @@
1
- {"version":3,"file":"DomRenderer.d.ts","sourceRoot":"","sources":["../src/DomRenderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DomRenderer.d.ts","sourceRoot":"","sources":["../src/DomRenderer.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -7261,6 +7261,7 @@ class DomRenderer {
7261
7261
  if (!this.clipOnRoot) this.releaseRootClip();
7262
7262
  if (this.pendingJobs.length) {
7263
7263
  if (!blitter || !blitter.flush(this.pendingJobs)) {
7264
+ this.meshBackendActive = "canvas2d";
7264
7265
  for (let i = 0; i < this.pendingJobs.length; i++) {
7265
7266
  const job = this.pendingJobs[i];
7266
7267
  this.pendingViews[i].meshBackendDrawn = "canvas2d";
@@ -8776,6 +8777,116 @@ function applySetToPose(view, raw, set) {
8776
8777
  clips
8777
8778
  };
8778
8779
  }
8780
+ const SEEK_FINE_STEP_LIMIT = 4096;
8781
+ const SEEK_COARSE_STRIDE = 8;
8782
+ const SEEK_EXACT_LIMIT = 1024;
8783
+ function capturePhysicsContext(ctx) {
8784
+ const states = /* @__PURE__ */ new Map();
8785
+ for (const [name, s] of ctx.states) states.set(name, { ...s });
8786
+ return {
8787
+ phase: ctx.phase,
8788
+ time: ctx.time,
8789
+ last: ctx.last,
8790
+ loop: ctx.loop,
8791
+ env: ctx.env,
8792
+ states
8793
+ };
8794
+ }
8795
+ function restorePhysicsContext(ctx, snap) {
8796
+ ctx.phase = snap.phase;
8797
+ ctx.time = snap.time;
8798
+ ctx.last = snap.last;
8799
+ if (snap.loop === void 0) delete ctx.loop;
8800
+ else ctx.loop = snap.loop;
8801
+ if (snap.env === void 0) delete ctx.env;
8802
+ else ctx.env = snap.env;
8803
+ ctx.states.clear();
8804
+ for (const [name, s] of snap.states) ctx.states.set(name, { ...s });
8805
+ }
8806
+ function captureStepperState(stepper) {
8807
+ if ("first" in stepper) {
8808
+ const internal2 = stepper;
8809
+ return {
8810
+ kind: "track",
8811
+ steps: internal2.steps,
8812
+ latest: internal2.latest,
8813
+ refused: internal2.refused,
8814
+ trackTime: internal2.track.trackTime,
8815
+ last: internal2.track.last,
8816
+ ctx: capturePhysicsContext(internal2.track.ctx)
8817
+ };
8818
+ }
8819
+ const internal = stepper;
8820
+ const entry = internal.mixer.tracks[0] ?? null;
8821
+ return {
8822
+ kind: "tracks",
8823
+ started: internal.started,
8824
+ steps: internal.steps,
8825
+ time: internal.time,
8826
+ refused: internal.refused,
8827
+ animationsChanged: internal.mixer.animationsChanged,
8828
+ propertyIds: new Map(internal.mixer.propertyIds),
8829
+ entry: entry === null ? null : {
8830
+ delay: entry.delay,
8831
+ trackTime: entry.trackTime,
8832
+ trackLast: entry.trackLast,
8833
+ nextTrackLast: entry.nextTrackLast,
8834
+ trackEnd: entry.trackEnd,
8835
+ animationLast: entry.animationLast,
8836
+ nextAnimationLast: entry.nextAnimationLast,
8837
+ mixTime: entry.mixTime,
8838
+ mixDuration: entry.mixDuration,
8839
+ totalAlpha: entry.totalAlpha,
8840
+ alpha: entry.alpha,
8841
+ additive: entry.additive,
8842
+ keepHold: entry.keepHold,
8843
+ timelineMode: [...entry.timelineMode],
8844
+ timelineHoldMix: [...entry.timelineHoldMix],
8845
+ timelinesRotation: [...entry.timelinesRotation]
8846
+ },
8847
+ ctx: capturePhysicsContext(internal.path.ctx)
8848
+ };
8849
+ }
8850
+ function restoreStepperState(stepper, snap) {
8851
+ if (snap.kind === "track") {
8852
+ const internal2 = stepper;
8853
+ internal2.steps = snap.steps;
8854
+ internal2.latest = snap.latest;
8855
+ internal2.refused = snap.refused;
8856
+ internal2.track.trackTime = snap.trackTime;
8857
+ internal2.track.last = snap.last;
8858
+ restorePhysicsContext(internal2.track.ctx, snap.ctx);
8859
+ return;
8860
+ }
8861
+ const internal = stepper;
8862
+ internal.started = snap.started;
8863
+ internal.steps = snap.steps;
8864
+ internal.time = snap.time;
8865
+ internal.refused = snap.refused;
8866
+ internal.mixer.animationsChanged = snap.animationsChanged;
8867
+ internal.mixer.propertyIds.clear();
8868
+ for (const [k, v] of snap.propertyIds) internal.mixer.propertyIds.set(k, v);
8869
+ const entry = internal.mixer.tracks[0] ?? null;
8870
+ if (entry !== null && snap.entry !== null) {
8871
+ entry.delay = snap.entry.delay;
8872
+ entry.trackTime = snap.entry.trackTime;
8873
+ entry.trackLast = snap.entry.trackLast;
8874
+ entry.nextTrackLast = snap.entry.nextTrackLast;
8875
+ entry.trackEnd = snap.entry.trackEnd;
8876
+ entry.animationLast = snap.entry.animationLast;
8877
+ entry.nextAnimationLast = snap.entry.nextAnimationLast;
8878
+ entry.mixTime = snap.entry.mixTime;
8879
+ entry.mixDuration = snap.entry.mixDuration;
8880
+ entry.totalAlpha = snap.entry.totalAlpha;
8881
+ entry.alpha = snap.entry.alpha;
8882
+ entry.additive = snap.entry.additive;
8883
+ entry.keepHold = snap.entry.keepHold;
8884
+ entry.timelineMode = [...snap.entry.timelineMode];
8885
+ entry.timelineHoldMix = [...snap.entry.timelineHoldMix];
8886
+ entry.timelinesRotation = [...snap.entry.timelinesRotation];
8887
+ }
8888
+ restorePhysicsContext(internal.path.ctx, snap.ctx);
8889
+ }
8779
8890
  class RigPlayer {
8780
8891
  /**
8781
8892
  * The renderer this player draws through — its knobs and counters are the
@@ -8830,6 +8941,7 @@ class RigPlayer {
8830
8941
  /** The un-overridden pose from the track/tracks (or setup pose when `setSet` is called before `play`). */
8831
8942
  rawPose = null;
8832
8943
  setup = null;
8944
+ seekCache = null;
8833
8945
  setList;
8834
8946
  setsByName;
8835
8947
  activeSet = null;
@@ -8927,6 +9039,7 @@ class RigPlayer {
8927
9039
  const alpha = options.alpha ?? 1;
8928
9040
  const additive = options.additive ?? false;
8929
9041
  this.paused = false;
9042
+ this.clearSeekCache();
8930
9043
  const plain = track === 0 && mix === 0 && alpha === 1 && !additive;
8931
9044
  if (!plain) this.beyondBase = true;
8932
9045
  if (this.tracks === null && plain && !this.trackMode) {
@@ -8955,6 +9068,7 @@ class RigPlayer {
8955
9068
  queue(name, options = {}) {
8956
9069
  const track = options.track ?? 0;
8957
9070
  this.beyondBase = true;
9071
+ this.clearSeekCache();
8958
9072
  const tracks = this.compose();
8959
9073
  tracks.addAnimation(track, name, { loop: options.loop ?? true, mixDuration: options.mix ?? 0, delay: options.delay ?? 0, alpha: options.alpha ?? 1, additive: options.additive ?? false });
8960
9074
  this.trackCount = Math.max(this.trackCount, track + 1);
@@ -8967,6 +9081,7 @@ class RigPlayer {
8967
9081
  */
8968
9082
  clear(track = 0, options = {}) {
8969
9083
  this.beyondBase = true;
9084
+ this.clearSeekCache();
8970
9085
  const tracks = this.compose();
8971
9086
  tracks.setEmptyAnimation(track, options.mix ?? 0);
8972
9087
  this.trackCount = Math.max(this.trackCount, track + 1);
@@ -8980,6 +9095,7 @@ class RigPlayer {
8980
9095
  */
8981
9096
  queueClear(track = 0, options = {}) {
8982
9097
  this.beyondBase = true;
9098
+ this.clearSeekCache();
8983
9099
  const tracks = this.compose();
8984
9100
  tracks.addEmptyAnimation(track, options.mix ?? 0, options.delay ?? 0);
8985
9101
  this.trackCount = Math.max(this.trackCount, track + 1);
@@ -8994,6 +9110,7 @@ class RigPlayer {
8994
9110
  */
8995
9111
  setAlpha(track, alpha) {
8996
9112
  this.beyondBase = true;
9113
+ this.clearSeekCache();
8997
9114
  const tracks = this.compose();
8998
9115
  tracks.setAlpha(track, alpha);
8999
9116
  this.setRawPose(tracks.step(0));
@@ -9024,6 +9141,7 @@ class RigPlayer {
9024
9141
  */
9025
9142
  compose() {
9026
9143
  if (this.tracks !== null) return this.tracks;
9144
+ this.clearSeekCache();
9027
9145
  const tracks = openTracks(this.view, { reset: "animation", adjust: this.adjustHook, clock: physicsClockStep });
9028
9146
  const single = this.track;
9029
9147
  const time = single?.trackTime ?? 0;
@@ -9060,8 +9178,10 @@ class RigPlayer {
9060
9178
  environment(environment) {
9061
9179
  if (environment === null) {
9062
9180
  this.env = null;
9181
+ this.clearSeekCache();
9063
9182
  this.stepper()?.setEnvironment(DEFAULT_ENVIRONMENT);
9064
9183
  } else if (environment !== void 0) {
9184
+ this.clearSeekCache();
9065
9185
  const live = this.stepper();
9066
9186
  if (live) {
9067
9187
  live.setEnvironment(environment);
@@ -9100,20 +9220,99 @@ class RigPlayer {
9100
9220
  this.paused = false;
9101
9221
  }
9102
9222
  /**
9103
- * Moves a single animation on track 0 to `time`: the tracks are reopened
9104
- * with that animation and stepped forward in `seekStep` increments (the
9105
- * last one shorter) until the time is reached. Events and completes crossed
9106
- * on the way are not fired. It has a meaning for one animation on one
9107
- * track only — the player cannot replay when a mix, a second track or a
9108
- * queue was asked for — so after any of those it refuses by name; step the
9109
- * player forward instead.
9223
+ * Moves a single animation on track 0 to `time`: snapshot-backed deterministic
9224
+ * seek (#141) that produces the exact pose and physics state of reopening at 0
9225
+ * and stepping forward in `seekStep` increments (the last one shorter) until
9226
+ * `time` is reached. Events and completes crossed on the way are not fired.
9227
+ * It has a meaning for one animation on one track only — the player cannot
9228
+ * replay when a mix, a second track or a queue was asked for — so after any
9229
+ * of those it refuses by name; step the player forward instead.
9110
9230
  */
9111
9231
  seek(time) {
9112
9232
  if (this.animation === null) throw new Error("seek before play: no animation is open");
9113
9233
  if (!(time >= 0) || !Number.isFinite(time)) throw new Error(`seek time must be a finite time at or above 0, got ${String(time)}`);
9114
9234
  if (this.beyondBase) throw new Error("seek is defined for a single animation on track 0; after a mix, another track, a queue or a clear the player cannot replay to a time — step it forward with frame/advance instead");
9115
- this.reopen();
9116
- this.stepTo(time);
9235
+ const cache = this.ensureSeekCache();
9236
+ const stepper = this.tracks ?? this.track;
9237
+ const exactHit = cache.exact.get(time);
9238
+ if (exactHit !== void 0) {
9239
+ restoreStepperState(stepper, exactHit.state);
9240
+ this.rawPose = exactHit.rawPose;
9241
+ this.pose = exactHit.pose;
9242
+ return;
9243
+ }
9244
+ const steps = Math.floor(time / this.seekStep);
9245
+ while (cache.frontierSteps < steps) {
9246
+ const raw = cache.frontier.step(this.seekStep);
9247
+ cache.frontierSteps++;
9248
+ if (cache.frontierSteps <= SEEK_FINE_STEP_LIMIT || cache.frontierSteps % SEEK_COARSE_STRIDE === 0) {
9249
+ cache.grid.set(cache.frontierSteps, {
9250
+ state: captureStepperState(cache.frontier),
9251
+ rawPose: raw
9252
+ });
9253
+ }
9254
+ }
9255
+ const gridHit = cache.grid.get(steps);
9256
+ if (gridHit !== void 0) {
9257
+ restoreStepperState(stepper, gridHit.state);
9258
+ this.rawPose = gridHit.rawPose;
9259
+ } else {
9260
+ const baseStep = steps - steps % SEEK_COARSE_STRIDE;
9261
+ const baseSnap = cache.grid.get(baseStep);
9262
+ restoreStepperState(stepper, baseSnap.state);
9263
+ this.rawPose = baseSnap.rawPose;
9264
+ for (let i = baseStep; i < steps; i++) this.rawPose = stepper.step(this.seekStep);
9265
+ }
9266
+ const rest = time - stepper.trackTime;
9267
+ if (rest > 0) this.rawPose = stepper.step(rest);
9268
+ if (this.rawPose !== null) this.setRawPose(this.rawPose);
9269
+ if (this.rawPose !== null && this.pose !== null) {
9270
+ if (cache.exact.size >= SEEK_EXACT_LIMIT) {
9271
+ const oldest = cache.exact.keys().next().value;
9272
+ if (oldest !== void 0) cache.exact.delete(oldest);
9273
+ }
9274
+ cache.exact.set(time, {
9275
+ state: captureStepperState(stepper),
9276
+ rawPose: this.rawPose,
9277
+ pose: this.pose
9278
+ });
9279
+ }
9280
+ }
9281
+ clearSeekCache() {
9282
+ this.seekCache = null;
9283
+ }
9284
+ ensureSeekCache() {
9285
+ const mode = this.tracks !== null ? "tracks" : "track";
9286
+ if (this.seekCache !== null && this.seekCache.mode === mode) {
9287
+ return this.seekCache;
9288
+ }
9289
+ if (this.tracks === null && this.track === null) {
9290
+ this.reopen();
9291
+ }
9292
+ let frontier;
9293
+ let firstPose;
9294
+ if (mode === "tracks") {
9295
+ const tracks = openTracks(this.view, { reset: "animation", adjust: this.adjustHook, clock: physicsClockStep });
9296
+ tracks.setAnimation(0, this.animation, { loop: this.loop, mixDuration: 0 });
9297
+ firstPose = tracks.start();
9298
+ this.applyEnvironment(tracks);
9299
+ frontier = tracks;
9300
+ } else {
9301
+ const track = openTrack(this.view, this.animation, { loop: this.loop, reset: "animation", adjust: this.adjustHook, clock: physicsClockStep });
9302
+ firstPose = track.first;
9303
+ this.applyEnvironment(track);
9304
+ frontier = track;
9305
+ }
9306
+ const grid = /* @__PURE__ */ new Map();
9307
+ grid.set(0, { state: captureStepperState(frontier), rawPose: firstPose });
9308
+ this.seekCache = {
9309
+ mode,
9310
+ frontier,
9311
+ frontierSteps: 0,
9312
+ grid,
9313
+ exact: /* @__PURE__ */ new Map()
9314
+ };
9315
+ return this.seekCache;
9117
9316
  }
9118
9317
  /** Whatever is open, opened again with track 0's animation as `play` last set it, at pose 0: the single track, or the tracks under `tracks: true`. */
9119
9318
  reopen() {
@@ -9216,6 +9415,7 @@ class RigPlayer {
9216
9415
  this.source = frameSource(view, this.read.parsed);
9217
9416
  this.skinName = name;
9218
9417
  this.setup = null;
9418
+ this.clearSeekCache();
9219
9419
  if (this.animation !== null && (this.track !== null || this.tracks !== null)) {
9220
9420
  const time = this.time;
9221
9421
  this.reopen();
@@ -9258,6 +9458,7 @@ class RigPlayer {
9258
9458
  }
9259
9459
  if (name === null) {
9260
9460
  this.activeSet = null;
9461
+ this.clearSeekCache();
9261
9462
  const base2 = this.rawPose ?? (this.setup ?? (this.setup = poseRawSetup(this.view)));
9262
9463
  this.rawPose = base2;
9263
9464
  this.pose = base2;
@@ -9270,6 +9471,7 @@ class RigPlayer {
9270
9471
  );
9271
9472
  }
9272
9473
  this.activeSet = found;
9474
+ this.clearSeekCache();
9273
9475
  const base = this.rawPose ?? (this.setup ?? (this.setup = poseRawSetup(this.view)));
9274
9476
  this.rawPose = base;
9275
9477
  this.pose = applySetToPose(this.view, base, found);
@@ -9319,6 +9521,7 @@ class RigPlayer {
9319
9521
  set adjust(fn) {
9320
9522
  if (fn !== null && typeof fn !== "function") throw new Error(`adjust must be a function or null, got ${typeof fn}`);
9321
9523
  this.adjustFn = fn;
9524
+ this.clearSeekCache();
9322
9525
  this.repose();
9323
9526
  }
9324
9527
  /**
@@ -9329,6 +9532,7 @@ class RigPlayer {
9329
9532
  * changed, then `draw`. Nothing before `play`.
9330
9533
  */
9331
9534
  repose() {
9535
+ this.clearSeekCache();
9332
9536
  const stepper = this.tracks ?? this.track;
9333
9537
  if (stepper === null || this.pose === null) return;
9334
9538
  this.setRawPose(stepper.step(0));
@@ -9421,6 +9625,7 @@ class RigPlayer {
9421
9625
  /** Removes the renderer's elements and hands its GPU pages back. The assets stay the caller's. */
9422
9626
  dispose() {
9423
9627
  this.renderer.dispose();
9628
+ this.clearSeekCache();
9424
9629
  this.tracks = null;
9425
9630
  this.track = null;
9426
9631
  this.pose = null;