nx_nxa2glb_gate.nx
buildroot/runtime/nx_nxa2glb_gate.nx
about
nx_nxa2glb_gate.nx -- THE GATE FOR THE RIGGED EXPORT LEG: NXANIM01 (SKEL+SKIN) -> glTF skins/JOINTS_0/WEIGHTS_0/IBM.
SUBJECT: the nx_mesh2glb ELF, forked for real (tr_run_capture). The rig surviving export is measured by
INDEPENDENT READERS, never by this gate re-parsing what the subject wrote with the subject's own assumptions:
(a) nx_gltf2mesh -- our glTF IMPORTER -- counts skin_joints in the exported .glb; it reads skins[].joints itself
(b) gltf_load_std -- our native LOADER lib -- must load it and agree on vertex and triangle counts
(c) ANTI-VACUITY, asserted BEFORE (a): the JSON declares skins, JOINTS_0, WEIGHTS_0, inverseBindMatrices, and
the JOINTS_0 accessor count equals the vertex count, parsed with the loader lib's own gls_accessor
(d) WEIGHTS: every vertex's four WEIGHTS_0 decode back to EXACTLY its source q12 sum -- FULL POPULATION, worst
deviation printed. The tolerance is DERIVED = 0: every k/4096 is exactly representable in f32 (23 mantissa
bits >> 12) and the encoder is exact for dyadic rationals, so any deviation at all is a defect.
(e) NEG-CONTROL via gv_bite: an NXA with NO SKEL exports NO skins (importer reports skin_joints=0), paired with
(a) -- a writer that reports success for everything cannot score on this pair.
(f) a truncated NXA is REFUSED BY NAME (the format's own checksum), never a silent empty .glb.
(g) NO SILENT INPUT CAP (2026-08-22): nx_mesh2glb carried a 32 MiB input read cap and a 400000-tri cap; an
intact NXMSH2 past either was refused, past the byte cap WITH THE WRONG REASON. The anti-vacuity fixture is
a synthetic NXMSH2 DERIVED to exceed BOTH, and the tooth asserts the exported accessor counts equal tris*3,
parsed from the JSON. Its truncated twin is refused by name (the NXMSH2 mirror of (f)), paired via gv_bite.
The output capacity must be DERIVED and ANNOUNCED (out_cap_derived / out_used) -- a cap nobody can see is
a cap nobody can check.
FIXTURES at runtime under /tmp/nx_nxa2glb_gate/; every subject output is unlinked at SETUP -- a gate that is not
idempotent reports on its first run and lies about every run after.
argv: [subject elf] [importer elf] [rigged donor nxa] [unrigged donor nxa] (defaults resolve from the serving root)
license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
dependencies 6 imports · 0 importers
imports: nx_syscalls.nxnx_gate_verdict.nxnx_tool_run.nxnx_nxa.nxnx_trimesh.nxnx_gltf_load.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
| 32 | const NG_SUBJECT_DEFAULT: *u8 = "_offc/nx_mesh2glb.elf" |
| 33 | const NG_IMPORTER_DEFAULT: *u8 = "_offc/nx_gltf2mesh.elf" |
| 34 | const NG_RIGGED_DEFAULT: *u8 = "sites/nishifamily/world/ref9d.nxa" |
| 35 | const NG_UNRIGGED_DEFAULT: *u8 = "sites/nishifamily/world/ref.nxa" |
| 36 | const NG_DIR: *u8 = "/tmp/nx_nxa2glb_gate" |
| 37 | const NG_GLB_RIGGED: *u8 = "/tmp/nx_nxa2glb_gate/rigged.glb" |
| 38 | const NG_GLB_UNRIGGED: *u8 = "/tmp/nx_nxa2glb_gate/unrigged.glb" |
| 39 | const NG_GLB_TRUNC: *u8 = "/tmp/nx_nxa2glb_gate/trunc.glb" |
| 40 | const NG_NXA_TRUNC: *u8 = "/tmp/nx_nxa2glb_gate/trunc.nxa" |
| 41 | const NG_MSH_RIGGED: *u8 = "/tmp/nx_nxa2glb_gate/rigged.nxmesh" |
| 42 | const NG_MSH_UNRIGGED: *u8 = "/tmp/nx_nxa2glb_gate/unrigged.nxmesh" |
| 43 | const NG_MODE_DIR: i64 = 493 // 0755 |
| 44 | const NG_CAPTURE_CAP: i64 = 262144 |
| 45 | const NG_ARGV_SLOTS: i64 = 8 |
| 46 | const NG_WORD: i64 = 8 |
| 47 | const NG_EXIT_OK: i64 = 0 |
| 48 | const NG_EXIT_REFUSE: i64 = 3 // the subject's refusal exit for an unusable input |
| 49 | const NG_EXEC_FAIL: i64 = 127 // execve failure as captured by tr_run_capture |
| 50 | const NG_Q12: i64 = 4096 |
| 51 | const NG_SKIN_REC_WORDS: i64 = 8 |
| 52 | const NG_SKIN_W0: i64 = 4 |
| 53 | const NG_INFL: i64 = 4 |
| 54 | const NG_F32_BYTES: i64 = 4 |
| 55 | const NG_GL_FLOAT: i64 = 5126 // glTF componentType FLOAT -- WEIGHTS_0 must be this |
| 56 | const NG_Q12_SHIFT: i64 = 12 // gls_f32s(bits, 12) yields value x 4096 as an integer |
| 57 | const NG_WEIGHT_SUM_TOL_Q12: i64 = 0 // DERIVED: k/4096 is exact in f32 and the encoder is exact for dyadics |
| 58 | const NG_GLB_JSONLEN_OFF: i64 = 12 |
| 59 | const NG_GLB_JSON_START: i64 = 20 |
| 60 | const NG_GLB_CHUNK_HDR: i64 = 8 |
| 61 | const NG_NXA_HDR_BYTES: i64 = 32 |
| 62 | const NG_NXA_TOC_ENTRY: i64 = 32 |
| 63 | const NG_TRUNC_PAYLOAD_TAIL: i64 = 64 // keep the whole TOC plus 64 B of payload so the TOC check PASSES and |
| 65 | const NG_LOAD_TARGET: i64 = 900 // the bbox-relative normalisation nx_gltf_load_gate passes; unit-free |
| 69 | const NG_OLD_INPUT_CAP_BYTES: i64 = 33554432 |
| 70 | const NG_OLD_TRI_CAP: i64 = 400000 |
| 71 | const NG_MSH_FIXED_HDR: i64 = 16 // NXMSH2: magic[8] + u32 nlay + u32 ntri |
| 72 | const NG_MSH_LAYROW: i64 = 24 |
| 73 | const NG_MSH_TRIREC: i64 = 84 // 9 position + 9 normal + 3 colour float32 |
| 74 | const NG_MSH_NLAY_OFF: i64 = 8 |
| 75 | const NG_MSH_NTRI_OFF: i64 = 12 |
| 76 | const NG_MSH_LAY_CNT_OFF: i64 = 20 |
| 77 | const NG_MSH_SMALL_TRIS: i64 = 10 // the truncation fixture: small, cut mid-record |
| 78 | const NG_HALF: i64 = 2 |
| 79 | const NG_CORNERS: i64 = 3 |
| 80 | const NG_BIG_MSH: *u8 = "/tmp/nx_nxa2glb_gate/big.nxmesh" |
| 81 | const NG_BIG_GLB: *u8 = "/tmp/nx_nxa2glb_gate/big.glb" |
| 82 | const NG_SMALL_MSH: *u8 = "/tmp/nx_nxa2glb_gate/small.nxmesh" |
| 83 | const NG_CUT_MSH: *u8 = "/tmp/nx_nxa2glb_gate/cut.nxmesh" |
| 84 | const NG_CUT_GLB: *u8 = "/tmp/nx_nxa2glb_gate/cut.glb" |
functions
| 86 | func ng_exists(path: *u8) -> i64 |
| 93 | func ng_run(elf: *u8, a1: *u8, a2: *u8, out: *u8, outlen: *i64) -> i64 |
| 101 | func ng_w32(b: *u8, o: i64, v: i64) -> i64 { b[o]=(v&255) as u8; b[o+1]=((v>>8)&255) as u8; b[o+2]=((v>>16)&255) as u8; b[o+3]=((v>>24)&255) as u8; return o+4 } called by 1: ng_write_msh |
| 104 | func ng_write_msh(path: *u8, ntri: i64) -> i64 |
| 120 | func ng_first_line(cap: *u8, n: i64) -> i64 |
| 126 | func ng_hasstr(b: *u8, n: i64, lit: *u8) -> i64 |
| 131 | func ng_skin_joints(cap: *u8, n: i64) -> i64 { return gll_nth_num(cap, 0, n, "\x22skin_joints\x22:" as *u8, 1) } |
| 132 | func ng_verts_seen(cap: *u8, n: i64) -> i64 { return gll_nth_num(cap, 0, n, "\x22verts_seen\x22:" as *u8, 1) } |
| 134 | func main(argc: i64, argv: *i64) -> i64 |