nx_gen_unified.nx source
↩ module page · 106 lines · 5296 B
1// nx_gen.nx -- ★R5 of the Infinigen ladder: the UNIFIED SOVEREIGN GENERATOR (their V2 bet = ProcFunc, a
2// function-oriented abstraction over ALL asset generators). One data-driven request envelope + a self-describing
3// registry dispatches to every heterogeneous organ, so a caller asks for any asset by KIND + SEED + PARAMS through
4// a single surface and gets back a standard result. This is the abstraction the eventual public generate-UI (R10)
5// and the world compositor both sit on. Adding a generator = one registry row + a thin adapter, never touching a
6// caller (composition over configuration). license_tier: ORIGINAL
7import "nx_worldgen.nx"
8import "nx_treegen.nx"
9import "nx_creaturegen.nx"
10import "nx_figuregen.nx"
11import "nx_persongen.nx"
12import "nx_sdfrender.nx" // fb_off / sdf_render / sdf_bytes for the FACE adapter
13const GEN_MAGIC_4800: i64 = 4800
14const GEN_MAGIC_4200: i64 = 4200
15
16const GEN_WORLD: i64 = 0
17const GEN_TREE: i64 = 1
18const GEN_CREATURE: i64 = 2
19const GEN_FIGURE: i64 = 3
20const GEN_FACE: i64 = 4
21const GEN_NKIND: i64 = 5
22const GEN_TREEBG: i64 = 13763290 // 210 + 224*256 + 238*65536
23const GEN_ANATBG: i64 = 2890778 // 26 + 28*256 + 44*65536
24
25// ---- self-describing registry (what makes this an ABSTRACTION, not a switch buried in each caller) ----
26func gen_kind_count() -> i64 { return GEN_NKIND }
27func gen_kind_name(k: i64) -> *u8 {
28 if k == GEN_WORLD { return "world" as *u8 }
29 if k == GEN_TREE { return "tree" as *u8 }
30 if k == GEN_CREATURE { return "creature" as *u8 }
31 if k == GEN_FIGURE { return "figure" as *u8 }
32 if k == GEN_FACE { return "face" as *u8 }
33 return "?" as *u8
34}
35func gen_param_schema(k: i64) -> *u8 {
36 if k == GEN_WORLD { return "seed, mode(0clear/1sunset/2overcast), biome(0temperate/1desert/2arctic/3autumn)" as *u8 }
37 if k == GEN_TREE { return "seed, species(0broadleaf/1conifer/2birch/3palm/4dead)" as *u8 }
38 if k == GEN_CREATURE { return "seed, plan(0quadruped/1bird/2fish)" as *u8 }
39 if k == GEN_FIGURE { return "seed" as *u8 }
40 if k == GEN_FACE { return "seed" as *u8 }
41 return "" as *u8
42}
43
44func gen_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
45func gen_lum(px: i64) -> i64 { return (px&255)+((px>>8)&255)+((px>>16)&255) }
46func gen_content_bg(fb: *i64, npx: i64, bg: i64) -> i64 { var c: i64=0; var i: i64=0; while i<npx { if fb[i]!=bg { c=c+1 } i=i+1 } return c }
47func gen_content_lum(fb: *i64, npx: i64, thr: i64) -> i64 { var c: i64=0; var i: i64=0; while i<npx { if gen_lum(fb[i])>thr { c=c+1 } i=i+1 } return c }
48
49// ★THE UNIFIED SURFACE. spec = [kind, seed, p0, p1]. res = [ok, W, H, content_px, fb_ptr, kind].
50// Renders the described asset into a fresh framebuffer; caller reads res[4] (fb ptr) to write PNG / composite.
51// Unknown kind -> res[0]=0 (fail-closed). Deterministic: same spec -> same bytes.
52func nx_gen(spec: *i64, res: *i64) -> i64 {
53 let kind: i64 = spec[0]
54 let seed: i64 = spec[1]
55 res[0]=0; res[1]=0; res[2]=0; res[3]=0; res[4]=0; res[5]=kind
56 if kind == GEN_WORLD {
57 let W: i64 = wg_w(); let H: i64 = wg_h()
58 let fb: *i64 = sys_mmap(W*H*8) as *i64
59 let dep: *i64 = sys_mmap(W*H*8) as *i64
60 wg_set_gi(1)
61 worldgen_render_bd(seed, spec[2], spec[3], fb, dep)
62 res[0]=1; res[1]=W; res[2]=H; res[3]=W*H; res[4]=fb as i64
63 return 1
64 }
65 if kind == GEN_TREE {
66 let P: *i64 = sys_mmap(TG_CAP*TG_STR*8) as *i64
67 let n: i64 = treegen_build_sp(P, seed, spec[2])
68 let W: i64 = tg_w(); let H: i64 = tg_h()
69 let fb: *i64 = sys_mmap(W*H*8) as *i64
70 treegen_render(P, n, 300, 4, 210, 224, 238, fb)
71 res[0]=1; res[1]=W; res[2]=H; res[3]=gen_content_bg(fb, W*H, GEN_TREEBG); res[4]=fb as i64
72 return 1
73 }
74 if kind == GEN_CREATURE {
75 let AP: *i64 = sys_mmap(96*AS_STRIDE*8) as *i64
76 let n: i64 = creaturegen_build_plan(AP, seed, spec[2])
77 let W: i64 = as_w(); let H: i64 = as_h()
78 let fb: *i64 = sys_mmap(W*H*8) as *i64
79 var yaw: i64 = GEN_MAGIC_4800
80 if spec[2] == 2 { yaw = GEN_MAGIC_4200 }
81 anatstack_render(AP, n, yaw, 3, 1, 45, 150, 116, 84, fb)
82 res[0]=1; res[1]=W; res[2]=H; res[3]=gen_content_bg(fb, W*H, GEN_ANATBG); res[4]=fb as i64
83 return 1
84 }
85 if kind == GEN_FIGURE {
86 let AP: *i64 = sys_mmap(96*AS_STRIDE*8) as *i64
87 let sk: *i64 = sys_mmap(8*8) as *i64
88 let n: i64 = figuregen_build(AP, seed, sk)
89 let W: i64 = as_w(); let H: i64 = as_h()
90 let fb: *i64 = sys_mmap(W*H*8) as *i64
91 anatstack_render(AP, n, 0, 3, 1, 42, sk[0], sk[1], sk[2], fb)
92 res[0]=1; res[1]=W; res[2]=H; res[3]=gen_content_bg(fb, W*H, GEN_ANATBG); res[4]=fb as i64
93 return 1
94 }
95 if kind == GEN_FACE {
96 let base: i64 = sys_mmap(sdf_bytes()) as i64
97 let sk: *i64 = sys_mmap(8*8) as *i64
98 let idv: *i64 = sys_mmap(8*8) as *i64
99 persongen_build(base, seed, sk, idv)
100 sdf_render(base, 200, 4, sk[0], sk[1], sk[2])
101 let fb: *i64 = (base + fb_off()) as *i64
102 res[0]=1; res[1]=512; res[2]=384; res[3]=gen_content_lum(fb, 512*384, 150); res[4]=fb as i64
103 return 1
104 }
105 return 0 // unknown kind: fail-closed
106}