rig-parts 1.73.1 → 1.74.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/docs/AUTHORING.md +31 -0
- package/package.json +1 -1
- package/src/build.ts +1 -0
- package/src/rig.ts +5 -0
- package/src/turn.ts +19 -0
package/docs/AUTHORING.md
CHANGED
|
@@ -2854,6 +2854,36 @@ shin's tip against the stage point it stands on.
|
|
|
2854
2854
|
with `exponent` 6 on `legwear`, 1.6. The same dance on `demo` as tracked, whose legs ride the
|
|
2855
2855
|
hip, reads 18.36.
|
|
2856
2856
|
|
|
2857
|
+
|
|
2858
|
+
### Equal-depth units in a sampled turn
|
|
2859
|
+
|
|
2860
|
+
With `turn.roles`, `turn.depths` remains a legacy layer-order table; it does
|
|
2861
|
+
not override sampled unit motion. Its See-through values (larger means farther
|
|
2862
|
+
back) are not interchangeable with `turn.unitDepths`, whose values are calibrated
|
|
2863
|
+
scalar depths in rig pixels (larger means nearer the viewer).
|
|
2864
|
+
|
|
2865
|
+
To make a mirrored pair of `"unit"` parts travel equally, author equal
|
|
2866
|
+
`turn.unitDepths.<part>` values. A part entry wins over a bone entry, including
|
|
2867
|
+
zero. Otherwise the producer samples the primary surface at each unit's setup
|
|
2868
|
+
landmark, calibrating `pivot + sampledZ - surfaceZRef`; mirrored landmarks on an
|
|
2869
|
+
asymmetric depth sheet can therefore travel differently. Only when that sample
|
|
2870
|
+
is unavailable does it fall back to the unit's own sheet. No symmetry is inferred
|
|
2871
|
+
from part names or positions, and equal legacy `depths` do not establish it.
|
|
2872
|
+
|
|
2873
|
+
Equal unit depths yield the same signed translation within a frame on both yaw
|
|
2874
|
+
and pitch; the sign reverses between negative and positive angles. Their local
|
|
2875
|
+
keys compensate for the parent carrier, so compare the complete inherited pose
|
|
2876
|
+
when measuring screen travel. For ears, the existing behind-cheek depth check
|
|
2877
|
+
still applies to an explicit override; use a depth at or behind both cheeks.
|
|
2878
|
+
|
|
2879
|
+
The build report prints `WARN RIG_TURN_UNIT_DEPTH_SUPPORT` when an implicit unit
|
|
2880
|
+
sample lies outside the surface's source pixel-index bounds or its sampled art
|
|
2881
|
+
alpha is below 255. It names the unit, source surface and sheet, raw crop
|
|
2882
|
+
coordinate, clamped art index and support alpha. Scalar-sheet alpha is not art
|
|
2883
|
+
support. This warning retains the extended scalar sample, all motion arithmetic
|
|
2884
|
+
and existing refusal behavior; it is not a gate. Explicit `unitDepths` entries
|
|
2885
|
+
bypass that sample and its warning, including an explicit zero.
|
|
2886
|
+
|
|
2857
2887
|
## 4. The command order
|
|
2858
2888
|
|
|
2859
2889
|
Two steps are external: the See-through runs (by any route; the optional `comfy seethrough` adapter is only a client for a ComfyUI box). Everything else is this tool.
|
|
@@ -4528,6 +4558,7 @@ and stay absent).
|
|
|
4528
4558
|
| <a id="RIG_TURN_HEAD_BONE"></a>`RIG_TURN_HEAD_BONE` | `buildRig` found no `"head"` (or body turn root) bone when emitting 2.5D turn carriers | declare `"head"` (or the body turn root bone) in `config.bones` |
|
|
4529
4559
|
| <a id="RIG_TURN_SHARED_DEPTH_SCALE"></a>`RIG_TURN_SHARED_DEPTH_SCALE` | `"surface"` parts bound to one head or body turn declare different `near` polarities or `zScale` values | use one shared `near` and `zScale` across all `"surface"` parts in the turn group |
|
|
4530
4560
|
| <a id="RIG_TURN_UNIT_DEPTH_REQUIRED"></a>`RIG_TURN_UNIT_DEPTH_REQUIRED` | a `"unit"` bone has neither a `unitDepths` entry nor a readable `"surface"` depth sheet | provide a `"surface"` depth sheet or an explicit `unitDepths.<part>` value |
|
|
4561
|
+
| <a id="RIG_TURN_UNIT_DEPTH_SUPPORT"></a>`RIG_TURN_UNIT_DEPTH_SUPPORT` | WARN only: an implicit unit depth sample is outside the source surface pixel-index bounds or its sampled art alpha is below 255 | author an explicit calibrated `unitDepths.<part>` value when this cross-part extrapolation is unintended; existing scalar sampling and refusal behavior are retained |
|
|
4531
4562
|
| <a id="RIG_TURN_EAR_DEPTH_BEHIND_CHEEK"></a>`RIG_TURN_EAR_DEPTH_BEHIND_CHEEK` | an ear bone in `config.turn.roles` has a calibrated depth at or in front of the cheek surface depth | place the ear behind the cheek surface (for example via `config.turn.unitDepths`) |
|
|
4532
4563
|
|
|
4533
4564
|
## 7. The bars `check` enforces, and what only an eye answers today
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rig-parts",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.74.0",
|
|
4
4
|
"description": "AI-authored 2D character parts from one anime painting and its See-through layer decomposition: measured parts, weighted-mesh rig specs, verified through rig-c before anything is written. A CLI for agents that cannot see the image.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/build.ts
CHANGED
|
@@ -1528,6 +1528,7 @@ export function rigStage(input: RigStageInput, rigc: RigcRunner, scratch: string
|
|
|
1528
1528
|
if (from !== null) log(` animations beside the idle, from ${from.file} as written: ${Object.keys(from.table).join(', ') || 'none'}`);
|
|
1529
1529
|
log(faceAxisLine(rig.faceAxis));
|
|
1530
1530
|
if (rig.turn !== null) log(turnLine(rig.turn));
|
|
1531
|
+
for (const w of rig.turnWarnings ?? []) log(` WARN ${w.code}: ${w.object} — ${w.detail}`);
|
|
1531
1532
|
log(
|
|
1532
1533
|
rig.idleKeys === 'ctl'
|
|
1533
1534
|
? ` idle keys ctl: ${rig.meshKeyed.length} mesh-driving bone(s) keyed by the idle, each keyed through a same-origin <bone>_ctl parent`
|
package/src/rig.ts
CHANGED
|
@@ -1132,6 +1132,8 @@ export interface AttachmentSetsFile {
|
|
|
1132
1132
|
}
|
|
1133
1133
|
|
|
1134
1134
|
export interface RigOutput {
|
|
1135
|
+
/** Sample-support warnings for the build report only; no emitted-file field. */
|
|
1136
|
+
turnWarnings?: Problem[];
|
|
1135
1137
|
depthReferences?: Array<{ part: string; size: [number, number]; depth: PartDepthReference }>;
|
|
1136
1138
|
rig: RigSpec;
|
|
1137
1139
|
/** Internal explicit-layout provenance; serialized only as an external companion. */
|
|
@@ -3653,8 +3655,10 @@ export function buildWaistPairSource(
|
|
|
3653
3655
|
for (const [bName, bEntry] of B) {
|
|
3654
3656
|
boneLandmarks.set(bName, [bEntry.x, bEntry.y]);
|
|
3655
3657
|
}
|
|
3658
|
+
const turnWarnings: Problem[] = [];
|
|
3656
3659
|
if (cfg.turn?.roles !== undefined || cfg.turn?.body !== undefined) {
|
|
3657
3660
|
buildDepth25DTurn(rig, motion, {
|
|
3661
|
+
warnings: turnWarnings,
|
|
3658
3662
|
turn: cfg.turn,
|
|
3659
3663
|
parts: parts.parts,
|
|
3660
3664
|
images,
|
|
@@ -3717,6 +3721,7 @@ export function buildWaistPairSource(
|
|
|
3717
3721
|
autoMotion,
|
|
3718
3722
|
faceAxis,
|
|
3719
3723
|
turn: turned?.rows ?? null,
|
|
3724
|
+
...(turnWarnings.length === 0 ? {} : { turnWarnings }),
|
|
3720
3725
|
...(sets === undefined ? {} : { sets }),
|
|
3721
3726
|
...(explicitLayout.plan === undefined ? {} : { layout: explicitLayout.plan }),
|
|
3722
3727
|
};
|
package/src/turn.ts
CHANGED
|
@@ -1478,6 +1478,8 @@ export function sampleUnitPartDepth(scalar: Raster, art: Raster, ref: PartDepthR
|
|
|
1478
1478
|
}
|
|
1479
1479
|
|
|
1480
1480
|
export interface Depth25DTurnOptions {
|
|
1481
|
+
/** Report-only diagnostics; never serialized into the rig or motion. */
|
|
1482
|
+
warnings?: Problem[];
|
|
1481
1483
|
turn: TurnSpec;
|
|
1482
1484
|
parts: ReadonlyArray<{ name: string; x: number; y: number; w: number; h: number; depth?: PartDepthReference }>;
|
|
1483
1485
|
images: ReadonlyMap<string, Raster>;
|
|
@@ -1684,6 +1686,23 @@ function buildDepth25DTurnGroup(
|
|
|
1684
1686
|
const padY = Math.floor((ext.height - rec.h) / 2);
|
|
1685
1687
|
const lx = Math.max(0, Math.min(ext.width - 1, Math.round(pt[0] - rec.x + padX)));
|
|
1686
1688
|
const ly = Math.max(0, Math.min(ext.height - 1, Math.round(pt[1] - rec.y + padY)));
|
|
1689
|
+
// The scalar extension has opaque alpha even where the source art
|
|
1690
|
+
// supplies no opaque support. Report that extrapolation, not its value.
|
|
1691
|
+
if (opts.warnings !== undefined) {
|
|
1692
|
+
const art = opts.images.get(rec.name);
|
|
1693
|
+
const rawX = pt[0] - rec.x, rawY = pt[1] - rec.y;
|
|
1694
|
+
const outside = rawX < 0 || rawY < 0 || rawX > rec.w - 1 || rawY > rec.h - 1;
|
|
1695
|
+
const artX = Math.max(0, Math.min(rec.w - 1, lx - padX));
|
|
1696
|
+
const artY = Math.max(0, Math.min(rec.h - 1, ly - padY));
|
|
1697
|
+
const alpha = art?.data[(artY * rec.w + artX) * 4 + 3];
|
|
1698
|
+
if (alpha !== undefined && (outside || alpha !== 255)) {
|
|
1699
|
+
opts.warnings.push({
|
|
1700
|
+
code: 'RIG_TURN_UNIT_DEPTH_SUPPORT',
|
|
1701
|
+
object: `${group.fieldPrefix}.roles.${part}`,
|
|
1702
|
+
detail: `unit part "${part}" (bone "${bName}") samples surface "${rec.name}" sheet "${rec.depth.image}" at raw crop [${pt[0]}, ${pt[1]}] (${outside ? 'outside' : 'inside'} source sample bounds [${rec.x}, ${rec.y}]..[${rec.x + rec.w - 1}, ${rec.y + rec.h - 1}]); sampled art [${artX}, ${artY}] has art alpha ${alpha}, expected 255 without clamping; the existing extended scalar sample is retained; author ${group.fieldPrefix}.unitDepths.${part} for an explicit calibrated depth`,
|
|
1703
|
+
});
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1687
1706
|
const zUnit = levelToDepthZ(ext.data[(ly * ext.width + lx) * 4], rec.depth);
|
|
1688
1707
|
resolved = pyRound(pivot + (zUnit - zRef), 4);
|
|
1689
1708
|
}
|