rig-c 0.0.0-stage → 2.20.4
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/.claude-plugin/marketplace.json +19 -0
- package/.claude-plugin/plugin.json +13 -0
- package/LICENSE +30 -0
- package/NOTICE.md +145 -0
- package/README.md +817 -3
- package/bin/rigc.cjs +83 -0
- package/cli.ts +61 -0
- package/cli_core.ts +46 -0
- package/docs/AUTHORING.md +9923 -0
- package/docs/FACE.md +1948 -0
- package/docs/INGEST.md +1488 -0
- package/docs/MOTION.md +1241 -0
- package/docs/PROMPTING.md +109 -0
- package/docs/RIGGING.md +1441 -0
- package/docs/SPEC_COVERAGE.md +357 -0
- package/package.json +108 -4
- package/skills/rigc/SKILL.md +133 -0
- package/skills/rigc-face/SKILL.md +60 -0
- package/skills/rigc-ingest/SKILL.md +78 -0
- package/skills/rigc-motion/SKILL.md +51 -0
- package/skills/rigc-rigging/SKILL.md +49 -0
- package/src/areaband.ts +159 -0
- package/src/assertions/bodies/a01.ts +23 -0
- package/src/assertions/bodies/a02.ts +21 -0
- package/src/assertions/bodies/a03.ts +27 -0
- package/src/assertions/bodies/a04.ts +40 -0
- package/src/assertions/bodies/a05.ts +56 -0
- package/src/assertions/bodies/a06.ts +245 -0
- package/src/assertions/bodies/a07.ts +68 -0
- package/src/assertions/bodies/a08.ts +76 -0
- package/src/assertions/bodies/a09.ts +82 -0
- package/src/assertions/bodies/a10.ts +116 -0
- package/src/assertions/bodies/a11.ts +15 -0
- package/src/assertions/bodies/a12.ts +30 -0
- package/src/assertions/bodies/a13.ts +51 -0
- package/src/assertions/bodies/a14.ts +35 -0
- package/src/assertions/bodies/a15.ts +97 -0
- package/src/assertions/bodies/a16.ts +24 -0
- package/src/assertions/bodies/a17.ts +26 -0
- package/src/assertions/bodies/a18.ts +62 -0
- package/src/assertions/bodies/a19.ts +404 -0
- package/src/assertions/bodies/a20.ts +122 -0
- package/src/assertions/bodies/a21.ts +190 -0
- package/src/assertions/bodies/a22.ts +39 -0
- package/src/assertions/bodies/a23.ts +305 -0
- package/src/assertions/bodies/a24.ts +68 -0
- package/src/assertions/bodies/a25.ts +39 -0
- package/src/assertions/bodies/a26.ts +61 -0
- package/src/assertions/bodies/a27.ts +33 -0
- package/src/assertions/bodies/a28.ts +70 -0
- package/src/assertions/bodies/a29.ts +34 -0
- package/src/assertions/bodies/a30.ts +50 -0
- package/src/assertions/bodies/a31.ts +61 -0
- package/src/assertions/bodies/a32.ts +44 -0
- package/src/assertions/bodies/a33.ts +110 -0
- package/src/assertions/bodies/a34.ts +133 -0
- package/src/assertions/bodies/a35.ts +160 -0
- package/src/assertions/bodies/a36.ts +81 -0
- package/src/assertions/bodies/a37.ts +77 -0
- package/src/assertions/bodies/a38.ts +73 -0
- package/src/assertions/bodies/a39.ts +303 -0
- package/src/assertions/bodies/a40.ts +128 -0
- package/src/assertions/bodies/a42.ts +97 -0
- package/src/assertions/bodies/a43.ts +181 -0
- package/src/assertions/bodies/a44.ts +23 -0
- package/src/assertions/bodies/a45.ts +172 -0
- package/src/assertions/bodies/a46.ts +224 -0
- package/src/assertions/bodies/a47.ts +126 -0
- package/src/assertions/bodies/a48.ts +83 -0
- package/src/assertions/bodies/a49.ts +81 -0
- package/src/assertions/bodies/a50.ts +97 -0
- package/src/assertions/constraint_words.ts +169 -0
- package/src/assertions/emitted/index.ts +148 -0
- package/src/assertions/facts/animated_bones.ts +30 -0
- package/src/assertions/facts/animation_durations.ts +37 -0
- package/src/assertions/facts/atlas_pages.ts +19 -0
- package/src/assertions/facts/atlas_regions.ts +52 -0
- package/src/assertions/facts/bone_timelines.ts +37 -0
- package/src/assertions/facts/constraint_targets.ts +56 -0
- package/src/assertions/facts/constraints.ts +155 -0
- package/src/assertions/facts/deform_survey.ts +27 -0
- package/src/assertions/facts/event_keys.ts +55 -0
- package/src/assertions/facts/linked_meshes.ts +38 -0
- package/src/assertions/facts/mesh_attachments.ts +100 -0
- package/src/assertions/facts/region_joins.ts +34 -0
- package/src/assertions/facts/sequences.ts +85 -0
- package/src/assertions/facts/skeleton_roster.ts +45 -0
- package/src/assertions/facts/skin_entries.ts +37 -0
- package/src/assertions/facts/skin_members.ts +53 -0
- package/src/assertions/facts/slider_composition.ts +78 -0
- package/src/assertions/facts/slot_colour.ts +43 -0
- package/src/assertions/facts/stage.ts +27 -0
- package/src/assertions/facts/stage_box.ts +65 -0
- package/src/assertions/facts/stepped_poses.ts +74 -0
- package/src/assertions/facts/two_colour.ts +52 -0
- package/src/assertions/facts/vertex_polygons.ts +53 -0
- package/src/assertions/footprints.ts +367 -0
- package/src/assertions/harness.ts +109 -0
- package/src/assertions/inward_advance.ts +58 -0
- package/src/assertions/kinds.ts +105 -0
- package/src/assertions/mesh_kinds.ts +56 -0
- package/src/assertions/model/animated_bones.ts +38 -0
- package/src/assertions/model/animation_durations.ts +57 -0
- package/src/assertions/model/atlas_pages.ts +15 -0
- package/src/assertions/model/atlas_regions.ts +76 -0
- package/src/assertions/model/bone_timelines.ts +58 -0
- package/src/assertions/model/constraint_targets.ts +82 -0
- package/src/assertions/model/constraints.ts +233 -0
- package/src/assertions/model/declared.ts +125 -0
- package/src/assertions/model/deform_survey.ts +24 -0
- package/src/assertions/model/event_keys.ts +45 -0
- package/src/assertions/model/given.ts +45 -0
- package/src/assertions/model/index.ts +398 -0
- package/src/assertions/model/linked_meshes.ts +24 -0
- package/src/assertions/model/mesh_attachments.ts +119 -0
- package/src/assertions/model/parse.ts +146 -0
- package/src/assertions/model/region_joins.ts +67 -0
- package/src/assertions/model/runtime_timelines.ts +78 -0
- package/src/assertions/model/sequences.ts +157 -0
- package/src/assertions/model/skeleton_roster.ts +23 -0
- package/src/assertions/model/skin_entries.ts +69 -0
- package/src/assertions/model/skin_members.ts +64 -0
- package/src/assertions/model/slider_composition.ts +193 -0
- package/src/assertions/model/slot_colour.ts +81 -0
- package/src/assertions/model/stage.ts +28 -0
- package/src/assertions/model/stage_box.ts +51 -0
- package/src/assertions/model/stepped_poses.ts +105 -0
- package/src/assertions/model/two_colour.ts +61 -0
- package/src/assertions/model/vertex_polygons.ts +72 -0
- package/src/assertions/reasons.ts +129 -0
- package/src/assertions/region_lookups.ts +61 -0
- package/src/assertions/report.ts +189 -0
- package/src/assertions/values.ts +39 -0
- package/src/atlas.ts +2870 -0
- package/src/ballot.ts +866 -0
- package/src/bonedist.ts +643 -0
- package/src/chainfit.ts +2752 -0
- package/src/chains.ts +170 -0
- package/src/check.ts +4303 -0
- package/src/checkpics.ts +295 -0
- package/src/cli/core_commands.ts +1627 -0
- package/src/cli/repack.ts +414 -0
- package/src/cli/shared.ts +2776 -0
- package/src/cli/spine_commands.ts +820 -0
- package/src/compile.ts +9414 -0
- package/src/core/additive.ts +458 -0
- package/src/core/animation.ts +1050 -0
- package/src/core/clipping.ts +696 -0
- package/src/core/constraints.ts +1876 -0
- package/src/core/constraints_path.ts +964 -0
- package/src/core/constraints_physics.ts +881 -0
- package/src/core/constraints_slider.ts +635 -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 +1400 -0
- package/src/core/raw.ts +739 -0
- package/src/core/skins.ts +129 -0
- package/src/core/uvs.ts +469 -0
- package/src/core/vertices.ts +490 -0
- package/src/core/walk.ts +197 -0
- package/src/core/world.ts +289 -0
- package/src/correspondence.ts +15 -0
- package/src/deformbuild.ts +60 -0
- package/src/deformgen.ts +630 -0
- package/src/deformmeasure.ts +732 -0
- package/src/deformreport.ts +373 -0
- package/src/deformstructure.ts +386 -0
- package/src/deformsurvey.ts +2162 -0
- package/src/depth.ts +784 -0
- package/src/diff.ts +2252 -0
- package/src/emit.ts +134 -0
- package/src/emit_spine.ts +854 -0
- package/src/errors.ts +53 -0
- package/src/framing.ts +819 -0
- package/src/generation.ts +139 -0
- package/src/ingest.ts +2293 -0
- package/src/json-position.ts +253 -0
- package/src/keyorder.ts +587 -0
- package/src/keys.ts +486 -0
- package/src/ladder.ts +121 -0
- package/src/mesh.ts +2382 -0
- package/src/meshcompare.ts +1188 -0
- package/src/meshquality.ts +2042 -0
- package/src/meshrasters.ts +944 -0
- package/src/meshreduce.ts +1425 -0
- package/src/model.ts +1245 -0
- package/src/motion.ts +809 -0
- package/src/nonfinite.ts +54 -0
- package/src/package_meta.ts +48 -0
- package/src/png.ts +297 -0
- package/src/pose.ts +2324 -0
- package/src/preview.ts +434 -0
- package/src/region_joins.ts +54 -0
- package/src/render.ts +1013 -0
- package/src/render_core.ts +871 -0
- package/src/render_shared.ts +2958 -0
- package/src/repack.ts +495 -0
- package/src/rig.ts +2941 -0
- package/src/slots.ts +892 -0
- package/src/spine_side.ts +138 -0
- package/src/timelines.ts +837 -0
- package/src/trackgen.ts +364 -0
- package/src/transform.ts +310 -0
- package/src/types.ts +1797 -0
- package/src/validate.ts +3875 -0
- package/tools/contact.ts +126 -0
- package/tools/editor_roundtrip.ts +1641 -0
- package/tools/font5x7.ts +101 -0
- package/tools/measure_contact_depth.ts +105 -0
- package/tools/plate.ts +508 -0
- package/tools/png_probe.mjs +72 -0
package/src/chains.ts
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bone chains — the unit an author actually repairs.
|
|
3
|
+
*
|
|
4
|
+
* ## Why a figure needs more than one number per shot
|
|
5
|
+
*
|
|
6
|
+
* `check` reports a shot's MAE and its worst slot. On a ball that is the whole
|
|
7
|
+
* story. On a figure with a dozen joints it is a verdict with nowhere to put it:
|
|
8
|
+
* spineboy's second attempt read "structure ✅, motion ✗" across sixteen sets, and
|
|
9
|
+
* the fix that verdict implies is *"animate it again"*. What an author repairs is
|
|
10
|
+
* a **limb** — the gun arm, the front leg — so the report has to be able to say
|
|
11
|
+
* which limb the error is in, and how much of it (issue #123).
|
|
12
|
+
*
|
|
13
|
+
* The decomposition is **candidate-side**, and that is not an implementation
|
|
14
|
+
* detail. `docs/LADDER.md`'s honesty rule says the reference is pixels; a chain
|
|
15
|
+
* derived from the reference skeleton would be `check` reading the answer. So the
|
|
16
|
+
* chains here come from the candidate's own bone tree — its own idea of what its
|
|
17
|
+
* parts are — and the reference stays a picture that gets carved up by where the
|
|
18
|
+
* candidate drew.
|
|
19
|
+
*
|
|
20
|
+
* ## The rule
|
|
21
|
+
*
|
|
22
|
+
* **Cut the bone tree at every branch point.** A chain starts at a root bone or
|
|
23
|
+
* at a child of a bone with more than one child, and runs down while each bone it
|
|
24
|
+
* reaches has exactly one child. On a biped that is exactly the set of parts an
|
|
25
|
+
* author names: `front-thigh → front-shin → front-foot`, `rear-upper-arm →
|
|
26
|
+
* rear-bracer → gun → muzzle`, `neck → head`. On a serial figure with no branch
|
|
27
|
+
* at all — rung 8's pendulum, seven bones in a line — it is one chain, which is
|
|
28
|
+
* the honest answer: a pendulum *has* one chain, and the per-slot table below it
|
|
29
|
+
* still names which link drifted.
|
|
30
|
+
*
|
|
31
|
+
* **A single-bone chain that is itself a branch point folds into its parent
|
|
32
|
+
* chain.** Without this, spineboy's `torso` — one bone with three children — is a
|
|
33
|
+
* chain of its own carrying one slot, and the trunk above it (`root`, `hip`) is a
|
|
34
|
+
* chain carrying none: two rows that between them say what one row says. With it
|
|
35
|
+
* the trunk reads `root, hip, torso` and the figure decomposes into six chains
|
|
36
|
+
* that each own a limb.
|
|
37
|
+
*
|
|
38
|
+
* ⚠️ **Only when it is a branch point.** A single-bone chain that is a *leaf* is a
|
|
39
|
+
* real part — a one-bone arm, or rung 3's two independent bones under one root —
|
|
40
|
+
* and folding those would collapse the whole fixture into a single chain and
|
|
41
|
+
* attribute nothing. The rule keys on "does this bone branch", not on length.
|
|
42
|
+
*
|
|
43
|
+
* A chain is **named after the first bone in it that carries a slot**, root-ward
|
|
44
|
+
* first, falling back to its first bone when none does. Membership never depends
|
|
45
|
+
* on the name: it is a label, chosen so the roster reads `torso` rather than
|
|
46
|
+
* `root`. Bone names are unique in a skeleton, so chain names are too.
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/** One bone, as much of it as a chain cares about. */
|
|
50
|
+
export interface BoneNode {
|
|
51
|
+
name: string;
|
|
52
|
+
/** The parent's name, or `null` for a root bone. */
|
|
53
|
+
parent: string | null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** One slot, as much of it as a chain cares about. */
|
|
57
|
+
export interface SlotNode {
|
|
58
|
+
name: string;
|
|
59
|
+
/** The bone it hangs from. */
|
|
60
|
+
bone: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** A run of bones cut out of the tree at its branch points, and what it draws. */
|
|
64
|
+
export interface BoneChain {
|
|
65
|
+
/** The first bone in it that carries a slot, else its first bone. */
|
|
66
|
+
name: string;
|
|
67
|
+
/** Its bones, root-ward first. */
|
|
68
|
+
bones: string[];
|
|
69
|
+
/** The slots those bones carry, in the skeleton's own slot order. */
|
|
70
|
+
slots: string[];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
interface Building {
|
|
74
|
+
bones: string[];
|
|
75
|
+
slots: string[];
|
|
76
|
+
/** Set when this chain was folded away into another. */
|
|
77
|
+
foldedInto: number | null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Cut a bone tree into chains — see the rule at the top of this file.
|
|
82
|
+
*
|
|
83
|
+
* Deterministic in the order the bones arrive: chains come back in the order
|
|
84
|
+
* their first bone appears, and a bone that folds is appended to its parent
|
|
85
|
+
* chain's list. Both matter, because the roster is printed and a report that
|
|
86
|
+
* reorders itself between runs is a report nobody can diff.
|
|
87
|
+
*/
|
|
88
|
+
export function chainsOf(bones: BoneNode[], slots: SlotNode[]): BoneChain[] {
|
|
89
|
+
const order = new Map<string, number>();
|
|
90
|
+
for (const bone of bones) if (!order.has(bone.name)) order.set(bone.name, order.size);
|
|
91
|
+
|
|
92
|
+
const children = new Map<string, string[]>();
|
|
93
|
+
for (const bone of bones) {
|
|
94
|
+
if (bone.parent === null || !order.has(bone.parent)) continue;
|
|
95
|
+
const list = children.get(bone.parent);
|
|
96
|
+
if (list) list.push(bone.name);
|
|
97
|
+
else children.set(bone.parent, [bone.name]);
|
|
98
|
+
}
|
|
99
|
+
const childrenOf = (name: string): string[] => children.get(name) ?? [];
|
|
100
|
+
|
|
101
|
+
// A chain starts at a root, or wherever the tree forked above it.
|
|
102
|
+
const starts = bones.filter((b) => b.parent === null || !order.has(b.parent) || childrenOf(b.parent).length > 1);
|
|
103
|
+
|
|
104
|
+
const built: Building[] = [];
|
|
105
|
+
const chainOfBone = new Map<string, number>();
|
|
106
|
+
for (const start of starts) {
|
|
107
|
+
const run = [start.name];
|
|
108
|
+
let at = start.name;
|
|
109
|
+
for (;;) {
|
|
110
|
+
const next = childrenOf(at);
|
|
111
|
+
if (next.length !== 1) break;
|
|
112
|
+
at = next[0];
|
|
113
|
+
run.push(at);
|
|
114
|
+
}
|
|
115
|
+
const index = built.length;
|
|
116
|
+
built.push({ bones: run, slots: [], foldedInto: null });
|
|
117
|
+
for (const bone of run) chainOfBone.set(bone, index);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Fold the hubs. Root-ward first, so a chain's parent is already final when it
|
|
121
|
+
// is asked for — and through `resolve`, so a hub whose own parent folded lands
|
|
122
|
+
// in the chain that absorbed it rather than in one that no longer exists.
|
|
123
|
+
const resolve = (index: number): number => {
|
|
124
|
+
let at = index;
|
|
125
|
+
while (built[at].foldedInto !== null) at = built[at].foldedInto as number;
|
|
126
|
+
return at;
|
|
127
|
+
};
|
|
128
|
+
const byDepth = built
|
|
129
|
+
.map((chain, index) => ({ index, at: order.get(chain.bones[0]) as number }))
|
|
130
|
+
.sort((a, b) => a.at - b.at);
|
|
131
|
+
for (const { index } of byDepth) {
|
|
132
|
+
const chain = built[index];
|
|
133
|
+
if (chain.bones.length !== 1) continue;
|
|
134
|
+
const only = chain.bones[0];
|
|
135
|
+
// A leaf that stands alone is a part in its own right; a hub is not.
|
|
136
|
+
if (childrenOf(only).length === 0) continue;
|
|
137
|
+
const parent = bones.find((b) => b.name === only)?.parent ?? null;
|
|
138
|
+
if (parent === null || !chainOfBone.has(parent)) continue;
|
|
139
|
+
const target = resolve(chainOfBone.get(parent) as number);
|
|
140
|
+
if (target === index) continue;
|
|
141
|
+
built[target].bones.push(only);
|
|
142
|
+
chain.foldedInto = target;
|
|
143
|
+
chainOfBone.set(only, target);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
for (const slot of slots) {
|
|
147
|
+
const owner = chainOfBone.get(slot.bone);
|
|
148
|
+
if (owner === undefined) continue;
|
|
149
|
+
built[resolve(owner)].slots.push(slot.name);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return built
|
|
153
|
+
.filter((chain) => chain.foldedInto === null)
|
|
154
|
+
.map((chain) => ({
|
|
155
|
+
name: chain.bones.find((bone) => chain.slots.some((slot) => slotBone(slots, slot) === bone)) ?? chain.bones[0],
|
|
156
|
+
bones: chain.bones,
|
|
157
|
+
slots: chain.slots,
|
|
158
|
+
}));
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function slotBone(slots: SlotNode[], name: string): string | null {
|
|
162
|
+
return slots.find((slot) => slot.name === name)?.bone ?? null;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** The chain each slot belongs to, keyed by slot name. */
|
|
166
|
+
export function chainBySlot(chains: BoneChain[]): Map<string, string> {
|
|
167
|
+
const out = new Map<string, string>();
|
|
168
|
+
for (const chain of chains) for (const slot of chain.slots) out.set(slot, chain.name);
|
|
169
|
+
return out;
|
|
170
|
+
}
|