Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

The examples of the rig-c toolchain ([`@rig-c/core`](https://github.com/rig-c/core),
[`@rig-c/parts`](https://github.com/rig-c/parts), [`@rig-c/play`](https://github.com/rig-c/play)),
in two halves:
as source assets, standalone samples and trials:

- **The corpus** — the inputs the toolchain's gates fetch by a pinned commit:
`demo`, `wind`, `scarf`, `reference-demo`, `reference-sample`,
`three-quarter` and `family`. Their paths are frozen. `@rig-c/parts`'
`scripts/fetch-examples.sh` copies files from a commit it pins, and
`@rig-c/play`'s fixture pins a commit too, so a change to a corpus
directory reaches a consumer only when that consumer moves its pin.
- **Standalone samples** — [`rigboy`](rigboy/README.md), the first SD-style motion character rig here: an original full side-profile character with seven modest motion/control samples and a live aim dial. It is not added to a consumer’s pinned corpus by this example.
- **The trials** — what was tried with the toolchain to answer "does this
work?", kept whether it passed or failed, under `trials/` (see
[Trials](#trials)).
Expand Down Expand Up @@ -87,6 +88,14 @@ corpus directory.
layers/full/parts/<tag>.png one RGBA PNG per See-through layer, named by its tag
layers/head/... the same for the head run
generation.json the generation record: checkpoint, sampler, control, seed, prompts, and how the seed was chosen
rigboy/generation/ the selected profile control, pose points and exact generation graph
rigboy/controls.js player helpers for the aim dial and optional world travel
rigboy/config.json the standalone character's mesh, bone and control authoring
rigboy/motions.json keyed motion clips and the aim dial's pose range
rigboy/assembled/ structural pieces from the existing layer runs
rigboy/rig/ the rig and motion specs with their part images
rigboy/build/ the packed player model, atlas and page
rigboy/preview.webp a labeled montage of seven motion/control samples
reference-demo/python-reference/ the reference implementation's rendered idle loop (gif, webp) and its two README images, kept for comparison with what rig-parts renders
reference-demo/candidates.json that character's eighteen measured candidates (figures only; the other images are not published)
scarf/candidates.json scarf's six measured seeds (figures only; the other images are not published)
Expand All @@ -102,7 +111,7 @@ Paths inside `meta.json` (`image`) are relative to the character directory.
`painting.png` still carries the ComfyUI workflow it was generated by, in its
`prompt` text chunk; it is left there as provenance.

The six characters:
The standalone paintings:

| key | seed | chosen from | See-through layers | notes |
|---|---|---|---|---|
Expand All @@ -112,6 +121,7 @@ The six characters:
| `reference-demo` | 71004 | 18 candidates over three prompt variants (`candidates.json`) | 29 full + 29 head | the reference implementation's twin-tail character with clasped hands; the README character until rig-parts issue #227 took it off display for its malformed fingers. Published as `demo` until then |
| `three-quarter` | 250011 | 10 seeds in two batches under two pose wordings (`generation.json`), read by eye at the face | 29 full + 29 head | the head turned toward image left and tilted, painted to read rig-parts' head-frame turn figures against the frontal faces (rig-parts issue #250); inputs only, no rig-parts example reads it yet |
| `wind` | 372108 | 24 seeds under three wordings (`candidates.json`), screened by `rig-parts painting`, the seven best re-read with eye-placed joints | 29 full + 29 head | a figure for wind interaction (rig-parts issue #372): very long twin tails wrapped in red ribbons and a wide two-layer skirt, arms and legs held apart so the painting passes `rig-parts painting` |
| [`rigboy`](rigboy/README.md) | 781301 | paired public-checkpoint comparison, selected by source and layer review (`generation.json`) | 29 full + 29 head | original short-haired side-profile boy, jacket, trousers, orange boots and a two-handed sci-fi toy grip; built rig, seven modest motion/control samples and preview included; [source-specific limits](rigboy/README.md#measured-limits) |

`reference-demo` and `reference-sample` are the two characters the reference
implementation ran: rig-parts keeps them as fixtures, compared against that
Expand Down Expand Up @@ -333,7 +343,7 @@ trial's README says what was withheld.

Each checkpoint's own terms are its publisher's.

`demo`, `three-quarter`, `wind` — **Hassaku XL (Illustrious)**, "v1.3 - Style A", by Ikena,
`demo`, `three-quarter`, `wind`, `rigboy` — **Hassaku XL (Illustrious)**, "v1.3 - Style A", by Ikena,
<https://civitai.com/models/140272>. Credit, as sharing it requires:

> Painted with Hassaku XL (Illustrious) v1.3 Style A by Ikena
Expand All @@ -353,7 +363,10 @@ observed 2026-09-27: `allowCommercialUse` is `["Image", "RentCivit"]`,
`allowDerivatives` is `true`, `allowDifferentLicense` is `false`. Those fields
are the publisher's statement about the model, reproduced here as observed;
they are not a licence this repository grants. The same holds for the
Hassaku XL fields above.
Hassaku XL fields above. `rigboy` uses the credited v1.3 Style A version
([publisher version](https://civitai.com/models/140272?modelVersionId=1240288));
its generation record retains that provenance without claiming an unrestricted
licence for the checkpoint.

See-through and its wrapper are not redistributed here, only their output.

Expand Down
88 changes: 88 additions & 0 deletions rigboy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# rigboy

![Seven modest motion and control samples](preview.webp)

The first SD-style motion character rig in the rig-c examples: an original short-haired boy in a jacket, trousers and orange boots, in full side profile with a two-handed sci-fi toy grip. It takes the motion-demo role of Spineboy, with original artwork and authoring; no benchmark art, rig data or coordinates were copied.

| Sample | What it demonstrates |
| --- | --- |
| `idle` | Translated chest breath, gentle head motion and fringe physics |
| `walk` | A modest keyed contact/passing loop with separate, level feet |
| `run` | A faster, modest keyed loop with shorter support and airborne intervals |
| `jump` | Anticipation, air and landing |
| `aim` | A live dial over −8° to +8° around the painted upward toy pose |
| `shoot` | Modest arm recoil and spring settling |
| `hit` | A small flinch and return |

The `aim` animation stores the dial's pose range. The `aim_dial` slider reads `aim_control.rotate`; interaction drives that property instead of autoplaying the range. Toy world angles are approximately 82°, 90° and 98° at the dial's endpoints and center. Both hands stay with the toy. The hidden far upper arm has no artwork for an independent gesture. `look` is omitted because this profile does not supply the hidden facial side.

## Play

Pins: `@rig-c/parts@1.79.1`, `@rig-c/core@2.81.1` (the `rigc` CLI), and `@rig-c/play@1.21.2`.

Serve this repository over HTTP. From an application page at the repository root, with the player package available to your module loader:

```js
import { loadModel, RigPlayer } from '@rig-c/play';
import { rigboyControls } from './rigboy/controls.js';

const assets = await loadModel({
modelUrl: new URL('./rigboy/build/skeleton.model.json', document.baseURI).href,
setsUrl: null,
regions: 'data',
});
// The loader resolves skeleton.png relative to the model URL.
// No separate atlas URL or attachment-sets file is needed.
const root = document.getElementById('rigboy'); // a positioned world origin, Y-up
const player = new RigPlayer(root, assets, { mode: 'dom', meshBackend: 'canvas2d' });
player.play('idle');
const controls = rigboyControls(player);
player.renderer.syncPixelRatio(); // call again after changing the root's display scale

let last = performance.now();
let frameId = requestAnimationFrame(function tick(now) {
player.frame((now - last) / 1000);
last = now;
frameId = requestAnimationFrame(tick);
});

// UI examples; invoke these when the user selects a control or clip:
// controls.setAimDegrees(4); // finite values clamp to −8°..+8°
// controls.aimAt([worldX, worldY]); // Y-up; returns requested/applied/clamped
// player.play('walk'); controls.setAimDegrees(0); controls.setTravel(true);
// player.play('shoot', { loop: false }); controls.setTravel(false);
// controls.setAimDegrees(0); controls.recoilPhysics(); // restore the authored arm spring

function unload() {
cancelAnimationFrame(frameId);
controls.dispose();
player.dispose();
assets.dispose();
}
```

The app lays out and scales the root element. Walk and run are **in-place** cycles: stance feet move backward relative to the body. `controls.setTravel(true)` adds root advance using unwrapped track time (64 rig pixels/s for walk, 192 for run); that helper was used for world contact checks. The model alone does not plant feet in an application's world. Disable travel for stationary clips; the application owns movement, collisions and camera. `aimAt` reports clamping outside the narrow arc and refuses targets inside its geometric reach. `setAimDegrees` disables arm settling for direct aim; `recoilPhysics` restores it for shooting.

## Files and reproduction

[`generation.json`](generation.json) records the exact selected painting, prompts, seed, checkpoint and See-through settings. [`generation/graph.json`](generation/graph.json), its adjacent `control.png` and `pose.json` preserve the selected synthetic profile conditioning. `painting.png`, `inputs/` and `layers/` retain the source and both layer runs, including depth files. `assembled/` holds the structural pieces and their per-piece provenance; `config.json` and `motions.json` author the rig. `rig/` is the generated rig/motion/image set and `build/` the packed model, atlas and page.

With the pinned packages installed, run from the repository root:

```sh
rig-parts rig --config rigboy/config.json --parts rigboy/assembled --out rigboy/rig --idle-keys direct
rigc build --rig rigboy/rig/rig.json --motion rigboy/rig/motion.json --out rigboy/build --profile rig-play --pack --page-edges free --pack-shape polygon
rig-parts check --rig rigboy/rig --parts rigboy/assembled --source rigboy/painting.png --requirements rigboy/requirements.json --out rigboy/check
```

The preview is a labeled loop montage; live aim is a property-driven control. Physics is stepped during playback, so keyed loop closure does not promise exact physics-state closure.

## Measured limits

This v1 keeps modest amplitudes within the tested full-profile range. The retained scoped check passed with 8/12 checks measured and 4 skipped (blink, idle lag chain, held arm/hand swing, stress chain). Sampled folds and native boundary review support that range, not pixel-perfect source fidelity or unseen-side motion. For this source and tested workflow, deeper gait needs artwork initially drawn as separate parts; this is not a universal side-profile limitation. See [issue #78](https://github.com/rig-c/examples/issues/78).

## Terms and credits

Painted with **Hassaku XL (Illustrious) v1.3 Style A by Ikena** ([publisher](https://civitai.com/models/140272?modelVersionId=1240288)), Fair AI Public License 1.0-SD, as recorded in the source provenance. No LoRA, existing-character prompt/reference, hand detailer or painted fill was used. Structural garment separations and automatic assembly operations are recorded in `assembled/parts.json`; the result is not claimed to be an unchanged copy of every raw layer.

The repository's [MIT licence](../LICENSE) and the checkpoint publisher's own terms concern their respective material. A package's MIT licence is not a licence grant for the checkpoint. The checkpoint and See-through implementation are not redistributed here.
Loading
Loading