nx_motion_rig.nx
buildroot/runtime/nx_motion_rig.nx
about
nx_motion_rig.nx -- THE JOB BEHIND /motion (2026-09-06): one upload directory in; a rigged, rendered, exported result out,
every composed organ's own report kept beside it, a sha256 of the rig, and a done marker written LAST.
nx_motion_rig rig <jobdir> [cells]
nx_motion_rig anim <jobdir> <donor.nxa> <pose_id> <clipkey>
The jobdir holds in.<kind> and kind (written by the door, nx_motion_serve). Nothing here re-implements anything: the
converters, the auto-rig, the UV unwrap, the rasteriser, the exporter, the retarget and the player are the estate's
PROMOTED organs, forked with their stdout kept as log_<stage>.txt. A stage that refuses leaves its exit code in the
status rows and the job still finishes with `done`, so the page reads FAILED at a named stage -- never green, never hung.
MEASURED ON THE FIRST REAL JOB (house mesh, 2026-09-06, 16.9 s): the textured rasteriser REFUSES an asset without a TEXC
section ("run nx_nxa_texc first"), so the render stage now composes nx_nxa_texc (a bone-anchored UV unwrap from the fresh
SKEL+SKIN) before nx_nxa_texbake view; and nx_filehash lives at the serving root, not in _offc, so every fork resolves
_offc/<name>.elf first and ./<name>.elf second -- a 127 from an absent twin is not a property of the organ.
HONEST LIMIT, stated here and on the page: the promoted nx_autorig_mesh applies [cells] to the WEIGHT solve; its skeleton
runs at the estate's conf resolution until the one-call organ takes the ladder for both stages (motion.plan MO12).
license_tier: ORIGINAL expect_exit: 0
dependencies 2 imports · 0 importers
imports: nx_syscalls.nxnx_motion_lib.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 19 | const MR_EXIT_OK: i64 = 0 |
| 20 | const MR_EXIT_USAGE: i64 = 2 |
| 21 | const MR_EXIT_REFUSE: i64 = 3 |
| 22 | const MR_CELLS_DEFAULT: i64 = 192 // the referee-measured rung on the house rig (923 permil); a caller's cells wins |
| 23 | const MR_STATUS_CAP: i64 = 8192 |
| 24 | const MR_RC_CONVERT: i64 = 0 |
| 25 | const MR_RC_RIG: i64 = 1 |
| 26 | const MR_RC_TEXC: i64 = 2 |
| 27 | const MR_RC_VIEW: i64 = 3 |
| 28 | const MR_RC_GLB: i64 = 4 |
| 29 | const MR_RC_HASH: i64 = 5 |
| 30 | const MR_RC_WORDS: i64 = 6 |
| 31 | const MR_N_VERTS: i64 = 0 |
| 32 | const MR_N_TRIS: i64 = 1 |
| 33 | const MR_N_LIMBS: i64 = 2 |
| 34 | const MR_N_JOINTS: i64 = 3 |
| 35 | const MR_N_BRANCHES: i64 = 4 |
| 36 | const MR_N_MIXED: i64 = 5 |
| 37 | const MR_N_WORDS: i64 = 6 |
| 38 | const MR_SHA_LEN: i64 = 64 |
| 39 | const MR_RC_KIND_REFUSED: i64 = 415 // the HTTP status the door would answer for the same refusal, kept as one vocabulary |
functions
| 41 | func mrw(s: *u8) -> i64 { sys_write(1, s, mo_slen(s)); return 0 } |
| 43 | func mr_elf(name: *u8) -> *u8 |
| 50 | func mr_kv(b: *u8, o: i64, k: *u8, v: i64) -> i64 { var p: i64 = mo_cat(b, o, k); b[p] = 61 as u8; p = mo_num(b, p + 1, v); b[p] = 10 as u8; return p + 1 } |
| 51 | func mr_ks(b: *u8, o: i64, k: *u8, s: *u8) -> i64 { var p: i64 = mo_cat(b, o, k); b[p] = 61 as u8; p = mo_cat(b, p + 1, s); b[p] = 10 as u8; return p + 1 } |
| 53 | func mr_status(jobdir: *u8, kind: *u8, cells: i64, stage: *u8, ok: i64, rcs: *i64, nums: *i64, sha: *u8, ms: i64) -> i64 |
| 78 | func mr_done(jobdir: *u8) -> i64 { return mo_write_all(mo_join(jobdir, "done" as *u8), "1\n" as *u8, 2) } |
| 80 | func mr_logv(path: *u8, key: *u8) -> i64 |
| 87 | func mr_sha_from_log(path: *u8, out: *u8) -> i64 |
| 103 | func mr_render(jobdir: *u8, src: *u8, texp: *u8, png: *u8, logt: *u8, logv: *u8, rc_texc: *i64) -> i64 |
| 113 | func mr_rig(jobdir: *u8, cells: i64) -> i64 |
| 214 | func mr_anim(jobdir: *u8, donor: *u8, pose: *u8, key: *u8) -> i64 |
| 280 | func main(argc: i64, argv: *i64) -> i64 |