nx_nxa_tier_pre_region_t143.nx
buildroot/runtime/nx_nxa_tier_pre_region_t143.nx
about
nx_nxa_tier.nx -- THE INGEST TIER LADDER FOR NXA ASSETS (/compare/modding MD5 ingest_tier_emit, 2026-09-05).
WHY (measured 2026-09-05 on the served /world/beach cast through nx_nxa_play): every visiting-cast donor
carries a COMPLETE rig (zero_weight_verts=0 on all five assets), and the cast still fails to arrive --
toon3d8.nxa is 61,939,208 B with 370 joints and 423,919 verts against the house girl's 11,728,120 B and
14,164 verts, and NOTHING on the ingest side emits a smaller tier, so the heaviest rip is served at full
weight or not at all. This organ turns one NXA into a SMALLER NXA under a declared vertex budget, so a
world can pick a door for every device (the scale-from-a-sensor-to-a-supercomputer law applied to assets).
HOW: dense-grid vertex clustering (Rossignac-Borrel 1993, the same idea nx_mesh_decimate applies to an
NxMesh) applied DIRECTLY to the NXA sections, with the cell size DERIVED by binary search so the result
is the finest grid whose occupied-cell count fits the budget -- never a hand-picked cell. Each occupied
cell becomes one vertex at the integer centroid of its members; the member NEAREST that centroid lends
its SKIN row (four joints and q12 weights summing 4096, so no weight is ever invented) and its TEXC row
(the bone-anchored UV, so the TEXM atlas still samples). Triangles are remapped and the collapsed ones
(two corners in one cell) dropped. Sections that do not index vertices or triangles (SKEL ANIM POSE MATL
TEXM HSTR) are copied verbatim with their checksums RECOMPUTED, never copied; any other section is
DROPPED BY NAME and counted, because a per-vertex or per-triangle section this rung does not understand
would silently desynchronise from the new VERT -- CLUS, MORF and the garment sections are the known
cases and each is a later rung, not a silent loss.
REFUSALS, each by name and each writing NOTHING: unreadable or corrupt input, no VERT or TRIS, a budget
at or above the source vertex count (a tier is never an upsample), a budget under 3, a degenerate bbox.
Usage: nx_nxa_tier <in.nxa> <out.nxa> <max_verts>
nx_nxa_tier ladder <in.nxa> <out_prefix> [ladder.conf] rows tier|<id>|<max_verts>|<why>
Exits: 0 ok | 2 usage | 3 refused-by-name | 5 missing section
100% sovereign, integer only. No hw writes (Rule 26). license_tier: ORIGINAL expect_exit: 0
dependencies 2 imports · 0 importers
imports: nx_syscalls.nxnx_nxa.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 TR_HDR: i64 = 32 |
| 33 | const TR_TOCE: i64 = 32 |
| 34 | const TR_TOC_W: i64 = 4 |
| 35 | const TR_MAXSEC: i64 = 64 |
| 36 | const TR_MODE: i64 = 0x1a4 // 0644 on the published asset, matching every sibling NXA writer |
| 37 | const TR_PAD: i64 = 4096 |
| 38 | const TR_SKIN_W: i64 = 8 // SKIN row: 4 joints + 4 q12 weights (spec) |
| 39 | const TR_Q12: i64 = 4096 |
| 40 | const TR_TEXC_HDR: i64 = 4 // TEXC payload header words: nverts, stride, grid, 0 (nx_nxa_texc_lib) |
| 41 | const TR_MIN_VERTS: i64 = 3 |
| 42 | const TR_HASH_A: i64 = 73856093 // the classic spatial-hash primes (Teschner 2003), integer only |
| 43 | const TR_HASH_B: i64 = 19349663 |
| 44 | const TR_HASH_C: i64 = 83492791 |
| 45 | const TR_TAG_BYTES: i64 = 4 |
| 46 | const TR_ERRFD: i64 = 2 |
| 47 | const TR_OUTFD: i64 = 1 |
| 48 | const TR_EXIT_USAGE: i64 = 2 |
| 49 | const TR_EXIT_REFUSE: i64 = 3 |
| 50 | const TR_EXIT_NOSEC: i64 = 5 |
| 51 | const TR_LADDER_DEFAULT: *u8 = "knowledge/nxa_tier_ladder.conf" |
| 52 | const TR_MAXTIERS: i64 = 16 |
| 53 | const TR_PATH_CAP: i64 = 1024 |
| 54 | const TR_ASCII_ZERO: i64 = 48 |
| 55 | const TR_ASCII_NINE: i64 = 57 |
| 56 | const TR_ASCII_NL: i64 = 10 |
| 57 | const TR_ASCII_PIPE: i64 = 124 |
| 58 | const TR_ASCII_HASH: i64 = 35 |
| 59 | const TR_ASCII_US: i64 = 95 |
| 60 | const TR_ASCII_DOT: i64 = 46 |
| 61 | const TR_ASCII_MINUS: i64 = 45 |
| 62 | const TR_ASCII_T: i64 = 116 |
| 63 | const TR_ASCII_I: i64 = 105 |
| 64 | const TR_ASCII_E: i64 = 101 |
| 65 | const TR_ASCII_R: i64 = 114 |
| 66 | const TR_ASCII_L: i64 = 108 |
| 67 | const TR_ASCII_A: i64 = 97 |
| 68 | const TR_ASCII_D: i64 = 100 |
| 69 | const TR_ASCII_N: i64 = 110 |
| 70 | const TR_ASCII_X: i64 = 120 |
| 71 | const TR_LADDER_F: i64 = 4 // tier|id|max_verts|why |
functions
| 73 | func tr_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 74 | func tr_out(s: *u8) -> i64 { sys_write(TR_OUTFD, s, tr_slen(s)); return 0 } |
| 75 | func tr_err(s: *u8) -> i64 { sys_write(TR_ERRFD, s, tr_slen(s)); return 0 } |
| 76 | func tr_num(v: i64) -> i64 |
| 89 | func tr_atoi(s: *u8) -> i64 called by 1: main |
| 99 | func tr_rd64(b: *u8, off: i64) -> i64 { let p: *i64 = ((b as i64) + off) as *i64; return p[0] } called by 1: tr_tier |
| 100 | func tr_wr64(b: *u8, off: i64, v: i64) -> i64 { let p: *i64 = ((b as i64) + off) as *i64; p[0] = v; return 0 } called by 1: tr_tier |
| 101 | func tr_tagout(tag: i64) -> i64 |
| 111 | func tr_copyable(tag: i64) -> i64 |
| 122 | func tr_pow2_at_least(n: i64) -> i64 { var p: i64 = 1; while p < n { p = p * 2 } return p } called by 1: tr_tier |
| 123 | func tr_hslot(hx: *i64, hy: *i64, hz: *i64, hu: *i64, mask: i64, cx: i64, cy: i64, cz: i64) -> i64 |
| 134 | func tr_occupied(vw: *i64, nv: i64, minx: i64, miny: i64, minz: i64, cell: i64, hx: *i64, hy: *i64, hz: *i64, hu: *i64, tsize: i64) -> i64 |
| 152 | func tr_tier(inp: *u8, outp: *u8, target: i64) -> i64 |
| 438 | func tr_ladder(inp: *u8, prefix: *u8, conf: *u8) -> i64 |
| 533 | func tr_is_ladder(a: *u8) -> i64 called by 1: main |
| 544 | func main(argc: i64, argv: *i64) -> i64 |