spine-rigc 2.18.0 → 2.19.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/package.json +1 -1
- package/src/mesh.ts +3 -0
- package/src/meshquality.ts +69 -5
- package/src/meshreduce.ts +1294 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spine-rigc",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.19.0",
|
|
4
4
|
"description": "AI-authored Spine 2D rigging and animation, verified before it is written. rigc compiles a rig spec into Spine 4.3 skeleton data, gates it with named assertions held to a spine-core round trip's verdicts, and emits nothing that fails. Output imports into the Spine editor. Ships as an agent skill.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/mesh.ts
CHANGED
|
@@ -49,7 +49,10 @@ import type { ModelBinding, ModelVertices } from './model.ts';
|
|
|
49
49
|
// `spine-rigc/mesh` names. That module imports helpers from this one, so the
|
|
50
50
|
// two form an import cycle: safe only because neither reads the other's
|
|
51
51
|
// bindings while it is being evaluated — every use is inside a function.
|
|
52
|
+
// The reduction (`reduceMesh`, stage B2 of #1224) sits in the same cycle, by
|
|
53
|
+
// the same rule.
|
|
52
54
|
export * from './meshquality.ts';
|
|
55
|
+
export * from './meshreduce.ts';
|
|
53
56
|
|
|
54
57
|
export interface MeshSpecInput {
|
|
55
58
|
/** Polygon in part-local pixels, y down, in manifest order. */
|
package/src/meshquality.ts
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* attachment draws, and the bounds the caller declared, measured into one
|
|
7
7
|
* `mesh-quality-report/1` document (`writeMeshQualityReport` writes its text).
|
|
8
8
|
* Every type the contract declares is declared here too, including the ones
|
|
9
|
-
* only the reduction (`reduceMesh`, stage B2) and the
|
|
10
|
-
* (stage C)
|
|
11
|
-
* than restating them.
|
|
9
|
+
* only the reduction (`reduceMesh`, stage B2, in `src/meshreduce.ts`) and the
|
|
10
|
+
* motion comparison (stage C) fill, so that those stages build on one set of
|
|
11
|
+
* types rather than restating them.
|
|
12
12
|
*
|
|
13
13
|
* ## What it is for
|
|
14
14
|
*
|
|
@@ -181,7 +181,28 @@ export interface InfluenceLimits {
|
|
|
181
181
|
minWeight: number;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
/**
|
|
184
|
+
/**
|
|
185
|
+
* One deform key of a timeline the reduced attachment is keyed under (§6, P18),
|
|
186
|
+
* in the form the compiler emits it: a `vertices` run is the emitted `offset`
|
|
187
|
+
* (an index into the deform array — two numbers per vertex unweighted, two per
|
|
188
|
+
* influence weighted, AUTHORING §4.11) and the numbers copied in from there; a
|
|
189
|
+
* `transform` key is a model the compile evaluates over the attachment's own
|
|
190
|
+
* geometry (§4.11.1), so it has no run to remap; a `setup` key carries no run.
|
|
191
|
+
*/
|
|
192
|
+
export type DeformKeyInput =
|
|
193
|
+
| { time: number; kind: 'setup' }
|
|
194
|
+
| { time: number; kind: 'vertices'; offset: number; vertices: number[] }
|
|
195
|
+
| { time: number; kind: 'transform' };
|
|
196
|
+
|
|
197
|
+
/** One deform timeline: the animation, the attachment it is keyed on, and its keys in order. */
|
|
198
|
+
export interface DeformTimelineInput {
|
|
199
|
+
animation: string;
|
|
200
|
+
/** The reduced attachment itself, or one of `MeshReductionInput.linkedMeshes`. */
|
|
201
|
+
attachment: AttachmentRef;
|
|
202
|
+
keys: DeformKeyInput[];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** Everything a reduction reads (stage B2, `reduceMesh` in `src/meshreduce.ts`). No field has a default inside the operation. */
|
|
185
206
|
export interface MeshReductionInput {
|
|
186
207
|
attachment: AttachmentRef;
|
|
187
208
|
art: ArtInput;
|
|
@@ -198,8 +219,16 @@ export interface MeshReductionInput {
|
|
|
198
219
|
boneOrder: string[] | null;
|
|
199
220
|
/** P5: the preset the caller expanded, if any, echoed and never read. */
|
|
200
221
|
preset: { name: string; version: string } | null;
|
|
201
|
-
/** Work bound — *Termination reasons*. */
|
|
222
|
+
/** Work bound — *Termination reasons*. Every refinement insertion and every removal attempted counts one. */
|
|
202
223
|
budget: { maxCandidates: number };
|
|
224
|
+
/** P9: the fewest art samples the attachment's raster rows are taken over. A whole number >= 1. */
|
|
225
|
+
minArtSamples: number;
|
|
226
|
+
/** P9: one floor per region, by region name — every region named once. */
|
|
227
|
+
regionArtSamples: Array<{ region: string; minArtSamples: number }>;
|
|
228
|
+
/** P18: every deform timeline keyed on the attachment or on one of its linked meshes; empty when none. */
|
|
229
|
+
deform: DeformTimelineInput[];
|
|
230
|
+
/** Every linked mesh of the source (they inherit the new topology); empty when none. */
|
|
231
|
+
linkedMeshes: AttachmentRef[];
|
|
203
232
|
}
|
|
204
233
|
|
|
205
234
|
/**
|
|
@@ -341,6 +370,29 @@ export interface CandidateReport {
|
|
|
341
370
|
accepted: boolean;
|
|
342
371
|
/** Opt-in (P7): every row's value at every frame. Absent unless asked for. */
|
|
343
372
|
perFrame?: Array<{ code: string; frame: string; value: number | null }>;
|
|
373
|
+
/** A `reduce` whose result exists: what the operation changed. Absent on a `measure` and when no mesh is returned. */
|
|
374
|
+
changes?: ReductionChanges;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* What a reduction changed, counted rather than described — the figures the
|
|
379
|
+
* contract says are reported (§6, P18 and P19) and that no geometry row carries.
|
|
380
|
+
*/
|
|
381
|
+
export interface ReductionChanges {
|
|
382
|
+
/** Source vertices the reduction removed. */
|
|
383
|
+
removedVertices: number;
|
|
384
|
+
/** Vertices the refinement inserted (§5). */
|
|
385
|
+
insertedVertices: number;
|
|
386
|
+
/** P19: positive interpolated shares that are 0 on the 6-decimal weight grid, dropped rather than written as 0. */
|
|
387
|
+
sharesDroppedOnGrid: number;
|
|
388
|
+
/** Interpolated shares pruned by `InfluenceLimits` — over `maxInfluences`, or under a nonzero `minWeight`. */
|
|
389
|
+
sharesPruned: number;
|
|
390
|
+
/** P18: `vertices` keys remapped, each with the source vertices whose offsets were dropped. */
|
|
391
|
+
deformRemapped: Array<{ animation: string; attachment: AttachmentRef; key: number; droppedVertices: number[] }>;
|
|
392
|
+
/** P18: `transform` keys, re-evaluated over the new geometry at compile rather than remapped. */
|
|
393
|
+
deformReevaluated: Array<{ animation: string; attachment: AttachmentRef; key: number }>;
|
|
394
|
+
/** Every linked mesh of the source: each inherits the new topology. */
|
|
395
|
+
linkedMeshes: AttachmentRef[];
|
|
344
396
|
}
|
|
345
397
|
|
|
346
398
|
export interface MeshQualityReport {
|
|
@@ -1470,6 +1522,18 @@ function candidateJson(c: CandidateReport): Json {
|
|
|
1470
1522
|
accepted: c.accepted,
|
|
1471
1523
|
};
|
|
1472
1524
|
if (c.perFrame !== undefined) out.perFrame = c.perFrame.map((p) => ({ code: p.code, frame: p.frame, value: p.value }));
|
|
1525
|
+
if (c.changes !== undefined) {
|
|
1526
|
+
const k = c.changes;
|
|
1527
|
+
out.changes = {
|
|
1528
|
+
removedVertices: k.removedVertices,
|
|
1529
|
+
insertedVertices: k.insertedVertices,
|
|
1530
|
+
sharesDroppedOnGrid: k.sharesDroppedOnGrid,
|
|
1531
|
+
sharesPruned: k.sharesPruned,
|
|
1532
|
+
deformRemapped: k.deformRemapped.map((d) => ({ animation: d.animation, attachment: attachmentJson(d.attachment), key: d.key, droppedVertices: [...d.droppedVertices] })),
|
|
1533
|
+
deformReevaluated: k.deformReevaluated.map((d) => ({ animation: d.animation, attachment: attachmentJson(d.attachment), key: d.key })),
|
|
1534
|
+
linkedMeshes: k.linkedMeshes.map(attachmentJson),
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1473
1537
|
return out;
|
|
1474
1538
|
}
|
|
1475
1539
|
|