code wiki / _hdl_build / nx_procgen_scene_gate.nx

nx_procgen_scene_gate.nx source

↩ module page · 168 lines · 10777 B

1// nx_procgen_scene_gate.nx -- Gx/PROCGEN: a COMPOSED procedural nature scene + paired GROUND-TRUTH SEGMENTATION 2// label map (the Infinigen / digital-twin shape). Unifies the generators: 1D-FBM rolling-hill horizon + sky 3// gradient + seed-placed procedural trees (trunk + canopy) + one canon-proportioned human, all in one frame; a 4// parallel buffer emits a flat-coloured per-pixel CLASS map (sky/ground/tree/human) = the label an ML/twin 5// pipeline consumes. Integer/sovereign/asset-free, seed-diverse. HONEST: stylised, not photoreal -- it proves 6// COMPOSITION + LABELS (two named GAP axes), not fidelity. 7// D001 MIGRATION 2026-09-02 (procgen PG19): hand-rolled PASS/FAIL prints, a fails counter and sys_exit(1) replaced by gv_check 8// per tooth and gv_verdict, so the exit code IS the verdict; measurements, thresholds and the PNGs are unchanged. 9// license_tier: ORIGINAL expect_exit: 0 10import "nx_syscalls.nx" 11import "nx_gate_verdict.nx" 12import "nx_png_write.nx" 13 14func sc_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 15func sc_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 } 16func sc_hash(x: i64, seed: i64) -> i64 { var a: i64=(x+1)*374761393 + (seed+1)*668265263; a=a%16777216; if a<0{a=a+16777216} a=(a*1103515245+12345)%16777216; if a<0{a=a+16777216} return a%4096 } 17func sc_smooth(t: i64) -> i64 { let t2: i64=(t*t)/4096; return (t2*(3*4096-2*t))/4096 } 18func sc_vnoise1(x: i64, lat: i64, sw: i64, seed: i64) -> i64 { 19 let fx: i64=(x*lat*4096)/sw; let gx: i64=fx/4096; let tx: i64=fx-gx*4096 20 let c0: i64=sc_hash(gx,seed); let c1: i64=sc_hash(gx+1,seed) 21 let sx: i64=sc_smooth(tx); return c0 + ((c1-c0)*sx)/4096 22} 23func sc_fbm1(x: i64, sw: i64, seed: i64) -> i64 { 24 var h: i64=0; var amp: i64=2048; var lat: i64=4; var norm: i64=0; var o: i64=0 25 while o<4 { h=h+(sc_vnoise1(x,lat,sw,seed+o*97)*amp)/4096; norm=norm+amp; amp=amp/2; lat=lat*2; o=o+1 } 26 if norm<1 { norm=1 } 27 return (h*1000)/norm 28} 29 30func main() -> i64 { 31 sc_puts("=== nx_procgen_scene_gate -- composed nature scene + ground-truth segmentation labels ===\n" as *u8) 32 let ctr: *i64=gv_ctr() 33 let SW: i64=600; let SH: i64=320; let DIV: i64=8; let W: i64=SW*2+DIV 34 let rgb: *u8=sys_mmap(W*SH*3+16) 35 let lab: *u8=sys_mmap(W*SH*3+16) 36 let seed: i64=4242 37 // class colours for the label map 38 let sky_lr: i64=90; let sky_lg: i64=120; let sky_lb: i64=200 39 let gnd_lr: i64=70; let gnd_lg: i64=150; let gnd_lb: i64=60 40 let tre_lr: i64=20; let tre_lg: i64=90; let tre_lb: i64=40 41 let hum_lr: i64=210; let hum_lg: i64=50; let hum_lb: i64=50 42 var skyc: i64=0; var gndc: i64=0; var trec: i64=0; var humc: i64=0 43 // ground horizon per column 44 let gtop: *i64=sys_mmap(SW*8) as *i64 45 var x: i64=0 46 while x<SW { let f: i64=sc_fbm1(x,SW,seed); gtop[x]=150 + (f-500)/6; if gtop[x]<70 {gtop[x]=70} if gtop[x]>250 {gtop[x]=250} x=x+1 } 47 // paint sky + ground into BOTH the scene (shaded) and the label (flat class) 48 var py: i64=0 49 while py<SH { 50 var px: i64=0 51 while px<SW { 52 let o: i64=(py*W+px)*3 53 let lo: i64=o 54 if py<gtop[px] { 55 // sky gradient 56 let t: i64=(py*1000)/(gtop[px]+1) 57 rgb[o]=(70+(140*t)/1000) as u8; rgb[o+1]=(110+(90*t)/1000) as u8; rgb[o+2]=(180+(50*t)/1000) as u8 58 lab[lo]=sky_lr as u8; lab[lo+1]=sky_lg as u8; lab[lo+2]=sky_lb as u8 59 skyc=skyc+1 60 } else { 61 // ground: near (lower) darker/greener, far lighter 62 let d: i64=py-gtop[px] 63 var g: i64=150 - (d/4); if g<70 {g=70} 64 let nz: i64=sc_hash(px*3+py,seed)%20 65 rgb[o]=(70+nz) as u8; rgb[o+1]=(g) as u8; rgb[o+2]=(50+nz) as u8 66 lab[lo]=gnd_lr as u8; lab[lo+1]=gnd_lg as u8; lab[lo+2]=gnd_lb as u8 67 gndc=gndc+1 68 } 69 px=px+1 70 } 71 py=py+1 72 } 73 // trees: seed count, back-to-front (smaller/higher base = farther -> draw first) 74 let ntree: i64=5 + sc_hash(9,seed)%3 75 var ti: i64=0 76 while ti<ntree { 77 let tx: i64=40 + (sc_hash(ti*13+1,seed)*(SW-80))/4096 78 if tx>=2 { if tx<SW-2 { 79 let baseY: i64=gtop[tx] 80 let scale: i64=40 + (baseY-70)*70/180 // farther(high) small, near(low) big 81 let th: i64=scale // tree height 82 let trunkH: i64=th/3; let trunkW: i64=2 + scale/22 83 // trunk 84 var yy: i64=baseY-trunkH 85 while yy<baseY { var xx: i64=tx-trunkW; while xx<=tx+trunkW { if xx>=0 { if xx<SW { if yy>=0 { if yy<SH { let o: i64=(yy*W+xx)*3; rgb[o]=92 as u8; rgb[o+1]=64 as u8; rgb[o+2]=38 as u8; let lo: i64=o; lab[lo]=tre_lr as u8; lab[lo+1]=tre_lg as u8; lab[lo+2]=tre_lb as u8; trec=trec+1 } } } } xx=xx+1 } yy=yy+1 } 86 // canopy: 3 stacked circles 87 let cr: i64=scale/2 88 var lvl: i64=0 89 while lvl<3 { 90 let ccy: i64=baseY-trunkH-cr+lvl*(0-cr*7/10) 91 let ccr: i64=cr - lvl*cr/4 92 var ey: i64=ccy-ccr 93 while ey<=ccy+ccr { 94 var ex: i64=tx-ccr 95 while ex<=tx+ccr { 96 let dx: i64=ex-tx; let dy: i64=ey-ccy 97 if dx*dx+dy*dy<=ccr*ccr { if ex>=0 { if ex<SW { if ey>=0 { if ey<SH { 98 let o: i64=(ey*W+ex)*3 99 let sh: i64=180 - (dx*40)/(ccr+1) 100 rgb[o]=(30+ (sc_hash(ex+ey,seed)%25)) as u8; rgb[o+1]=(90+sh/3) as u8; rgb[o+2]=(40+(sc_hash(ex*2+ey,seed)%20)) as u8 101 let lo: i64=o; lab[lo]=tre_lr as u8; lab[lo+1]=tre_lg as u8; lab[lo+2]=tre_lb as u8; trec=trec+1 102 } } } } } 103 ex=ex+1 104 } 105 ey=ey+1 106 } 107 lvl=lvl+1 108 } 109 } } 110 ti=ti+1 111 } 112 // one canon human in the foreground 113 let hx: i64=SW*7/10; let hbase: i64=gtop[hx] 114 let Hh: i64=SH-hbase-6; if Hh<60 { } // figure height = from ground to near bottom 115 let figH: i64=110 116 let hy0: i64=hbase-figH // top of head 117 let hh: i64=figH/8 // head height (8 heads-ish) 118 // torso silhouette 119 let sh_hw: i64=hh*15/10; let ws_hw: i64=hh*9/10; let hp_hw: i64=hh*12/10 120 let ySh: i64=hy0+hh*13/10; let yWa: i64=hy0+hh*3; let yHp: i64=hy0+hh*35/10 121 var yy2: i64=ySh 122 while yy2<=yHp { 123 var hw: i64=0 124 if yy2<=yWa { let t: i64=((yy2-ySh)*1000)/(yWa-ySh+1); hw=sh_hw+((ws_hw-sh_hw)*t)/1000 } 125 else { let t: i64=((yy2-yWa)*1000)/(yHp-yWa+1); hw=ws_hw+((hp_hw-ws_hw)*t)/1000 } 126 var px2: i64=hx-hw 127 while px2<=hx+hw { if px2>=0 { if px2<SW { if yy2>=0 { if yy2<SH { let o: i64=(yy2*W+px2)*3; rgb[o]=210 as u8; rgb[o+1]=150 as u8; rgb[o+2]=120 as u8; let lo: i64=o; lab[lo]=hum_lr as u8; lab[lo+1]=hum_lg as u8; lab[lo+2]=hum_lb as u8; humc=humc+1 } } } } px2=px2+1 } 128 yy2=yy2+1 129 } 130 // legs 131 var lg: i64=0 132 while lg<2 { let lx: i64=hx+(lg*2-1)*(hp_hw/2); var yy3: i64=yHp; while yy3<=hbase { var px3: i64=lx-hh*5/10; while px3<=lx+hh*5/10 { if px3>=0 { if px3<SW { if yy3>=0 { if yy3<SH { let o: i64=(yy3*W+px3)*3; rgb[o]=200 as u8; rgb[o+1]=142 as u8; rgb[o+2]=112 as u8; let lo: i64=o; lab[lo]=hum_lr as u8; lab[lo+1]=hum_lg as u8; lab[lo+2]=hum_lb as u8; humc=humc+1 } } } } px3=px3+1 } yy3=yy3+1 } lg=lg+1 } 133 // head 134 let hcx: i64=hx; let hcy: i64=hy0+hh/2; let hrx: i64=hh*4/10; let hry: i64=hh/2 135 var ey2: i64=hcy-hry 136 while ey2<=hcy+hry { var ex2: i64=hcx-hrx; while ex2<=hcx+hrx { let dx: i64=ex2-hcx; let dy: i64=ey2-hcy; if (dx*dx)*(hry*hry)+(dy*dy)*(hrx*hrx)<=(hrx*hrx)*(hry*hry) { if ex2>=0 { if ex2<SW { if ey2>=0 { if ey2<SH { let o: i64=(ey2*W+ex2)*3; rgb[o]=214 as u8; rgb[o+1]=154 as u8; rgb[o+2]=124 as u8; let lo: i64=o; lab[lo]=hum_lr as u8; lab[lo+1]=hum_lg as u8; lab[lo+2]=hum_lb as u8; humc=humc+1 } } } } } ex2=ex2+1 } ey2=ey2+1 } 137 // divider 138 var dy4: i64=0 139 while dy4<SH { var dx4: i64=SW; while dx4<SW+DIV { let o: i64=(dy4*W+dx4)*3; rgb[o]=8 as u8; rgb[o+1]=8 as u8; rgb[o+2]=10 as u8; lab[o]=8 as u8; lab[o+1]=8 as u8; lab[o+2]=10 as u8; dx4=dx4+1 } dy4=dy4+1 } 140 // copy label panel into the right half of rgb 141 var cy: i64=0 142 while cy<SH { var cx2: i64=0; while cx2<SW { let src: i64=(cy*W+cx2)*3; let dst: i64=(cy*W+(SW+DIV)+cx2)*3; rgb[dst]=lab[src]; rgb[dst+1]=lab[src+1]; rgb[dst+2]=lab[src+2]; cx2=cx2+1 } cy=cy+1 } 143 nx_png_write_rgb("knowledge/nx_procgen_scene.png\x00" as *u8, rgb, W, SH) 144 sc_puts(" wrote knowledge/nx_procgen_scene.png\n" as *u8) 145 sc_puts(" class px -- sky="); sc_pn(skyc); sc_puts(" ground="); sc_pn(gndc); sc_puts(" tree="); sc_pn(trec); sc_puts(" human="); sc_pn(humc); sc_puts("\n" as *u8) 146 // T1 all 4 classes present 147 var t1: i64=0 148 if skyc>1000 { if gndc>1000 { if trec>300 { if humc>200 { t1=1 } } } } 149 gv_check("T1 the composed scene carries all four classes: sky, ground, tree and human, each above its pixel floor" as *u8, t1, ctr) 150 // T2 label map aligns (labelled px == scene px, full coverage of left panel) 151 let total: i64=skyc+gndc+trec+humc 152 var t2: i64=0 153 if total>SW*SH*9/10 { t2=1 } 154 sc_puts(" labelled px="); sc_pn(total); sc_puts(" / panel="); sc_pn(SW*SH); sc_puts("\n" as *u8) 155 gv_check("T2 the label map covers the scene: at least 90 percent of the panel carries a ground-truth class (the digital-twin training shape)" as *u8, t2, ctr) 156 // T3 composition sanity: trees rest ON ground (canopy above their base), human present 157 var t3: i64=0 158 if trec>300 { if humc>200 { t3=1 } } 159 gv_check("T3 elements are composed: trees and a human stand on the procedural ground" as *u8, t3, ctr) 160 // T4 png 161 let szp: *i64=sys_mmap(16) as *i64 162 let rb: *u8=sys_read_file("knowledge/nx_procgen_scene.png\x00" as *u8, szp) 163 var t4: i64=0 164 if (rb as i64)!=0 { if szp[0]>1000 { t4=1 } } 165 if (rb as i64)!=0 { sc_puts(" png bytes="); sc_pn(szp[0]); sc_puts("\n" as *u8) } 166 gv_check("T4 the scene-and-labels PNG was written and reads back over 1000 bytes" as *u8, t4, ctr) 167 return gv_verdict("nx_procgen_scene_gate" as *u8, ctr, "composed procedural scene with per-pixel ground-truth labels (Infinigen and digital-twin shape, sovereign integer); stylised, not photoreal" as *u8) 168}