nx_gate_rig_motion_stream_t140.nx
buildroot/runtime/nx_gate_rig_motion_stream_t140.nx
about
Native real-asset gate; admission oracle copied unchanged from nx_nxa_retarget 2026-09-09.
Test-only oracle, no live runtime dependency or asset writer invocation.
nx_nxa_retarget.nx -- DONOR RETARGET: drive a rigged NXA that carries NO authored clips from a
SOURCE rig's POSE, preserving the TARGET's OWN bone lengths BY CONSTRUCTION.
WHY (measured 2026-08-23): all five donors report poses_in_library=0 -- they carry rigs but no
authored motion, so the visiting cast on /world/beach stand as statues while every other piece
of the character stack ships. This organ is the missing leg.
THE NAIVE RETARGET IS PROVABLY WRONG, AND THAT PROOF IS WHY THIS FILE EXISTS. In the NXA
normative form M x = D(x-b) + b + dt, applying joint j's transform to its own bind position
gives M_j b_j = b_j + dt_j. So a posed joint sits at b_j + dt_j and POSED BONE LENGTH IS A PURE
FUNCTION OF dt. Copying source dt -- or scaling it by a height ratio -- therefore cannot preserve
the target's bone lengths unless the two skeletons are proportionally identical, and ours are
emphatically not (104 joints at 1.715 m against 370 joints on a differently-proportioned donor).
A dt-transfer retarget stretches and shears limbs on every donor: the exact defect the operator
named as awful motion. It is not shipped here.
THE ALGORITHM (four lines, and limb length is preserved BY CONSTRUCTION, not by tolerance):
A_j = conj(D_parent) . D_j source: world delta -> local articulation
W_j = W_parent . A_j target: parent-first composition
P_j = P_parent + W_parent (x) (b'_j - b'_p) the TARGET's OWN bone vector, ROTATED ONLY
dt'_j = P_j - b'_j
The target bone vector is only ever rotated -- never scaled, never replaced -- so no pose this
organ can emit is able to change a target bone's length. The limb-length tooth in the gate is a
REGRESSION GUARD on that property, not the thing that establishes it.
The general form needs a similarity conjugation by each joint's bind orientation. It collapses
to the four lines above because NXA bind orientation is IDENTITY BY CONSTRUCTION -- nx_nxa_skin
emits SKEL quats as identity and states the reason in its own header (delta-LBS convention:
animation is applied RELATIVE to bind). VERIFY THAT BEFORE TRUSTING IT: the `bindquats` verb
measures it per asset and is the reason this organ has three verbs instead of one.
JOINT MAPPING IS BY TOPOLOGY AND NORMALIZED BIND POSITION, NEVER BY NAME. SKEL carries no names
by design, and the donors come from different authoring tools -- a name map would be the
classifier-keys-on-a-string defect. The normalized space is the same one nx_nxa_joints uses:
every axis divided by the rig's OWN stature extent, so a taller or differently-scaled rig lands
in the same space. The stature axis is DERIVED as the largest bind extent, never assumed z-up:
the FBX/VRM donors arrive Y-up, which is the axis-convention defect a sibling lane measured in
the renderer on the same day.
dependencies 7 imports · 0 importers
imports: nx_syscalls.nxnx_nxa.nxnx_nxa_fk.nxnx_skeleton.nxnx_nxa_posewrite_lib.nxnx_nxa_anim_lib.nxnx_nxa_rig_motion_stream_t140.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
| 57 | const NR_Q12: i64 = 4096 // quaternion fixed-point unit (NXA v1 spec) |
| 58 | const NR_WJ: i64 = 8 // words per SKEL joint (spec: parent,tx,ty,tz,qx,qy,qz,qw) |
| 59 | const NR_WPE: i64 = 8 // words per POSE entry (spec: joint,qx,qy,qz,qw,dtx,dty,dtz) |
| 60 | const NR_PERMIL: i64 = 1000 |
| 61 | const NR_INF: i64 = 4 // SKIN influences per vertex, fixed by the format |
| 62 | const NR_WQ: i64 = 4096 // SKIN weight scale q12, sum = 4096 (spec) |
| 63 | const NR_FX: i64 = 256 // nx_skeleton weight scale fx256, sum = 256 |
| 67 | const NR_DT_MODEL: i64 = 1 |
| 68 | const NR_WFULL: i64 = 1000 |
| 69 | const NR_MODE: i64 = 0x1a4 // 0644, matching every sibling NXA writer |
| 70 | const NR_EXIT_USAGE: i64 = 2 |
| 71 | const NR_EXIT_REFUSE: i64 = 3 |
| 72 | const NR_EXIT_NOSEC: i64 = 5 |
| 73 | const NR_EXIT_NONIDENT: i64 = 1 // bindquats: a measurement outcome, not an error |
functions
| 75 | func nrw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 76 | func nrerr(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(2, s, n); return 0 } |
| 77 | func nrn(v: i64) -> i64 |
| 90 | func nr_atoi(s: *u8) -> i64 called by 1: main |
| 100 | func nr_streq(a: *u8, b: *u8) -> i64 called by 1: main |
| 109 | func nr_q(p: *i64, i: i64) -> *i64 { return ((p as i64) + i * 32) as *i64 } |
| 114 | func nr_norm(bind: *i64, n: i64, out: *i64) -> i64 |
| 152 | func nr_d2(a: *i64, ai: i64, b: *i64, bi: i64) -> i64 |
| 162 | func nr_mean_nn(nrm: *i64, n: i64) -> i64 |
| 182 | func nr_load(path: *u8, lp: *i64) -> *u8 |
| 196 | func nr_sym(bind: *i64, n: i64, k: i64, tol: i64) -> i64 called by 1: nr_frame |
| 236 | func nr_frame(bind: *i64, n: i64, ax: *i64) -> i64 |
| 277 | func nr_permute(bind: *i64, n: i64, ax: *i64, sg: *i64, out: *i64) -> i64 called by 1: nmg_asset |
| 289 | func nr_reframe_v(v: *i64, out: *i64, sax: *i64, ssg: *i64, tax: *i64, tsg: *i64) -> i64 called by 1: nmg_sample |
| 294 | func nr_frame_det(sax: *i64, ssg: *i64, tax: *i64, tsg: *i64) -> i64 |
| 306 | func nr_parity(ax: *i64) -> i64 called by 1: nmg_asset |
| 328 | func nr_extremity_band(bind: *i64, par: *i64, n: i64, upax: i64, want_max: i64) -> i64 |
| 374 | func nr_band_for_pop(vert: *i64, nv: i64, upax: i64, want_max: i64, minpop: i64, ulo: i64, uhi: i64) -> i64 called by 1: nr_anterior |
| 393 | func nr_anterior(vert: *i64, nv: i64, ax: *i64, blo: i64, bhi: i64, minpop: i64, ev: *i64) -> i64 |
| 474 | func nr_bindquats(path: *u8) -> i64 |
| 508 | func nmg_sample(anim: *i64, tidx: *i64, order: *i64, ns: i64, t: i64, sax: *i64, ssg: *i64, tax: *i64, tsg: *i64, q: *i64, d: *i64) -> i64 called by 1: nmg_asset calls 6: sys_mmapnr_frame_detna_eval_track_orderedna_eval_tracknr_reframe_vsys_munmap |
| 534 | func nmg_bones(nt: i64, par: *i64, bind: *i64, W: *i64, P: *i64) -> i64 |
| 572 | func nmp_num(b:*u8,o:i64,v:i64)->i64 called by 1: nmg_asset |
| 582 | func nmp_rows(nj:i64,bind:*i64,q:*i64,dt:*i64,out:*i64,scr:*i64)->i64 |
| 613 | func nmg_asset(spath: *u8, dpath: *u8, outpath:*u8, samples:i64) -> i64 |
| 988 | func main(argc: i64, argv: *i64) -> i64 |