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}