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}