code wiki / (root) / nx_meshrig.nx

nx_meshrig.nx

buildroot/runtime/nx_meshrig.nx

23693 B610 linesdepth 2pulls 2 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_meshrig.nx -- THE BINDER: a GENERATED mesh + a GENERATED skeleton -> a first-class rigged NXA. WHY THIS EXISTS (measured 2026-08-23, capsearch over 1,284 tools): the ONLY organ that filled SKEL+SKIN was nx_nxa_skin, and it requires a BINARY FBX. So every GENERATED body was unriggable -- it could not enter a world, could not be scored on the asset floor's rig axes, and could not receive the soft-tissue or skeletal-animation work that shipped the same day; all of that reached IMPORTED donors only. It is also why the one rigged character in the corpus was the corpus MINIMUM (14,164 verts) while the donors ran to 423,919. nx_meshrig <mesh.nxmesh> <skel.txt> <out.nxa> INPUT A -- NXMSH2 triangle soup: byte0=N, byte5=2, u32 at 8 = nlayers, u32 at 12 = ntris, header = 16 + nlayers*24, then ntris records of 84 bytes whose first 9 f32 are the triangle's three xyz corners in MILLIMETRES. INPUT B -- nx_skelgen's emitted rest skeleton: J rows (J idx parent side x y z) in world MILLIMETRES. Its B rows are bone lengths and joint limits and are skipped here. OUTPUT -- NXANIM01 carrying VERT + TRIS + SKEL + SKIN per knowledge/nxa_format_spec.md: VERT and SKEL translations are 0.01 mm; SKIN is 8 words per vertex, [j0 j1 j2 j3][w0..w3 q12], the four weights summing to EXACTLY 4096; every section carries the spec's rolling order-sensitive checksum, and the TOC carries one over its own words. THE WEIGHTING METHOD, AND WHY -- the one real design choice, stated rather than buried: Shepard normalised INVERSE DISTANCE (exponent 1) over the k nearest BONE SEGMENTS, where a bone is a (joint,parent) pair -- the canon's OWN structure, never an invented body-part map. k = 4 is STRUCTURAL, not a cap: the NXA SKIN record holds exactly four joint/weight lanes, so the FORMAT fixes it and no author picked it. Exponent 1 is used because it is the only exponent that requires no justification: every other value is a sharpness knob, and a knob with no derivation is the magic number this estate bans. Distance is to the SEGMENT (clamped projection), not to the joint -- a joint-distance bind pulls mid-limb vertices toward the wrong end and is the classic candy-wrapper cause. HONEST CEILING, NAMED NOT SILENTLY APPROXIMATED: bone-heat and bounded-biharmonic weights are the higher-quality methods because they respect mesh CONNECTIVITY, so a weight cannot leak across a gap the way a pure distance metric can (the inner thigh and the armpit are where this shows). Both require a sparse Laplacian solve over the mesh, which in integer-only NishiLang is an iterative solver needing its own convergence proof. That is the named next rung. UP-AXIS IS DERIVED FROM BOTH INPUTS, NEVER ASSUMED: the stature axis of each is its own LARGEST EXTENT -- the estate's proven method, the same one that caught FBX Y-up against NXA Z-up on the donors and confirmed axis 2 on the shipped character. A mismatch is corrected by a PROPER rotation (determinant +1, never a mirror); an unhandled pairing REFUSES BY NAME rather than

dependencies 1 imports · 0 importers

nx_syscalls.nx nx_meshrig.nx

imports: nx_syscalls.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main mr_puts sys_write sys_mmap nxa_die sys_write ↻ sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ mr_load_skel sys_mmap ↻ sys_read_file sys_openat_rd sys_lseek sys_mmap ↻ sys_read sys_munmap sys_close mr_refuse mr_puts ↻ mr_scan_int mr_kv mr_puts ↻ mr_num sys_mmap ↻ sys_write ↻ sys_read_file ↻ mr_refuse ↻ mr_u32 mr_load_mesh sys_mmap ↻

structs

none

consts

50const MR_MODE: i64 = 420
51const MR_Q12: i64 = 4096
52const MR_INF: i64 = 4
53const MR_BIG: i64 = 4611686018427387903
54const MR_M23: i64 = 8388607
55const MR_M24: i64 = 8388608
56const MR_MMQ: i64 = 100
57const MR_TRIB: i64 = 84
58const MR_HDR0: i64 = 16
59const MR_LAYB: i64 = 24
60const MR_RECIP: i64 = 1073741824
61const MR_CHK: i64 = 1000003
62const MR_NSECT: i64 = 4
63const MR_SP: i64 = 32
64const MR_NL: i64 = 10
65const MR_JCH: i64 = 74
66const MR_MINUS: i64 = 45
67const MR_D0: i64 = 48
68const MR_D9: i64 = 57

functions

70func mr_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
called by 3: mr_kvmr_refusemain calls 1: sys_write
71func mr_num(v: i64) -> i64
called by 1: mr_kv calls 2: sys_mmapsys_write
83func mr_kv(k: *u8, v: i64) -> i64 { mr_puts(k); mr_num(v); mr_puts("\n" as *u8); return 0 }
called by 1: main calls 2: mr_putsmr_num
84func mr_refuse(reason: *u8) -> i64 { mr_puts("MESHRIG REFUSED: " as *u8); mr_puts(reason); mr_puts("\n" as *u8); return 0 }
86func mr_u32(b: *u8, o: i64) -> i64
called by 2: mr_load_meshmain
90func mr_f32q(w: i64) -> i64
called by 1: mr_load_mesh
106func mr_isqrt(n: i64) -> i64
called by 1: mr_dseg
113func mr_dseg(px: i64, py: i64, pz: i64, ax: i64, ay: i64, az: i64, bx: i64, by: i64, bz: i64) -> i64
called by 1: main calls 1: mr_isqrt
137func mr_check(w: *i64, n: i64) -> i64
called by 1: main
143func mr_tag(a: i64, b: i64, c: i64, d: i64) -> i64 { return a + (b << 8) + (c << 16) + (d << 24) }
called by 1: main
147func mr_scan_int(b: *u8, n: i64, pos: *i64) -> i64
called by 1: mr_load_skel
174func mr_load_mesh(path: *u8, vxp: *i64) -> i64
201func mr_load_skel(path: *u8, jp: *i64, jx: *i64, jy: *i64, jz: *i64, maxj: i64) -> i64
253func mr_up_axis(c: *i64, n: i64, stride: i64, base: i64, ext_out: *i64) -> i64
called by 1: main
286func main(argc: i64, argv: *i64) -> i64