rig-play 1.9.1 → 1.9.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.
- package/README.md +4 -1
- package/dist/index.js +30 -9
- package/dist/index.js.map +1 -1
- package/dist/player.d.ts +5 -1
- package/dist/player.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -219,7 +219,10 @@ apart), `pause()` / `resume()` hold and release it, `timeScale` scales every
|
|
|
219
219
|
step, and `seek(t)` moves it to a time. A seek is "reopen, then step to the
|
|
220
220
|
time" in `seekStep` increments (1/60 s by default) — never a jump, because a
|
|
221
221
|
physics rig has history and its pose at a time depends on the steps that
|
|
222
|
-
reached it.
|
|
222
|
+
reached it. The physics integrates on rig-c's render clock (`physicsClockStep`:
|
|
223
|
+
each step and 2⁻³⁰ of it more), so stepping at a fixed rate — `frame(1/60)`, a
|
|
224
|
+
capture, a test — shows no single-frame spring jump where a frame ends on a
|
|
225
|
+
physics step; the animation, the events and `time` stay on the steps (#103). `on('event', …)` receives the event keys each step crosses, in the
|
|
223
226
|
runtime's order across a loop's wrap; `on('complete', …)` fires once a step
|
|
224
227
|
completes a cycle. `skin` (a constructor option) poses under a named skin;
|
|
225
228
|
without it the rig is posed the way a fresh Spine skeleton is, with no skin
|
package/dist/index.js
CHANGED
|
@@ -4927,6 +4927,17 @@ function setupPosed(doc, plant, mode) {
|
|
|
4927
4927
|
if (world === null || shown === null || setup.slots === null || setup.drawOrder === null) throw new CoreInputError("the raw setup pose was not posed");
|
|
4928
4928
|
return { world, shown, slots: setup.slots, drawOrder: setup.drawOrder };
|
|
4929
4929
|
}
|
|
4930
|
+
const PHYSICS_CLOCK_LEAD = 2 ** -30;
|
|
4931
|
+
function physicsClockStep(step) {
|
|
4932
|
+
return step + step * PHYSICS_CLOCK_LEAD;
|
|
4933
|
+
}
|
|
4934
|
+
function checkedClock(clock, who) {
|
|
4935
|
+
return (dt) => {
|
|
4936
|
+
const moved = clock(dt);
|
|
4937
|
+
if (typeof moved !== "number" || !Number.isFinite(moved) || moved < 0) throw new CoreInputError(`${who} clock moved the physics by ${String(moved)} for a step of ${dt}, not a finite time at or above 0`);
|
|
4938
|
+
return moved;
|
|
4939
|
+
};
|
|
4940
|
+
}
|
|
4930
4941
|
function loopedTime(trackTime, duration) {
|
|
4931
4942
|
return duration === 0 ? 0 : trackTime % duration;
|
|
4932
4943
|
}
|
|
@@ -5031,7 +5042,10 @@ function openTrack(doc, animation, options, plant = {}) {
|
|
|
5031
5042
|
if (typeof options !== "object" || options === null || typeof options.loop !== "boolean") throw new CoreInputError(`the live track's options.loop is ${JSON.stringify(options?.loop)}, not true or false`);
|
|
5032
5043
|
if (options.reset !== "animation" && options.reset !== "setup") throw new CoreInputError(`the live track's options.reset is ${JSON.stringify(options.reset)}, not "animation" or "setup"`);
|
|
5033
5044
|
if (options.adjust !== void 0 && typeof options.adjust !== "function") throw new CoreInputError(`the live track's options.adjust is ${typeof options.adjust}, not a function`);
|
|
5034
|
-
|
|
5045
|
+
if (options.clock !== void 0 && typeof options.clock !== "function") throw new CoreInputError(`the live track's options.clock is ${typeof options.clock}, not a function`);
|
|
5046
|
+
const mode = options.loop ? LOOPED : HELD;
|
|
5047
|
+
const clock = options.clock === void 0 ? void 0 : checkedClock(options.clock, "the live track's");
|
|
5048
|
+
const { track, first } = openRawTrack(doc, animation, plant, options.reset, clock === void 0 ? mode : { ...mode, clock: (dt) => clock(dt) }, options.adjust);
|
|
5035
5049
|
return new Track(track, first);
|
|
5036
5050
|
}
|
|
5037
5051
|
class Track {
|
|
@@ -5953,13 +5967,16 @@ function delayOf(v, call) {
|
|
|
5953
5967
|
function openTracks(doc, options, plant = {}) {
|
|
5954
5968
|
if (typeof options !== "object" || options === null || options.reset !== "animation" && options.reset !== "setup") throw new CoreInputError(`the live tracks' options.reset is ${JSON.stringify(options?.reset)}, not "animation" or "setup"`);
|
|
5955
5969
|
if (options.adjust !== void 0 && typeof options.adjust !== "function") throw new CoreInputError(`the live tracks' options.adjust is ${typeof options.adjust}, not a function`);
|
|
5956
|
-
|
|
5970
|
+
if (options.clock !== void 0 && typeof options.clock !== "function") throw new CoreInputError(`the live tracks' options.clock is ${typeof options.clock}, not a function`);
|
|
5971
|
+
const clock = options.clock === void 0 ? void 0 : checkedClock(options.clock, "the live tracks'");
|
|
5972
|
+
return new Tracks(doc, options.reset, options.adjust, clock, plant, openRawTracksPath(doc, plant));
|
|
5957
5973
|
}
|
|
5958
5974
|
class Tracks {
|
|
5959
|
-
constructor(doc, reset, adjust, plant, path) {
|
|
5975
|
+
constructor(doc, reset, adjust, clock, plant, path) {
|
|
5960
5976
|
this.doc = doc;
|
|
5961
5977
|
this.reset = reset;
|
|
5962
5978
|
this.adjust = adjust;
|
|
5979
|
+
this.clock = clock;
|
|
5963
5980
|
this.plant = plant;
|
|
5964
5981
|
this.path = path;
|
|
5965
5982
|
this.started = false;
|
|
@@ -6064,7 +6081,7 @@ class Tracks {
|
|
|
6064
6081
|
const { doc, path } = this;
|
|
6065
6082
|
const ctx = path.ctx;
|
|
6066
6083
|
const before = ctx.time;
|
|
6067
|
-
ctx.time += dt;
|
|
6084
|
+
ctx.time += this.clock === void 0 ? dt : this.clock(dt);
|
|
6068
6085
|
const pose = new Pose(doc, this.plant);
|
|
6069
6086
|
const animationTime = this.mixer.apply(pose);
|
|
6070
6087
|
const mixed = new Map(doc.slots.map((s, k) => [s.name, { deform: pose.slots[k].deform, seen: pose.slots[k].seen }]));
|
|
@@ -8582,7 +8599,7 @@ class RigPlayer {
|
|
|
8582
8599
|
if (this.tracks === null && plain && !this.trackMode) {
|
|
8583
8600
|
this.animation = name;
|
|
8584
8601
|
this.loop = loop;
|
|
8585
|
-
this.track = openTrack(this.view, name, { loop, reset: "animation", adjust: this.adjustHook });
|
|
8602
|
+
this.track = openTrack(this.view, name, { loop, reset: "animation", adjust: this.adjustHook, clock: physicsClockStep });
|
|
8586
8603
|
this.pose = this.track.first;
|
|
8587
8604
|
return;
|
|
8588
8605
|
}
|
|
@@ -8673,7 +8690,7 @@ class RigPlayer {
|
|
|
8673
8690
|
*/
|
|
8674
8691
|
compose() {
|
|
8675
8692
|
if (this.tracks !== null) return this.tracks;
|
|
8676
|
-
const tracks = openTracks(this.view, { reset: "animation", adjust: this.adjustHook });
|
|
8693
|
+
const tracks = openTracks(this.view, { reset: "animation", adjust: this.adjustHook, clock: physicsClockStep });
|
|
8677
8694
|
const single = this.track;
|
|
8678
8695
|
const time = single?.trackTime ?? 0;
|
|
8679
8696
|
if (single !== null && this.animation !== null) {
|
|
@@ -8713,14 +8730,14 @@ class RigPlayer {
|
|
|
8713
8730
|
/** 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`. */
|
|
8714
8731
|
reopen() {
|
|
8715
8732
|
if (this.tracks !== null) {
|
|
8716
|
-
const tracks = openTracks(this.view, { reset: "animation", adjust: this.adjustHook });
|
|
8733
|
+
const tracks = openTracks(this.view, { reset: "animation", adjust: this.adjustHook, clock: physicsClockStep });
|
|
8717
8734
|
tracks.setAnimation(0, this.animation, { loop: this.loop, mixDuration: 0 });
|
|
8718
8735
|
this.trackCount = 1;
|
|
8719
8736
|
this.tracks = tracks;
|
|
8720
8737
|
this.pose = tracks.start();
|
|
8721
8738
|
return;
|
|
8722
8739
|
}
|
|
8723
|
-
this.track = openTrack(this.view, this.animation, { loop: this.loop, reset: "animation", adjust: this.adjustHook });
|
|
8740
|
+
this.track = openTrack(this.view, this.animation, { loop: this.loop, reset: "animation", adjust: this.adjustHook, clock: physicsClockStep });
|
|
8724
8741
|
this.pose = this.track.first;
|
|
8725
8742
|
}
|
|
8726
8743
|
/** Steps whatever is open forward to `time` in `seekStep` increments, the last one shorter. */
|
|
@@ -8748,7 +8765,11 @@ class RigPlayer {
|
|
|
8748
8765
|
* Steps the track by `dt × timeScale` seconds and fires the step's listeners,
|
|
8749
8766
|
* without drawing. A paused player, or a step of zero, keeps the pose it
|
|
8750
8767
|
* holds without re-posing it, so a held rig costs the renderer's dirty
|
|
8751
|
-
* checks and nothing else.
|
|
8768
|
+
* checks and nothing else. The physics clock moves by `physicsClockStep`
|
|
8769
|
+
* of the step — the step and 2⁻³⁰ of it more, rig-c's render clock — so a
|
|
8770
|
+
* caller stepping at a fixed rate whose frame is a whole number of physics
|
|
8771
|
+
* steps (`frame(1/60)`, a capture) shows no spring jump; the animation time,
|
|
8772
|
+
* the events and `time` stay on the steps themselves (#103).
|
|
8752
8773
|
*/
|
|
8753
8774
|
advance(dt) {
|
|
8754
8775
|
if (this.pose === null) return;
|