nx_creaturegen.nx source
↩ module page · 256 lines · 15492 B
1// nx_creaturegen.nx -- ★SOVEREIGN INFINIGEN: procedural ANIMALS. Reuses the SAME layered-anatomy method as the
2// human head (nx_anatstack: skeleton -> muscle -> skin envelope), generalized to a seed-parametric QUADRUPED body
3// plan -- skull+snout, neck, spine, ribcage, pelvis, tail, four (upper+lower+foot) legs, + shoulder/haunch/belly
4// muscles. The skin EMERGES as the smooth-union envelope + dermal offset (not eyeballed). Seeded proportions
5// (body/leg/neck length, head/tail size, build) -> different creatures (dog-ish, deer-ish, ...). Renders via the
6// shared anatstack ray-marcher. No ML, no assets. license_tier: ORIGINAL
7import "nx_anatstack.nx"
8const K_MAGIC_6364136223846793005: i64 = 6364136223846793005
9const K_MAGIC_1442695040888963407: i64 = 1442695040888963407
10const K_MAGIC_2147483647: i64 = 2147483647
11const K_MAGIC_4096: i64 = 4096
12const K_MAGIC_65536: i64 = 65536
13const K_MAGIC_2654435761: i64 = 2654435761
14const K_MAGIC_40503: i64 = 40503
15const K_MAGIC_90001: i64 = 90001
16const K_MAGIC_1013904223: i64 = 1013904223
17
18func cg_next(st: *i64) -> i64 { var h: i64=st[0]; h=h*K_MAGIC_6364136223846793005+K_MAGIC_1442695040888963407; st[0]=h; return (h>>33)&K_MAGIC_2147483647 }
19func cg_range(st: *i64, lo: i64, hi: i64) -> i64 { return lo + cg_next(st) % (hi-lo+1) }
20
21// ★R9 ARTICULATION: forward kinematics for a 2-bone leg in the sagittal (Y-Z) plane. thigh rotates the WHOLE
22// leg about the hip; shin bends the knee (the lower bone only). angles it4096; 0 = straight down. Fills
23// out[0..2]=knee, out[3..5]=foot. This is the FK the census demands: parent joint moves the subtree, child
24// joint moves only its descendants.
25func cg_fk_leg(hipx: i64, hipy: i64, hipz: i64, thigh: i64, shin: i64, L1: i64, L2: i64, out: *i64) -> i64 {
26 let ct1: i64 = it_cos4096(thigh)
27 let st1: i64 = it_sin4096(thigh)
28 let kneeY: i64 = hipy - L1*ct1/K_MAGIC_4096
29 let kneeZ: i64 = hipz + L1*st1/K_MAGIC_4096
30 let a2: i64 = thigh + shin
31 let ct2: i64 = it_cos4096(a2)
32 let st2: i64 = it_sin4096(a2)
33 out[0]=hipx; out[1]=kneeY; out[2]=kneeZ
34 out[3]=hipx; out[4]=kneeY - L2*ct2/K_MAGIC_4096; out[5]=kneeZ + L2*st2/K_MAGIC_4096
35 return 0
36}
37// place a POSED 2-bone leg (upper hip->knee + lower knee->foot + hoof) from FK.
38func cg_leg_posed(P: *i64, i: i64, hipx: i64, hipy: i64, hipz: i64, thigh: i64, shin: i64, L1: i64, L2: i64, r: i64) -> i64 {
39 let fk: *i64 = sys_mmap(8*8) as *i64
40 cg_fk_leg(hipx, hipy, hipz, thigh, shin, L1, L2, fk)
41 var n: i64 = i
42 n = as_caps(P, n, hipx, hipy, hipz, fk[0], fk[1], fk[2], r, AS_BONE)
43 n = as_fuzz_last(P, n)
44 n = as_caps(P, n, fk[0], fk[1], fk[2], fk[3], fk[4], fk[5], r*8/10, AS_BONE)
45 n = as_fuzz_last(P, n)
46 n = as_ellip(P, n, fk[3], fk[4], fk[5], r, r*7/10, r*13/10, AS_BONE)
47 n = as_color_last(P, n, 52 + 44*256 + 38*K_MAGIC_65536 + AS_GLOSS)
48 return n
49}
50
51// one leg = upper capsule (joint->knee) + lower capsule (knee->foot) + foot/hoof ellipsoid
52func cg_leg(P: *i64, i: i64, lx: i64, lz: i64, topY: i64, footY: i64, r: i64) -> i64 {
53 let kneeY: i64 = (topY + footY)/2
54 let kneeZ: i64 = lz + r/2
55 var n: i64 = i
56 n = as_caps(P, n, lx, topY, lz, lx, kneeY, kneeZ, r, AS_BONE)
57 n = as_caps(P, n, lx, kneeY, kneeZ, lx, footY, lz, r*8/10, AS_BONE)
58 n = as_ellip(P, n, lx, footY, lz, r, r*7/10, r*13/10, AS_BONE)
59 return n
60}
61
62// ★R1 DIVERSITY: BODY-PLAN LIBRARY (census critic: "ONE quadruped body plan; theirs: multi-class creatures").
63// Plans over the SAME layered-anatomy method: 0 QUADRUPED (below) · 1 BIRD · 2 FISH.
64func creaturegen_build_plan(P: *i64, seed: i64, plan: i64) -> i64 {
65 if plan == 1 { return cg_build_bird(P, seed) }
66 if plan == 2 { return cg_build_fish(P, seed) }
67 return creaturegen_build(P, seed)
68}
69
70// BIRD: ovoid tilted body, 2 thin legs, folded WINGS (flattened fuzzy ellipsoids), tail fan, small head + BEAK.
71func cg_build_bird(P: *i64, seed: i64) -> i64 {
72 let st: *i64 = sys_mmap(16) as *i64
73 st[0] = seed*K_MAGIC_2654435761 + K_MAGIC_40503; cg_next(st); cg_next(st)
74 let bodyl: i64 = cg_range(st, 210, 290) // body half-length
75 let bodyr: i64 = cg_range(st, 130, 175) // body radius
76 let legl: i64 = cg_range(st, 150, 230)
77 let headr: i64 = cg_range(st, 62, 84)
78 let bodyY: i64 = 0 - 40
79 let footY: i64 = bodyY - bodyr - legl
80 let headY: i64 = bodyY + bodyr + headr*6/10
81 let headZ: i64 = 0 - bodyl*7/10
82 var i: i64 = 0
83 // body (fuzzy = feathers), tilted ovoid (front-down)
84 i = as_ellip(P, i, 0, bodyY, 0, bodyr, bodyr*9/10, bodyl, AS_BONE)
85 i = as_fuzz_last(P, i)
86 // breast
87 i = as_ellip(P, i, 0, bodyY - bodyr*3/10, 0-bodyl*4/10, bodyr*8/10, bodyr*8/10, bodyr*8/10, AS_MUSCLE)
88 i = as_fuzz_last(P, i)
89 // head + neck
90 i = as_caps(P, i, 0, bodyY + bodyr*6/10, headZ*8/10, 0, headY, headZ, headr*5/10, AS_BONE)
91 i = as_ellip(P, i, 0, headY, headZ, headr, headr, headr*11/10, AS_BONE)
92 i = as_fuzz_last(P, i)
93 // BEAK (crisp gloss cone-ish)
94 i = as_ellip(P, i, 0, headY - headr*15/100, headZ - headr*12/10, headr*32/100, headr*22/100, headr*7/10, AS_MUSCLE)
95 i = as_feature_last(P, i, 224 + 168*256 + 64*K_MAGIC_65536 + AS_GLOSS)
96 // eyes
97 i = as_ellip(P, i, 0-headr*62/100, headY + headr*15/100, headZ - headr*45/100, headr*16/100, headr*16/100, headr*16/100, AS_MUSCLE)
98 i = as_feature_last(P, i, 20 + 16*256 + 14*K_MAGIC_65536 + AS_GLOSS)
99 i = as_ellip(P, i, headr*62/100, headY + headr*15/100, headZ - headr*45/100, headr*16/100, headr*16/100, headr*16/100, AS_MUSCLE)
100 i = as_feature_last(P, i, 20 + 16*256 + 14*K_MAGIC_65536 + AS_GLOSS)
101 // WINGS: flattened fuzzy ellipsoids folded on the flanks
102 i = as_ellip(P, i, 0-bodyr*95/100, bodyY + bodyr*15/100, bodyl*5/100, bodyr*35/100, bodyr*7/10, bodyl*85/100, AS_MUSCLE)
103 i = as_fuzz_last(P, i)
104 i = as_ellip(P, i, bodyr*95/100, bodyY + bodyr*15/100, bodyl*5/100, bodyr*35/100, bodyr*7/10, bodyl*85/100, AS_MUSCLE)
105 i = as_fuzz_last(P, i)
106 // TAIL FAN: flattened wedge behind
107 i = as_ellip(P, i, 0, bodyY + bodyr*2/10, bodyl*115/100, bodyr*55/100, bodyr*25/100, bodyl*55/100, AS_MUSCLE)
108 i = as_fuzz_last(P, i)
109 // 2 thin legs + feet
110 i = as_caps(P, i, 0-bodyr*55/100, bodyY - bodyr*8/10, 0, 0-bodyr*55/100, footY, 0, 13, AS_BONE)
111 i = as_color_last(P, i, 224 + 168*256 + 64*K_MAGIC_65536)
112 i = as_ellip(P, i, 0-bodyr*55/100, footY, 0-20, 19, 8, 30, AS_BONE)
113 i = as_feature_last(P, i, 224 + 168*256 + 64*K_MAGIC_65536)
114 i = as_caps(P, i, bodyr*55/100, bodyY - bodyr*8/10, 0, bodyr*55/100, footY, 0, 13, AS_BONE)
115 i = as_color_last(P, i, 224 + 168*256 + 64*K_MAGIC_65536)
116 i = as_ellip(P, i, bodyr*55/100, footY, 0-20, 19, 8, 30, AS_BONE)
117 i = as_feature_last(P, i, 224 + 168*256 + 64*K_MAGIC_65536)
118 return i / AS_STRIDE
119}
120
121// FISH: fusiform body, tail fin, dorsal fin, pectoral fins, gloss eye. No legs; renders mid-frame (as if swimming).
122func cg_build_fish(P: *i64, seed: i64) -> i64 {
123 let st: *i64 = sys_mmap(16) as *i64
124 st[0] = seed*K_MAGIC_2654435761 + K_MAGIC_90001; cg_next(st); cg_next(st)
125 let bl: i64 = cg_range(st, 330, 430) // body half-length
126 let br: i64 = cg_range(st, 95, 140) // body radius
127 let finr: i64 = cg_range(st, 80, 130)
128 var i: i64 = 0
129 // fusiform body: main + tapered snout + tapered rear
130 i = as_ellip(P, i, 0, 0, 0, br, br*88/100, bl, AS_BONE)
131 i = as_ellip(P, i, 0, 0-br*6/100, 0-bl*78/100, br*55/100, br*48/100, bl*38/100, AS_BONE) // snout taper
132 i = as_ellip(P, i, 0, 0, bl*75/100, br*45/100, br*40/100, bl*40/100, AS_BONE) // rear taper
133 // TAIL FIN: thin vertical wedge (crisp so it stays a blade)
134 i = as_ellip(P, i, 0, 0, bl*128/100, br*8/100, finr*13/10, finr*9/10, AS_MUSCLE)
135 i = as_feature_last(P, i, 0)
136 // DORSAL FIN
137 i = as_ellip(P, i, 0, br*95/100, 0-bl*5/100, br*7/100, finr*75/100, bl*42/100, AS_MUSCLE)
138 i = as_feature_last(P, i, 0)
139 // PECTORAL fins
140 i = as_ellip(P, i, 0-br*92/100, 0-br*25/100, 0-bl*28/100, br*6/100, finr*38/100, finr*55/100, AS_MUSCLE)
141 i = as_feature_last(P, i, 0)
142 i = as_ellip(P, i, br*92/100, 0-br*25/100, 0-bl*28/100, br*6/100, finr*38/100, finr*55/100, AS_MUSCLE)
143 i = as_feature_last(P, i, 0)
144 // eyes (gloss)
145 i = as_ellip(P, i, 0-br*72/100, br*18/100, 0-bl*62/100, br*13/100, br*13/100, br*13/100, AS_MUSCLE)
146 i = as_feature_last(P, i, 22 + 20*256 + 18*K_MAGIC_65536 + AS_GLOSS)
147 i = as_ellip(P, i, br*72/100, br*18/100, 0-bl*62/100, br*13/100, br*13/100, br*13/100, AS_MUSCLE)
148 i = as_feature_last(P, i, 22 + 20*256 + 18*K_MAGIC_65536 + AS_GLOSS)
149 // belly
150 i = as_ellip(P, i, 0, 0-br*45/100, 0-bl*15/100, br*70/100, br*55/100, bl*55/100, AS_FAT)
151 return i / AS_STRIDE
152}
153
154// ★R9 POSED quadruped: the same seed's body with 4 FK-driven legs placed from a POSE (8 angles: FL/FR/BL/BR
155// x thigh/shin, it4096). Rest pose = all zeros = standing. A walk cycle = animate the angles. Returns part count.
156func creaturegen_build_posed(P: *i64, seed: i64, pose: *i64) -> i64 {
157 let st: *i64 = sys_mmap(16) as *i64
158 st[0] = seed*K_MAGIC_2654435761 + K_MAGIC_1013904223; cg_next(st); cg_next(st)
159 let bodylen: i64 = cg_range(st, 360, 500)
160 let build: i64 = cg_range(st, 90, 118)
161 let sZ: i64 = 0 - bodylen/2
162 let hZ: i64 = bodylen/2
163 let backY: i64 = 160
164 let L1: i64 = 132 // upper-leg length
165 let L2: i64 = 120 // lower-leg length
166 let hipY: i64 = backY - 40
167 let headZ: i64 = sZ - 150
168 let headY: i64 = backY + 130
169 var i: i64 = 0
170 // body barrel (fuzzy), chest, neck, head, snout, tail
171 i = as_ellip(P, i, 0, backY-70, 0, 150*build/100, 128, bodylen/2, AS_BONE); i = as_fuzz_last(P, i)
172 i = as_ellip(P, i, 0, backY-40, sZ+40, 150*build/100, 150, 175, AS_BONE); i = as_fuzz_last(P, i)
173 i = as_caps(P, i, 0, backY, sZ, 0, headY, headZ, 54*build/100, AS_BONE); i = as_fuzz_last(P, i)
174 i = as_ellip(P, i, 0, headY, headZ, 118, 106, 130, AS_BONE); i = as_fuzz_last(P, i)
175 i = as_ellip(P, i, 0, headY-48, headZ-108, 72, 60, 84, AS_BONE)
176 i = as_caps(P, i, 0, backY, hZ, 0, backY-100, hZ+300, 28, AS_BONE); i = as_fuzz_last(P, i)
177 // 4 FK legs from the pose
178 i = cg_leg_posed(P, i, 0-108, hipY, sZ+34, pose[0], pose[1], L1, L2, 40)
179 i = cg_leg_posed(P, i, 108, hipY, sZ+34, pose[2], pose[3], L1, L2, 40)
180 i = cg_leg_posed(P, i, 0-114, hipY, hZ-16, pose[4], pose[5], L1, L2, 44)
181 i = cg_leg_posed(P, i, 114, hipY, hZ-16, pose[6], pose[7], L1, L2, 44)
182 // eyes
183 i = as_ellip(P, i, 0-92, headY+20, headZ-108, 18, 18, 18, AS_MUSCLE); i = as_feature_last(P, i, 24 + 20*256 + 18*K_MAGIC_65536 + AS_GLOSS)
184 i = as_ellip(P, i, 92, headY+20, headZ-108, 18, 18, 18, AS_MUSCLE); i = as_feature_last(P, i, 24 + 20*256 + 18*K_MAGIC_65536 + AS_GLOSS)
185 return i / AS_STRIDE
186}
187
188// build a QUADRUPED from a seed (plan 0; the original). Returns the part count.
189func creaturegen_build(P: *i64, seed: i64) -> i64 {
190 let st: *i64 = sys_mmap(16) as *i64
191 st[0] = seed*K_MAGIC_2654435761 + K_MAGIC_1013904223; cg_next(st); cg_next(st)
192 let bodylen: i64 = cg_range(st, 360, 500)
193 let leglen: i64 = cg_range(st, 360, 560)
194 let necklen: i64 = cg_range(st, 170, 440)
195 let headsz: i64 = cg_range(st, 96, 148)
196 let taillen: i64 = cg_range(st, 130, 420)
197 let build: i64 = cg_range(st, 85, 122)
198 let sZ: i64 = 0 - bodylen/2 // shoulder z (front)
199 let hZ: i64 = bodylen/2 // hip z (back)
200 let backY: i64 = 160
201 let footY: i64 = backY - leglen // ground
202 let headY: i64 = backY + necklen*7/10
203 let headZ: i64 = sZ - necklen*7/10
204 var i: i64 = 0
205 // --- SKELETON (body masses are FUZZY = fur displacement in the geometry) ---
206 i = as_ellip(P, i, 0, backY-40, sZ+40, 150*build/100, 152*build/100, 185, AS_BONE) // ribcage
207 i = as_fuzz_last(P, i)
208 i = as_ellip(P, i, 0, backY-28, hZ-30, 140*build/100, 142, 150, AS_BONE) // pelvis
209 i = as_fuzz_last(P, i)
210 i = as_caps(P, i, 0, backY, sZ, 0, backY, hZ, 58, AS_BONE) // spine
211 i = as_fuzz_last(P, i)
212 i = as_caps(P, i, 0, backY, sZ, 0, headY, headZ, 54*build/100, AS_BONE) // neck
213 i = as_fuzz_last(P, i)
214 i = as_ellip(P, i, 0, headY, headZ, headsz, headsz*9/10, headsz*11/10, AS_BONE) // skull
215 i = as_fuzz_last(P, i)
216 i = as_ellip(P, i, 0, headY-headsz*4/10, headZ-headsz*9/10, headsz*6/10, headsz*5/10, headsz*7/10, AS_BONE) // snout
217 i = as_caps(P, i, 0, backY, hZ, 0, backY-taillen/3, hZ+taillen, 28, AS_BONE) // tail
218 i = as_fuzz_last(P, i)
219 let hoof: i64 = 52 + 44*256 + 38*K_MAGIC_65536 + AS_GLOSS
220 i = cg_leg(P, i, 0-108, sZ+34, backY-58, footY, 40) // front-left
221 i = as_color_last(P, i, hoof)
222 i = cg_leg(P, i, 108, sZ+34, backY-58, footY, 40) // front-right
223 i = as_color_last(P, i, hoof)
224 i = cg_leg(P, i, 0-114, hZ-16, backY-70, footY, 44) // back-left
225 i = as_color_last(P, i, hoof)
226 i = cg_leg(P, i, 114, hZ-16, backY-70, footY, 44) // back-right
227 i = as_color_last(P, i, hoof)
228 // --- MUSCLE (fuzzy too) ---
229 i = as_ellip(P, i, 0-100, backY-64, sZ+24, 100, 132, 122, AS_MUSCLE) // L shoulder
230 i = as_fuzz_last(P, i)
231 i = as_ellip(P, i, 100, backY-64, sZ+24, 100, 132, 122, AS_MUSCLE) // R shoulder
232 i = as_fuzz_last(P, i)
233 i = as_ellip(P, i, 0-104, backY-86, hZ-22, 116, 150, 132, AS_MUSCLE) // L haunch (thigh)
234 i = as_fuzz_last(P, i)
235 i = as_ellip(P, i, 104, backY-86, hZ-22, 116, 150, 132, AS_MUSCLE) // R haunch
236 i = as_fuzz_last(P, i)
237 i = as_ellip(P, i, 0, backY-120, 0, 150*build/100, 120, bodylen/2, AS_MUSCLE) // belly/barrel
238 i = as_fuzz_last(P, i)
239 i = as_caps(P, i, 0, backY+8, sZ, 0, headY-18, headZ+28, 60, AS_MUSCLE) // neck muscle
240 i = as_fuzz_last(P, i)
241 // --- FEATURES (Phase-1: ears, eyes, nose leather, tail tuft; crisp + low-inflate so they stay sharp) ---
242 let er: i64 = headsz*30/100
243 i = as_ellip(P, i, 0-headsz*52/100, headY+headsz*85/100, headZ+headsz*10/100, er, er*140/100, er*70/100, AS_MUSCLE)
244 i = as_feature_last(P, i, 0) // L ear (skin, crisp)
245 i = as_ellip(P, i, headsz*52/100, headY+headsz*85/100, headZ+headsz*10/100, er, er*140/100, er*70/100, AS_MUSCLE)
246 i = as_feature_last(P, i, 0) // R ear
247 i = as_ellip(P, i, 0-headsz*78/100, headY+headsz*18/100, headZ-headsz*95/100, headsz*16/100, headsz*16/100, headsz*16/100, AS_MUSCLE)
248 i = as_feature_last(P, i, 24 + 20*256 + 18*K_MAGIC_65536 + AS_GLOSS) // L eye (dark, glint)
249 i = as_ellip(P, i, headsz*78/100, headY+headsz*18/100, headZ-headsz*95/100, headsz*16/100, headsz*16/100, headsz*16/100, AS_MUSCLE)
250 i = as_feature_last(P, i, 24 + 20*256 + 18*K_MAGIC_65536 + AS_GLOSS) // R eye (glint)
251 i = as_ellip(P, i, 0, headY-headsz*45/100, headZ-headsz*180/100, headsz*20/100, headsz*16/100, headsz*18/100, AS_MUSCLE)
252 i = as_feature_last(P, i, 56 + 44*256 + 40*K_MAGIC_65536 + AS_GLOSS) // nose leather (moist gloss)
253 i = as_ellip(P, i, 0, backY-taillen/3, hZ+taillen, 40, 40, 52, AS_MUSCLE)
254 i = as_color_last(P, i, 88 + 66*256 + 48*K_MAGIC_65536 + AS_MATTE) // tail tuft (darker, matte)
255 return i / AS_STRIDE
256}