nx_nxa_write_lib.nx
buildroot/runtime/nx_nxa_write_lib.nx
about
nx_nxa_write_lib.nx -- THE NXANIM01 CONTAINER WRITER AS A LIBRARY (/compare/modding MD2, 2026-09-06). The estate held three
INLINE emitters of the same container (nx_meshrig, nx_fbx2nxa, nx_gltf2mesh) and one append-only section writer
(nx_nxa_posewrite_lib); a fourth reader (XPS) would have been a fourth copy. This lib composes nx_nxa.nx -- the ONLY
place the magic, the tag encoding and the rolling checksum are defined -- so a writer and every reader cannot drift.
LAYOUT (knowledge/nxa_format_spec.md, as nx_mesh2glb and nx_meshrig read it): header words [magic][version=1][nsect]
[toc check]; TOC entries of 4 words [tag][byte_off][word_len][check]; payloads of i64 words. VERT [nv][x y z ...] in
0.01 mm model units; TRIS [nt][a b c ...] one word per index; SKEL [nj] + 8 words per joint [parent][tx ty tz]
[qx qy qz qw q12] with the bind rotation the IDENTITY quaternion by the estate's rig convention (stated, never smuggled);
SKIN [nv] + 8 words per vertex [j0 j1 j2 j3][w0 w1 w2 w3] with the four q12 weights summing to exactly 4096.
EVERY REFUSAL IS NAMED: a triangle index outside the vertex table, a skin joint outside the skeleton, a vertex whose
weights do not sum to 4096, or an empty mesh, all refuse BEFORE a byte is written -- the container never carries a
section the spec would call malformed. SKEL and SKIN are written together or not at all (nj == 0 writes VERT and TRIS only).
license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 2 imports · 7 importers
imports: nx_syscalls.nxnx_nxa.nx
imported by: nx_fbx_affine_math_gate_t32.nxnx_nxa_bind.nxnx_nxa_bind_t29.nxnx_nxa_write_append_t37.nxnx_witch_skin_replace_t140.nxnx_xps.nxnx_xps_gate.nx
structs
| none |
consts
| 17 | const NXW_HDR_WORDS: i64 = 4 |
| 18 | const NXW_TOC_WORDS: i64 = 4 |
| 19 | const NXW_SKEL_REC: i64 = 8 |
| 20 | const NXW_SKIN_REC: i64 = 8 |
| 21 | const NXW_VERT_REC: i64 = 3 |
| 22 | const NXW_TRI_REC: i64 = 3 |
| 23 | const NXW_INF: i64 = 4 |
| 24 | const NXW_Q12: i64 = 4096 |
| 25 | const NXW_MODE: i64 = 420 |
| 26 | const NXW_ROOT: i64 = 0 - 1 |
| 27 | const NXW_ERR_OPEN: i64 = 0 - 1 |
| 28 | const NXW_ERR_SHORT_WRITE: i64 = 0 - 2 |
| 29 | const NXW_ERR_WEIGHTS: i64 = 0 - 3 |
| 30 | const NXW_ERR_JOINT: i64 = 0 - 4 |
| 31 | const NXW_ERR_TRI: i64 = 0 - 5 |
| 32 | const NXW_ERR_EMPTY: i64 = 0 - 6 |
| 33 | const NXW_ERR_PARENT: i64 = 0 - 7 |
| 35 | const NXW_R_BYTES: i64 = 0 |
| 36 | const NXW_R_SECTIONS: i64 = 1 |
| 37 | const NXW_R_WORDS: i64 = 2 |
| 38 | const NXW_R_FIRSTBAD: i64 = 3 |
| 39 | const NXW_R_N: i64 = 4 |
| 185 | const NXW_ERR_CONTAINER: i64 = 0-8 |
| 186 | const NXW_ERR_EXTENT: i64 = 0-9 |
| 187 | const NXW_ERR_OVERLAP: i64 = 0-10 |
functions
| 41 | func nxw_err_name(e: i64) -> *u8 |
| 51 | func nxw_nsect(nj: i64) -> i64 { if nj > 0 { return 4 } return 2 } |
| 53 | func nxw_words(nv: i64, nt: i64, nj: i64) -> i64 |
| 59 | func nxw_validate(nv: i64, tr: *i64, nt: i64, jpar: *i64, nj: i64, sj: *i64, sw: *i64, rc: *i64) -> i64 called by 1: nxw_build |
| 93 | func nxw_toc(buf: *i64, toc0: i64, slot: i64, tag: *u8, word_off: i64, wl: i64) -> i64 |
| 102 | func nxw_build(buf: *i64, vx: *i64, nv: i64, tr: *i64, nt: i64, jpar: *i64, jpos: *i64, nj: i64, sj: *i64, sw: *i64, rc: *i64) -> i64 |
| 165 | func nxw_write(path: *u8, vx: *i64, nv: i64, tr: *i64, nt: i64, jpar: *i64, jpos: *i64, nj: i64, sj: *i64, sw: *i64, rc: *i64) -> i64 |
| 188 | func nxw_ranges_overlap(a: i64,an: i64,b: i64,bn: i64) -> i64 |
| 194 | func nxw_replace_same_size(b: *u8,n: i64,tag: i64,payload: *i64,words: i64,out: *u8,cap: i64) -> i64 called by 3: nb_convert_bytesnb_convert_bytesmain calls 3: nxa_section_entrynxw_ranges_overlapnxa_check2 |