code wiki / (root) / nx_gltf2mesh_preserve_t145.nx

nx_gltf2mesh_preserve_t145.nx

buildroot/runtime/nx_gltf2mesh_preserve_t145.nx

86763 B1753 linesdepth 9pulls 38 transitivereach 0 importersview sourcekind tooltopic gltf2mesh
docsdependenciesstructsconstsfunctions

about

nx_gltf2mesh.nx -- GLB/VRM -> NXMSH2 mesh-oracle extractor (debt 1785902685, the D2 POSITION slice). The whole bench suite (nx_bodybench / nx_twinbench / nx_curvebench / nx_facemark) judges .nxmesh oracles, but NO organ could turn a donor .glb/.vrm into one -- donor FORM was invisible to every instrument we own (operator 2026-08-05: the T2 being is still a clay blob because the ruler only reads skeletons). This organ reads ONLY what a form oracle needs: every TRIANGLES primitive's POSITION + indices (u16 AND u32, tight or strided bufferViews), multi-mesh multi-primitive concat. FAIL-CLOSED at every offset (D1): a file this cannot parse REFUSES with a named reason and a nonzero exit -- never a segfault, never a silent empty mesh (zero accepted tris = REFUSAL). Morph-target POSITIONs are excluded by scoping the attribute scan to the primitive's attributes{}. Skinned bind-pose positions are model-space per the glTF spec (node transforms ignored for skinned meshes); VRM avatars are skinned throughout -- reported in the status line, never silent. nx_gltf2mesh <in.glb|.vrm> <out.nxmesh> | nx_gltf2mesh selftest nx_gltf2mesh <in.glb|.vrm> <out.nxa> -- R22 RIG-CARRYING INGEST (charsim.plan, contract symbol g2_skin_weights): when the OUTPUT name ends in .nxa the donor's skin is carried into the estate's rig container NXANIM01 -- VERT (shared vertex table, mm) / TRIS (index triples) / SKEL (one record per skins[].joints entry: parent, bind position from inverseBindMatrices, identity quat) / SKIN (per vertex four joint indices + four Q12 weights summing to EXACTLY 4096). That layout is the one nx_nxa_skin WRITES, nx_nxa_check ENFORCES and nx_nxa_rig_emit DIVIDES BY -- read from those three, never invented here. NXMSH2 structurally cannot carry a rig (84-byte triangle soup, no joint section, 17 consumers hardcode that arithmetic), which is why the round trip measured 2026-08-22 lost every named part of every rigged donor. An unskinned donor asked for .nxa is REFUSED by name; the .nxmesh path is byte-identical. license_tier: ORIGINAL expect_exit: 0

dependencies 5 imports · 0 importers

nx_syscalls.nx nx_nxa.nx nx_vecmath.nx nx_gltf_load.nx nx_bundle_ingest.nx nx_gltf2mesh_preserve_t145.nx

imports: nx_syscalls.nxnx_nxa.nxnx_vecmath.nxnx_gltf_load.nxnx_bundle_ingest.nx

imported by: nobody (leaf or entry point)

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

main gpn_main hw sys_write bix_uint bix_alias fsx_seq 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 ↻ sys_munmap sys_fstatat sys_mmap ↻ sys_openat_rd sys_lseek sys_close gpn_convert cgo_read gpn_deps sys_mmap ↻ glp_reset nx_json_next nx_json_skip_ws nx_json_lit nx_ascii_is_digit glp_member nx_json_next ↻ glp_eq

structs

none

consts

27const G2_MAGIC_2000000000: i64 = 2000000000
28const G2_MAGIC_4096: i64 = 4096
33const G2_SCALE_STEP: i64 = 1000
34const G2_MAX_SCALE_TRIES: i64 = 4
35const G2_DEF_SLIVER_FLOOR_MM: i64 = 100
36const G2_ASCII_EQ: i64 = 61
37const G2_ASCII_NL: i64 = 10
38const G2_ASCII_ZERO: i64 = 48
39const G2_ASCII_NINE: i64 = 57
40const G2_CONFBUF: i64 = 16
41const G2_UNITS_CONF: *u8 = "knowledge/gltf2mesh_units.conf"
42const G2_UCONF_PFXLEN: i64 = 11 // len("units_conf=")
44const G2_CAP: i64 = 33554432
45const G2_MAXEL: i64 = 1024
46const G2_MAXTRI: i64 = 400000
47const G2_Q14: i64 = 16384
48const G2_M8388607: i64 = 8388607
49const G2_M8388608: i64 = 8388608
50const G2_GREY: i64 = 780
51const G2_CT_F32: i64 = 5126
52const G2_CT_U16: i64 = 5123
53const G2_CT_U32: i64 = 5125
54const G2_MODE_TRIS: i64 = 4
55const G2_HDR: i64 = 16
56const G2_LAYROW: i64 = 24
57const G2_TRIREC: i64 = 84
60const G2_CT_U8: i64 = 5121 // glTF UNSIGNED_BYTE: JOINTS_0, normalized WEIGHTS_0
61const G2_Q12: i64 = 4096 // SKIN weight unit AND SKEL quat unit (nx_nxa_check: sum == 4096)
62const G2_VEC4_SLOTS: i64 = 4 // JOINTS_0/WEIGHTS_0 are VEC4: four influences per vertex
63const G2_U8_MAX: i64 = 255 // normalized u8 denominator (glTF: v/255)
64const G2_U16_MAX: i64 = 65535 // normalized u16 denominator (glTF: v/65535)
65const G2_F32_MANT_DENOM: i64 = 16777216 // 2^24: a float32 weight in [0,1] is exact to below 1/2^24
66const G2_F32_BYTES: i64 = 4
67const G2_U16_BYTES: i64 = 2
68const G2_U32_BYTES: i64 = 4
69const G2_VEC3_F32_BYTES: i64 = 12
70const G2_MAT4_BYTES: i64 = 64
71const G2_MAT4_COL: i64 = 4 // column-major: element (row r, col c) sits at c*4 + r
72const G2_IBM_T_COL: i64 = 3 // the translation column of a MAT4
73const G2_IBM_W_ROW: i64 = 3 // the affine row: must decode to 0 0 0 1
74const G2_Q12_IDENT_TOL: i64 = 1 // f32 1.0 / 0.0 decode EXACTLY to 4096 / 0 and the decode truncates below one unit, so any rotation or scale in a bind matrix shows as a deviation above ONE unit
75const G2_NXA_HDR_BYTES: i64 = 32 // magic, version, section count, TOC check
76const G2_NXA_TOC_BYTES: i64 = 32 // tag, byte offset, wordlen, payload check
77const G2_NXA_TOC_WORDS: i64 = 4
78const G2_NXA_SECS: i64 = 4 // VERT TRIS SKEL SKIN
79const G2_SKEL_WORDS: i64 = 8 // parent, tx, ty, tz, qx, qy, qz, qw
80const G2_SKIN_WORDS: i64 = 8 // j0 j1 j2 j3 w0 w1 w2 w3
81const G2_VERT_WORDS: i64 = 3
82const G2_TRI_WORDS: i64 = 3
83const G2_NXA_EXT_LEN: i64 = 4 // ".nxa"
84const G2_IBM_DEFAULT_IDENTITY: i64 = 1 // glTF: absent inverseBindMatrices == identity == every joint binds at the origin
85const G2_CX_WORDS: i64 = 32 // the emitter's context record
87const G2_SW_OK: i64 = 0
88const G2_SW_SHAPE: i64 = 1
89const G2_SW_JOINT_RANGE: i64 = 2
90const G2_SW_SUM_TOL: i64 = 3
91const G2_SW_ZERO_WEIGHT: i64 = 4
92const G2_SW_NEGATIVE: i64 = 5
93const G2_IB_NONIDENT: i64 = 2
94const G2_IB_SHEAR: i64 = 3
95const G2_MAT3_DIM: i64 = 3
100const G2_SHEAR_TOL_Q12: i64 = 7
102const G2_IBM_CONFLICT_TOL_MM: i64 = 1
1566const GPN_CTX_WORDS:i64=18

functions

104func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
105func pn(v: i64) -> i64 { let b: *u8=sys_mmap(32) as *u8; var x: i64=v; var ng: i64=0; if x<0{ng=1;x=0-x} var i: i64=31; if x==0{b[i]=48 as u8;i=i-1} while x>0{b[i]=(48+x%10) as u8;x=x/10;i=i-1} if ng==1{b[i]=45 as u8;i=i-1} sys_write(1,(b as i64+i+1) as *u8,31-i); return 0 }
110func g2_u16(b: *u8, o: i64) -> i64
115func g2_u32(b: *u8, o: i64) -> i64
124func g2_f32s(w: i64, scale: i64) -> i64
139func g2_f32mm(w: i64) -> i64 { return g2_f32s(w, 1000) }
140func g2_ceil_div(a: i64, d: i64) -> i64 { return (a + d - 1) / d }
called by 1: g2_skin_weights
144func g2_conf_i64(path: *u8, key: *u8, miss: i64) -> i64
called by 1: g2_convert calls 2: sys_mmapsys_read_file
206func g2_pick_scale(hgt: i64, floor_mm: i64) -> i64
called by 1: g2_convert
219func g2_enc(v: i64, scale: i64) -> i64
called by 2: g2_convertst_mkglb
234func g2_wr32(b: *u8, o: i64, v: i64) -> i64
called by 2: g2_convertst_mkglb
240func g2_isqrt(x: i64) -> i64 { return vm_isqrt(x) }
called by 1: g2_convert calls 1: vm_isqrt
243func g2_lit_at(b: *u8, o: i64, e: i64, lit: *u8) -> i64
252func g2_topkey(b: *u8, s: i64, e: i64, lit: *u8) -> i64
called by 1: g2_convert calls 1: g2_lit_at
279func g2_elems(b: *u8, arr: i64, e: i64, starts: *i64, ends: *i64, maxn: i64) -> i64
called by 1: g2_convert
318func g2_key(b: *u8, s: i64, e: i64, lit: *u8) -> i64
337func g2_ifield(b: *u8, s: i64, e: i64, lit: *u8, def: i64) -> i64
called by 1: g2_convert calls 1: g2_key
358func g2_objend(b: *u8, off: i64, e: i64) -> i64
called by 1: g2_convert
384func g2_hasstr(b: *u8, s: i64, e: i64, lit: *u8) -> i64
390func g2_refuse(reason: *u8) -> i64
called by 2: g2_emit_nxag2_convert calls 1: hw
398func g2_name_has(b: *u8, s: i64, e: i64, skip: *u8) -> i64
called by 1: g2_convert calls 2: g2_keyg2_hasstr
424func g2_filter(f: *u8) -> i64
called by 1: main calls 2: sys_mmapg2_lit_at
450func g2_intarray(b: *u8, arr: i64, e: i64, out: *i64, maxn: i64) -> i64
called by 1: g2_convert
481func g2_nodename(b: *u8, s: i64, e: i64, out: *i64) -> i64
called by 1: g2_convert calls 1: g2_key
501func g2_ends_nxa(path: *u8) -> i64
called by 1: g2_convert
536func g2_skin_weights(cx: *i64, joi: i64, wei: i64, nvp: i64, vbase: i64, nj: i64, skin: *i64, st: *i64) -> i64
620func g2_ibm_one(cx: *i64, ibi: i64, kloc: i64, dv: i64, out3: *i64, st: *i64) -> i64
called by 1: g2_emit_nxa calls 3: g2_f32sg2_u32g2_f32mm
702func g2_toc(toc: *i64, ti: i64, tag: *u8, off: i64, wl: i64, words: *i64) -> i64
called by 1: g2_emit_nxa calls 2: nxa_tag4nxa_check2
717func g2_emit_nxa(cx: *i64) -> i64
1019func g2_convert(inp: *u8, outp: *u8, skip: *u8) -> i64
1497func st_wr(path: *u8, buf: *u8, n: i64) -> i64
1504func st_mkglb(buf: *u8, breakmode: i64) -> i64
called by 1: g2_selftest calls 2: g2_wr32g2_enc
1535func g2_selftest() -> i64
1567func gpn_reason(code:i64)->*u8
called by 1: gpn_convert
1584func gpn_deps(cx:*i64,w:*JsonWriter)->i64
1636func gpn_receipt(cx:*i64)->i64
1679func gpn_convert(cx:*i64,src:*u8,out:*u8,sha:*u8,digest:*u8)->i64
1699func gpn_main(argc:i64,argv:*i64)->i64
1735func main(argc: i64, argv: *i64) -> i64