nx_genome.nx source
↩ module page · 136 lines · 7107 B
1// nx_genome.nx -- ★CREATURE GENOME (operator 2026-07-12: "the humans look awful clay monsters with no anatomy
2// intelligence... a human and a rabbit and a fantasy monster all get the right gen up... if we don't need the
3// internals, just show the outer body -- whatever the research shows"). The Infinigen creature lesson, banked
4// (knowledge/creature_genome_banked.txt): a TREE GENOME -- nodes are part specs, edges are attachment points,
5// "limbs don't form closed loops" -- with ONE generative walker, many body plans. And the research default is
6// SURFACE-ONLY (their creatures have rigs + skin, no internals) -> creatures here emit OUTER BODY only; the
7// human's 8 internal systems remain the opt-in medical-view exceed.
8// GENE ROW (stride 12): kind(0 blob | 1 chain), ax,ay,az (attachment), dy,dz (chain direction fx1024),
9// segs, len, rad, taper(fx1024 per segment), mirrorX(0/1), aux (blob: rz | chain: 0)
10// The CHAIN generator is the shared anatomy intelligence: tapered segment ellipsoids walked from the
11// attachment point along the direction -- legs, arms, ears, horns, tails across every plan (the integer
12// cousin of their "deviations from a center curve").
13// Plans: 0 HUMAN (delegates to the canon-validated atlas_build), 1 RABBIT (quadruped), 2 MONSTER (composition:
14// four arms + horns + tail). license_tier: ORIGINAL
15import "nx_syscalls.nx"
16import "nx_bodyatlas.nx"
17const G_MAGIC_2048: i64 = 2048
18const G_MAGIC_1024: i64 = 1024
19const G_MAGIC_65536: i64 = 65536
20const G_MAGIC_1080: i64 = 1080
21
22const G_STRIDE: i64 = 12
23static GEN_TAB: i64 // gene table ptr
24static GEN_N: i64 // gene count
25static GEN_EARLEN: i64 // ★a live GENE (rabbit ear segment length) -- edits must change the creature
26// ★parametric feature genes (the authoring layer drives these): monster arm-pairs / horns / tail
27static GEN_ARMPAIRS: i64 // 1 (two arms) or 2 (four arms)
28static GEN_HORNS: i64 // 0/1
29static GEN_TAIL: i64 // 0/1
30static GEN_INIT: i64 // defaults set once
31func gen_defaults() -> i64 { GEN_EARLEN = 95; GEN_ARMPAIRS = 2; GEN_HORNS = 1; GEN_TAIL = 1; GEN_INIT = 1; return 0 }
32
33func gen_reset() -> i64 {
34 if GEN_TAB == 0 { GEN_TAB = sys_mmap(64*G_STRIDE*8) as i64 }
35 if GEN_INIT == 0 { gen_defaults() }
36 GEN_N = 0
37 return 0
38}
39func gen_set_earlen(v: i64) -> i64 { GEN_EARLEN = v; return 0 }
40func gen_set_armpairs(v: i64) -> i64 { GEN_ARMPAIRS = v; return 0 }
41func gen_set_horns(v: i64) -> i64 { GEN_HORNS = v; return 0 }
42func gen_set_tail(v: i64) -> i64 { GEN_TAIL = v; return 0 }
43func gene(kind: i64, ax: i64, ay: i64, az: i64, dy: i64, dz: i64, segs: i64, len: i64, rad: i64, taper: i64, mirror: i64, aux: i64) -> i64 {
44 let G: *i64 = GEN_TAB as *i64
45 let i: i64 = GEN_N*G_STRIDE
46 G[i]=kind; G[i+1]=ax; G[i+2]=ay; G[i+3]=az; G[i+4]=dy; G[i+5]=dz
47 G[i+6]=segs; G[i+7]=len; G[i+8]=rad; G[i+9]=taper; G[i+10]=mirror; G[i+11]=aux
48 GEN_N = GEN_N + 1
49 return 0
50}
51
52// the shared part-walker: emit one gene (and its mirror twin) as SKIN parts
53func gen_emit_one(ax: i64, ay: i64, az: i64, kind: i64, dy: i64, dz: i64, segs: i64, len: i64, rad: i64, taper: i64, aux: i64, col: i64, nid: i64) -> i64 {
54 if kind == 0 {
55 ba_add(BS_SKIN, ax, ay, az, rad, len, aux, col, nid) // blob: len=ry, rad=rx, aux=rz
56 return 0
57 }
58 // chain: tapered segments from the attachment along (0, dy, dz)/1024
59 var px: i64 = ax
60 var py: i64 = ay
61 var pz: i64 = az
62 var r: i64 = rad
63 var s: i64 = 0
64 while s < segs {
65 let cy: i64 = py + dy*len/G_MAGIC_2048
66 let cz: i64 = pz + dz*len/G_MAGIC_2048
67 var rl: i64 = len*6/10
68 if rl < r { rl = r }
69 ba_add(BS_SKIN, px, cy, cz, r, rl, r, col, nid)
70 py = py + dy*len/G_MAGIC_1024
71 pz = pz + dz*len/G_MAGIC_1024
72 r = r*taper/G_MAGIC_1024
73 if r < 6 { r = 6 }
74 s = s + 1
75 }
76 return 0
77}
78func gen_walk(col: i64) -> i64 {
79 let G: *i64 = GEN_TAB as *i64
80 var g: i64 = 0
81 while g < GEN_N {
82 let i: i64 = g*G_STRIDE
83 gen_emit_one(G[i+1], G[i+2], G[i+3], G[i], G[i+4], G[i+5], G[i+6], G[i+7], G[i+8], G[i+9], G[i+11], col, 70+g)
84 if G[i+10] == 1 {
85 gen_emit_one(0-G[i+1], G[i+2], G[i+3], G[i], G[i+4], G[i+5], G[i+6], G[i+7], G[i+8], G[i+9], G[i+11], col, 70+g)
86 }
87 g = g + 1
88 }
89 return 0
90}
91
92// ---- RABBIT genome (quadruped: horizontal spine, long ears, crouched hind legs; ~900 units long) ----
93func genome_rabbit() -> i64 {
94 gen_reset()
95 // body: chest + rump blobs along +z
96 gene(0, 0, 40, 120, 0, 0, 1, 240, 200, 0, 0, 300) // chest
97 gene(0, 0, 70, 0-160, 0, 0, 1, 280, 240, 0, 0, 320) // rump (bigger -- crouched power)
98 gene(0, 0, 230, 380, 0, 0, 1, 160, 150, 0, 0, 170) // head
99 gene(0, 0, 170, 520, 0, 0, 1, 90, 80, 0, 0, 110) // muzzle
100 gene(1, 70, 330, 330, 960, 0-340, 2, GEN_EARLEN, 52, 880, 1, 0) // ★EARS: 2-seg chains up-back (the gene)
101 gene(1, 150, 0-40, 260, 0-1000, 120, 2, 130, 56, 900, 1, 0) // front legs down
102 gene(1, 170, 0-20, 0-200, 0-1000, 60, 2, 160, 70, 880, 1, 0) // hind legs down (thicker)
103 gene(0, 150, 0-320, 300, 0, 0, 1, 60, 62, 0, 1, 150) // front feet (z-long)
104 gene(0, 170, 0-330, 0-140, 0, 0, 1, 65, 70, 0, 1, 190) // hind feet
105 gene(0, 0, 120, 0-420, 0, 0, 1, 90, 85, 0, 0, 90) // tail puff
106 atlas_custom_reset()
107 gen_walk(214 + 196*256 + 182*G_MAGIC_65536)
108 atlas_custom_finish()
109 return atlas_part_count()
110}
111
112// ---- MONSTER genome (fantasy composition: biped, FOUR arms, two horns, tail; ~1900 tall) ----
113func genome_monster() -> i64 {
114 gen_reset()
115 gene(0, 0, 350, 0, 0, 0, 1, 480, 300, 0, 0, 260) // torso
116 gene(0, 0, 0-150, 0, 0, 0, 1, 260, 240, 0, 0, 220) // pelvis
117 gene(0, 0, 800, 20, 0, 0, 1, 190, 160, 0, 0, 170) // head
118 if GEN_HORNS == 1 { gene(1, 90, 950, 10, 980, 0-280, 2, 130, 46, 650, 1, 0) } // ★HORNS: tapered 2-seg chains
119 gene(1, 330, 620, 20, 0-1000, 90, 3, 200, 78, 860, 1, 0) // upper arm pair (3-seg chains)
120 if GEN_ARMPAIRS == 2 { gene(1, 330, 260, 30, 0-1000, 140, 3, 180, 66, 860, 1, 0) } // ★LOWER arm pair -- four arms
121 gene(1, 150, 0-360, 10, 0-1000, 40, 3, 230, 96, 880, 1, 0) // legs
122 gene(0, 150, 0-G_MAGIC_1080, 90, 0, 0, 1, 70, 80, 0, 1, 180) // feet
123 if GEN_TAIL == 1 { gene(1, 0, 0-240, 0-200, 0-320, 0-960, 3, 190, 70, 800, 0, 0) } // tail (back-down chain)
124 atlas_custom_reset()
125 gen_walk(150 + 168*256 + 128*G_MAGIC_65536)
126 atlas_custom_finish()
127 return atlas_part_count()
128}
129
130// plan dispatch: 0 human (canon-validated atlas_build) / 1 rabbit / 2 monster. Returns part count.
131func genome_build(plan: i64) -> i64 {
132 if plan == 1 { return genome_rabbit() }
133 if plan == 2 { return genome_monster() }
134 atlas_hand_curl(0)
135 return atlas_build(0)
136}