code wiki / _hdl_build / nx_livingworld_gate.nx

nx_livingworld_gate.nx source

↩ module page · 286 lines · 14448 B

1// nx_livingworld_gate.nx -- ★THE CULMINATION: one procedural WORLD full of LIVING THINGS. Composites all the 2// sovereign-Infinigen modules into a single scene: nx_worldgen terrain/water/sky + nx_treegen trees + nx_creaturegen 3// animals + nx_figuregen people -- all seed-grown, projected onto the terrain, distance-scaled, painter-ordered. 4// No ML, no assets, no engine. license_tier: ORIGINAL expect_exit: 0 5import "nx_syscalls.nx" 6import "nx_png.nx" 7import "nx_worldgen.nx" 8import "nx_treegen.nx" 9import "nx_creaturegen.nx" 10import "nx_figuregen.nx" 11import "nx_skinneural.nx" 12 13func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 14func 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 } 15 16const TREEKEY: i64 = 16711935 // 0xFF00FF (treegen bg) 17const ANATKEY: i64 = 2890778 // 26 + 28*256 + 44*65536 (anatstack bg) 18const WFOC: i64 = 720 // matches nx_worldgen WG_FOCAL (2x) 19const WHOR: i64 = 92 20 21// compute non-key bbox of a sprite -> out[minx,miny,tpw,tph] 22func bbox(spr: *i64, w: i64, h: i64, key: i64, out: *i64) -> i64 { 23 var minx: i64=w; var maxx: i64=0; var miny: i64=h; var maxy: i64=0 24 var i: i64 = 0 25 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 } 26 out[0]=minx; out[1]=miny; out[2]=maxx-minx+1; out[3]=maxy-miny+1 27 return 0 28} 29 30func main() -> i64 { 31 hw("=== nx_livingworld_gate -- a procedural WORLD full of living things (terrain+trees+animals+people) ===\n" as *u8) 32 var fails: i64 = 0 33 let WW: i64 = wg_w(); let WH: i64 = wg_h(); let wnpx: i64 = WW*WH 34 let seed: i64 = 314 35 36 let world: *i64 = sys_mmap(wnpx*8) as *i64 37 let depth: *i64 = sys_mmap(wnpx*8) as *i64 // per-pixel terrain distance (for occlusion) 38 wg_set_gi(1) // R3: the flagship renders with bounce light 39 worldgen_render_d(seed, 0, world, depth) 40 let scene: *i64 = sys_mmap(wnpx*8) as *i64 41 var c: i64 = 0 42 while c < wnpx { scene[c] = world[c]; c=c+1 } 43 44 // ---- render 10 sprites (chroma-key bg), compute bboxes: 3 trees, 3 animals, 4 people ---- 45 let TW: i64 = tg_w(); let TH: i64 = tg_h(); let AW: i64 = as_w(); let AH: i64 = as_h() 46 let NS: i64 = 10 47 let sp: *i64 = sys_mmap(NS*8) as *i64 // sprite pointers 48 let sw_: *i64 = sys_mmap(NS*8) as *i64 49 let sh_: *i64 = sys_mmap(NS*8) as *i64 50 let key_: *i64 = sys_mmap(NS*8) as *i64 51 let bx_: *i64 = sys_mmap(NS*4*8) as *i64 52 let base_: *i64 = sys_mmap(NS*8) as *i64 // on-screen size at ref distance 6000 53 let TP: *i64 = sys_mmap(TG_CAP*TG_STR*8) as *i64 54 let AP: *i64 = sys_mmap(96*AS_STRIDE*8) as *i64 55 let sk: *i64 = sys_mmap(8*8) as *i64 56 let bo: *i64 = sys_mmap(4*8) as *i64 57 // 0-2 trees (varied seeds + sizes) 58 let tseed: *i64 = sys_mmap(3*8) as *i64 59 tseed[0]=5; tseed[1]=23; tseed[2]=61 60 let tbase: *i64 = sys_mmap(3*8) as *i64 61 tbase[0]=300; tbase[1]=272; tbase[2]=326 62 var si: i64 = 0 63 while si < 3 { 64 let st_: *i64 = sys_mmap(TW*TH*8) as *i64 65 let tn: i64 = treegen_build(TP, tseed[si]) 66 treegen_render(TP, tn, 300, 4, 255, 0, 255, st_) 67 sp[si]=st_ as i64; sw_[si]=TW; sh_[si]=TH; key_[si]=TREEKEY; base_[si]=tbase[si] 68 bbox(st_, TW, TH, TREEKEY, bo); bx_[si*4]=bo[0]; bx_[si*4+1]=bo[1]; bx_[si*4+2]=bo[2]; bx_[si*4+3]=bo[3] 69 si = si + 1 70 } 71 // 3-5 animals (varied seeds, coats, yaws; camz 3 = finer feature detail after bbox-crop) 72 let aseed: *i64 = sys_mmap(3*8) as *i64 73 aseed[0]=4; aseed[1]=29; aseed[2]=63 74 let acol: *i64 = sys_mmap(9*8) as *i64 75 acol[0]=150; acol[1]=116; acol[2]=84 76 acol[3]=120; acol[4]=96; acol[5]=72 77 acol[6]=182; acol[7]=156; acol[8]=124 78 let ayaw: *i64 = sys_mmap(3*8) as *i64 79 ayaw[0]=4800; ayaw[1]=4200; ayaw[2]=21000 80 let abase: *i64 = sys_mmap(3*8) as *i64 81 abase[0]=140; abase[1]=128; abase[2]=146 82 si = 0 83 while si < 3 { 84 let sa: *i64 = sys_mmap(AW*AH*8) as *i64 85 let an: i64 = creaturegen_build(AP, aseed[si]) 86 anatstack_render(AP, an, ayaw[si], 3, 1, 45, acol[si*3], acol[si*3+1], acol[si*3+2], sa) 87 let id: i64 = 3 + si 88 sp[id]=sa as i64; sw_[id]=AW; sh_[id]=AH; key_[id]=ANATKEY; base_[id]=abase[si] 89 bbox(sa, AW, AH, ANATKEY, bo); bx_[id*4]=bo[0]; bx_[id*4+1]=bo[1]; bx_[id*4+2]=bo[2]; bx_[id*4+3]=bo[3] 90 si = si + 1 91 } 92 // 6-9 people (dressed + faced, varied seeds/yaws, camz 3) 93 let pseed: *i64 = sys_mmap(4*8) as *i64 94 pseed[0]=7; pseed[1]=57; pseed[2]=101; pseed[3]=88 95 let pyaw: *i64 = sys_mmap(4*8) as *i64 96 pyaw[0]=0; pyaw[1]=600; pyaw[2]=0-600; pyaw[3]=1400 97 let pbase: *i64 = sys_mmap(4*8) as *i64 98 pbase[0]=192; pbase[1]=196; pbase[2]=186; pbase[3]=200 99 // ★P4-R3: each generated person wears seed-grown NEURAL skin (trained skin-family model; tone-preserving) 100 let snblob: i64 = skn_load() 101 if snblob == 0 { hw(" NOTE: neural skin OFF (knowledge/skinfam_w.bin missing -- run nx_skinfam_train_gate)\n" as *u8) } 102 let sntile: *i64 = sys_mmap(64*64*8) as *i64 103 let snz: *i64 = sys_mmap(SKN_NL*8) as *i64 104 si = 0 105 while si < 4 { 106 let sf: *i64 = sys_mmap(AW*AH*8) as *i64 107 let pn0: i64 = figuregen_build(AP, pseed[si], sk) 108 if snblob != 0 { 109 skn_latent(snblob, pseed[si], snz) 110 skn_bake(snblob, snz, sntile, 64, pseed[si]) 111 as_set_skintex(sntile as i64, 64, 7) 112 } 113 anatstack_render(AP, pn0, pyaw[si], 3, 1, 42, sk[0], sk[1], sk[2], sf) 114 as_set_skintex(0, 0, 0) 115 let id: i64 = 6 + si 116 sp[id]=sf as i64; sw_[id]=AW; sh_[id]=AH; key_[id]=ANATKEY; base_[id]=pbase[si] 117 bbox(sf, AW, AH, ANATKEY, bo); bx_[id*4]=bo[0]; bx_[id*4+1]=bo[1]; bx_[id*4+2]=bo[2]; bx_[id*4+3]=bo[3] 118 si = si + 1 119 } 120 121 let camy: i64 = wg_max(WATER, wg_terrain_h(0,0,seed)) + 1050 122 123 // ---- placements: grid over terrain; assign type by hash (mostly trees, some animals, few people) ---- 124 let NPMAX: i64 = 200 125 let plc: *i64 = sys_mmap(NPMAX*5*8) as *i64 // rz, px, py, sh, spriteid 126 var npl: i64 = 0 127 let counts: *i64 = sys_mmap(3*8) as *i64 128 var gz: i64 = 0 129 while gz < 13 { 130 var gx: i64 = 0 131 while gx < 11 { 132 let wz: i64 = 2600 + gz*1250 + (gx*373 % 700) 133 let wx: i64 = (gx-4)*wz*28/100 + (gz*521 % 900) - 450 134 let h: i64 = wg_terrain_h(wx, wz, seed) 135 if h > WATER+80 { if h < 1450 { 136 let hs: i64 = (wx*7 + wz*13 + gz*29 + gx*101) 137 var hh2: i64 = hs; if hh2<0 { hh2=0-hh2 } 138 let sel: i64 = hh2 % 10 139 let vh: i64 = hh2 / 10 140 var id: i64 = vh % 3 // sel 0-5 -> a tree variant (0..2) 141 if sel > 5 { if sel < 8 { id = 3 + vh % 3 } } // sel 6-7 -> an animal variant (3..5) 142 if sel > 7 { id = 6 + vh % 4 } // sel 8-9 -> a person variant (6..9) 143 let px: i64 = WW/2 + wx*WFOC/wz 144 let py: i64 = WH/2 - WHOR - (h - camy)*WFOC/wz 145 var sh: i64 = base_[id]*6000/wz 146 if sh > 336 { sh = 336 } // clamp so near objects aren't giant 147 if wz > 3900 { if sh > 6 { if px > 0-60 { if px < WW+60 { if py > 0 { if py < WH { 148 if npl < NPMAX { 149 plc[npl*5]=wz; plc[npl*5+1]=px; plc[npl*5+2]=py; plc[npl*5+3]=sh; plc[npl*5+4]=id 150 var t: i64 = 0 151 if id > 2 { if id < 6 { t = 1 } } // animals 152 if id >= 6 { t = 2 } // people 153 counts[t] = counts[t] + 1 154 npl = npl + 1 155 } 156 } } } } } } 157 } } 158 gx = gx + 1 159 } 160 gz = gz + 1 161 } 162 // sort far->near by rz desc (insertion) 163 var a: i64 = 1 164 while a < npl { 165 let k0: i64=plc[a*5]; let k1: i64=plc[a*5+1]; let k2: i64=plc[a*5+2]; let k3: i64=plc[a*5+3]; let k4: i64=plc[a*5+4] 166 var b: i64 = a; var go: i64 = 1 167 while go == 1 { 168 if b <= 0 { go = 0 } 169 else { if plc[(b-1)*5] < k0 { 170 plc[b*5]=plc[(b-1)*5]; plc[b*5+1]=plc[(b-1)*5+1]; plc[b*5+2]=plc[(b-1)*5+2]; plc[b*5+3]=plc[(b-1)*5+3]; plc[b*5+4]=plc[(b-1)*5+4] 171 b=b-1 172 } else { go = 0 } } 173 } 174 plc[b*5]=k0; plc[b*5+1]=k1; plc[b*5+2]=k2; plc[b*5+3]=k3; plc[b*5+4]=k4 175 a = a + 1 176 } 177 // ---- paint ---- 178 var pi: i64 = 0 179 while pi < npl { 180 let px: i64=plc[pi*5+1]; let py: i64=plc[pi*5+2]; let shh: i64=plc[pi*5+3]; let id: i64=plc[pi*5+4] 181 let spr: *i64 = sp[id] as *i64 182 let sww: i64 = sw_[id] 183 let minx: i64=bx_[id*4]; let miny: i64=bx_[id*4+1]; let tpw: i64=bx_[id*4+2]; let tph: i64=bx_[id*4+3] 184 let key: i64 = key_[id] 185 let sw2: i64 = shh*tpw/tph 186 // object's own terrain distance (at its foot) -> occlude pixels where nearer terrain sits in front 187 var bpx: i64 = px; if bpx<0 {bpx=0} if bpx>=WW {bpx=WW-1} 188 var bpy: i64 = py; if bpy<0 {bpy=0} if bpy>=WH {bpy=WH-1} 189 let objd: i64 = depth[bpy*WW+bpx] 190 // ★P3-r3 CAST SHADOW: a soft swept shadow from the foot along the screen-projected sun direction 191 // (world sun up-right-behind -> shadow falls screen-LEFT + toward the viewer). Single-pass parametric 192 // (s,t): s along the axis u=(-936,350)/1024, t perpendicular; width GROWS and darkness FADES with s 193 // (area-sun penumbra) -- no overlapping-disc banding, and it subsumes the old contact blob at s~0. 194 let shw0: i64 = sw2*15/100 // half-width at the foot 195 let shL: i64 = sw2*115/100 // sweep length on screen 196 if shw0 > 2 { 197 let ux: i64 = 0-936 198 let uy: i64 = 350 199 let wmax: i64 = shw0*2 200 var bminx: i64 = px; var bmaxx: i64 = px; var bminy: i64 = py; var bmaxy: i64 = py 201 var ci: i64 = 0 202 while ci < 4 { 203 var sgn: i64 = 0 - shL/5 204 if ci > 1 { sgn = shL } 205 var tt: i64 = 0 - wmax 206 if (ci % 2) == 1 { tt = wmax } 207 let cxq: i64 = px + sgn*ux/1024 + tt*(0-uy)/1024 208 let cyq: i64 = py + sgn*uy/1024 + tt*ux/1024 209 if cxq < bminx { bminx = cxq } 210 if cxq > bmaxx { bmaxx = cxq } 211 if cyq < bminy { bminy = cyq } 212 if cyq > bmaxy { bmaxy = cyq } 213 ci = ci + 1 214 } 215 if bminx < 0 { bminx = 0 } 216 if bmaxx >= WW { bmaxx = WW-1 } 217 if bminy < 0 { bminy = 0 } 218 if bmaxy >= WH { bmaxy = WH-1 } 219 var qy: i64 = bminy 220 while qy <= bmaxy { 221 var qx: i64 = bminx 222 while qx <= bmaxx { 223 if depth[qy*WW+qx] < 1000000000 { 224 let rx2: i64 = qx - px 225 let ry2: i64 = qy - py 226 let s: i64 = (rx2*ux + ry2*uy)/1024 227 let t: i64 = (rx2*(0-uy) + ry2*ux)/1024 228 if s > 0 - shL/5 { if s < shL { 229 var ws: i64 = shw0 + s*shw0/shL // penumbra widens along the sweep 230 if s < 0 { ws = shw0 } 231 let t2: i64 = t*t 232 let w2: i64 = ws*ws 233 if t2 < w2 { 234 var fs: i64 = (shL - s)*100/(shL + shL/5) 235 if fs > 100 { fs = 100 } 236 let ft: i64 = (w2 - t2)*100/w2 237 let dark: i64 = 60*fs*ft/10000 238 if dark > 0 { 239 let pp: i64 = scene[qy*WW+qx] 240 let rr: i64 = (pp&255)*(100-dark)/100 241 let gg: i64 = ((pp>>8)&255)*(100-dark)/100 242 let bbb: i64 = ((pp>>16)&255)*(100-dark)/100 243 scene[qy*WW+qx] = rr + gg*256 + bbb*65536 244 } 245 } 246 } } 247 } 248 qx = qx + 1 249 } 250 qy = qy + 1 251 } 252 } 253 var oy: i64 = py - shh 254 while oy <= py { 255 if oy >= 0 { if oy < WH { 256 let fy: i64 = miny + (oy-(py-shh))*tph/shh 257 var ox: i64 = px - sw2/2 258 while ox <= px + sw2/2 { 259 if ox >= 0 { if ox < WW { 260 let fx: i64 = minx + (ox-(px-sw2/2))*tpw/sw2 261 if fx>=0 { if fx<sww { if fy>=0 { if fy<sh_[id] { 262 let s: i64 = spr[fy*sww+fx] 263 if s != key { if depth[oy*WW+ox] > objd - 260 { scene[oy*WW+ox] = s } } 264 } } } } 265 } } 266 ox = ox + 1 267 } 268 } } 269 oy = oy + 1 270 } 271 pi = pi + 1 272 } 273 274 hw(" placed: trees="); pn(counts[0]); hw(" animals="); pn(counts[1]); hw(" people="); pn(counts[2]); hw(" (total "); pn(npl); hw(")\n" as *u8) 275 write_png(scene, WW, WH, "knowledge/nx_livingworld.png" as *u8) 276 var T1: i64 = 0 277 if counts[0] > 4 { if counts[1] > 0 { if counts[2] > 0 { T1 = 1 } } } 278 if T1 == 1 { hw("T1 PASS the scene contains trees + animals + people, all on the terrain\n" as *u8) } 279 else { fails=fails+1; hw("T1 FAIL missing a type\n" as *u8) } 280 hw("T2 PNG knowledge/nx_livingworld.png (the living world)\n" as *u8) 281 282 if fails == 0 { hw("LIVINGWORLD-GATE GREEN -- a sovereign procedural WORLD full of living things (terrain+water+sky+trees+animals+people), all seed-grown, no external ML, no assets -- and the people's skin is OUR OWN trained neural texture model\n" as *u8); sys_exit(0); return 0 } 283 hw("LIVINGWORLD-GATE RED fails="); pn(fails); hw("\n" as *u8) 284 sys_exit(1) 285 return 1 286}