rig-play 1.9.0 → 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 +12 -2
- package/dist/CanvasRenderer.d.ts +3 -0
- package/dist/CanvasRenderer.d.ts.map +1 -1
- package/dist/DomRenderer.d.ts +12 -0
- package/dist/DomRenderer.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +58 -13
- 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
|
|
@@ -607,6 +610,12 @@ onto shared pages instead. Both play here, unchanged:
|
|
|
607
610
|
mesh once (no reallocation), so it is fine to expose as a user setting.
|
|
608
611
|
- `renderer.triangleExpand` — how far (canvas px) each triangle edge's clip is
|
|
609
612
|
moved outward to close antialiased mesh seams (default 0.5). Also re-rasters every mesh once when changed.
|
|
613
|
+
- `renderer.meshSourceRect` — what a canvas2d mesh triangle is drawn from:
|
|
614
|
+
`'page'` (the whole page) or `'triangle'` (a sub-rect covering its clip). Both
|
|
615
|
+
draw the same picture; the default is `'triangle'` on Linux WebKit, which
|
|
616
|
+
garbles whole-page draws, and `'page'` elsewhere, because macOS Safari ran the
|
|
617
|
+
sub-rect 12–15% slower (#25). Also on `CanvasRenderer` for its canvas2d
|
|
618
|
+
fallback. Re-rasters every mesh once when changed.
|
|
610
619
|
- `renderer.clipping` — apply the clips the frame carries (default `true`).
|
|
611
620
|
Which slots a clip covers is decided where the frame is made — the player's
|
|
612
621
|
adapter walks the draw order the way the runtime's draw loop does (one clip in
|
|
@@ -872,7 +881,8 @@ scenes (floors 0.585–1.553%, Chromium and WebKit). The DOM tier's two mesh
|
|
|
872
881
|
backends get the same A/B (`?backend=canvas2d` against `?backend=webgl`, at most
|
|
873
882
|
0.5%). Hairline seams are guarded by a deterministic canary (`?expand=0` must
|
|
874
883
|
change the canvas2d raster), the canvas2d source sub-rect by another (expand 32
|
|
875
|
-
against 8
|
|
884
|
+
against 8, forced to the sub-rect), the two source rects by an A/B that must
|
|
885
|
+
match exactly, and counter tests pin the dirty-skip / grow-only-backing /
|
|
876
886
|
clip-counter invariants plus the region corner order (BL, UL, UR, BR) and the
|
|
877
887
|
turned-region UVs, read off rig-c's pose against hand-written numbers.
|
|
878
888
|
|
package/dist/CanvasRenderer.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type MeshSourceRect } from './DomRenderer.js';
|
|
1
2
|
import type { PosedFrame } from './posedFrame.js';
|
|
2
3
|
/** What actually drew the last frame of a `CanvasRenderer`. */
|
|
3
4
|
export type CanvasBackend = 'webgl' | 'canvas2d';
|
|
@@ -69,6 +70,8 @@ export declare class CanvasRenderer {
|
|
|
69
70
|
viewport: CanvasViewport | null;
|
|
70
71
|
/** The backend to draw with: 'webgl' (default) through the shared context, or 'canvas2d' to force the fallback. */
|
|
71
72
|
backend: CanvasBackend;
|
|
73
|
+
/** What the canvas2d fallback draws each mesh triangle from — as `DomRenderer.meshSourceRect`, with the same default. */
|
|
74
|
+
meshSourceRect: MeshSourceRect;
|
|
72
75
|
/** What drew the last frame (or would have, had it not been reused). */
|
|
73
76
|
backendActive: CanvasBackend;
|
|
74
77
|
/** The visible canvas — the renderer's one element in the root. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CanvasRenderer.d.ts","sourceRoot":"","sources":["../src/CanvasRenderer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CanvasRenderer.d.ts","sourceRoot":"","sources":["../src/CanvasRenderer.ts"],"names":[],"mappings":"AAEA,OAAO,EAA+C,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGpG,OAAO,KAAK,EAAwB,UAAU,EAAa,MAAM,iBAAiB,CAAC;AAEnF,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,UAAU,CAAC;AAEjD,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAYD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBAAa,cAAc;IAuEvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAvExB;;;;;OAKG;IACH,UAAU,SAA+D;IACzE,6HAA6H;IAC7H,QAAQ,UAAQ;IAChB;;;;OAIG;IACH,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAQ;IACvC,mHAAmH;IACnH,OAAO,EAAE,aAAa,CAAW;IACjC,yHAAyH;IACzH,cAAc,EAAE,cAAc,CAA2B;IACzD,wEAAwE;IACxE,aAAa,EAAE,aAAa,CAAW;IACvC,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAEnC,8EAA8E;IAC9E,SAAS,SAAK;IACd,oEAAoE;IACpE,YAAY,SAAK;IACjB,iEAAiE;IACjE,cAAc,SAAK;IACnB,oFAAoF;IACpF,YAAY,SAAK;IACjB,yDAAyD;IACzD,KAAK,SAAK;IACV,wEAAwE;IACxE,kBAAkB,SAAK;IACvB,yCAAyC;IACzC,SAAS,SAAK;IACd,gIAAgI;IAChI,aAAa,SAAK;IAElB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAkC;IACtD,gHAAgH;IAChH,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,IAAI,CAA0B;IACtC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkB;IACvC,sFAAsF;IACtF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;IACvD,yGAAyG;IACzG,OAAO,CAAC,GAAG,CAAyB;IACpC,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,QAAQ,CAAiB;IAEjC;;;;;;OAMG;gBAEgB,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAgB/D,uGAAuG;IACvG;;;;;;;;OAQG;IACH,cAAc,IAAI,MAAM;IAKxB,OAAO,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI;IAIlC,uBAAuB;IACvB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAuD/B,+GAA+G;IAC/G,OAAO,IAAI,IAAI;IAYf,OAAO,CAAC,MAAM;IAkBd,OAAO,CAAC,OAAO;IAUf,oFAAoF;IACpF,OAAO,CAAC,WAAW;IAkBnB,uGAAuG;IACvG,OAAO,CAAC,gBAAgB;IAqExB,iFAAiF;IACjF,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,MAAM,CAAa;IAE3B;;;OAGG;IACH,OAAO,CAAC,QAAQ;IA4BhB,+CAA+C;IAC/C,OAAO,CAAC,aAAa;IAmErB,OAAO,CAAC,MAAM;CAmEf"}
|
package/dist/DomRenderer.d.ts
CHANGED
|
@@ -2,6 +2,12 @@ import { type RegionImage } from './DomTexture.js';
|
|
|
2
2
|
import type { PosedFrame } from './posedFrame.js';
|
|
3
3
|
/** Rasterizer used for the mesh (deform) tier. */
|
|
4
4
|
export type MeshBackend = 'canvas2d' | 'webgl';
|
|
5
|
+
/**
|
|
6
|
+
* What a canvas2d mesh triangle is drawn from: `'triangle'`, a source sub-rect
|
|
7
|
+
* of the page covering the triangle's clip, or `'page'`, the whole page. Both
|
|
8
|
+
* draw the same picture under the same clip; they differ in cost by engine.
|
|
9
|
+
*/
|
|
10
|
+
export type MeshSourceRect = 'triangle' | 'page';
|
|
5
11
|
/**
|
|
6
12
|
* Renders a posed frame (`PosedFrame`) as DOM, split by slot kind:
|
|
7
13
|
*
|
|
@@ -88,6 +94,12 @@ export declare class DomRenderer {
|
|
|
88
94
|
* to see them.
|
|
89
95
|
*/
|
|
90
96
|
triangleExpand: number;
|
|
97
|
+
/**
|
|
98
|
+
* What the canvas2d mesh backend draws each triangle from (`MeshSourceRect`):
|
|
99
|
+
* by default the sub-rect on Linux WebKit and the whole page elsewhere.
|
|
100
|
+
* Re-rasters every mesh once when changed.
|
|
101
|
+
*/
|
|
102
|
+
meshSourceRect: MeshSourceRect;
|
|
91
103
|
/**
|
|
92
104
|
* Mesh-canvas backing-store pixels per CSS pixel. Defaults to the device
|
|
93
105
|
* pixel ratio. If the caller scales the root element, fold that scale in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DomRenderer.d.ts","sourceRoot":"","sources":["../src/DomRenderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,WAAW,EAAuB,MAAM,iBAAiB,CAAC;AAEzF,OAAO,KAAK,EAAwB,UAAU,EAAqC,MAAM,iBAAiB,CAAC;AAE3G,kDAAkD;AAClD,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"DomRenderer.d.ts","sourceRoot":"","sources":["../src/DomRenderer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { type CanvasBackend, CanvasRenderer, type CanvasViewport } from './CanvasRenderer.js';
|
|
2
|
-
export { DomRenderer, type MeshBackend } from './DomRenderer.js';
|
|
2
|
+
export { DomRenderer, type MeshBackend, type MeshSourceRect } from './DomRenderer.js';
|
|
3
3
|
export { type PageLayout, type PageRegion, type RegionEncoding, type RegionImage, revokeRegions, type UnpackRegionsOptions, unpackRegions } from './DomTexture.js';
|
|
4
4
|
export { type LoadModelOptions, loadModel, type ModelAssets, type ModelDocument, type RegionLoading } from './loadModel.js';
|
|
5
5
|
export { type AdjustableBones, type BoneAdjust, type BoneLocals, type BoneWorld, type PlayOptions, type PoseBounds, type QueueOptions, type RenderMode, type RigComplete, type RigEvent, RigPlayer, type RigPlayerOptions, type SlotFilter, type TrackEntry } from './player.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACtF,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACnK,OAAO,EAAE,KAAK,gBAAgB,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5H,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AACjR,YAAY,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,GACV,MAAM,iBAAiB,CAAC"}
|
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 }]));
|
|
@@ -6842,6 +6859,10 @@ function getMeshGlBlitter() {
|
|
|
6842
6859
|
}
|
|
6843
6860
|
return shared && !shared.lost ? shared : null;
|
|
6844
6861
|
}
|
|
6862
|
+
function defaultMeshSourceRect(userAgent = typeof navigator === "object" ? navigator.userAgent : "") {
|
|
6863
|
+
const linuxWebKit = /AppleWebKit/.test(userAgent) && /Linux|X11/.test(userAgent) && !/Android|Chrome|Chromium|CriOS|Edg/.test(userAgent);
|
|
6864
|
+
return linuxWebKit ? "triangle" : "page";
|
|
6865
|
+
}
|
|
6845
6866
|
const regionVertices = new Float32Array(8);
|
|
6846
6867
|
const SVG_NS = "http://www.w3.org/2000/svg";
|
|
6847
6868
|
let tintFilterSeq = 0;
|
|
@@ -6965,6 +6986,12 @@ class DomRenderer {
|
|
|
6965
6986
|
* to see them.
|
|
6966
6987
|
*/
|
|
6967
6988
|
triangleExpand = 0.5;
|
|
6989
|
+
/**
|
|
6990
|
+
* What the canvas2d mesh backend draws each triangle from (`MeshSourceRect`):
|
|
6991
|
+
* by default the sub-rect on Linux WebKit and the whole page elsewhere.
|
|
6992
|
+
* Re-rasters every mesh once when changed.
|
|
6993
|
+
*/
|
|
6994
|
+
meshSourceRect = defaultMeshSourceRect();
|
|
6968
6995
|
/**
|
|
6969
6996
|
* Mesh-canvas backing-store pixels per CSS pixel. Defaults to the device
|
|
6970
6997
|
* pixel ratio. If the caller scales the root element, fold that scale in
|
|
@@ -7238,7 +7265,7 @@ class DomRenderer {
|
|
|
7238
7265
|
const ratio = this.pixelRatio;
|
|
7239
7266
|
const uvs = slot.uvs;
|
|
7240
7267
|
const triangles = slot.triangles;
|
|
7241
|
-
let dirty = view.meshUvs !== uvs || view.meshTriangles !== triangles || view.meshPage !== page || view.meshSequenceIndex !== sequenceIndex || view.meshExpand !== this.triangleExpand || view.meshVertexCount !== count || view.meshBackendDrawn !== this.meshBackendActive;
|
|
7268
|
+
let dirty = view.meshUvs !== uvs || view.meshTriangles !== triangles || view.meshPage !== page || view.meshSequenceIndex !== sequenceIndex || view.meshExpand !== this.triangleExpand || view.meshSourceRect !== this.meshSourceRect || view.meshVertexCount !== count || view.meshBackendDrawn !== this.meshBackendActive;
|
|
7242
7269
|
const needW = Math.max(1, Math.round(w * ratio));
|
|
7243
7270
|
const needH = Math.max(1, Math.round(h * ratio));
|
|
7244
7271
|
const ratioChanged = view.meshRatio !== ratio;
|
|
@@ -7278,6 +7305,7 @@ class DomRenderer {
|
|
|
7278
7305
|
view.meshPage = page;
|
|
7279
7306
|
view.meshSequenceIndex = sequenceIndex;
|
|
7280
7307
|
view.meshExpand = this.triangleExpand;
|
|
7308
|
+
view.meshSourceRect = this.meshSourceRect;
|
|
7281
7309
|
view.meshVertexCount = count;
|
|
7282
7310
|
view.meshBackendDrawn = this.meshBackendActive;
|
|
7283
7311
|
if (this.meshBackendActive === "webgl") {
|
|
@@ -7410,7 +7438,7 @@ class DomRenderer {
|
|
|
7410
7438
|
* class of offset the `uv * size` addressing removes.
|
|
7411
7439
|
*/
|
|
7412
7440
|
drawTriangle(ctx, img, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2) {
|
|
7413
|
-
drawTexturedTriangle(ctx, img, this.triangleExpand, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
|
|
7441
|
+
drawTexturedTriangle(ctx, img, this.triangleExpand, this.meshSourceRect, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
|
|
7414
7442
|
}
|
|
7415
7443
|
// --- clipping tier ---------------------------------------------------------
|
|
7416
7444
|
/**
|
|
@@ -7636,6 +7664,7 @@ class DomRenderer {
|
|
|
7636
7664
|
meshPage: null,
|
|
7637
7665
|
meshSequenceIndex: -1,
|
|
7638
7666
|
meshExpand: -1,
|
|
7667
|
+
meshSourceRect: "",
|
|
7639
7668
|
meshVertexCount: -1,
|
|
7640
7669
|
meshBackendDrawn: "",
|
|
7641
7670
|
meshVertices: new Float64Array(0),
|
|
@@ -7654,7 +7683,7 @@ class DomRenderer {
|
|
|
7654
7683
|
this.setClipPath(view, "");
|
|
7655
7684
|
}
|
|
7656
7685
|
}
|
|
7657
|
-
function drawTexturedTriangle(ctx, img, expand, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2) {
|
|
7686
|
+
function drawTexturedTriangle(ctx, img, expand, sourceRect, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2) {
|
|
7658
7687
|
const corners = offsetTriangle(x0, y0, x1, y1, x2, y2, expand);
|
|
7659
7688
|
const px0 = corners[0], py0 = corners[1];
|
|
7660
7689
|
const px1 = corners[2], py1 = corners[3];
|
|
@@ -7677,6 +7706,14 @@ function drawTexturedTriangle(ctx, img, expand, x0, y0, u0, v0, x1, y1, u1, v1,
|
|
|
7677
7706
|
const d = (eu1 * ey2 - eu2 * ey1) * det;
|
|
7678
7707
|
const e = x0 - a * u0 - c * v0;
|
|
7679
7708
|
const f = y0 - b * u0 - d * v0;
|
|
7709
|
+
if (sourceRect === "page") {
|
|
7710
|
+
ctx.save();
|
|
7711
|
+
ctx.transform(a, b, c, d, e, f);
|
|
7712
|
+
ctx.clip();
|
|
7713
|
+
ctx.drawImage(img, 0, 0);
|
|
7714
|
+
ctx.restore();
|
|
7715
|
+
return;
|
|
7716
|
+
}
|
|
7680
7717
|
let minU = Math.min(u0, u1, u2);
|
|
7681
7718
|
let maxU = Math.max(u0, u1, u2);
|
|
7682
7719
|
let minV = Math.min(v0, v1, v2);
|
|
@@ -7768,6 +7805,8 @@ class CanvasRenderer {
|
|
|
7768
7805
|
viewport = null;
|
|
7769
7806
|
/** The backend to draw with: 'webgl' (default) through the shared context, or 'canvas2d' to force the fallback. */
|
|
7770
7807
|
backend = "webgl";
|
|
7808
|
+
/** What the canvas2d fallback draws each mesh triangle from — as `DomRenderer.meshSourceRect`, with the same default. */
|
|
7809
|
+
meshSourceRect = defaultMeshSourceRect();
|
|
7771
7810
|
/** What drew the last frame (or would have, had it not been reused). */
|
|
7772
7811
|
backendActive = "webgl";
|
|
7773
7812
|
/** The visible canvas — the renderer's one element in the root. */
|
|
@@ -7941,7 +7980,8 @@ class CanvasRenderer {
|
|
|
7941
7980
|
this.nextSig = grown;
|
|
7942
7981
|
}
|
|
7943
7982
|
};
|
|
7944
|
-
need(
|
|
7983
|
+
need(9);
|
|
7984
|
+
sig[n++] = this.meshSourceRect === "triangle" ? 1 : 0;
|
|
7945
7985
|
sig[n++] = this.left;
|
|
7946
7986
|
sig[n++] = this.top;
|
|
7947
7987
|
sig[n++] = this.backingW;
|
|
@@ -8156,6 +8196,7 @@ class CanvasRenderer {
|
|
|
8156
8196
|
ctx,
|
|
8157
8197
|
source,
|
|
8158
8198
|
0.5,
|
|
8199
|
+
this.meshSourceRect,
|
|
8159
8200
|
X(vertices[i0]),
|
|
8160
8201
|
Y(vertices[i0 + 1]),
|
|
8161
8202
|
uvs[i0] * uw,
|
|
@@ -8558,7 +8599,7 @@ class RigPlayer {
|
|
|
8558
8599
|
if (this.tracks === null && plain && !this.trackMode) {
|
|
8559
8600
|
this.animation = name;
|
|
8560
8601
|
this.loop = loop;
|
|
8561
|
-
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 });
|
|
8562
8603
|
this.pose = this.track.first;
|
|
8563
8604
|
return;
|
|
8564
8605
|
}
|
|
@@ -8649,7 +8690,7 @@ class RigPlayer {
|
|
|
8649
8690
|
*/
|
|
8650
8691
|
compose() {
|
|
8651
8692
|
if (this.tracks !== null) return this.tracks;
|
|
8652
|
-
const tracks = openTracks(this.view, { reset: "animation", adjust: this.adjustHook });
|
|
8693
|
+
const tracks = openTracks(this.view, { reset: "animation", adjust: this.adjustHook, clock: physicsClockStep });
|
|
8653
8694
|
const single = this.track;
|
|
8654
8695
|
const time = single?.trackTime ?? 0;
|
|
8655
8696
|
if (single !== null && this.animation !== null) {
|
|
@@ -8689,14 +8730,14 @@ class RigPlayer {
|
|
|
8689
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`. */
|
|
8690
8731
|
reopen() {
|
|
8691
8732
|
if (this.tracks !== null) {
|
|
8692
|
-
const tracks = openTracks(this.view, { reset: "animation", adjust: this.adjustHook });
|
|
8733
|
+
const tracks = openTracks(this.view, { reset: "animation", adjust: this.adjustHook, clock: physicsClockStep });
|
|
8693
8734
|
tracks.setAnimation(0, this.animation, { loop: this.loop, mixDuration: 0 });
|
|
8694
8735
|
this.trackCount = 1;
|
|
8695
8736
|
this.tracks = tracks;
|
|
8696
8737
|
this.pose = tracks.start();
|
|
8697
8738
|
return;
|
|
8698
8739
|
}
|
|
8699
|
-
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 });
|
|
8700
8741
|
this.pose = this.track.first;
|
|
8701
8742
|
}
|
|
8702
8743
|
/** Steps whatever is open forward to `time` in `seekStep` increments, the last one shorter. */
|
|
@@ -8724,7 +8765,11 @@ class RigPlayer {
|
|
|
8724
8765
|
* Steps the track by `dt × timeScale` seconds and fires the step's listeners,
|
|
8725
8766
|
* without drawing. A paused player, or a step of zero, keeps the pose it
|
|
8726
8767
|
* holds without re-posing it, so a held rig costs the renderer's dirty
|
|
8727
|
-
* 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).
|
|
8728
8773
|
*/
|
|
8729
8774
|
advance(dt) {
|
|
8730
8775
|
if (this.pose === null) return;
|