spine-rigc 1.5.3 → 1.6.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 +2 -1
- package/cli.ts +131 -403
- package/docs/AUTHORING.md +63 -14
- package/docs/INGEST.md +1 -0
- package/docs/MOTION.md +1 -0
- package/package.json +1 -1
- package/src/atlas.ts +25 -0
- package/src/check.ts +113 -24
- package/src/checkpics.ts +2 -0
- package/src/compile.ts +641 -506
- package/src/core/animation.ts +982 -0
- package/src/core/clipping.ts +696 -0
- package/src/core/constraints.ts +1721 -0
- package/src/core/constraints_path.ts +942 -0
- package/src/core/constraints_physics.ts +830 -0
- package/src/core/constraints_slider.ts +505 -0
- package/src/core/deform.ts +613 -0
- package/src/core/draw_order.ts +125 -0
- package/src/core/events.ts +135 -0
- package/src/core/hooks.ts +249 -0
- package/src/core/index.ts +1103 -0
- package/src/core/raw.ts +347 -0
- package/src/core/skins.ts +104 -0
- package/src/core/uvs.ts +448 -0
- package/src/core/vertices.ts +490 -0
- package/src/core/world.ts +233 -0
- package/src/deformmeasure.ts +337 -73
- package/src/deformreport.ts +370 -0
- package/src/depth.ts +101 -2
- package/src/emit_spine.ts +860 -0
- package/src/mesh.ts +24 -15
- package/src/model.ts +958 -0
- package/src/render.ts +649 -143
- package/src/render_core.ts +582 -0
- package/src/rig.ts +34 -6
- package/src/transform.ts +26 -4
- package/src/types.ts +18 -0
- package/src/validate.ts +30 -2
package/src/transform.ts
CHANGED
|
@@ -31,7 +31,29 @@
|
|
|
31
31
|
* wrong. `computeWorldTransforms` below is `BonePose.updateWorldTransform`
|
|
32
32
|
* (spine-core 4.3.13, `BonePose.js:110-216`) at setup, with a skeleton scale of 1.
|
|
33
33
|
*/
|
|
34
|
-
|
|
34
|
+
/**
|
|
35
|
+
* What `computeWorldTransforms` reads off a bone — a structural type, so both a
|
|
36
|
+
* Spine bone (`SpineBone`, what spine-parts and every skeleton reader hold) and
|
|
37
|
+
* a compiled-model bone (`ModelBone`, what `compile` holds) satisfy it as they
|
|
38
|
+
* are, without a cast.
|
|
39
|
+
*
|
|
40
|
+
* The two differ in one key, the inherit mode: Spine 4.3 spells it `inherit`
|
|
41
|
+
* and the model `inheritMode`. The union below admits exactly one of the two on
|
|
42
|
+
* any one bone (the other is `never`), so a bone carrying both is a type error
|
|
43
|
+
* rather than a question of which one wins, and the mode is read as
|
|
44
|
+
* `inheritMode ?? inherit` — whichever the bone has.
|
|
45
|
+
*/
|
|
46
|
+
export type PosableBone = {
|
|
47
|
+
name: string;
|
|
48
|
+
parent?: string;
|
|
49
|
+
x?: number;
|
|
50
|
+
y?: number;
|
|
51
|
+
rotation?: number;
|
|
52
|
+
scaleX?: number;
|
|
53
|
+
scaleY?: number;
|
|
54
|
+
shearX?: number;
|
|
55
|
+
shearY?: number;
|
|
56
|
+
} & ({ inherit?: string; inheritMode?: never } | { inheritMode?: string; inherit?: never });
|
|
35
57
|
|
|
36
58
|
export interface BoneTransform {
|
|
37
59
|
a: number;
|
|
@@ -79,7 +101,7 @@ export function cropToSpineY(cropY: number, cropHeight: number): number {
|
|
|
79
101
|
* inheriting rig emits moves by a byte. The five `inherit` cases are the
|
|
80
102
|
* runtime's, transcribed.
|
|
81
103
|
*/
|
|
82
|
-
export function computeWorldTransforms(bones:
|
|
104
|
+
export function computeWorldTransforms(bones: readonly PosableBone[]): Map<string, BoneTransform> {
|
|
83
105
|
const out = new Map<string, BoneTransform>();
|
|
84
106
|
for (const bone of bones) {
|
|
85
107
|
const rotation = bone.rotation ?? 0;
|
|
@@ -144,8 +166,8 @@ const INHERIT_MODES: readonly InheritMode[] = ['normal', 'onlyTranslation', 'noR
|
|
|
144
166
|
* leaves the matrix where it was, and the rig spec's parse refuses that
|
|
145
167
|
* spelling first (issue #733), so reaching this throw is rigc's own defect.
|
|
146
168
|
*/
|
|
147
|
-
function inheritMode(bone:
|
|
148
|
-
const value = bone.inherit;
|
|
169
|
+
function inheritMode(bone: PosableBone): InheritMode {
|
|
170
|
+
const value = bone.inheritMode ?? bone.inherit;
|
|
149
171
|
if (value === undefined) return 'normal';
|
|
150
172
|
const folded = value.length === 0 ? value : value[0].toLowerCase() + value.slice(1);
|
|
151
173
|
const mode = INHERIT_MODES.find((m) => m === folded);
|
package/src/types.ts
CHANGED
|
@@ -19,6 +19,7 @@ import type { DeformTransform, DeformTransformReport } from './deformgen.ts';
|
|
|
19
19
|
import type { TurnCeiling } from './depth.ts';
|
|
20
20
|
import type { SpecEnumTable, SpecTypeRow } from './keys.ts';
|
|
21
21
|
import type { MeshKind } from './mesh.ts';
|
|
22
|
+
import type { CompiledModel } from './model.ts';
|
|
22
23
|
import type { TrackDerive, TrackDeriveReport } from './trackgen.ts';
|
|
23
24
|
|
|
24
25
|
// ---------------------------------------------------------------------------
|
|
@@ -1320,6 +1321,12 @@ export interface SpineSkeletonJson {
|
|
|
1320
1321
|
>;
|
|
1321
1322
|
}
|
|
1322
1323
|
|
|
1324
|
+
/** One entry of the emitted `skins` array — what `emitSkins` in `src/emit_spine.ts` writes per skin. */
|
|
1325
|
+
export type SpineSkin = SpineSkeletonJson['skins'][number];
|
|
1326
|
+
|
|
1327
|
+
/** One animation of the emitted `animations` object — what `emitAnimations` in `src/emit_spine.ts` writes per animation. */
|
|
1328
|
+
export type SpineAnimation = SpineSkeletonJson['animations'][string];
|
|
1329
|
+
|
|
1323
1330
|
/** One entry of the emitted `events` map: the payload a firing inherits. */
|
|
1324
1331
|
export interface SpineEvent {
|
|
1325
1332
|
int?: number;
|
|
@@ -1550,6 +1557,17 @@ export interface DroppedState {
|
|
|
1550
1557
|
}
|
|
1551
1558
|
|
|
1552
1559
|
export interface CompileResult {
|
|
1560
|
+
/**
|
|
1561
|
+
* The compiled model (`src/model.ts`): what the skeleton below was emitted
|
|
1562
|
+
* from. This cut fills its `bones` and `setupWorld`; every other field is
|
|
1563
|
+
* this result's own, carried by reference.
|
|
1564
|
+
*/
|
|
1565
|
+
model: CompiledModel;
|
|
1566
|
+
/**
|
|
1567
|
+
* The Spine 4.3 skeleton: `emitSkeleton`'s value over `model` (issue #922),
|
|
1568
|
+
* the one call the assembly makes. `build` writes its text, and beside it
|
|
1569
|
+
* `modelDocument(model)` as `skeleton.model.json`.
|
|
1570
|
+
*/
|
|
1553
1571
|
skeleton: SpineSkeletonJson;
|
|
1554
1572
|
skeletonText: string;
|
|
1555
1573
|
atlasText: string;
|
package/src/validate.ts
CHANGED
|
@@ -355,8 +355,14 @@ export interface ValidateInput {
|
|
|
355
355
|
atlasDir: string;
|
|
356
356
|
/** Declared durations from the motion spec. */
|
|
357
357
|
declaredDurations?: Record<string, number>;
|
|
358
|
-
/**
|
|
359
|
-
|
|
358
|
+
/**
|
|
359
|
+
* The compiled model's document (`modelDocument`, `rigc-compiled/1`) — the
|
|
360
|
+
* third file `build` writes. Required whenever `reEmit` is given, since `A18`
|
|
361
|
+
* compares it with the second compile's (issue #922).
|
|
362
|
+
*/
|
|
363
|
+
modelText?: string;
|
|
364
|
+
/** Re-emitted artifacts, for the determinism check: a second, independent compile's three texts. */
|
|
365
|
+
reEmit?: { skeletonText: string; atlasText: string; modelText: string };
|
|
360
366
|
/**
|
|
361
367
|
* Structural expectations the artifact cannot state about itself: which mesh is
|
|
362
368
|
* a ribbon, which bone carries the axis, which parentage is forbidden, what the
|
|
@@ -1123,6 +1129,19 @@ export function timelineAddBehaviour(data: ReturnType<SkeletonJson['readSkeleton
|
|
|
1123
1129
|
return wrote ? 'overwrites' : 'inert';
|
|
1124
1130
|
}
|
|
1125
1131
|
|
|
1132
|
+
/**
|
|
1133
|
+
* Where two texts first differ, as A18 names it: the 1-based line and each
|
|
1134
|
+
* side's line, trimmed and cut to 120 characters.
|
|
1135
|
+
*/
|
|
1136
|
+
function firstDifferingLine(first: string, second: string): string {
|
|
1137
|
+
const a = first.split('\n');
|
|
1138
|
+
const b = second.split('\n');
|
|
1139
|
+
let i = 0;
|
|
1140
|
+
while (i < a.length && i < b.length && a[i] === b[i]) i += 1;
|
|
1141
|
+
const cut = (line: string | undefined): string => (line === undefined ? '(end of text)' : JSON.stringify(line.trim().slice(0, 120)));
|
|
1142
|
+
return `${i + 1}: ${cut(a[i])} first, ${cut(b[i])} second`;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1126
1145
|
export function validate(input: ValidateInput): ValidateReport {
|
|
1127
1146
|
const failures: Failure[] = [];
|
|
1128
1147
|
const passed: string[] = [];
|
|
@@ -6149,6 +6168,15 @@ export function validate(input: ValidateInput): ValidateReport {
|
|
|
6149
6168
|
if (input.reEmit.atlasText !== input.atlasText) {
|
|
6150
6169
|
fail('A18_DETERMINISTIC_EMIT', 'recompiling produced a different skeleton.atlas');
|
|
6151
6170
|
}
|
|
6171
|
+
// The model document is compared like the Spine pair (issue #922): it is
|
|
6172
|
+
// written beside them, and a map iterated in an order nothing fixed would
|
|
6173
|
+
// reach it before it reached either of them — the document writes every
|
|
6174
|
+
// `Map` of the model as an array in the map's order.
|
|
6175
|
+
if (input.modelText === undefined) {
|
|
6176
|
+
fail('A18_DETERMINISTIC_EMIT', 'a second compile was handed over with no first model document to compare its skeleton.model.json against');
|
|
6177
|
+
} else if (input.reEmit.modelText !== input.modelText) {
|
|
6178
|
+
fail('A18_DETERMINISTIC_EMIT', `recompiling produced a different skeleton.model.json (first differing line ${firstDifferingLine(input.modelText, input.reEmit.modelText)})`);
|
|
6179
|
+
}
|
|
6152
6180
|
});
|
|
6153
6181
|
|
|
6154
6182
|
// --- every assertion leaves a row ----------------------------------------
|