spine-html 1.12.1 → 1.14.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 CHANGED
@@ -450,6 +450,42 @@ box, an inverse clip removes nothing, and bounding boxes, paths and points do
450
450
  not draw and do not count. Both cost nothing until called and read the same
451
451
  numbers in `dom` and `canvas` mode.
452
452
 
453
+ `readSetupMesh` reads a named mesh from loaded assets before or during playback,
454
+ including an attachment the setup pose does not select:
455
+
456
+ ```ts
457
+ import { readSetupMesh } from '@rig-c/play';
458
+
459
+ const mesh = readSetupMesh(assets, { slot: 'flag', attachment: 'alternate' });
460
+ // mesh: { slot, attachment, skin, vertices, triangles, hull }
461
+ // vertices: flat world x,y pairs, Y up; hull counts vertices, or is null.
462
+ ```
463
+
464
+ Names are exact slot names and attachment table keys, not display names or atlas
465
+ regions. Omitted or `null` skin means no skin set, as for a fresh player. A named
466
+ `skin` uses that skin's activation lists with default-table fallback; the returned
467
+ `skin` names the supplying table. `skin: 'all'` uses all activation lists and
468
+ refuses differing definitions rather than guessing a merge order. Linked meshes
469
+ retain the requested identity and borrow source topology/bindings; unweighted
470
+ vertices use the queried slot's bone. Inactive bones retain core's zero matrix.
471
+ The result and its arrays are detached and mutable. Missing slot/attachment/skin,
472
+ non-mesh and ambiguous targets throw core's named `CoreInputError` messages;
473
+ setup/non-finite refusals propagate unchanged. The read creates no player and
474
+ changes no document, existing player, time, generation or rendered frame.
475
+
476
+ **Setup-slider boundary (core 2.66.0):** selected meshes include setup-slider
477
+ deform, exactly as core's setup pose does. Unselected meshes use stored geometry
478
+ through the same setup constraint/reset-physics matrices, without switching the
479
+ attachment or borrowing another selection's deform. Core measured **four of six
480
+ nonselected official-runtime comparisons differing by up to
481
+ `2.9999999999999982` world units (about 3.0)**: spine-core 4.3.13's
482
+ `computeWorldVertices` borrows the selected slot's deform, including for a linked
483
+ mesh with `timelines: false`. The other two nonselected calls and all three
484
+ selected reads agree exactly. This wrapper passes core's output through; it does
485
+ not correct or round it. Stored-only formula comparisons therefore have a
486
+ different domain from selected geometry with setup deform. See
487
+ [core AUTHORING §14, including S1538_09](https://github.com/rig-c/core/blob/v2.66.0/docs/AUTHORING.md#14-read-a-named-mesh-at-setup).
488
+
453
489
  ### Drawing some slots only
454
490
 
455
491
  `slots` is a draw filter — an allow list of slot names or a predicate — settable up
@@ -649,6 +685,77 @@ firing events or drawing. A non-finite value, a bone the document does not have,
649
685
  or an error the function throws refuses that step in the core's words, and the
650
686
  track is reopened by the next `play` or `seek`.
651
687
 
688
+ The callback also receives a `BoneAdjustContext` from the core:
689
+
690
+ ```ts
691
+ player.adjust = (bones, ctx) => {
692
+ bones.bone('head').rotation = 12 * (ctx.trackTime ?? 0);
693
+ };
694
+ ```
695
+
696
+ `ctx.trackTime` is the **current track-0 entry's unwrapped seconds**, starting at
697
+ 0 for each new entry. Loops do not wrap it, and a nonlooping entry keeps counting
698
+ past its duration. `ctx.animation` names that entry. Without a track-0 entry both
699
+ are null; an explicit empty entry has **numeric trackTime and null animation**.
700
+ Upper tracks supply no fallback. `ctx.globalTime` is the core walk's running sum
701
+ of steps in seconds, so it can differ from a new entry's time. Neither clock is
702
+ wall time, wrapped animation time, nor the physics clock's small lead. Unary
703
+ callbacks remain compatible. The hook runs once after composition, including a
704
+ crossfade, rather than once for each contributing entry.
705
+
706
+ Seek evaluates its replay times (`seekStep` plus any final remainder), independent
707
+ of the currently displayed player time. Exact cache hits may reuse a pose without
708
+ calling the hook. A continuous walk and seek are bit-identical for an **unchanged
709
+ patch and matched history**: the same animation, environment, adjustment, reset
710
+ and step partition. Closed-over callback state still needs `repose()` or the
711
+ adjust setter to invalidate cached poses. Pause, zero advance and renderer mode
712
+ changes add no evaluations; explicit `repose()` keeps the same context time.
713
+
714
+ ### Live physics parameters
715
+
716
+ ```ts
717
+ player.play('hang');
718
+ player.setPhysicsParameters('link_1_phys', { damping: 0.4, wind: 8 });
719
+ player.readPhysicsParameters('link_1_phys'); // { override, effective }
720
+ player.clearPhysicsParameters('link_1_phys');
721
+ ```
722
+
723
+ `setPhysicsParameters(name, patch)` forwards a per-player patch of `strength`,
724
+ `damping`, `inertia`, `wind`, `gravity`, and `mix` to the core. Omitted fields keep
725
+ their standing override. Values are runtime scalars with no clamping, conversion,
726
+ new clock or solver. The core applies them **after authored/keyed values and
727
+ sliders, before the integrator**. Unknown constraints, a non-physics constraint,
728
+ unknown fields and non-finite/non-number values are refused atomically by name.
729
+ These methods require a live track: before `play`/`queue`, set, read and clear
730
+ refuse with `no live track` instead of creating one. The model and other players
731
+ sharing its assets are untouched.
732
+
733
+ `PhysicsParameterRead` contains detached readonly snapshots: `override` is the
734
+ pending patch or null; `effective` is the six values from the last active
735
+ evaluation, or null until evaluated. An inactive constraint can retain its last
736
+ active values within that live core instance. Setting or clearing changes no
737
+ pose, time or physics state, and **does not evaluate**: effective keeps the last
738
+ values until a normal evaluation (or an explicitly requested `repose()`). Clear
739
+ removes the patch; authored keys resume at the next evaluation. It preserves
740
+ integrated history and does not instantly undo the motion caused by old values.
741
+
742
+ The player retains the **current standing patch** across new play, seek, skin
743
+ replay and promotion to composed tracks. Like `environment()`, it records no
744
+ historical changes. **After a mid-run patch change, a backward seek recomputes the
745
+ past interval with the patch standing now**, under the current environment; it
746
+ does not reproduce the old trajectory across that change. New single tracks and
747
+ new composed tracks first evaluate their ordinary authored first pose, then
748
+ receive the standing patch as pending, with no extra adjustment callback. At
749
+ seek time 0, effective can therefore still be the initial authored value while
750
+ override already reports the patch. The next normal core evaluation uses it.
751
+ Changing entries on existing composed tracks follows that core instance's
752
+ lifetime. Existing seek/skin restrictions after composition remain unchanged.
753
+
754
+ Set/clear invalidate seek caches without re-posing. Seek snapshots retain the
755
+ public effective read alongside their held pose, so backward and exact cache
756
+ hits report that pose's evaluation rather than the frontier's latest evaluation.
757
+ Readback itself never advances, evaluates or resets physics.
758
+
652
759
  ### One load, several players
653
760
 
654
761
  One `loadModel` backs any number of players: the regions are cut once, and
@@ -1007,8 +1114,10 @@ name, and unloading is still elements first, bitmaps second.
1007
1114
  | dark (two-colour) tint: unsupported | `DomRenderer`: unsupported. `CanvasRenderer`: drawn | Carried as `dark` on a `PosedSlot`. The canvas mode's canvas2d fallback draws alpha only. |
1008
1115
  | `renderer.dispose()` | `player.dispose()` | Then `assets.dispose()`, as before. `DomRenderer.dispose()` and `CanvasRenderer.dispose()` exist for a renderer you constructed yourself. |
1009
1116
  | `skeleton.findBone('head').worldX`, `.worldY`, `.a` … `.d` | `player.bone('head')` | `{ x, y, a, b, c, d, rotationX, rotationY, scaleX, scaleY, active }`, the core's world transform for the pose the player holds (the setup pose before `play`). An unknown name is refused by name. Since 1.1.0. |
1010
- | `bone.scaleY = …` on a `Skeleton` between `state.apply` and `updateWorldTransform` | `RigPlayerOptions.adjust`, `player.adjust`, `player.repose()` | A function called once per pose with the pose's bone locals (`bones.bone('mouth').scaleY = v`). A write lasts one pose: the core poses every step from the setup pose, so write the value you want, every pose — nothing compounds. See *Adjusting bones*. Since 1.2.0. |
1117
+ | `bone.scaleY = …` on a `Skeleton` between `state.apply` and `updateWorldTransform` | `RigPlayerOptions.adjust`, `player.adjust`, `player.repose()` | A function `(bones, ctx)` called once per pose with the pose's bone locals and current-entry context (unary callbacks remain valid) (`bones.bone('mouth').scaleY = v`). A write lasts one pose: the core poses every step from the setup pose, so write the value you want, every pose — nothing compounds. See *Adjusting bones*. Since 1.2.0. |
1011
1118
  | `skeleton.getBounds(offset, size)` | `player.bounds()` | `{ x, y, width, height }` or null, world units, Y up: the box of every drawn region's corners and mesh's vertices, a slot under a clip counted inside the clip's own box. `ModelAssets.stage` remains the declared framing, not this box. Since 1.1.0. |
1119
+ | live named physics constraint tuning | `player.setPhysicsParameters(name, patch)`, `readPhysicsParameters(name)`, `clearPhysicsParameters(name)` | Six scalar fields, per-player pending patch plus last evaluated effective values. Clear resumes authored values without resetting history. Replay uses the current standing patch, with no historical journal. See *Live physics parameters*. |
1120
+ | named setup mesh geometry | `readSetupMesh(assets, { slot, attachment, skin? })` | Detached full-double world x/y (Y up), triangles and hull for any named mesh/linked mesh, including non-setup selections; no player/time mutation. Selected geometry includes setup-slider deform; unselected geometry is stored geometry through unchanged setup matrices. See the measured official-runtime distinction under *Reading the pose*. |
1012
1121
 
1013
1122
  ### No counterpart in 1.0.0
1014
1123
 
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, type MeshSourceRect } from './DomRenderer.js';
3
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, type RigSet } from './loadModel.js';
5
- export { type AdjustableBones, type BoneAdjust, type BoneLocals, type BoneWorld, type PlayOptions, type PoseBounds, type QueueOptions, type RenderMode, type RigComplete, type RigEnvironment, type RigEvent, RigPlayer, type RigPlayerOptions, type SlotFilter, type SlotIdentity, type SlotIdentityReason, type SlotIdentitySnapshot, type TrackEntry } from './player.js';
4
+ export { type LoadModelOptions, loadModel, type ModelAssets, type ModelDocument, readSetupMesh, type RegionLoading, type RigSet, type SetupMesh, type SetupMeshTarget } from './loadModel.js';
5
+ export { type AdjustableBones, type BoneAdjust, type BoneAdjustContext, type BoneLocals, type BoneWorld, type PhysicsParameters, type PhysicsParameterPatch, type PhysicsParameterRead, type PlayOptions, type PoseBounds, type QueueOptions, type RenderMode, type RigComplete, type RigEnvironment, type RigEvent, RigPlayer, type RigPlayerOptions, type SlotFilter, type SlotIdentity, type SlotIdentityReason, type SlotIdentitySnapshot, type TrackEntry } from './player.js';
6
6
  export type { BlendMode, PosedClip, PosedFrame, PosedMesh, PosedRegion, PosedSlot, } from './posedFrame.js';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -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,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,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACzI,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,cAAc,EAAE,KAAK,QAAQ,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC7W,YAAY,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,GACV,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,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,aAAa,EAAE,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC9L,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,KAAK,iBAAiB,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,KAAK,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,QAAQ,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AACpd,YAAY,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,GACV,MAAM,iBAAiB,CAAC"}