@rig-c/core 2.41.0 → 2.43.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 +8 -3
- package/docs/AUTHORING.md +75 -14
- package/package.json +1 -1
- package/src/cli/core_commands.ts +43 -5
- package/src/cli/shared.ts +36 -5
- package/src/inspect.ts +941 -216
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ installed.
|
|
|
41
41
|
| the same, and one texture instead of many | `rigc build --pack` | the parts arranged onto shared atlas pages, written beside the skeleton — losslessly, so the picture is the picture |
|
|
42
42
|
| a pack somebody already made | `rigc build --atlas-in` | the same skeleton, with every part resolved to a region of that atlas — or a named refusal, never a part that silently does not draw |
|
|
43
43
|
| a compiled rig | `rigc render` | every animation as PNG frames, plus one labelled contact sheet of the whole shot |
|
|
44
|
-
| a compiled rig and a question about its geometry | `rigc inspect` | one picture of its bones, axes, a world grid or a declared axis over the art — at the setup pose, one time or a sheet of several, zoomed to a bone or a slot — and a legend that puts every mark back in world units |
|
|
44
|
+
| a compiled rig and a question about its geometry | `rigc inspect` | one picture of its bones, axes, mesh edges and hulls, one bone's weights, the draw order, a world grid or a declared axis over the art — at the setup pose, one time or a sheet of several, zoomed to a bone or a slot, or beside a second build on one transform — and a legend that puts every mark back in world units |
|
|
45
45
|
| a compiled rig | `rigc preview` | one self-contained `.html` that plays it in Spine's own web player |
|
|
46
46
|
| two to four compiled rigs | `rigc vote` | one ballot page a human picks from, and the answer checked into a ledger |
|
|
47
47
|
| a picture of a key pose | `rigc pose` | where each loose part PNG sits in it, in spec coordinates — the movement between two poses is then yours to key ([docs/MOTION.md](docs/MOTION.md)) |
|
|
@@ -410,10 +410,15 @@ rigc inspect --candidate spine --show art,bones,names --dim # inspect.png + in
|
|
|
410
410
|
bone where the art is*, *which way does it squash*, *where in rig units is this
|
|
411
411
|
point*, *is this axis held*. It draws the build's art, framed as `render` frames it,
|
|
412
412
|
and over it any of `bones` (origin to tip, a bone of length 0 marked as one),
|
|
413
|
-
`names
|
|
413
|
+
`names` (one label per pixel), `axes` (each bone's world x and y), `mesh` and `hull`
|
|
414
|
+
(each mesh's edges and outline), `weights:<bone>` (what that bone moves, as a heat),
|
|
415
|
+
`slots` (the draw order at the pose), `grid` (in world units) and `declared`
|
|
414
416
|
(each `invariants.axes` line and the bones held to it), at the setup pose, at
|
|
415
417
|
`--animation <name> --at <s[,s…]>` — one picture, or a sheet — or zoomed with
|
|
416
|
-
`--zoom <bone|slot>[:pad]` or `--viewport x,y,w,h
|
|
418
|
+
`--zoom <bone|slot>[:pad]` or `--viewport x,y,w,h`; `--bone`/`--hide-bone` pick the
|
|
419
|
+
bones by glob, `--overlay-slot`/`--hide-overlay-slot` the slots whose mesh, hull,
|
|
420
|
+
weights and number are drawn over the whole painting, and `--compare <dir>` draws a second build beside the first on one
|
|
421
|
+
transform, to see what a change moved. Beside the PNG it writes a legend:
|
|
417
422
|
the world-to-pixel transform both ways, what each colour means, and every bone's
|
|
418
423
|
origin and tip in world units and in pixels, so a position read off the picture goes
|
|
419
424
|
straight back into the spec. [AUTHORING §13](docs/AUTHORING.md#13-asking-the-picture-a-question--rigc-inspect)
|
package/docs/AUTHORING.md
CHANGED
|
@@ -10093,12 +10093,11 @@ pixel (`IN09`).
|
|
|
10093
10093
|
| Where in rig units is this point? | `--show art,grid --zoom <bone or slot>` or `--viewport x,y,w,h` | grid lines at whole multiples of a step in **world units**, each labelled with its value, the lines through 0 darker. The legend's transform converts any pixel exactly; the grid is for reading by eye |
|
|
10094
10094
|
| Is this axis declared, and held? | `--show art,declared,bones` | each `invariants.axes` line (§3.7) through its two bones' origins, drawn across the whole tile, and the bones it holds drawn in their own colour; the legend states each held bone's world x axis and how far off the line it lies, as `A51` measures it, at the pose drawn |
|
|
10095
10095
|
| Did it break during the move? | any of the above `--animation <name> --at <s,s,…>` | one tile per time, left to right on one grid, each labelled with its time and frame |
|
|
10096
|
-
|
|
10097
|
-
|
|
10098
|
-
|
|
10099
|
-
|
|
10100
|
-
|
|
10101
|
-
or flag is, naming what this version draws.
|
|
10096
|
+
| What does this bone move? | `--show art,mesh,weights:<bone> --dim` | the bone's weight over every region and mesh it moves, as a heat: a pixel whose centre lies in a triangle is painted the ramp's colour at the blend of its corners' weights — blue near 0, yellow at 0.5, red at 1 (the stops are in the legend) — and a weight of 0 is not painted, so the art shows where the bone does not reach. A region and an unweighted mesh are moved whole by their slot's bone. The weights are read off `skeleton.json`, the file both posers skin from; a bone that weights nothing paints nothing and the run says so on a line of its own |
|
|
10097
|
+
| Does this part's edge follow that bone? | `--show art,weights:<bone>,mesh --overlay-slot <part> --zoom slot:<part>` | the part's own triangles and the bone's weight over them alone, over the whole painting. Where slots stack — a neck under the face, the hair, a collar — every mesh crossing the box is drawn and the heat is the union of every slot the bone moves, so the part's edge has no pixel of its own until the others are left out. The legend's `meshes[]` gives the part's weight for the bone at every vertex, so "does the top row follow the head" is read as numbers as well as colour |
|
|
10098
|
+
| How is this part triangulated? | `--show art,mesh,hull --zoom slot:<slot>` | each mesh's triangle edges, and over them its hull — vertex 0 to 1 to … to `hull − 1` and back. Regions are not drawn: a region is not a mesh. The legend lists every vertex in world units and in pixels |
|
|
10099
|
+
| Which is drawn over which? | `--show art,slots` | each slot that shows a region or mesh numbered by its place in the draw order **at the pose drawn** (0 is drawn first), on a white box at the centre of its attachment's box — so a `drawOrder` key (§4.7) shows from the first frame `render` draws it on |
|
|
10100
|
+
| Did this change move anything? | `--compare <dir>` beside any view | the same view of a second build beside the first, at the same times, on **one** world box and one transform, each half labelled `A`/`B` with the poser that posed it. A mark on a different pixel in the two halves is at a different place in the two rigs |
|
|
10102
10101
|
|
|
10103
10102
|
### 13.2 Where it looks
|
|
10104
10103
|
|
|
@@ -10119,11 +10118,50 @@ or flag is, naming what this version draws.
|
|
|
10119
10118
|
(default a quarter of the box's longer side). A name that is both a bone and a slot
|
|
10120
10119
|
is refused until it is written `bone:<name>` or `slot:<name>`; a bone of length 0
|
|
10121
10120
|
with no pad is one point, and is refused asking for one.
|
|
10121
|
+
- **Two builds** — `--compare <dir | skeleton.json>`. The second build is loaded as
|
|
10122
|
+
the first is (its own poser, chosen by what it carries, on a `poser B:` line),
|
|
10123
|
+
posed at the same times, and drawn beside it: one time is two halves side by side,
|
|
10124
|
+
several are pairs, four to a row. The box is the one `--viewport` names, or the
|
|
10125
|
+
union of what `--zoom` names in **both** builds, or — with neither — the union of
|
|
10126
|
+
`render`'s framing of each, so a half is `render`'s frame of its build only where
|
|
10127
|
+
the two framings agree. A name either build lacks is refused naming that build.
|
|
10122
10128
|
- `--max` is each tile's longer side in pixels (default 256), as on `render`.
|
|
10123
10129
|
- `--dim` fades the art toward white (each channel keeps 0.4 of its distance from
|
|
10124
10130
|
white) so what is drawn over it reads.
|
|
10125
10131
|
|
|
10126
|
-
### 13.3
|
|
10132
|
+
### 13.3 Labels, and which bones and slots are drawn
|
|
10133
|
+
|
|
10134
|
+
- **One label per pixel.** Bones whose origins land on one pixel — a `_ctl` bone and
|
|
10135
|
+
its identity child, a chain's joint — are one label: the first by declaration
|
|
10136
|
+
order, then `+N` for the rest (`leg0_ctl +2`). The pixel is the unit because it is
|
|
10137
|
+
what overprints: two origins a third of a pixel apart print their names on each
|
|
10138
|
+
other as surely as two that coincide. The legend's `labels` lists every bone of
|
|
10139
|
+
each label, and `bones` keeps every bone.
|
|
10140
|
+
- **No label over another.** Labels are placed in declaration order (slot numbers
|
|
10141
|
+
first); one that would touch an earlier label moves down a text line at a time
|
|
10142
|
+
until it is clear, and a grey leader joins it to its origin. After 16 lines it
|
|
10143
|
+
stays where it began and the legend marks it `overlaps`.
|
|
10144
|
+
- **`--bone <glob[,glob…]>`** draws only the bones a pattern matches, and
|
|
10145
|
+
**`--hide-bone <glob[,glob…]>`** none of the ones it matches, applied after
|
|
10146
|
+
`--bone` — so `--bone 'bang_*' --hide-bone '*_ctl,*_px'` is the fringe chains
|
|
10147
|
+
without their control bones. A pattern is a glob — `*` any run of characters, `?`
|
|
10148
|
+
one, matched against the whole name — rather than a regular expression: bone names
|
|
10149
|
+
are identifiers, the patterns are comma-separated, and a glob needs no escaping in
|
|
10150
|
+
the shell. The filter is on `bones`, `axes` and `names`; every bone stays in the
|
|
10151
|
+
legend, and a left-out one says which flag left it out in `undrawn`. A pattern
|
|
10152
|
+
that matches no bone is refused naming the bones there are.
|
|
10153
|
+
- **`--overlay-slot <glob[,glob…]>`** draws the per-slot views — `mesh`, `hull`,
|
|
10154
|
+
`weights:<bone>` and `slots` — only for the slots a pattern matches, and
|
|
10155
|
+
**`--hide-overlay-slot <glob[,glob…]>`** for none of the ones it matches, applied
|
|
10156
|
+
after `--overlay-slot`; the patterns are globs, as `--bone`'s are. The **art is not
|
|
10157
|
+
filtered**: the painting is what the edge is read against, and `--dim` already
|
|
10158
|
+
quiets it. A slot left out is absent from `meshes[]` and `slots[]`, and a slot kept
|
|
10159
|
+
keeps its number — its place in the whole draw order, not among the slots drawn. A
|
|
10160
|
+
pattern that matches no slot is refused naming the slots there are. It is not
|
|
10161
|
+
`--slot`: on `render` that flag draws a subset of the *art*, by exact name, which is
|
|
10162
|
+
the opposite of what this keeps whole.
|
|
10163
|
+
|
|
10164
|
+
### 13.4 The legend
|
|
10127
10165
|
|
|
10128
10166
|
`<out>.json` beside `<out>.png`, `rigc-inspect/1`. What it states:
|
|
10129
10167
|
|
|
@@ -10139,29 +10177,52 @@ or flag is, naming what this version draws.
|
|
|
10139
10177
|
top-left pixel), and `bones[]` — every bone in declaration order with its
|
|
10140
10178
|
`parent`, `length`, `zeroLength`, `origin` and `tip` each as `{ world, pixel }`,
|
|
10141
10179
|
`undrawn` (why it is not drawn — its world matrix is 0 at this time, unposed by the
|
|
10142
|
-
skin or scaled to 0
|
|
10143
|
-
`grid`, the step and every line's
|
|
10144
|
-
|
|
10180
|
+
skin or scaled to 0, or a `--bone`/`--hide-bone` pattern left it out — or `null`),
|
|
10181
|
+
and with `axes` shown, the two axis ends. With `grid`, the step and every line's
|
|
10182
|
+
value; with `declared`, each entry's line in degrees, its two points, and each held
|
|
10183
|
+
bone's angle and how far off the line it is. With `names`, `labels[]`: each label's
|
|
10184
|
+
`text`, the `bones` it stands for, its `anchor` pixel, the `box` it is drawn in,
|
|
10185
|
+
and whether it was `moved` or `overlaps`. With `mesh`, `hull` or `weights`,
|
|
10186
|
+
`meshes[]`: every region and mesh the pose shows, in draw order, with its `kind`,
|
|
10187
|
+
`vertexCount`, `triangleCount`, `hull` (a mesh's hull vertex count), its unique
|
|
10188
|
+
triangle `edges` as vertex pairs, every posed vertex in `world` and `pixel`, and
|
|
10189
|
+
with `weights` the bone's weight at each vertex. With `slots`, `slots[]`: each
|
|
10190
|
+
slot's `order`, `slot`, `attachment`, `bone`, its `anchor` and number's `box`.
|
|
10191
|
+
On a sheet or a compare, `label` — the tile's label text and box; with `--compare`,
|
|
10192
|
+
`build` — `A` or `B`.
|
|
10145
10193
|
- `colours` — every colour the picture draws, as RGBA, with what it means.
|
|
10146
10194
|
- `poser`, `show`, `dim`, `skin`, `animation`, `fps` and `framing` — what was drawn
|
|
10147
10195
|
and how it was framed (`shot`, `zoom` with the bone or slot, the pad and whether it
|
|
10148
10196
|
was stated, or `viewport`).
|
|
10197
|
+
- `weights` — with `weights:<bone>`: the bone, the ramp's stops as RGBA, the floor
|
|
10198
|
+
below which nothing is painted, and how a pixel's weight is read.
|
|
10199
|
+
- `boneFilter` — `--bone` and `--hide-bone` as given.
|
|
10200
|
+
- `slotFilter` — `--overlay-slot` and `--hide-overlay-slot` as given; with it,
|
|
10201
|
+
`meshes[]` and `slots[]` list only the slots it keeps.
|
|
10202
|
+
- `builds` — with `--compare`: each build (`A`, `B`), the poser that posed it, and
|
|
10203
|
+
its `skeleton.json`'s sha256. `poser` is build `A`'s.
|
|
10149
10204
|
|
|
10150
10205
|
Every number is `JSON.stringify`'s, the double the pose produced, not a rounding of
|
|
10151
10206
|
it. The same build and flags write the same bytes (`IN10`).
|
|
10152
10207
|
|
|
10153
|
-
### 13.
|
|
10208
|
+
### 13.5 What it refuses
|
|
10154
10209
|
|
|
10155
10210
|
Each of these exits 2, writes nothing, and names what exists: a bone or slot the
|
|
10156
10211
|
build does not have (both rosters listed), an animation or skin it does not declare,
|
|
10157
10212
|
a `--show` word it does not draw, a flag it does not take, a time off the frame grid
|
|
10158
10213
|
or past the end, `--at` without `--animation` and the reverse, `--zoom` beside
|
|
10159
|
-
`--viewport`,
|
|
10160
|
-
beside it whose `spine.sha256` is its own — a Spine export states no rig invariants
|
|
10214
|
+
`--viewport`, `--show declared` on a skeleton with no `skeleton.model.json`
|
|
10215
|
+
beside it whose `spine.sha256` is its own — a Spine export states no rig invariants —
|
|
10216
|
+
`weights` with no bone or with a bone the build lacks (the bones listed), a
|
|
10217
|
+
`--bone`/`--hide-bone` pattern that matches no bone (the bones listed), an
|
|
10218
|
+
`--overlay-slot`/`--hide-overlay-slot` pattern that matches no slot (the slots
|
|
10219
|
+
listed), and, with
|
|
10220
|
+
`--compare`, any of these that holds of the second build, said as `the --compare
|
|
10221
|
+
build: …`.
|
|
10161
10222
|
A rig that declares no `invariants.axes` is not refused: the picture draws nothing
|
|
10162
10223
|
for `declared` and the run says so on a line of its own.
|
|
10163
10224
|
|
|
10164
|
-
### 13.
|
|
10225
|
+
### 13.6 What it is not
|
|
10165
10226
|
|
|
10166
10227
|
- **Not a score.** Nothing in it is a pass bar; the picture is read, and what is read
|
|
10167
10228
|
is acted on in the spec.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rig-c/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.43.0",
|
|
4
4
|
"description": "AI-authored 2D rigging and animation, verified before it is written. rigc compiles a rig spec into skeleton data in the Spine 4.3 format, gates it with named assertions held to a spine-core round trip's verdicts, and emits nothing that fails. Ships as an agent skill.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/cli/core_commands.ts
CHANGED
|
@@ -30,7 +30,7 @@ import { ingest, INGEST_GUTTERS, type IngestFinding, IngestSpecRefused, type Ing
|
|
|
30
30
|
import { PARSER_DEFAULTS, parserReading } from '../keyorder.ts';
|
|
31
31
|
import { MODEL_DOCUMENT_FILE, modelDocument } from '../model.ts';
|
|
32
32
|
import { parseMotionSpec } from '../motion.ts';
|
|
33
|
-
import { type InspectFrame, InspectError, inspectCandidate, INSPECT_DEFAULT_FPS, legendText,
|
|
33
|
+
import { type InspectCompare, type InspectFrame, InspectError, inspectCandidate, INSPECT_DEFAULT_FPS, legendText, readBonePatterns, readShow, readTimes, readZoom } from '../inspect.ts';
|
|
34
34
|
import { estimatePose, poseLines, type PoseOptions } from '../pose.ts';
|
|
35
35
|
import { BACKGROUND, contactSheet, type Frame, FRAMES_SIDECAR, FRAMES_SPEC, type FrameSet, type FramesSidecar, framingViewport, GEOMETRY_FILE, geometryFileOf, geometryText, loadCandidate, POSER_NAMES, type PoserName, PROTOCOL_FPS, refuseUnchosen, renderFrame, sampleAll, sampleAnimation, SETUP_POSE_DIR, SHEET_FILE, SHEET_TILE, sidecarViewport, type SkeletonFacts, type SlotSubset, SlotSubsetError, throughPoser } from '../render_shared.ts';
|
|
36
36
|
import { type CompileResult } from '../types.ts';
|
|
@@ -676,7 +676,16 @@ export function cmdInspect(flags: Record<string, string>): void {
|
|
|
676
676
|
if (flags.zoom !== undefined && flags.viewport !== undefined) {
|
|
677
677
|
throw new InspectError('--zoom and --viewport both choose the box the picture is of; give one of them');
|
|
678
678
|
}
|
|
679
|
-
const show =
|
|
679
|
+
const { show, weightsBone } = readShow(flags.show);
|
|
680
|
+
const include = readBonePatterns('bone', flags.bone);
|
|
681
|
+
const exclude = readBonePatterns('hide-bone', flags['hide-bone']);
|
|
682
|
+
const boneFilter = include === undefined && exclude === undefined ? undefined : { ...(include === undefined ? {} : { include }), ...(exclude === undefined ? {} : { exclude }) };
|
|
683
|
+
const slotInclude = readBonePatterns('overlay-slot', flags['overlay-slot'], 'neck,hair_*');
|
|
684
|
+
const slotExclude = readBonePatterns('hide-overlay-slot', flags['hide-overlay-slot'], 'neck,hair_*');
|
|
685
|
+
const slotFilter =
|
|
686
|
+
slotInclude === undefined && slotExclude === undefined
|
|
687
|
+
? undefined
|
|
688
|
+
: { ...(slotInclude === undefined ? {} : { include: slotInclude }), ...(slotExclude === undefined ? {} : { exclude: slotExclude }) };
|
|
680
689
|
const times = readTimes(flags.at);
|
|
681
690
|
const fps = readPositiveNumber(flags, 'fps', INSPECT_DEFAULT_FPS, 1);
|
|
682
691
|
const maxSide = readPositiveNumber(flags, 'max', 256, 16);
|
|
@@ -709,14 +718,43 @@ export function cmdInspect(flags: Record<string, string>): void {
|
|
|
709
718
|
const animation = readAnimationFlag(flags, [...candidate.facts.animations]) ?? null;
|
|
710
719
|
readPoserFlag(flags);
|
|
711
720
|
refuseUnchosen(candidate.choice);
|
|
721
|
+
// `--compare`: the second build, loaded the way the first was — its own poser chosen by what it carries, and said.
|
|
722
|
+
let compare: InspectCompare | undefined;
|
|
723
|
+
if (flags.compare !== undefined) {
|
|
724
|
+
const other = resolveDrawable(flags.compare, undefined);
|
|
725
|
+
const otherText = readSkeletonText(other.skeletonPath);
|
|
726
|
+
console.log(` .. compare ${other.skeletonPath}`);
|
|
727
|
+
const otherCandidate = loadCandidate(
|
|
728
|
+
{ skeletonText: otherText, atlasText: other.atlasText, atlasDir: dirname(other.atlasPath), label: other.skeletonPath },
|
|
729
|
+
{ skeleton: other.skeletonPath, atlas: other.atlasPath },
|
|
730
|
+
posersAsked(flags),
|
|
731
|
+
);
|
|
732
|
+
refuseUnchosen(otherCandidate.choice);
|
|
733
|
+
compare = { candidate: otherCandidate, texts: { skeletonText: otherText, modelText: modelTextBeside(other.skeletonPath, otherText) } };
|
|
734
|
+
}
|
|
712
735
|
const result = inspectCandidate(
|
|
713
736
|
candidate,
|
|
714
737
|
{ skeletonText, modelText: modelTextBeside(skeletonPath, skeletonText) },
|
|
715
|
-
{
|
|
738
|
+
{
|
|
739
|
+
show,
|
|
740
|
+
...(weightsBone === undefined ? {} : { weightsBone }),
|
|
741
|
+
...(boneFilter === undefined ? {} : { boneFilter }),
|
|
742
|
+
...(slotFilter === undefined ? {} : { slotFilter }),
|
|
743
|
+
dim: flags.dim !== undefined,
|
|
744
|
+
animation,
|
|
745
|
+
times,
|
|
746
|
+
fps,
|
|
747
|
+
skin: flags.skin,
|
|
748
|
+
frame,
|
|
749
|
+
maxSide,
|
|
750
|
+
},
|
|
751
|
+
{},
|
|
752
|
+
compare,
|
|
716
753
|
);
|
|
717
754
|
const { legend } = result;
|
|
718
|
-
console.log(` .. poser ${result.poserNote}`);
|
|
719
|
-
|
|
755
|
+
console.log(` .. poser ${compare === undefined ? '' : 'A: '}${result.poserNote}`);
|
|
756
|
+
if (result.comparePoserNote !== undefined) console.log(` .. poser B: ${result.comparePoserNote}`);
|
|
757
|
+
const when = animation === null ? 'the setup pose' : `${animation} at ${legend.tiles.filter((t) => t.build !== 'B').map((t) => `${t.time.toFixed(4)}s (frame ${t.frame})`).join(', ')}, ${fps} fps grid`;
|
|
720
758
|
console.log(` .. view ${legend.show.join(',')}${legend.dim ? ' over dimmed art' : ''} — ${when}`);
|
|
721
759
|
const v = legend.viewport;
|
|
722
760
|
// Four places for reading; the legend carries every number exactly.
|
package/src/cli/shared.ts
CHANGED
|
@@ -56,7 +56,7 @@ import { BallotError } from '../ballot.ts';
|
|
|
56
56
|
import { ChainFitError } from '../chainfit.ts';
|
|
57
57
|
import { CheckError } from '../check.ts';
|
|
58
58
|
import { IngestError, type IngestStage } from '../ingest.ts';
|
|
59
|
-
import { InspectError, DEFAULT_SHOW, DIM_KEEP, INSPECT_DEFAULT_FPS, ON_GRID_FRAMES,
|
|
59
|
+
import { InspectError, DEFAULT_SHOW, DIM_KEEP, INSPECT_DEFAULT_FPS, ON_GRID_FRAMES, SHOW_SPELLINGS } from '../inspect.ts';
|
|
60
60
|
import { NotAPngError } from '../png.ts';
|
|
61
61
|
import { PoseError } from '../pose.ts';
|
|
62
62
|
import { RepackError } from '../repack.ts';
|
|
@@ -1063,10 +1063,13 @@ const FLAG_MEANINGS: Record<string, string> = {
|
|
|
1063
1063
|
'refused the same way. Not with `--slot`: the two are one statement',
|
|
1064
1064
|
max: 'longest side of a rendered frame, in pixels (default 256)',
|
|
1065
1065
|
show:
|
|
1066
|
-
`what \`inspect\` draws, comma-separated, from [${
|
|
1067
|
-
"build's own frame; grid = lines at whole multiples of a step in world units, labelled;
|
|
1066
|
+
`what \`inspect\` draws, comma-separated, from [${SHOW_SPELLINGS.join(', ')}] (default \`${DEFAULT_SHOW.join(',')}\`): art = the ` +
|
|
1067
|
+
"build's own frame; grid = lines at whole multiples of a step in world units, labelled; weights:<bone> = that bone's " +
|
|
1068
|
+
'weight over every region and mesh it moves, as a heat on a ramp the legend states; mesh = each mesh\'s triangle edges; ' +
|
|
1069
|
+
"hull = each mesh's hull outline; declared = each invariants.axes " +
|
|
1068
1070
|
"line through its two bones' origins, its held bones drawn in their own colour; bones = each bone from origin to tip, " +
|
|
1069
|
-
'a bone of length 0 marked as one; axes = each bone\'s world x and y axes;
|
|
1071
|
+
'a bone of length 0 marked as one; axes = each bone\'s world x and y axes; slots = each slot\'s place in the posed ' +
|
|
1072
|
+
'draw order; names = the bones\' names, one label per pixel (bones sharing an origin pixel are "first +N"). Any other word ' +
|
|
1070
1073
|
'is refused naming these',
|
|
1071
1074
|
dim: `fade the art toward white (each channel keeps ${DIM_KEEP} of its distance from white), so what is drawn over it reads`,
|
|
1072
1075
|
at:
|
|
@@ -1078,6 +1081,26 @@ const FLAG_MEANINGS: Record<string, string> = {
|
|
|
1078
1081
|
'frame the picture to one bone (origin to tip) or one slot (its attachment\'s vertices) over every time drawn, padded ' +
|
|
1079
1082
|
'by <pad> world units on every side (default: a quarter of the box\'s longer side). A name that is both a bone and a ' +
|
|
1080
1083
|
'slot is refused until written bone:<name> or slot:<name>; a name that is neither lists both rosters. Not with --viewport',
|
|
1084
|
+
bone:
|
|
1085
|
+
"draw only the bones these globs match (`*` any run of characters, `?` one, the whole name; comma-separated) — on `inspect`, " +
|
|
1086
|
+
"for bones, axes and names; every bone stays in the legend, a left-out one saying why in `undrawn`. A pattern that matches no " +
|
|
1087
|
+
'bone is refused naming the bones there are',
|
|
1088
|
+
'hide-bone':
|
|
1089
|
+
"draw none of the bones these globs match — `--bone` the other way round, applied after it, so `--bone 'bang_*' " +
|
|
1090
|
+
"--hide-bone '*_ctl'` is the fringe chains without their control bones",
|
|
1091
|
+
'overlay-slot':
|
|
1092
|
+
"draw the per-slot views — mesh, hull, weights:<bone> and slots — only for the slots these globs match (`*` any run of " +
|
|
1093
|
+
"characters, `?` one, the whole name; comma-separated); the art is every slot's still, since it is what the geometry is read " +
|
|
1094
|
+
"against. Not `--slot`: that flag draws a subset of the art on `render`, by exact name. The legend's meshes[] and slots[] list " +
|
|
1095
|
+
'only the slots kept, a slot number stays its place in the whole draw order, and a pattern that matches no slot is refused ' +
|
|
1096
|
+
'naming the slots there are',
|
|
1097
|
+
'hide-overlay-slot':
|
|
1098
|
+
"draw none of the per-slot views for the slots these globs match — `--overlay-slot` the other way round, applied after it, " +
|
|
1099
|
+
"so `--overlay-slot 'hair_*' --hide-overlay-slot hair_back` is the hair but its back layer",
|
|
1100
|
+
compare:
|
|
1101
|
+
'a second build to draw beside --candidate, the same view at the same times on one world box and one transform — the union ' +
|
|
1102
|
+
'of both framings unless --zoom or --viewport pins it — each half labelled with its build and the poser that posed it. A ' +
|
|
1103
|
+
'name, animation or skin the second build lacks is refused naming it',
|
|
1081
1104
|
record: 'a saved vote to check against its ballot and append to the ledger, instead of writing a ballot',
|
|
1082
1105
|
ballot: `the ballot the --record'd vote answers (default \`${DEFAULT_BALLOT}\`); its embedded manifest is what the vote is checked against`,
|
|
1083
1106
|
ledger: `the append-only JSONL the vote lands in (default \`${DEFAULT_LEDGER}\`)`,
|
|
@@ -1178,6 +1201,11 @@ const FLAG_VALUES: Record<string, string> = {
|
|
|
1178
1201
|
show: '<view[,view…]>',
|
|
1179
1202
|
at: '<s[,s…]>',
|
|
1180
1203
|
zoom: '<name>[:<pad>]',
|
|
1204
|
+
bone: '<glob[,glob…]>',
|
|
1205
|
+
'hide-bone': '<glob[,glob…]>',
|
|
1206
|
+
'overlay-slot': '<glob[,glob…]>',
|
|
1207
|
+
'hide-overlay-slot': '<glob[,glob…]>',
|
|
1208
|
+
compare: '<dir|skeleton.json>',
|
|
1181
1209
|
record: '<result.json>',
|
|
1182
1210
|
ballot: '<ballot.html>',
|
|
1183
1211
|
ledger: '<votes.jsonl>',
|
|
@@ -1564,8 +1592,11 @@ export const COMMANDS: CommandDoc[] = [
|
|
|
1564
1592
|
'rigc inspect --candidate <dir | skeleton.json> [--show art,bones,…] [--dim] [--max 256] [--poser core|spine] [--out inspect.png] (the setup pose)',
|
|
1565
1593
|
'rigc inspect … --animation <name> --at <s[,s…]> [--fps 12] [--skin <name>] (one time, or a sheet of several on one grid)',
|
|
1566
1594
|
'rigc inspect … --zoom <bone|slot>[:<pad>] | --viewport <x,y,w,h> (a box, in world units)',
|
|
1595
|
+
"rigc inspect … --bone 'bang_*' --hide-bone '*_ctl' (which bones bones, axes and names draw)",
|
|
1596
|
+
'rigc inspect … --overlay-slot neck --hide-overlay-slot <glob> (which slots mesh, hull, weights and slots draw; the art stays whole)',
|
|
1597
|
+
'rigc inspect … --compare <dir | skeleton.json> (a second build beside the first, on one transform)',
|
|
1567
1598
|
],
|
|
1568
|
-
flags: ['candidate', 'atlas', 'show', 'dim', 'animation', 'at', 'fps', 'skin', 'zoom', 'viewport', 'max', 'poser', 'out'],
|
|
1599
|
+
flags: ['candidate', 'atlas', 'show', 'dim', 'animation', 'at', 'fps', 'skin', 'zoom', 'viewport', 'bone', 'hide-bone', 'overlay-slot', 'hide-overlay-slot', 'compare', 'max', 'poser', 'out'],
|
|
1569
1600
|
overrides: {
|
|
1570
1601
|
animation: { meaning: 'the animation --at reads its times from (default: the setup pose, with no --at)' },
|
|
1571
1602
|
fps: { meaning: `the frame grid --at is read on, which is the grid \`render --fps\` draws (default ${INSPECT_DEFAULT_FPS})` },
|