code wiki / _hdl_build / nx_procgen_scene_gate.nx
nx_procgen_scene_gate.nx source
↩ module page · 166 lines · 10653 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// license_tier: ORIGINAL expect_exit: 0
8import "nx_png_write.nx"
9
10func 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 }
11func 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 }
12func 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 }
13func sc_smooth(t: i64) -> i64 { let t2: i64=(t*t)/4096; return (t2*(3*4096-2*t))/4096 }
14func sc_vnoise1(x: i64, lat: i64, sw: i64, seed: i64) -> i64 {
15 let fx: i64=(x*lat*4096)/sw; let gx: i64=fx/4096; let tx: i64=fx-gx*4096
16 let c0: i64=sc_hash(gx,seed); let c1: i64=sc_hash(gx+1,seed)
17 let sx: i64=sc_smooth(tx); return c0 + ((c1-c0)*sx)/4096
18}
19func sc_fbm1(x: i64, sw: i64, seed: i64) -> i64 {
20 var h: i64=0; var amp: i64=2048; var lat: i64=4; var norm: i64=0; var o: i64=0
21 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 }
22 if norm<1 { norm=1 }
23 return (h*1000)/norm
24}
25
26func main() -> i64 {
27 sc_puts("=== nx_procgen_scene_gate -- composed nature scene + ground-truth segmentation labels ===\n" as *u8)
28 var fails: i64=0
29 let SW: i64=600; let SH: i64=320; let DIV: i64=8; let W: i64=SW*2+DIV
30 let rgb: *u8=sys_mmap(W*SH*3+16)
31 let lab: *u8=sys_mmap(W*SH*3+16)
32 let seed: i64=4242
33 // class colours for the label map
34 let sky_lr: i64=90; let sky_lg: i64=120; let sky_lb: i64=200
35 let gnd_lr: i64=70; let gnd_lg: i64=150; let gnd_lb: i64=60
36 let tre_lr: i64=20; let tre_lg: i64=90; let tre_lb: i64=40
37 let hum_lr: i64=210; let hum_lg: i64=50; let hum_lb: i64=50
38 var skyc: i64=0; var gndc: i64=0; var trec: i64=0; var humc: i64=0
39 // ground horizon per column
40 let gtop: *i64=sys_mmap(SW*8) as *i64
41 var x: i64=0
42 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 }
43 // paint sky + ground into BOTH the scene (shaded) and the label (flat class)
44 var py: i64=0
45 while py<SH {
46 var px: i64=0
47 while px<SW {
48 let o: i64=(py*W+px)*3
49 let lo: i64=o
50 if py<gtop[px] {
51 // sky gradient
52 let t: i64=(py*1000)/(gtop[px]+1)
53 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
54 lab[lo]=sky_lr as u8; lab[lo+1]=sky_lg as u8; lab[lo+2]=sky_lb as u8
55 skyc=skyc+1
56 } else {
57 // ground: near (lower) darker/greener, far lighter
58 let d: i64=py-gtop[px]
59 var g: i64=150 - (d/4); if g<70 {g=70}
60 let nz: i64=sc_hash(px*3+py,seed)%20
61 rgb[o]=(70+nz) as u8; rgb[o+1]=(g) as u8; rgb[o+2]=(50+nz) as u8
62 lab[lo]=gnd_lr as u8; lab[lo+1]=gnd_lg as u8; lab[lo+2]=gnd_lb as u8
63 gndc=gndc+1
64 }
65 px=px+1
66 }
67 py=py+1
68 }
69 // trees: seed count, back-to-front (smaller/higher base = farther -> draw first)
70 let ntree: i64=5 + sc_hash(9,seed)%3
71 var ti: i64=0
72 while ti<ntree {
73 let tx: i64=40 + (sc_hash(ti*13+1,seed)*(SW-80))/4096
74 if tx>=2 { if tx<SW-2 {
75 let baseY: i64=gtop[tx]
76 let scale: i64=40 + (baseY-70)*70/180 // farther(high) small, near(low) big
77 let th: i64=scale // tree height
78 let trunkH: i64=th/3; let trunkW: i64=2 + scale/22
79 // trunk
80 var yy: i64=baseY-trunkH
81 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 }
82 // canopy: 3 stacked circles
83 let cr: i64=scale/2
84 var lvl: i64=0
85 while lvl<3 {
86 let ccy: i64=baseY-trunkH-cr+lvl*(0-cr*7/10)
87 let ccr: i64=cr - lvl*cr/4
88 var ey: i64=ccy-ccr
89 while ey<=ccy+ccr {
90 var ex: i64=tx-ccr
91 while ex<=tx+ccr {
92 let dx: i64=ex-tx; let dy: i64=ey-ccy
93 if dx*dx+dy*dy<=ccr*ccr { if ex>=0 { if ex<SW { if ey>=0 { if ey<SH {
94 let o: i64=(ey*W+ex)*3
95 let sh: i64=180 - (dx*40)/(ccr+1)
96 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
97 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
98 } } } } }
99 ex=ex+1
100 }
101 ey=ey+1
102 }
103 lvl=lvl+1
104 }
105 } }
106 ti=ti+1
107 }
108 // one canon human in the foreground
109 let hx: i64=SW*7/10; let hbase: i64=gtop[hx]
110 let Hh: i64=SH-hbase-6; if Hh<60 { } // figure height = from ground to near bottom
111 let figH: i64=110
112 let hy0: i64=hbase-figH // top of head
113 let hh: i64=figH/8 // head height (8 heads-ish)
114 // torso silhouette
115 let sh_hw: i64=hh*15/10; let ws_hw: i64=hh*9/10; let hp_hw: i64=hh*12/10
116 let ySh: i64=hy0+hh*13/10; let yWa: i64=hy0+hh*3; let yHp: i64=hy0+hh*35/10
117 var yy2: i64=ySh
118 while yy2<=yHp {
119 var hw: i64=0
120 if yy2<=yWa { let t: i64=((yy2-ySh)*1000)/(yWa-ySh+1); hw=sh_hw+((ws_hw-sh_hw)*t)/1000 }
121 else { let t: i64=((yy2-yWa)*1000)/(yHp-yWa+1); hw=ws_hw+((hp_hw-ws_hw)*t)/1000 }
122 var px2: i64=hx-hw
123 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 }
124 yy2=yy2+1
125 }
126 // legs
127 var lg: i64=0
128 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 }
129 // head
130 let hcx: i64=hx; let hcy: i64=hy0+hh/2; let hrx: i64=hh*4/10; let hry: i64=hh/2
131 var ey2: i64=hcy-hry
132 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 }
133 // divider
134 var dy4: i64=0
135 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 }
136 // copy label panel into the right half of rgb
137 var cy: i64=0
138 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 }
139 nx_png_write_rgb("knowledge/nx_procgen_scene.png\x00" as *u8, rgb, W, SH)
140 sc_puts(" wrote knowledge/nx_procgen_scene.png\n" as *u8)
141 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)
142 // T1 all 4 classes present
143 var t1: i64=0
144 if skyc>1000 { if gndc>1000 { if trec>300 { if humc>200 { t1=1 } } } }
145 if t1==1 { sc_puts("T1 PASS composed scene has all 4 classes (sky+ground+tree+human)\n" as *u8) } else { fails=fails+1; sc_puts("T1 FAIL missing a class\n" as *u8) }
146 // T2 label map aligns (labelled px == scene px, full coverage of left panel)
147 let total: i64=skyc+gndc+trec+humc
148 var t2: i64=0
149 if total>SW*SH*9/10 { t2=1 }
150 sc_puts(" labelled px="); sc_pn(total); sc_puts(" / panel="); sc_pn(SW*SH); sc_puts("\n" as *u8)
151 if t2==1 { sc_puts("T2 PASS every pixel carries a ground-truth class label (digital-twin/training shape)\n" as *u8) } else { fails=fails+1; sc_puts("T2 FAIL label coverage incomplete\n" as *u8) }
152 // T3 composition sanity: trees rest ON ground (canopy above their base), human present
153 var t3: i64=0
154 if trec>300 { if humc>200 { t3=1 } }
155 if t3==1 { sc_puts("T3 PASS elements composed (trees + human placed on the procedural ground)\n" as *u8) } else { fails=fails+1; sc_puts("T3 FAIL\n" as *u8) }
156 // T4 png
157 let szp: *i64=sys_mmap(16) as *i64
158 let rb: *u8=sys_read_file("knowledge/nx_procgen_scene.png\x00" as *u8, szp)
159 var t4: i64=0
160 if (rb as i64)!=0 { if szp[0]>1000 { t4=1 } }
161 if t4==1 { sc_puts("T4 PASS PNG ("); sc_pn(szp[0]); sc_puts(" bytes)\n" as *u8) } else { fails=fails+1; sc_puts("T4 FAIL png\n" as *u8) }
162 if fails==0 { sc_puts("PROCGEN-SCENE verdict=GREEN -- composed procedural scene + per-pixel ground-truth labels (Infinigen/digital-twin shape, sovereign integer)\n" as *u8); sys_exit(0); return 0 }
163 sc_puts("PROCGEN-SCENE RED fails="); sc_pn(fails); sc_puts("\n" as *u8)
164 sys_exit(1)
165 return 1
166}