rig-play 1.3.0 → 1.4.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/README.md +20 -5
- package/dist/DomTexture.d.ts +11 -1
- package/dist/DomTexture.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -4
- package/dist/index.js.map +1 -1
- package/dist/loadModel.d.ts +24 -4
- package/dist/loadModel.d.ts.map +1 -1
- package/dist/player.d.ts +18 -2
- package/dist/player.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -338,6 +338,23 @@ calling it twice is a no-op. Load once for the page's lifetime and you can
|
|
|
338
338
|
ignore it; load and unload repeatedly without it and you leak an atlas per
|
|
339
339
|
cycle.
|
|
340
340
|
|
|
341
|
+
### Loading for the canvas mode only, and `data:` regions
|
|
342
|
+
|
|
343
|
+
The region cut makes the rigid tier's bitmaps, which only the DOM mode draws.
|
|
344
|
+
`loadModel({ regions })` says what to do about it:
|
|
345
|
+
|
|
346
|
+
- `'blob'` (default) — `blob:` URLs the load owns; `assets.dispose()` frees them.
|
|
347
|
+
- `'data'` — `data:` URLs instead, for a content policy or a snapshot that does
|
|
348
|
+
not carry `blob:`. The same PNG bytes, inline; nothing is minted, so there is
|
|
349
|
+
nothing to free, and the base64 lives as long as the map does.
|
|
350
|
+
- `'none'` — no cut: the pages load, `assets.regionImages` is empty, and the
|
|
351
|
+
load is for the canvas mode. A DOM-mode player opened on it — `new RigPlayer`
|
|
352
|
+
without `mode: 'canvas'`, or `player.mode = 'dom'` — is refused by name, and
|
|
353
|
+
a refused mode change leaves the player as it was.
|
|
354
|
+
|
|
355
|
+
`assets.regions` records the choice. `unpackRegions` takes the same thing as
|
|
356
|
+
`{ encoding: 'blob' | 'data' }`.
|
|
357
|
+
|
|
341
358
|
### Pages that ship at another resolution
|
|
342
359
|
|
|
343
360
|
A page image may ship at a resolution its document does not declare — a
|
|
@@ -389,7 +406,8 @@ the page's own URL holds premultiplied pixels (see below).
|
|
|
389
406
|
### What unloading frees
|
|
390
407
|
|
|
391
408
|
`revokeRegions()` — and `assets.dispose()`, which calls it — frees the blob URLs
|
|
392
|
-
`unpackRegions` minted, and nothing else
|
|
409
|
+
`unpackRegions` minted, and nothing else (a `regions: 'data'` or `'none'` load
|
|
410
|
+
minted none, so it frees nothing). The page images are held by
|
|
393
411
|
`assets.pageImages` and by every player drawing from them, so a page is
|
|
394
412
|
released once you drop the assets and every player is disposed. With the
|
|
395
413
|
`webgl` mesh backend the shared blitter also uploads each page image on first
|
|
@@ -583,7 +601,7 @@ name, and unloading is still elements first, bitmaps second.
|
|
|
583
601
|
| holding a pose (the caller stopped advancing) | `player.pause()`, `player.resume()` | `frame` keeps drawing the held pose. |
|
|
584
602
|
| moving to a time (the caller's own, on the spine-core side) | `player.seek(time)`, `RigPlayerOptions.seekStep`, `player.time` | A seek reopens the animation and steps forward in `seekStep` increments (1/60 s by default). Events and completes crossed on the way are not fired. |
|
|
585
603
|
| events (the caller's own listener on the spine-core side) | `player.on('event', listener)`, `player.on('complete', listener)` | `'event'` hands a `RigEvent` (`name`, `time`, `int`, `float`, `string`); `'complete'` hands `{ animation }`. `on` returns a function that removes the listener. |
|
|
586
|
-
| skin (set by the caller on its `Skeleton`) | `RigPlayerOptions.skin` | A constructor option. The names are in `ModelAssets.skins`. Without it the rig is posed with no skin set. |
|
|
604
|
+
| skin (set by the caller on its `Skeleton`) | `RigPlayerOptions.skin`, `player.skin` | A constructor option, and settable on a live player since 1.4.0: the pose re-resolves under the new skin and the track keeps its animation, loop and time (reopened and stepped there, as `seek` does). The names are in `ModelAssets.skins`. Without it the rig is posed with no skin set. |
|
|
587
605
|
| `SpineHtmlRenderer` | `DomRenderer`, reached as `player.renderer` | In `mode: 'dom'`, the default. `mode: 'canvas'` is new and makes `player.renderer` a `CanvasRenderer`. |
|
|
588
606
|
| `new SpineHtmlRenderer(root, regionImages)` | `new DomRenderer(root, regionImages, pages?)` | Only for drawing your own frames; `RigPlayer` constructs its renderer. `pages` is the page-image map the mesh tier samples (`ModelAssets.pageImages`). A hand-built `regionImages` map is still accepted. |
|
|
589
607
|
| `renderer.render(skeleton)` | `renderer.render(frame)` | Takes a `PosedFrame`, not a skeleton. `player.posedFrame()` returns the one the player would draw. |
|
|
@@ -618,9 +636,6 @@ export, for which 1.0.0 declares nothing:
|
|
|
618
636
|
load, several players.
|
|
619
637
|
- **More than one track, mixing between animations, or queueing one after another.**
|
|
620
638
|
`RigPlayer` declares one track; `play` reopens it at the animation's first pose.
|
|
621
|
-
- **Changing the skin after construction.** `skin` is a `RigPlayerOptions` field and
|
|
622
|
-
`RigPlayer` declares no way to change it later; a second player over the same assets
|
|
623
|
-
is the declared route.
|
|
624
639
|
- **Changing one slot from code** (its attachment, its colour). `RigPlayer` declares only
|
|
625
640
|
the whole-rig `color`. The frame record is a plain object, so a caller that draws its
|
|
626
641
|
own frames through `DomRenderer.render` or `CanvasRenderer.render` decides what is in
|
package/dist/DomTexture.d.ts
CHANGED
|
@@ -90,6 +90,16 @@ export declare function straightAlphaDerivations(): number;
|
|
|
90
90
|
* happens once it has.
|
|
91
91
|
*/
|
|
92
92
|
export declare function straightAlphaSource(page: HTMLImageElement, pma: boolean): PageSource;
|
|
93
|
+
/**
|
|
94
|
+
* How a cut region's PNG is handed to the `<img>`: a `blob:` URL this module
|
|
95
|
+
* owns and `revokeRegions` frees (the default), or a `data:` URL that owns
|
|
96
|
+
* nothing and needs no revoke.
|
|
97
|
+
*/
|
|
98
|
+
export type RegionEncoding = 'blob' | 'data';
|
|
99
|
+
export interface UnpackRegionsOptions {
|
|
100
|
+
/** `'blob'` by default. */
|
|
101
|
+
encoding?: RegionEncoding;
|
|
102
|
+
}
|
|
93
103
|
/**
|
|
94
104
|
* Cuts every region of a page layout — a model document's `pages` section —
|
|
95
105
|
* out of its page image into its own bitmap once at load time, restoring 90°
|
|
@@ -151,7 +161,7 @@ export declare function straightAlphaSource(page: HTMLImageElement, pma: boolean
|
|
|
151
161
|
* unpackRegions() with a revokeRegions(); a caller that loads once for the
|
|
152
162
|
* page lifetime can ignore it.
|
|
153
163
|
*/
|
|
154
|
-
export declare function unpackRegions(pages: readonly PageLayout[], pageImages: ReadonlyMap<string, HTMLImageElement
|
|
164
|
+
export declare function unpackRegions(pages: readonly PageLayout[], pageImages: ReadonlyMap<string, HTMLImageElement>, options?: UnpackRegionsOptions): Promise<Map<string, RegionImage>>;
|
|
155
165
|
/**
|
|
156
166
|
* Frees the blob URLs unpackRegions minted for `images` — the counterpart of
|
|
157
167
|
* unpackRegions, to call once the skeletons using them are gone (after
|
package/dist/DomTexture.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DomTexture.d.ts","sourceRoot":"","sources":["../src/DomTexture.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;CAChC;AAQD,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;;;OASG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;CAChB;AAkBD;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAqC9D;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,EAAE,OAAO,GAAG,UAAU,CAcpF;
|
|
1
|
+
{"version":3,"file":"DomTexture.d.ts","sourceRoot":"","sources":["../src/DomTexture.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;CAChC;AAQD,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;;;OASG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;CAChB;AAkBD;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAqC9D;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,EAAE,OAAO,GAAG,UAAU,CAcpF;AAuSD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7C,MAAM,WAAW,oBAAoB;IACnC,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,EACjD,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CA4EnC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,IAAI,CAEpE"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { type CanvasBackend, CanvasRenderer, type CanvasViewport } from './CanvasRenderer.js';
|
|
2
2
|
export { DomRenderer, type MeshBackend } from './DomRenderer.js';
|
|
3
|
-
export { type PageLayout, type PageRegion, type RegionImage, revokeRegions, unpackRegions } from './DomTexture.js';
|
|
4
|
-
export { type LoadModelOptions, loadModel, type ModelAssets, type ModelDocument } from './loadModel.js';
|
|
3
|
+
export { type PageLayout, type PageRegion, type RegionEncoding, type RegionImage, revokeRegions, type UnpackRegionsOptions, unpackRegions } from './DomTexture.js';
|
|
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 PoseBounds, type RenderMode, type RigEvent, RigPlayer, type RigPlayerOptions } from './player.js';
|
|
6
6
|
export type { BlendMode, PosedClip, PosedFrame, PosedMesh, PosedRegion, PosedSlot, } from './posedFrame.js';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
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;AACjE,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,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,MAAM,kBAAkB,CAAC;AACjE,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,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACxL,YAAY,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,GACV,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5236,7 +5236,7 @@ function cutBackingPixels(placed, pageImages) {
|
|
|
5236
5236
|
const plan = planCut(placed, image);
|
|
5237
5237
|
return plan.cw * plan.ch;
|
|
5238
5238
|
}
|
|
5239
|
-
async function cutRegion(placed, pageImages) {
|
|
5239
|
+
async function cutRegion(placed, pageImages, encoding) {
|
|
5240
5240
|
const { region, page } = placed;
|
|
5241
5241
|
const image = pageImages.get(page.name);
|
|
5242
5242
|
if (!image) throw new Error(`Missing page image: ${page.name}`);
|
|
@@ -5255,6 +5255,7 @@ async function cutRegion(placed, pageImages) {
|
|
|
5255
5255
|
}
|
|
5256
5256
|
const source = straightAlphaSource(image, page.pma === true);
|
|
5257
5257
|
ctx.drawImage(source, plan.sx, plan.sy, plan.sw, plan.sh, 0, 0, plan.sw, plan.sh);
|
|
5258
|
+
if (encoding === "data") return { url: canvas.toDataURL("image/png"), width: w, height: h };
|
|
5258
5259
|
const blob = await new Promise((resolve, reject) => {
|
|
5259
5260
|
canvas.toBlob((b) => b ? resolve(b) : reject(new Error("toBlob failed")), "image/png");
|
|
5260
5261
|
});
|
|
@@ -5262,7 +5263,9 @@ async function cutRegion(placed, pageImages) {
|
|
|
5262
5263
|
ownedUrls.add(url);
|
|
5263
5264
|
return { url, width: w, height: h };
|
|
5264
5265
|
}
|
|
5265
|
-
async function unpackRegions(pages, pageImages) {
|
|
5266
|
+
async function unpackRegions(pages, pageImages, options = {}) {
|
|
5267
|
+
const encoding = options.encoding ?? "blob";
|
|
5268
|
+
if (encoding !== "blob" && encoding !== "data") throw new Error(`encoding must be 'blob' or 'data', got ${String(options.encoding)}`);
|
|
5266
5269
|
const regions = pages.flatMap((page) => page.regions.map((region) => ({ region, page })));
|
|
5267
5270
|
const cuts = new Array(regions.length);
|
|
5268
5271
|
let failedIndex = -1;
|
|
@@ -5283,7 +5286,7 @@ async function unpackRegions(pages, pageImages) {
|
|
|
5283
5286
|
const job = { done: false, promise: Promise.resolve() };
|
|
5284
5287
|
job.promise = (async () => {
|
|
5285
5288
|
try {
|
|
5286
|
-
cuts[index] = await cutRegion(region, pageImages);
|
|
5289
|
+
cuts[index] = await cutRegion(region, pageImages, encoding);
|
|
5287
5290
|
} catch (error) {
|
|
5288
5291
|
if (failedIndex === -1 || index < failedIndex) {
|
|
5289
5292
|
failedIndex = index;
|
|
@@ -7128,6 +7131,10 @@ async function loadModel(options) {
|
|
|
7128
7131
|
`${modelUrl} is a Spine export; this player reads a compiled model document (${CORE_DOCUMENT_SPECS[0]}, skeleton.model.json) — build it with \`rigc build\``
|
|
7129
7132
|
);
|
|
7130
7133
|
}
|
|
7134
|
+
const regions = options.regions ?? "blob";
|
|
7135
|
+
if (regions !== "blob" && regions !== "data" && regions !== "none") {
|
|
7136
|
+
throw new Error(`regions must be 'blob', 'data' or 'none', got ${String(options.regions)}`);
|
|
7137
|
+
}
|
|
7131
7138
|
const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
7132
7139
|
const resolvePage = options.resolvePage ?? resolveAgainstModel;
|
|
7133
7140
|
const read = readModelText(await fetchText(fetchImpl, modelUrl), modelUrl);
|
|
@@ -7138,13 +7145,14 @@ async function loadModel(options) {
|
|
|
7138
7145
|
pageImages.set(page.name, await loadImage(resolvePage(page.name, modelUrl), crossOrigin));
|
|
7139
7146
|
})
|
|
7140
7147
|
);
|
|
7141
|
-
const regionImages = await unpackRegions(pages, pageImages);
|
|
7148
|
+
const regionImages = regions === "none" ? /* @__PURE__ */ new Map() : await unpackRegions(pages, pageImages, { encoding: regions });
|
|
7142
7149
|
let disposed = false;
|
|
7143
7150
|
return {
|
|
7144
7151
|
spec: read.spec,
|
|
7145
7152
|
animations: read.doc.animations.map((a) => ({ name: a.name, duration: a.timelines.duration })),
|
|
7146
7153
|
skins: read.doc.skins.map((s) => s.name),
|
|
7147
7154
|
stage: stageOf(read.doc),
|
|
7155
|
+
regions,
|
|
7148
7156
|
regionImages,
|
|
7149
7157
|
pageImages,
|
|
7150
7158
|
document: read,
|
|
@@ -7311,6 +7319,8 @@ class RigPlayer {
|
|
|
7311
7319
|
meshBackend;
|
|
7312
7320
|
view;
|
|
7313
7321
|
source;
|
|
7322
|
+
read;
|
|
7323
|
+
skinName;
|
|
7314
7324
|
seekStep;
|
|
7315
7325
|
track = null;
|
|
7316
7326
|
animation = null;
|
|
@@ -7329,6 +7339,8 @@ class RigPlayer {
|
|
|
7329
7339
|
};
|
|
7330
7340
|
constructor(root, assets, options = {}) {
|
|
7331
7341
|
const read = assets.document;
|
|
7342
|
+
this.read = read;
|
|
7343
|
+
this.skinName = options.skin;
|
|
7332
7344
|
this.view = options.skin === void 0 ? underNoSkin(read.doc) : underSkin(read.doc, options.skin);
|
|
7333
7345
|
this.source = frameSource(this.view, read.parsed);
|
|
7334
7346
|
this.seekStep = options.seekStep ?? 1 / 60;
|
|
@@ -7367,6 +7379,11 @@ class RigPlayer {
|
|
|
7367
7379
|
return renderer2;
|
|
7368
7380
|
}
|
|
7369
7381
|
if (mode !== "dom") throw new Error(`mode must be 'dom' or 'canvas', got ${String(mode)}`);
|
|
7382
|
+
if (this.assets.regions === "none") {
|
|
7383
|
+
throw new Error(
|
|
7384
|
+
"these assets were loaded with regions: 'none' (no region bitmaps, for the canvas mode only); the DOM mode needs a load with regions 'blob' or 'data'"
|
|
7385
|
+
);
|
|
7386
|
+
}
|
|
7370
7387
|
const renderer = new DomRenderer(this.root, this.assets.regionImages, this.assets.pageImages);
|
|
7371
7388
|
if (this.meshBackend) renderer.meshBackend = this.meshBackend;
|
|
7372
7389
|
return renderer;
|
|
@@ -7406,6 +7423,10 @@ class RigPlayer {
|
|
|
7406
7423
|
if (this.animation === null) throw new Error("seek before play: no animation is open");
|
|
7407
7424
|
if (!(time >= 0) || !Number.isFinite(time)) throw new Error(`seek time must be a finite time at or above 0, got ${String(time)}`);
|
|
7408
7425
|
this.open();
|
|
7426
|
+
this.stepTo(time);
|
|
7427
|
+
}
|
|
7428
|
+
/** Steps the freshly opened track forward to `time` in `seekStep` increments, the last one shorter. */
|
|
7429
|
+
stepTo(time) {
|
|
7409
7430
|
const track = this.track;
|
|
7410
7431
|
const steps = Math.floor(time / this.seekStep);
|
|
7411
7432
|
for (let i = 0; i < steps; i++) this.pose = track.step(this.seekStep);
|
|
@@ -7445,6 +7466,32 @@ class RigPlayer {
|
|
|
7445
7466
|
if (this.pose === null) return;
|
|
7446
7467
|
this.renderer.render(this.posedFrame());
|
|
7447
7468
|
}
|
|
7469
|
+
/**
|
|
7470
|
+
* The skin the rig is posed under — `RigPlayerOptions.skin`, or undefined
|
|
7471
|
+
* for no skin set. Setting it re-resolves the pose under the new skin
|
|
7472
|
+
* (which attachment each slot shows, which bones and constraints are
|
|
7473
|
+
* active) and keeps the animation, its loop and its track time: the track
|
|
7474
|
+
* is reopened under the new skin and stepped to the same time the way
|
|
7475
|
+
* `seek` does, so a physics rig's history restarts there and nothing is
|
|
7476
|
+
* fired on the way. The pose is drawn on the next `draw`/`frame`. An
|
|
7477
|
+
* unknown skin is refused by name, and the player is left as it was.
|
|
7478
|
+
*/
|
|
7479
|
+
get skin() {
|
|
7480
|
+
return this.skinName;
|
|
7481
|
+
}
|
|
7482
|
+
set skin(name) {
|
|
7483
|
+
if (name === this.skinName) return;
|
|
7484
|
+
const view = name === void 0 ? underNoSkin(this.read.doc) : underSkin(this.read.doc, name);
|
|
7485
|
+
this.view = view;
|
|
7486
|
+
this.source = frameSource(view, this.read.parsed);
|
|
7487
|
+
this.skinName = name;
|
|
7488
|
+
this.setup = null;
|
|
7489
|
+
if (this.animation !== null && this.track !== null) {
|
|
7490
|
+
const time = this.track.trackTime;
|
|
7491
|
+
this.open();
|
|
7492
|
+
this.stepTo(time);
|
|
7493
|
+
}
|
|
7494
|
+
}
|
|
7448
7495
|
/**
|
|
7449
7496
|
* The per-pose adjustment of bone locals (`BoneAdjust`), or null for none.
|
|
7450
7497
|
* It is applied by every track the player opens — `play`, the reopen inside
|