rig-parts 1.2.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 +23 -2
- package/cli.ts +39 -11
- package/docs/AUTHORING.md +291 -17
- package/docs/STABILITY.md +8 -5
- package/package.json +1 -1
- package/skills/rig-parts/SKILL.md +22 -4
- package/src/assemble.ts +418 -41
- package/src/automesh.ts +23 -4
- package/src/build.ts +47 -8
- package/src/check.ts +252 -6
- package/src/config.ts +157 -16
- package/src/contour.ts +400 -13
- package/src/propose.ts +24 -1
- package/src/rig.ts +46 -6
- package/src/scene.ts +277 -25
package/README.md
CHANGED
|
@@ -306,8 +306,10 @@ These are limits of the approach, stated so nobody reads more into a green run:
|
|
|
306
306
|
layer that is in front of another in one place and behind it in another is drawn
|
|
307
307
|
right in the still (the painting's own pixels are projected onto it) and wrong once
|
|
308
308
|
it moves.
|
|
309
|
-
- **No expression or lip-sync.** The mouth is one layer; there is no
|
|
310
|
-
and no expression axis
|
|
309
|
+
- **No expression or lip-sync, and no jiggle.** The mouth is one layer; there is no
|
|
310
|
+
mouth-shape set and no expression axis, and nothing here proposes, keys or judges a
|
|
311
|
+
soft region. An expression that moves the face's parts, and a jiggle, can be built on
|
|
312
|
+
the rig it writes ([below](#what-can-be-built-on-top)); lip-sync cannot.
|
|
311
313
|
- **Occluded pixels are See-through's synthesis**, not the artist's. How much of a rig
|
|
312
314
|
that is, is below.
|
|
313
315
|
- **No success rate is claimed.** Ten characters have been measured stage by stage
|
|
@@ -331,6 +333,25 @@ These are limits of the approach, stated so nobody reads more into a green run:
|
|
|
331
333
|
measures is a hanging strand on a headwear or earwear layer: each gets a pendulum
|
|
332
334
|
chain, and a strand it cannot chain is named in a note rather than left stiff.
|
|
333
335
|
|
|
336
|
+
### What can be built on top
|
|
337
|
+
|
|
338
|
+
This package makes no expression and no jiggle, but the rig it writes is the material for
|
|
339
|
+
both, and the config has a field for each. [docs/AUTHORING.md](docs/AUTHORING.md) has a recipe
|
|
340
|
+
for each — a config fragment, the `check` lines it passes with, and its limit:
|
|
341
|
+
|
|
342
|
+
- [**Expressions and other named animations**](docs/AUTHORING.md#recipe-expressions-and-other-named-animations):
|
|
343
|
+
the face's parts are bones; animations written over them in rig-c's motion-spec shape and
|
|
344
|
+
named by `motion.animations_from` are built and gated beside the idle on every build. One
|
|
345
|
+
attachment per slot, so a part moves, turns and scales but is never swapped for another
|
|
346
|
+
image; `check` measures the idle alone.
|
|
347
|
+
- [**A soft region driven by physics**](docs/AUTHORING.md#recipe-a-soft-region-driven-by-physics)
|
|
348
|
+
(a bust, the hips): a bone the config authors, a contour-mode region that hands it the patch,
|
|
349
|
+
and a `physics` constraint on it; `examples/sample` carries one. Under the sample's slow
|
|
350
|
+
4 s idle the bust moves at most 0.066 rig px and the hips not at all: the spring answers
|
|
351
|
+
faster keys on the body. The sample's `hop`, a named animation keying only `hip`, moves the
|
|
352
|
+
bust up to 6.583 and the hips up to 4.432 rig px; the region's `band` caps how far a patch may
|
|
353
|
+
go before the texture-stretch ceiling, and `check` measures the idle alone.
|
|
354
|
+
|
|
334
355
|
### How much of a rig the model painted
|
|
335
356
|
|
|
336
357
|
`parts.json` splits each part's opaque pixels (`opaque_px`) into `visible_px` — no
|
package/cli.ts
CHANGED
|
@@ -205,7 +205,7 @@ usage:
|
|
|
205
205
|
rounding, and so is the per-frame mesh work (AUTHORING §5).
|
|
206
206
|
rig-parts check --rig <dir> --out <dir> [--parts <dir>] [--source <painting.png>]
|
|
207
207
|
[--page-edges pot|free] [--pack-shape rect|polygon]
|
|
208
|
-
[--requirements <file.json>]
|
|
208
|
+
[--requirements <file.json>] [--seam-pairs]
|
|
209
209
|
Build, gate, render and measure a rig through rig-c's CLI (the rigc at
|
|
210
210
|
node_modules/.bin/rigc, or on PATH). --rig holds rig.json and motion.json:
|
|
211
211
|
a rig spec, which rigc build compiles, not a compiled skeleton.json.
|
|
@@ -222,7 +222,11 @@ usage:
|
|
|
222
222
|
entry that gated the build, and pack_mode, the two pack flags). PASS needs every gate summary
|
|
223
223
|
"0 failed", the seam (setup pose vs the flat composite of parts/) at mean
|
|
224
224
|
|d| <= ${SEAM_MEAN_BAR.toFixed(1)} with <= ${SEAM_PX_BAR} px over ${SEAM_PX_LEVEL}, and the loop (idle frame 0 vs the
|
|
225
|
-
frame at t = duration) at max |d| 0.
|
|
225
|
+
frame at t = duration) at max |d| 0. A failing seam, or any seam under
|
|
226
|
+
--seam-pairs, is split by the pair of parts each counted pixel lies
|
|
227
|
+
between: one "seam pair" line each, worst first, with its count, frame
|
|
228
|
+
and rig boxes and a picture under seam/, and check.json's seam_pairs
|
|
229
|
+
(AUTHORING §7). Then six judgement lines, each in
|
|
226
230
|
check.json and on the console as NAME: PASS|FAIL|SKIP with its figures and
|
|
227
231
|
bars (AUTHORING §7): BREATH_VISIBLE (the topwear moves, the footwear does
|
|
228
232
|
not, each rendered alone), BLINK_NO_HOLE (the setup pose with the blink
|
|
@@ -326,14 +330,18 @@ usage:
|
|
|
326
330
|
<out>/render/recomposite_rig.png and <out>/render/${ERROR_MAP_FILE} (the error
|
|
327
331
|
map: uncovered error px red, covered error px blue, the rest the painting in
|
|
328
332
|
light grey). Reads config.seethrough.head_box and
|
|
329
|
-
.resolution and config.assemble.rig_scale, .plan, .extend_below_crop
|
|
333
|
+
.resolution and config.assemble.rig_scale, .plan, .extend_below_crop,
|
|
330
334
|
.patches — extra parts cut from the painting itself over a rig-pixel box
|
|
331
335
|
(alpha "silhouette": the painting's figure inside it; "box": all of it),
|
|
332
336
|
drawn "back", "front" or {"before": <plan part>}, recorded in parts.json
|
|
333
|
-
as from "painting:<name>" and counted 100 % source — and
|
|
337
|
+
as from "painting:<name>" and counted 100 % source — and .cuts — a plan
|
|
338
|
+
part's pixels inside a rig-pixel polygon taken into a new part, drawn the
|
|
339
|
+
same way, recorded with the plan part's from — and no rig section:
|
|
334
340
|
bones, meshes, regions and motion need not exist yet, because propose
|
|
335
341
|
drafts them from these parts (AUTHORING §4, the table).
|
|
336
|
-
Prints one line per part,
|
|
342
|
+
Prints one line per part, one \`cut:\` line per part a cut split (its
|
|
343
|
+
opaque pixels = what it kept + what each cut took), the seam override
|
|
344
|
+
counts, the \`pixels:\` totals
|
|
337
345
|
(opaque = visible + occluded; taken from the painting; visible but not
|
|
338
346
|
projected), and \`recomposite vs source\` (mean |d| and % within 8 over the
|
|
339
347
|
mean channel; error px: max channel > 40; uncovered: of those, where no
|
|
@@ -421,9 +429,14 @@ usage:
|
|
|
421
429
|
Bind several finished characters into one rig. The scene file (spec
|
|
422
430
|
"${SCENE_SPEC}") states the canvas {width, height}, an optional plate
|
|
423
431
|
{image, provenance: ${PROVENANCES.join(' | ')}, note?}, the characters
|
|
424
|
-
[{id, build, offset: [x, y]}] — each build the --out of a green
|
|
432
|
+
[{id, build, offset: [x, y], scale?}] — each build the --out of a green
|
|
425
433
|
\`rig-parts build\` (its check/check.json PASS), each offset a
|
|
426
|
-
translation from its rig px to canvas px
|
|
434
|
+
translation from its rig px to canvas px, each scale (a positive
|
|
435
|
+
number, 1 when absent) the character's size about its stage's top-left
|
|
436
|
+
corner: every length it carries is scaled as Spine's loader scales a
|
|
437
|
+
skeleton (bones, regions, weight binds, constraint lengths, translate
|
|
438
|
+
keys), and a physics wind or gravity, which no per-character value
|
|
439
|
+
can scale, is refused (SCENE_SCALE_EXACT) — and order: the draw order,
|
|
427
440
|
back to front, of character ids (that character's remaining slots, in
|
|
428
441
|
its own order) and "<id>:<slot>" entries, every slot exactly once.
|
|
429
442
|
Paths are relative to the scene file. Every bone, slot, attachment,
|
|
@@ -435,7 +448,9 @@ usage:
|
|
|
435
448
|
shared, so a character whose idle keys it, or whose constraint names it,
|
|
436
449
|
is refused. The plate is a region on bone "${PLATE}" under
|
|
437
450
|
root, drawn first, its image at canvas (0, 0). One idle holds every
|
|
438
|
-
character's tracks
|
|
451
|
+
character's tracks; an animation beside a character's idle (its
|
|
452
|
+
config's motion.animations_from) rides along as "<id>:<name>",
|
|
453
|
+
prefixed as the idle is and scheduled by nothing. Refused by name, every problem at once: an id
|
|
439
454
|
repeated, empty or holding ":" (or "/", "\\", a leading "."); a build
|
|
440
455
|
missing a file or whose own check is not green; characters built at
|
|
441
456
|
different rig_scale; a character whose parts' boxes, placed, leave the
|
|
@@ -447,7 +462,7 @@ usage:
|
|
|
447
462
|
rig-c as rig gates its own (build --profile spine-html --pack, the
|
|
448
463
|
compile and the packed pages on disk); --out receives rig/ (rig.json,
|
|
449
464
|
motion.json, images/) and ${SCENE_REPORT_FILE} (spec "${SCENE_REPORT_SPEC}":
|
|
450
|
-
every setting, each character's offset, bounds and shift (and what it
|
|
465
|
+
every setting, each character's offset, scale, bounds and shift (and what it
|
|
451
466
|
moved),
|
|
452
467
|
the plate's provenance, the declared and the composed order) only when
|
|
453
468
|
it is green; then check runs over rig/ into check/, as on a rig it did
|
|
@@ -682,7 +697,15 @@ function flags(args: string[], known: readonly string[], command: string, option
|
|
|
682
697
|
}
|
|
683
698
|
|
|
684
699
|
function cmdCheck(args: string[]): number {
|
|
685
|
-
|
|
700
|
+
// The one switch check takes (issue #202): it carries no value, so it is taken out before the valued flags are read.
|
|
701
|
+
const seamPairs = args.filter((a) => a === '--seam-pairs').length;
|
|
702
|
+
if (seamPairs > 1) return usage('--seam-pairs is given twice');
|
|
703
|
+
const f = flags(
|
|
704
|
+
args.filter((a) => a !== '--seam-pairs'),
|
|
705
|
+
['--rig', '--out'],
|
|
706
|
+
'check',
|
|
707
|
+
['--parts', '--source', '--page-edges', '--pack-shape', '--requirements'],
|
|
708
|
+
);
|
|
686
709
|
if (typeof f === 'string') return usage(f);
|
|
687
710
|
const rig = f.get('--rig') as string;
|
|
688
711
|
const out = f.get('--out') as string;
|
|
@@ -692,7 +715,12 @@ function cmdCheck(args: string[]): number {
|
|
|
692
715
|
if (!isPackShape(shape)) return usage(shape);
|
|
693
716
|
try {
|
|
694
717
|
const bin = findRigc(import.meta.dir, process.env.PATH ?? '');
|
|
695
|
-
const r = checkStage(
|
|
718
|
+
const r = checkStage(
|
|
719
|
+
{ rig, parts: f.get('--parts'), source: f.get('--source'), out, pageEdges: edges, packShape: shape, requirements: f.get('--requirements'), seamPairs: seamPairs === 1 },
|
|
720
|
+
rigcRunner(bin),
|
|
721
|
+
bin,
|
|
722
|
+
console.log,
|
|
723
|
+
);
|
|
696
724
|
return r.figures.PASS ? EXIT_OK : EXIT_REFUSED;
|
|
697
725
|
} catch (err) {
|
|
698
726
|
return printRefusal(err);
|