nx_nxa_texc_gate.nx source
↩ module page · 244 lines · 11042 B
1// nx_nxa_texc_gate.nx -- GATE for the TEXC format rung (debt 1785794796 rung 1). Fixtures are ASSEMBLED AT
2// RUNTIME in /tmp (a detector that scans source finds its own fixture). Anti-vacuity: T5 tiles-disjoint and
3// T6 coordinate-discrimination kill a constant-UV implementation; T8 is the named neg-control (no SKIN ->
4// refuse, never fabricate); T9 runs the REAL rigged asset (ref9.nxa) behind gv_need. gv-based (D001 clean).
5// license_tier: ORIGINAL expect_exit: 0
6import "nx_syscalls.nx"
7import "nx_nxa.nx"
8import "nx_nxa_texc_lib.nx"
9import "nx_gate_verdict.nx"
10
11const GXT_NV: i64 = 6
12const GXT_NJ: i64 = 3
13
14func gx_wfile(path: *u8, b: *u8, n: i64) -> i64 {
15 let fd: i64 = sys_openat_wr(path, 0x1a4)
16 if fd < 0 { return 0 }
17 sys_write(fd, b, n)
18 sys_close(fd)
19 return 1
20}
21// build the synthetic rigged NXA: VERT(6) + SKEL(3-joint chain up +z) + optionally SKIN(6)
22func gx_mkfix(path: *u8, withskin: i64) -> i64 {
23 let vwl: i64 = 1 + GXT_NV*3
24 let swl: i64 = 1 + GXT_NJ*8
25 let kwl: i64 = 1 + GXT_NV*8
26 var ns: i64 = 3
27 if withskin == 0 { ns = 2 }
28 let toclen: i64 = 32 + ns*32
29 var total: i64 = toclen + vwl*8 + swl*8
30 if withskin == 1 { total = total + kwl*8 }
31 let nb: *u8 = sys_mmap(total + 4096)
32 nt_wr64(nb, 0, nxa_magic())
33 nt_wr64(nb, 8, 1)
34 nt_wr64(nb, 16, ns)
35 // VERT payload: 3 verts around bone j1 (z 0..1000) + 3 around j2 (z 1000..2000)
36 let vp: *i64 = sys_mmap(vwl*8 + 64) as *i64
37 vp[0] = GXT_NV
38 vp[1] = 100; vp[2] = 0; vp[3] = 250
39 vp[4] = 0; vp[5] = 100; vp[6] = 500
40 vp[7] = 0-100; vp[8] = 0; vp[9] = 750
41 vp[10] = 100; vp[11] = 0; vp[12] = 1250
42 vp[13] = 0; vp[14] = 0-100; vp[15] = 1500
43 vp[16] = 0-100; vp[17] = 0; vp[18] = 1750
44 // SKEL payload: j0 root(0,0,0) <- j1(0,0,1000) <- j2(0,0,2000), identity bind quats
45 let sp: *i64 = sys_mmap(swl*8 + 64) as *i64
46 sp[0] = GXT_NJ
47 sp[1] = 0-1; sp[2] = 0; sp[3] = 0; sp[4] = 0; sp[5] = 0; sp[6] = 0; sp[7] = 0; sp[8] = 4096
48 sp[9] = 0; sp[10] = 0; sp[11] = 0; sp[12] = 1000; sp[13] = 0; sp[14] = 0; sp[15] = 0; sp[16] = 4096
49 sp[17] = 1; sp[18] = 0; sp[19] = 0; sp[20] = 2000; sp[21] = 0; sp[22] = 0; sp[23] = 0; sp[24] = 4096
50 // SKIN payload: v0-v2 owned by j1, v3-v5 owned by j2 (full weight in slot 0)
51 let kp: *i64 = sys_mmap(kwl*8 + 64) as *i64
52 kp[0] = GXT_NV
53 var r: i64 = 0
54 while r < GXT_NV {
55 var oj: i64 = 1
56 if r >= 3 { oj = 2 }
57 kp[1 + r*8] = oj
58 kp[1 + r*8 + 1] = 0
59 kp[1 + r*8 + 2] = 0
60 kp[1 + r*8 + 3] = 0
61 kp[1 + r*8 + 4] = 4096
62 kp[1 + r*8 + 5] = 0
63 kp[1 + r*8 + 6] = 0
64 kp[1 + r*8 + 7] = 0
65 r = r + 1
66 }
67 // lay out TOC + payloads, checksums recomputed over the written words
68 var wo: i64 = toclen
69 var ti: i64 = 0
70 nt_wr64(nb, 32 + ti*32, nxa_tag4("VERT" as *u8))
71 nt_wr64(nb, 32 + ti*32 + 8, wo)
72 nt_wr64(nb, 32 + ti*32 + 16, vwl)
73 var k: i64 = 0
74 while k < vwl { nt_wr64(nb, wo + k*8, vp[k]); k = k + 1 }
75 nt_wr64(nb, 32 + ti*32 + 24, nxa_check2(1, ((nb as i64) + wo) as *i64, vwl))
76 wo = wo + vwl*8
77 ti = ti + 1
78 nt_wr64(nb, 32 + ti*32, nxa_tag4("SKEL" as *u8))
79 nt_wr64(nb, 32 + ti*32 + 8, wo)
80 nt_wr64(nb, 32 + ti*32 + 16, swl)
81 k = 0
82 while k < swl { nt_wr64(nb, wo + k*8, sp[k]); k = k + 1 }
83 nt_wr64(nb, 32 + ti*32 + 24, nxa_check2(1, ((nb as i64) + wo) as *i64, swl))
84 wo = wo + swl*8
85 ti = ti + 1
86 if withskin == 1 {
87 nt_wr64(nb, 32 + ti*32, nxa_tag4("SKIN" as *u8))
88 nt_wr64(nb, 32 + ti*32 + 8, wo)
89 nt_wr64(nb, 32 + ti*32 + 16, kwl)
90 k = 0
91 while k < kwl { nt_wr64(nb, wo + k*8, kp[k]); k = k + 1 }
92 nt_wr64(nb, 32 + ti*32 + 24, nxa_check2(1, ((nb as i64) + wo) as *i64, kwl))
93 wo = wo + kwl*8
94 ti = ti + 1
95 }
96 nt_wr64(nb, 24, nxa_check2(1, ((nb as i64) + 32) as *i64, ns*4))
97 return gx_wfile(path, nb, wo)
98}
99
100func main() -> i64 {
101 let ctr: *i64 = gv_ctr()
102 gv_head("nx_nxa_texc_gate -- TEXC format rung: bone-anchored UV atlas written into the NXA (debt 1785794796)" as *u8)
103
104 let pf: *u8 = "/tmp/nxt_fix.nxa" as *u8
105 let po: *u8 = "/tmp/nxt_out.nxa" as *u8
106 gx_mkfix(pf, 1)
107 let rc: i64 = ntx_apply(pf, po)
108 gv_check("T1 unwrap runs clean on the synthetic rigged fixture" as *u8, rc == 0, ctr)
109
110 let lp: *i64 = sys_mmap(16) as *i64
111 let ob: *u8 = sys_read_file(po, lp)
112 let olen: i64 = lp[0]
113 var wo: i64 = 0 - 1
114 if (ob as i64) != 0 { wo = nxa_find(ob, olen, nxa_tag4("TEXC" as *u8)) }
115 gv_check("T2 output is a valid NXA and nxa_find(TEXC) verifies toc+payload checksums" as *u8, wo >= 0, ctr)
116
117 var t3: i64 = 0
118 var t4: i64 = 0
119 var t5: i64 = 0
120 var t6: i64 = 0
121 if wo >= 0 {
122 let w: *i64 = ob as *i64
123 if w[wo] == GXT_NV { if w[wo+1] == 3 { if w[wo+2] == 2 { t3 = 1 } } }
124 // ranges + region tags: rows 0-2 tagged joint 1, rows 3-5 joint 2, all uv in [0,65535]
125 t4 = 1
126 var r2: i64 = 0
127 while r2 < GXT_NV {
128 let uu: i64 = w[wo + 4 + r2*3]
129 let vv: i64 = w[wo + 4 + r2*3 + 1]
130 let jj: i64 = w[wo + 4 + r2*3 + 2]
131 if uu < 0 { t4 = 0 }
132 if uu > 65535 { t4 = 0 }
133 if vv < 0 { t4 = 0 }
134 if vv > 65535 { t4 = 0 }
135 var wantj: i64 = 1
136 if r2 >= 3 { wantj = 2 }
137 if jj != wantj { t4 = 0 }
138 r2 = r2 + 1
139 }
140 // tiles disjoint: v0 (joint 1) and v3 (joint 2) land in different atlas tiles (grid 2 -> tile 32768)
141 let tw2: i64 = 65536 / 2
142 let tile0: i64 = w[wo+4]/tw2 + (w[wo+4+1]/tw2)*2
143 let tile3: i64 = w[wo+4+9]/tw2 + (w[wo+4+9+1]/tw2)*2
144 if tile0 != tile3 { t5 = 1 }
145 // discrimination: angle varies u (v0 vs v1), height along the bone varies v (v0 vs v2)
146 if w[wo+4] != w[wo+4+3] { if w[wo+4+1] != w[wo+4+6+1] { t6 = 1 } }
147 gv_puts(" v0=(" as *u8); gv_num(w[wo+4]); gv_puts("," as *u8); gv_num(w[wo+4+1])
148 gv_puts(") v1=(" as *u8); gv_num(w[wo+4+3]); gv_puts("," as *u8); gv_num(w[wo+4+4])
149 gv_puts(") v2=(" as *u8); gv_num(w[wo+4+6]); gv_puts("," as *u8); gv_num(w[wo+4+7])
150 gv_puts(") v3=(" as *u8); gv_num(w[wo+4+9]); gv_puts("," as *u8); gv_num(w[wo+4+10]); gv_puts(")\n" as *u8)
151 }
152 gv_check("T3 payload header nv=6 stride=3 grid=2" as *u8, t3, ctr)
153 gv_check("T4 all uv in [0,65535] and region tag equals the owning SKIN joint" as *u8, t4, ctr)
154 gv_check("T5 anti-vacuity: different bones land in DISJOINT atlas tiles" as *u8, t5, ctr)
155 gv_check("T6 anti-vacuity: angle varies u and bone-height varies v (kills constant-uv)" as *u8, t6, ctr)
156
157 // T7 idempotency: applying to our own output reproduces it byte-for-byte
158 let p2: *u8 = "/tmp/nxt_out2.nxa" as *u8
159 let rc2: i64 = ntx_apply(po, p2)
160 var t7: i64 = 0
161 if rc2 == 0 {
162 let lpa: *i64 = sys_mmap(16) as *i64
163 let lpb: *i64 = sys_mmap(16) as *i64
164 let ba: *u8 = sys_read_file(po, lpa)
165 let bb: *u8 = sys_read_file(p2, lpb)
166 if lpa[0] == lpb[0] { if (ba as i64) != 0 { if (bb as i64) != 0 {
167 t7 = 1
168 var ci: i64 = 0
169 while ci < lpa[0] { if ba[ci] != bb[ci] { t7 = 0; ci = lpa[0] } else { ci = ci + 1 } }
170 } } }
171 if t7 == 0 { gv_puts(" detail: len1=" as *u8); gv_num(lpa[0]); gv_puts(" len2=" as *u8); gv_num(lpb[0]); gv_puts("\n" as *u8) }
172 }
173 gv_check("T7 idempotent: re-running on its own output is byte-identical" as *u8, t7, ctr)
174
175 // T8 neg-control: an NXA without SKIN must REFUSE (no fabricated ownership), with the named exit
176 let pn: *u8 = "/tmp/nxt_noskin.nxa" as *u8
177 gx_mkfix(pn, 0)
178 let rcn: i64 = ntx_apply(pn, "/tmp/nxt_noskin_out.nxa" as *u8)
179 if rcn != NT_E_NOSEC { gv_puts(" detail: rc=" as *u8); gv_num(rcn); gv_puts(" want=" as *u8); gv_num(NT_E_NOSEC); gv_puts("\n" as *u8) }
180 gv_check("T8 neg-control-no-skin refuses with the named missing-section exit" as *u8, rcn == NT_E_NOSEC, ctr)
181
182 // T9 the REAL asset (gv_need: absent file = SKIP, not RED)
183 var haveref: i64 = 0
184 let rfd: i64 = sys_openat_rd("sites/nishifamily/world/ref9d.nxa" as *u8)
185 if rfd >= 0 { haveref = 1; sys_close(rfd) }
186 if gv_need("sites/nishifamily/world/ref9d.nxa" as *u8, haveref, ctr) == 1 {
187 // ref9d = the SHIPPED character (the asset nx_asset_floor_gate measures: ref9 + DYNA)
188 let pr: *u8 = "/tmp/nxt_ref9d.nxa" as *u8
189 let rcr: i64 = ntx_apply("sites/nishifamily/world/ref9d.nxa" as *u8, pr)
190 gv_check("T9 the SHIPPED rigged asset (ref9d.nxa) gains a TEXC section cleanly" as *u8, rcr == 0, ctr)
191 let lpr: *i64 = sys_mmap(16) as *i64
192 let rb: *u8 = sys_read_file(pr, lpr)
193 // (T10/T11 below scan the ref9d output)
194 let rlen: i64 = lpr[0]
195 var rwo: i64 = 0 - 1
196 var rvo: i64 = 0 - 1
197 var rso: i64 = 0 - 1
198 if (rb as i64) != 0 {
199 rwo = nxa_find(rb, rlen, nxa_tag4("TEXC" as *u8))
200 rvo = nxa_find(rb, rlen, nxa_tag4("VERT" as *u8))
201 rso = nxa_find(rb, rlen, nxa_tag4("SKEL" as *u8))
202 }
203 var t10: i64 = 0
204 var t11: i64 = 0
205 if rwo >= 0 { if rvo >= 0 { if rso >= 0 {
206 let rw: *i64 = rb as *i64
207 let rnv: i64 = rw[rvo]
208 let rnj: i64 = rw[rso]
209 if rw[rwo] == rnv { if rw[rwo+1] == 3 { t10 = 1 } }
210 // full population scan: every row in range, every tag a real joint; count distinct joints
211 t11 = 1
212 let seen: *i64 = sys_mmap(rnj*8 + 64) as *i64
213 var rr: i64 = 0
214 while rr < rnv {
215 let ru: i64 = rw[rwo + 4 + rr*3]
216 let rv: i64 = rw[rwo + 4 + rr*3 + 1]
217 let rj: i64 = rw[rwo + 4 + rr*3 + 2]
218 if ru < 0 { t11 = 0 }
219 if ru > 65535 { t11 = 0 }
220 if rv < 0 { t11 = 0 }
221 if rv > 65535 { t11 = 0 }
222 if rj < 0 { t11 = 0 }
223 if rj >= rnj { t11 = 0 }
224 if rj >= 0 { if rj < rnj { seen[rj] = 1 } }
225 rr = rr + 1
226 }
227 var dj: i64 = 0
228 var js: i64 = 0
229 while js < rnj { if seen[js] == 1 { dj = dj + 1 } js = js + 1 }
230 gv_puts(" ref9: nv=" as *u8); gv_num(rnv)
231 gv_puts(" nj=" as *u8); gv_num(rnj)
232 gv_puts(" grid=" as *u8); gv_num(rw[rwo+2])
233 gv_puts(" distinct_joints_used=" as *u8); gv_num(dj)
234 gv_puts("\n" as *u8)
235 if dj < 10 { t11 = 0 }
236 } } }
237 gv_check("T10 ref9 TEXC covers every vertex (count matches VERT, stride 3)" as *u8, t10, ctr)
238 gv_check("T11 ref9 full-population scan: all uv in range, all tags real joints, >=10 regions" as *u8, t11, ctr)
239 }
240
241 let rcv: i64 = gv_verdict("NXA-TEXC-GATE" as *u8, ctr, "the NXA format now carries UV atlas coordinates; sampling a texture is POSSIBLE" as *u8)
242 sys_exit(rcv)
243 return rcv
244}