code wiki / _hdl_build / nx_gt_annotations_gate.nx
nx_gt_annotations_gate.nx source
↩ module page · 244 lines · 11199 B
1// nx_gt_annotations_gate.nx -- ★R2 of the Infinigen ladder: the GROUND-TRUTH ANNOTATION SUITE (their flagship
2// use-case: synthetic data for CV training, per the banked GroundTruthAnnotations doc title). Our renderers know
3// everything at hit time -- this gate proves we EMIT it: per-pixel DEPTH + SEMANTIC SEGMENTATION (sky/terrain/
4// water/tree/animal/person) + INSTANCE IDs + SURFACE NORMALS + OCCLUSION BOUNDARIES (depth discontinuities).
5// Flow needs animation (R4) -- named residual, not claimed.
6// T1 world GT: seg classes 0/1/2 present with sane counts; terrain normals unit-length; sky normals zero
7// T2 scene GT: 3 placed objects (tree/animal/person) paint classes 3/4/5 + DISTINCT instance ids 1/2/3
8// T3 occlusion boundaries: depth-discontinuity edges exist in a sane band + PNG knowledge/nx_gt_panel.png
9// (colour | segmentation | normals | depth+occlusion) + determinism of the GT buffers
10// license_tier: ORIGINAL expect_exit: 0
11import "nx_syscalls.nx"
12import "nx_png.nx"
13import "nx_worldgen.nx"
14import "nx_treegen.nx"
15import "nx_creaturegen.nx"
16import "nx_figuregen.nx"
17import "nx_skinneural.nx"
18
19func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
20func 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 }
21
22const TREEKEY: i64 = 16711935
23const ANATKEY: i64 = 2890778
24const WFOC: i64 = 720
25const WHOR: i64 = 92
26
27func bbox(spr: *i64, w: i64, h: i64, key: i64, out: *i64) -> i64 {
28 var minx: i64=w; var maxx: i64=0; var miny: i64=h; var maxy: i64=0
29 var i: i64 = 0
30 while i < w*h { if spr[i] != key { let x: i64=i%w; let y: i64=i/w; if x<minx{minx=x} if x>maxx{maxx=x} if y<miny{miny=y} if y>maxy{maxy=y} } i=i+1 }
31 out[0]=minx; out[1]=miny; out[2]=maxx-minx+1; out[3]=maxy-miny+1
32 return 0
33}
34
35// paint a sprite at (px,py foot, height sh), writing scene + seg class + instance id, depth-occluded vs terrain
36func paint(scene: *i64, seg: *i64, inst: *i64, depth: *i64, WW: i64, WH: i64, spr: *i64, sw: i64, shh2: i64, bo: *i64, key: i64, px: i64, py: i64, sh: i64, cls: i64, id: i64) -> i64 {
37 let minx: i64=bo[0]; let miny: i64=bo[1]; let tpw: i64=bo[2]; let tph: i64=bo[3]
38 let sw2: i64 = sh*tpw/tph
39 var bpx: i64 = px; if bpx<0 {bpx=0} if bpx>=WW {bpx=WW-1}
40 var bpy: i64 = py; if bpy<0 {bpy=0} if bpy>=WH {bpy=WH-1}
41 let objd: i64 = depth[bpy*WW+bpx]
42 var oy: i64 = py - sh
43 while oy <= py {
44 if oy >= 0 { if oy < WH {
45 let fy: i64 = miny + (oy-(py-sh))*tph/sh
46 var ox: i64 = px - sw2/2
47 while ox <= px + sw2/2 {
48 if ox >= 0 { if ox < WW {
49 let fx: i64 = minx + (ox-(px-sw2/2))*tpw/sw2
50 if fx>=0 { if fx<sw { if fy>=0 { if fy<shh2 {
51 let s: i64 = spr[fy*sw+fx]
52 if s != key { if depth[oy*WW+ox] > objd - 260 {
53 scene[oy*WW+ox] = s
54 seg[oy*WW+ox] = cls
55 inst[oy*WW+ox] = id
56 depth[oy*WW+ox] = objd // GT: the object's own depth
57 } }
58 } } } }
59 } }
60 ox = ox + 1
61 }
62 } }
63 oy = oy + 1
64 }
65 return 0
66}
67
68func main() -> i64 {
69 hw("=== nx_gt_annotations_gate -- R2: depth + segmentation + instances + normals + occlusion ===\n" as *u8)
70 var fails: i64 = 0
71 let WW: i64 = wg_w(); let WH: i64 = wg_h(); let npx: i64 = WW*WH
72 let seed: i64 = 314
73 let fb: *i64 = sys_mmap(npx*8) as *i64
74 let depth: *i64 = sys_mmap(npx*8) as *i64
75 let seg: *i64 = sys_mmap(npx*8) as *i64
76 let nrm: *i64 = sys_mmap(npx*8) as *i64
77 let inst: *i64 = sys_mmap(npx*8) as *i64
78 let cam0: *i64 = sys_mmap(4*8) as *i64
79 worldgen_render_full(seed, 0, 0, cam0, fb, depth, seg, nrm)
80
81 // ---- T1 world GT sanity ----
82 var csky: i64 = 0
83 var cterr: i64 = 0
84 var cwat: i64 = 0
85 var nrmok: i64 = 0
86 var nrmbad: i64 = 0
87 var skynrm0: i64 = 1
88 var i: i64 = 0
89 while i < npx {
90 let sv: i64 = seg[i]
91 if sv == 0 { csky = csky + 1; if nrm[i] != 0 { skynrm0 = 0 } }
92 if sv == 1 {
93 cterr = cterr + 1
94 let nv: i64 = nrm[i]
95 let ux: i64 = ((nv & 255) - 128)*1024/127
96 let uy: i64 = (((nv >> 8) & 255) - 128)*1024/127
97 let uz: i64 = (((nv >> 16) & 255) - 128)*1024/127
98 let l2: i64 = ux*ux + uy*uy + uz*uz
99 if l2 > 800000 { if l2 < 1300000 { nrmok = nrmok + 1 } else { nrmbad = nrmbad + 1 } } else { nrmbad = nrmbad + 1 }
100 }
101 if sv == 2 { cwat = cwat + 1 }
102 i = i + 1
103 }
104 hw(" world GT: sky="); pn(csky); hw(" terrain="); pn(cterr); hw(" water="); pn(cwat); hw(" unit-normals ok="); pn(nrmok); hw(" bad="); pn(nrmbad); hw(" sky-nrm-zero="); pn(skynrm0); hw("\n" as *u8)
105 var t1: i64 = 0
106 if csky > 50000 { if cterr > 100000 { if cwat > 2000 { if skynrm0 == 1 { if nrmok*100 > (nrmok+nrmbad)*97 { t1 = 1 } } } } }
107 if t1 == 1 { hw("T1 PASS world GT: classes present, terrain normals unit, sky normals zero\n" as *u8) }
108 else { fails=fails+1; hw("T1 FAIL world GT\n" as *u8) }
109
110 // ---- T2 scene GT: place tree/animal/person with instance ids ----
111 let TW: i64 = tg_w(); let TH: i64 = tg_h(); let AW: i64 = as_w(); let AH: i64 = as_h()
112 let bo: *i64 = sys_mmap(4*8) as *i64
113 let camy: i64 = wg_max(WATER, wg_terrain_h(0,0,seed)) + 1050
114 // tree sprite
115 let TP: *i64 = sys_mmap(TG_CAP*TG_STR*8) as *i64
116 let ts: *i64 = sys_mmap(TW*TH*8) as *i64
117 let tn: i64 = treegen_build_sp(TP, 5, 0)
118 treegen_render(TP, tn, 300, 4, 255, 0, 255, ts)
119 bbox(ts, TW, TH, TREEKEY, bo)
120 var wz: i64 = 5200
121 var wx: i64 = 0 - 1400
122 var h: i64 = wg_terrain_h(wx, wz, seed)
123 paint(fb, seg, inst, depth, WW, WH, ts, TW, TH, bo, TREEKEY, WW/2 + wx*WFOC/wz, WH/2 - WHOR - (h-camy)*WFOC/wz, 300*6000/wz, 3, 1)
124 // animal sprite
125 let AP: *i64 = sys_mmap(96*AS_STRIDE*8) as *i64
126 let asld: *i64 = sys_mmap(AW*AH*8) as *i64
127 let an: i64 = creaturegen_build_plan(AP, 4, 0)
128 anatstack_render(AP, an, 4800, 3, 1, 45, 150, 116, 84, asld)
129 bbox(asld, AW, AH, ANATKEY, bo)
130 wz = 4600
131 wx = 200
132 h = wg_terrain_h(wx, wz, seed)
133 paint(fb, seg, inst, depth, WW, WH, asld, AW, AH, bo, ANATKEY, WW/2 + wx*WFOC/wz, WH/2 - WHOR - (h-camy)*WFOC/wz, 140*6000/wz, 4, 2)
134 // person sprite (neural skin if the model is present)
135 let ps: *i64 = sys_mmap(AW*AH*8) as *i64
136 let sk: *i64 = sys_mmap(8*8) as *i64
137 let pn2: i64 = figuregen_build(AP, 7, sk)
138 let snblob: i64 = skn_load()
139 if snblob != 0 {
140 let sntile: *i64 = sys_mmap(64*64*8) as *i64
141 let snz: *i64 = sys_mmap(SKN_NL*8) as *i64
142 skn_latent(snblob, 7, snz)
143 skn_bake(snblob, snz, sntile, 64, 7)
144 as_set_skintex(sntile as i64, 64, 7)
145 }
146 anatstack_render(AP, pn2, 0, 3, 1, 42, sk[0], sk[1], sk[2], ps)
147 as_set_skintex(0, 0, 0)
148 bbox(ps, AW, AH, ANATKEY, bo)
149 wz = 4000
150 wx = 1300
151 h = wg_terrain_h(wx, wz, seed)
152 paint(fb, seg, inst, depth, WW, WH, ps, AW, AH, bo, ANATKEY, WW/2 + wx*WFOC/wz, WH/2 - WHOR - (h-camy)*WFOC/wz, 192*6000/wz, 5, 3)
153
154 var c3: i64 = 0
155 var c4: i64 = 0
156 var c5: i64 = 0
157 var seen1: i64 = 0
158 var seen2: i64 = 0
159 var seen3: i64 = 0
160 i = 0
161 while i < npx {
162 if seg[i] == 3 { c3 = c3 + 1 }
163 if seg[i] == 4 { c4 = c4 + 1 }
164 if seg[i] == 5 { c5 = c5 + 1 }
165 if inst[i] == 1 { seen1 = 1 }
166 if inst[i] == 2 { seen2 = 1 }
167 if inst[i] == 3 { seen3 = 1 }
168 i = i + 1
169 }
170 hw(" scene GT: tree px="); pn(c3); hw(" animal px="); pn(c4); hw(" person px="); pn(c5); hw(" instances "); pn(seen1); pn(seen2); pn(seen3); hw("\n" as *u8)
171 var t2: i64 = 0
172 if c3 > 400 { if c4 > 400 { if c5 > 400 { if seen1+seen2+seen3 == 3 { t2 = 1 } } } }
173 if t2 == 1 { hw("T2 PASS scene GT: object classes + distinct instance ids painted\n" as *u8) }
174 else { fails=fails+1; hw("T2 FAIL scene GT\n" as *u8) }
175
176 // ---- T3 occlusion boundaries + panel + determinism ----
177 var occl: i64 = 0
178 var y: i64 = 0
179 while y < WH-1 {
180 var x: i64 = 0
181 while x < WW-1 {
182 let d0: i64 = depth[y*WW+x]
183 var big: i64 = 0
184 var dr: i64 = depth[y*WW+x+1] - d0
185 if dr < 0 { dr = 0 - dr }
186 if dr > 900 { big = 1 }
187 var db: i64 = depth[(y+1)*WW+x] - d0
188 if db < 0 { db = 0 - db }
189 if db > 900 { big = 1 }
190 if d0 < 1000000000 { if big == 1 { occl = occl + 1 } }
191 x = x + 1
192 }
193 y = y + 1
194 }
195 hw(" occlusion-boundary px: "); pn(occl); hw("\n" as *u8)
196 // panel: colour | seg | normals | depth+occl (2x2)
197 let GW: i64 = WW*2
198 let gal: *i64 = sys_mmap(GW*WH*2*8) as *i64
199 var dmax: i64 = 1
200 i = 0
201 while i < npx { if depth[i] < 1000000000 { if depth[i] > dmax { dmax = depth[i] } } i = i + 1 }
202 y = 0
203 while y < WH {
204 var x: i64 = 0
205 while x < WW {
206 let pi2: i64 = y*WW+x
207 gal[y*GW+x] = fb[pi2]
208 var segc: i64 = 20 + 24*256 + 40*65536
209 let sv: i64 = seg[pi2]
210 if sv == 1 { segc = 60 + 150*256 + 60*65536 }
211 if sv == 2 { segc = 200 + 120*256 + 40*65536 }
212 if sv == 3 { segc = 40 + 230*256 + 90*65536 }
213 if sv == 4 { segc = 60 + 140*256 + 240*65536 }
214 if sv == 5 { segc = 230 + 60*256 + 200*65536 }
215 gal[y*GW+WW+x] = segc
216 gal[(WH+y)*GW+x] = nrm[pi2]
217 var dg: i64 = 0
218 if depth[pi2] < 1000000000 { dg = 255 - depth[pi2]*220/dmax }
219 var dc: i64 = dg + dg*256 + dg*65536
220 // occl overlay: red edge px
221 if x < WW-1 { if y < WH-1 { if depth[pi2] < 1000000000 {
222 var dr2: i64 = depth[pi2+1] - depth[pi2]
223 if dr2 < 0 { dr2 = 0 - dr2 }
224 var db2: i64 = depth[pi2+WW] - depth[pi2]
225 if db2 < 0 { db2 = 0 - db2 }
226 if dr2 > 900 { dc = 230 + 40*256 + 30*65536 }
227 if db2 > 900 { dc = 230 + 40*256 + 30*65536 }
228 } } }
229 gal[(WH+y)*GW+WW+x] = dc
230 x = x + 1
231 }
232 y = y + 1
233 }
234 write_png(gal, GW, WH*2, "knowledge/nx_gt_panel.png" as *u8)
235 var t3: i64 = 0
236 if occl > 1500 { if occl < npx/4 { t3 = 1 } }
237 if t3 == 1 { hw("T3 PASS occlusion boundaries derived + panel knowledge/nx_gt_panel.png (colour|seg|normals|depth+occl)\n" as *u8) }
238 else { fails=fails+1; hw("T3 FAIL occl="); pn(occl); hw("\n" as *u8) }
239
240 if fails == 0 { hw("GT-ANNOTATIONS-GATE GREEN -- R2: depth + semantic seg + instance ids + unit normals + occlusion boundaries, per-pixel, from OUR renderers (flow = named residual pending animation)\n" as *u8); sys_exit(0); return 0 }
241 hw("GT-ANNOTATIONS-GATE RED fails="); pn(fails); hw("\n" as *u8)
242 sys_exit(1)
243 return 1
244}