code wiki / (root) / nx_creaturegen.nx

nx_creaturegen.nx source

↩ module page · 474 lines · 28441 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 17const CGB_ROWS: i64 = 2 18const CGB_KIND_SONGBIRD: i64 = 1 19const CG_PLAN_GULL: i64 = 3 20 21func 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 } 22func cg_range(st: *i64, lo: i64, hi: i64) -> i64 { return lo + cg_next(st) % (hi-lo+1) } 23 24// ★R9 ARTICULATION: forward kinematics for a 2-bone leg in the sagittal (Y-Z) plane. thigh rotates the WHOLE 25// leg about the hip; shin bends the knee (the lower bone only). angles it4096; 0 = straight down. Fills 26// out[0..2]=knee, out[3..5]=foot. This is the FK the census demands: parent joint moves the subtree, child 27// joint moves only its descendants. 28func cg_fk_leg(hipx: i64, hipy: i64, hipz: i64, thigh: i64, shin: i64, L1: i64, L2: i64, out: *i64) -> i64 { 29 let ct1: i64 = it_cos4096(thigh) 30 let st1: i64 = it_sin4096(thigh) 31 let kneeY: i64 = hipy - L1*ct1/K_MAGIC_4096 32 let kneeZ: i64 = hipz + L1*st1/K_MAGIC_4096 33 let a2: i64 = thigh + shin 34 let ct2: i64 = it_cos4096(a2) 35 let st2: i64 = it_sin4096(a2) 36 out[0]=hipx; out[1]=kneeY; out[2]=kneeZ 37 out[3]=hipx; out[4]=kneeY - L2*ct2/K_MAGIC_4096; out[5]=kneeZ + L2*st2/K_MAGIC_4096 38 return 0 39} 40// place a POSED 2-bone leg (upper hip->knee + lower knee->foot + hoof) from FK. 41func cg_leg_posed(P: *i64, i: i64, hipx: i64, hipy: i64, hipz: i64, thigh: i64, shin: i64, L1: i64, L2: i64, r: i64) -> i64 { 42 let fk: *i64 = sys_mmap(8*8) as *i64 43 cg_fk_leg(hipx, hipy, hipz, thigh, shin, L1, L2, fk) 44 var n: i64 = i 45 n = as_caps(P, n, hipx, hipy, hipz, fk[0], fk[1], fk[2], r, AS_BONE) 46 n = as_fuzz_last(P, n) 47 n = as_caps(P, n, fk[0], fk[1], fk[2], fk[3], fk[4], fk[5], r*8/10, AS_BONE) 48 n = as_fuzz_last(P, n) 49 n = as_ellip(P, n, fk[3], fk[4], fk[5], r, r*7/10, r*13/10, AS_BONE) 50 n = as_color_last(P, n, 52 + 44*256 + 38*K_MAGIC_65536 + AS_GLOSS) 51 return n 52} 53 54// one leg = upper capsule (joint->knee) + lower capsule (knee->foot) + foot/hoof ellipsoid 55func cg_leg(P: *i64, i: i64, lx: i64, lz: i64, topY: i64, footY: i64, r: i64) -> i64 { 56 let kneeY: i64 = (topY + footY)/2 57 let kneeZ: i64 = lz + r/2 58 var n: i64 = i 59 n = as_caps(P, n, lx, topY, lz, lx, kneeY, kneeZ, r, AS_BONE) 60 n = as_caps(P, n, lx, kneeY, kneeZ, lx, footY, lz, r*8/10, AS_BONE) 61 n = as_ellip(P, n, lx, footY, lz, r, r*7/10, r*13/10, AS_BONE) 62 return n 63} 64 65// ★R1 DIVERSITY: BODY-PLAN LIBRARY (census critic: "ONE quadruped body plan; theirs: multi-class creatures"). 66// Plans over the SAME layered-anatomy method: 0 QUADRUPED (below) · 1 BIRD · 2 FISH. 67func creaturegen_build_plan(P: *i64, seed: i64, plan: i64) -> i64 { 68 if plan == 1 { return cg_bird_row(P, seed, cg_bird_canon(), CGB_ROWS, CGB_KIND_SONGBIRD) } 69 if plan == 2 { return cg_build_fish(P, seed) } 70 if plan == CG_PLAN_GULL { return cg_shorebird(P, seed) } 71 return creaturegen_build(P, seed) 72} 73 74// BIRD: ovoid tilted body, 2 thin legs, folded WINGS (flattened fuzzy ellipsoids), tail fan, small head + BEAK. 75func cg_build_bird(P: *i64, seed: i64) -> i64 { 76 let st: *i64 = sys_mmap(16) as *i64 77 st[0] = seed*K_MAGIC_2654435761 + K_MAGIC_40503; cg_next(st); cg_next(st) 78 let bodyl: i64 = cg_range(st, 210, 290) // body half-length 79 let bodyr: i64 = cg_range(st, 130, 175) // body radius 80 let legl: i64 = cg_range(st, 150, 230) 81 let headr: i64 = cg_range(st, 62, 84) 82 let bodyY: i64 = 0 - 40 83 let footY: i64 = bodyY - bodyr - legl 84 let headY: i64 = bodyY + bodyr + headr*6/10 85 let headZ: i64 = 0 - bodyl*7/10 86 var i: i64 = 0 87 // body (fuzzy = feathers), tilted ovoid (front-down) 88 i = as_ellip(P, i, 0, bodyY, 0, bodyr, bodyr*9/10, bodyl, AS_BONE) 89 i = as_fuzz_last(P, i) 90 // breast 91 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) 92 i = as_fuzz_last(P, i) 93 // head + neck 94 i = as_caps(P, i, 0, bodyY + bodyr*6/10, headZ*8/10, 0, headY, headZ, headr*5/10, AS_BONE) 95 i = as_ellip(P, i, 0, headY, headZ, headr, headr, headr*11/10, AS_BONE) 96 i = as_fuzz_last(P, i) 97 // BEAK (crisp gloss cone-ish) 98 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) 99 i = as_feature_last(P, i, 224 + 168*256 + 64*K_MAGIC_65536 + AS_GLOSS) 100 // eyes 101 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) 102 i = as_feature_last(P, i, 20 + 16*256 + 14*K_MAGIC_65536 + AS_GLOSS) 103 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) 104 i = as_feature_last(P, i, 20 + 16*256 + 14*K_MAGIC_65536 + AS_GLOSS) 105 // WINGS: flattened fuzzy ellipsoids folded on the flanks 106 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) 107 i = as_fuzz_last(P, i) 108 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) 109 i = as_fuzz_last(P, i) 110 // TAIL FAN: flattened wedge behind 111 i = as_ellip(P, i, 0, bodyY + bodyr*2/10, bodyl*115/100, bodyr*55/100, bodyr*25/100, bodyl*55/100, AS_MUSCLE) 112 i = as_fuzz_last(P, i) 113 // 2 thin legs + feet 114 i = as_caps(P, i, 0-bodyr*55/100, bodyY - bodyr*8/10, 0, 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, 0-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 i = as_caps(P, i, bodyr*55/100, bodyY - bodyr*8/10, 0, bodyr*55/100, footY, 0, 13, AS_BONE) 119 i = as_color_last(P, i, 224 + 168*256 + 64*K_MAGIC_65536) 120 i = as_ellip(P, i, bodyr*55/100, footY, 0-20, 19, 8, 30, AS_BONE) 121 i = as_feature_last(P, i, 224 + 168*256 + 64*K_MAGIC_65536) 122 return i / AS_STRIDE 123} 124 125// ★PG37 BIRD CANON -- bird species are ROWS over the ONE bird body plan above, never a second builder. A species 126// with no row is not emitted: cg_bird_row returns 0 parts and writes nothing, so the table IS the species list 127// (the rung's done-rule: a canon without the gull row emits no gull). Row fields: the seeded ranges the incumbent 128// draws from, permil shape ratios of those draws, and per-part rgb where CGB_RGB_NONE (0) is the anatstack 129// 'inherit the base colour' word -- as_color_last(0) leaves the slot exactly as as_ellip wrote it, so the songbird 130// row reproduces the hand-written cg_build_bird BYTE FOR BYTE (nx_shorebird_gate holds it to that). 131const CGB_F: i64 = 24 132const CGB_KIND: i64 = 0 133const CGB_BODYL_LO: i64 = 1 134const CGB_BODYL_HI: i64 = 2 135const CGB_BODYR_LO: i64 = 3 136const CGB_BODYR_HI: i64 = 4 137const CGB_LEGL_LO: i64 = 5 138const CGB_LEGL_HI: i64 = 6 139const CGB_HEADR_LO: i64 = 7 140const CGB_HEADR_HI: i64 = 8 141const CGB_WING_LEN: i64 = 9 // permil of bodyl (half-length of the folded wing) 142const CGB_WING_THICK: i64 = 10 // permil of bodyr 143const CGB_WING_H: i64 = 11 // permil of bodyr 144const CGB_LEG_R: i64 = 12 145const CGB_BODY_RGB: i64 = 13 146const CGB_WING_RGB: i64 = 14 147const CGB_HEAD_RGB: i64 = 15 148const CGB_BEAK_RGB: i64 = 16 149const CGB_LEG_RGB: i64 = 17 150const CGB_SALT: i64 = 18 151const CGB_TIP_RGB: i64 = 19 // wingtip colour; CGB_RGB_NONE = no tip parts at all 152const CGB_FOOT_RX: i64 = 20 153const CGB_FOOT_RY: i64 = 21 154const CGB_FOOT_RZ: i64 = 22 155const CGB_TAIL_LEN: i64 = 23 // permil of bodyl 156const CGB_RGB_NONE: i64 = 0 157const CGB_KIND_GULL: i64 = 2 158const CGB_PERMIL: i64 = 1000 159const CGB_SONGBIRD_YELLOW: i64 = 4237536 // 224 + 168*256 + 64*65536, the incumbent's beak and leg yellow 160const CGB_EYE: i64 = 921620 // 20 + 16*256 + 14*65536, the incumbent's eye (gloss added at the call) 161const CGB_GULL_WHITE: i64 = 15920876 // 236 + 238*256 + 242*65536 162const CGB_GULL_GREY: i64 = 10919576 // 152 + 158*256 + 166*65536 163const CGB_GULL_BLACK: i64 = 2367518 // 30 + 32*256 + 36*65536 164const CGB_GULL_BILL: i64 = 3196136 // 232 + 196*256 + 48*65536 165const CGB_GULL_LEG: i64 = 9871574 // 214 + 160*256 + 150*65536 166const CGB_GULL_SALT: i64 = 77003 167const CGB_TIP_AT: i64 = 850 // permil of the wing half-length behind the wing centre 168const CGB_TIP_LEN: i64 = 220 // permil of the wing half-length 169const CGB_TIP_H: i64 = 450 // permil of the wing half-height 170const CGB_TIP_X: i64 = 900 // permil of bodyr (the wing itself sits at 950) 171const CGB_TIB: i64 = 550 // posed leg: tibiotarsus share of hip-to-ground, permil 172const CGB_SHIN_R: i64 = 800 // posed leg: lower capsule radius, permil of the upper 173const CGB_TOE_Z: i64 = 20 // the incumbent's foot-forward offset 174static CGB_TBL: i64 175 176func cgb_set(t: *i64, r: i64, f: i64, v: i64) -> i64 { t[r*CGB_F + f] = v; return 0 } 177func cgb_get(t: *i64, r: i64, f: i64) -> i64 { return t[r*CGB_F + f] } 178// row: the SONGBIRD, transcribed field for field from cg_build_bird above (the KAT twin the gate holds it to) 179func cgb_fill_songbird(t: *i64, r: i64) -> i64 { 180 cgb_set(t, r, CGB_KIND, CGB_KIND_SONGBIRD) 181 cgb_set(t, r, CGB_BODYL_LO, 210); cgb_set(t, r, CGB_BODYL_HI, 290) 182 cgb_set(t, r, CGB_BODYR_LO, 130); cgb_set(t, r, CGB_BODYR_HI, 175) 183 cgb_set(t, r, CGB_LEGL_LO, 150); cgb_set(t, r, CGB_LEGL_HI, 230) 184 cgb_set(t, r, CGB_HEADR_LO, 62); cgb_set(t, r, CGB_HEADR_HI, 84) 185 cgb_set(t, r, CGB_WING_LEN, 850); cgb_set(t, r, CGB_WING_THICK, 350); cgb_set(t, r, CGB_WING_H, 700) 186 cgb_set(t, r, CGB_LEG_R, 13) 187 cgb_set(t, r, CGB_BODY_RGB, CGB_RGB_NONE); cgb_set(t, r, CGB_WING_RGB, CGB_RGB_NONE); cgb_set(t, r, CGB_HEAD_RGB, CGB_RGB_NONE) 188 cgb_set(t, r, CGB_BEAK_RGB, CGB_SONGBIRD_YELLOW); cgb_set(t, r, CGB_LEG_RGB, CGB_SONGBIRD_YELLOW) 189 cgb_set(t, r, CGB_SALT, K_MAGIC_40503) 190 cgb_set(t, r, CGB_TIP_RGB, CGB_RGB_NONE) 191 cgb_set(t, r, CGB_FOOT_RX, 19); cgb_set(t, r, CGB_FOOT_RY, 8); cgb_set(t, r, CGB_FOOT_RZ, 30) 192 cgb_set(t, r, CGB_TAIL_LEN, 550) 193 return 0 194} 195// row: the GULL -- slimmer, longer body; folded wings past the tail with dark tips; stilt legs; webbed feet; 196// white body and head, grey mantle, yellow bill, pink legs. Standing on the ground like the songbird row. 197func cgb_fill_gull(t: *i64, r: i64) -> i64 { 198 cgb_set(t, r, CGB_KIND, CGB_KIND_GULL) 199 cgb_set(t, r, CGB_BODYL_LO, 300); cgb_set(t, r, CGB_BODYL_HI, 380) 200 cgb_set(t, r, CGB_BODYR_LO, 118); cgb_set(t, r, CGB_BODYR_HI, 150) 201 cgb_set(t, r, CGB_LEGL_LO, 210); cgb_set(t, r, CGB_LEGL_HI, 290) 202 cgb_set(t, r, CGB_HEADR_LO, 60); cgb_set(t, r, CGB_HEADR_HI, 78) 203 cgb_set(t, r, CGB_WING_LEN, 1150); cgb_set(t, r, CGB_WING_THICK, 280); cgb_set(t, r, CGB_WING_H, 640) 204 cgb_set(t, r, CGB_LEG_R, 9) 205 cgb_set(t, r, CGB_BODY_RGB, CGB_GULL_WHITE); cgb_set(t, r, CGB_WING_RGB, CGB_GULL_GREY); cgb_set(t, r, CGB_HEAD_RGB, CGB_GULL_WHITE) 206 cgb_set(t, r, CGB_BEAK_RGB, CGB_GULL_BILL); cgb_set(t, r, CGB_LEG_RGB, CGB_GULL_LEG) 207 cgb_set(t, r, CGB_SALT, CGB_GULL_SALT) 208 cgb_set(t, r, CGB_TIP_RGB, CGB_GULL_BLACK) 209 cgb_set(t, r, CGB_FOOT_RX, 26); cgb_set(t, r, CGB_FOOT_RY, 6); cgb_set(t, r, CGB_FOOT_RZ, 34) 210 cgb_set(t, r, CGB_TAIL_LEN, 450) 211 return 0 212} 213// the default canon: one table, filled once, the same on every door (no file read, so the wasm lane carries it too) 214func cg_bird_canon() -> *i64 { 215 if CGB_TBL == 0 { 216 let t: *i64 = sys_mmap(CGB_ROWS*CGB_F*8) as *i64 217 cgb_fill_songbird(t, 0) 218 cgb_fill_gull(t, 1) 219 CGB_TBL = t as i64 220 } 221 return CGB_TBL as *i64 222} 223func cg_bird_canon_rows() -> i64 { return CGB_ROWS } 224// first row of a kind, or -1: the caller decides what an absent species means (the builder emits nothing) 225func cg_bird_canon_find(t: *i64, nrows: i64, kind: i64) -> i64 { 226 var r: i64 = 0 227 while r < nrows { if cgb_get(t, r, CGB_KIND) == kind { return r } r = r + 1 } 228 return 0 - 1 229} 230// a posed bird leg through the SAME FK the quadruped uses (cg_fk_leg): upper capsule hip->joint, lower joint->foot, 231// webbed foot ellipsoid; every dimension and colour from the row 232func cgb_leg_fk(P: *i64, i: i64, hipx: i64, hipy: i64, thigh: i64, shin: i64, L1: i64, L2: i64, t: *i64, r: i64) -> i64 { 233 let fk: *i64 = sys_mmap(8*8) as *i64 234 cg_fk_leg(hipx, hipy, 0, thigh, shin, L1, L2, fk) 235 let legr: i64 = cgb_get(t, r, CGB_LEG_R) 236 let rgb: i64 = cgb_get(t, r, CGB_LEG_RGB) 237 var n: i64 = i 238 n = as_caps(P, n, hipx, hipy, 0, fk[0], fk[1], fk[2], legr, AS_BONE) 239 n = as_color_last(P, n, rgb) 240 n = as_caps(P, n, fk[0], fk[1], fk[2], fk[3], fk[4], fk[5], legr*CGB_SHIN_R/CGB_PERMIL, AS_BONE) 241 n = as_color_last(P, n, rgb) 242 n = as_ellip(P, n, fk[3], fk[4], fk[5] - CGB_TOE_Z, cgb_get(t, r, CGB_FOOT_RX), cgb_get(t, r, CGB_FOOT_RY), cgb_get(t, r, CGB_FOOT_RZ), AS_BONE) 243 n = as_feature_last(P, n, rgb) 244 return n 245} 246// ONE builder for every bird row. pose == 0: static capsule legs (byte-identical to the incumbent for the songbird 247// row). pose[0..3] = L thigh, L shin, R thigh, R shin (it4096, 0 = straight down): the legs become FK 2-bone legs, 248// so the bird stands and WALKS through the existing articulation. There is no wing pose on this plan: NOT FLYING. 249func cg_bird_row_posed(P: *i64, seed: i64, t: *i64, nrows: i64, kind: i64, pose: *i64) -> i64 { 250 let r: i64 = cg_bird_canon_find(t, nrows, kind) 251 if r < 0 { return 0 } 252 let st: *i64 = sys_mmap(16) as *i64 253 st[0] = seed*K_MAGIC_2654435761 + cgb_get(t, r, CGB_SALT); cg_next(st); cg_next(st) 254 let bodyl: i64 = cg_range(st, cgb_get(t, r, CGB_BODYL_LO), cgb_get(t, r, CGB_BODYL_HI)) 255 let bodyr: i64 = cg_range(st, cgb_get(t, r, CGB_BODYR_LO), cgb_get(t, r, CGB_BODYR_HI)) 256 let legl: i64 = cg_range(st, cgb_get(t, r, CGB_LEGL_LO), cgb_get(t, r, CGB_LEGL_HI)) 257 let headr: i64 = cg_range(st, cgb_get(t, r, CGB_HEADR_LO), cgb_get(t, r, CGB_HEADR_HI)) 258 let body_rgb: i64 = cgb_get(t, r, CGB_BODY_RGB) 259 let wing_rgb: i64 = cgb_get(t, r, CGB_WING_RGB) 260 let head_rgb: i64 = cgb_get(t, r, CGB_HEAD_RGB) 261 let beak_rgb: i64 = cgb_get(t, r, CGB_BEAK_RGB) 262 let leg_rgb: i64 = cgb_get(t, r, CGB_LEG_RGB) 263 let tip_rgb: i64 = cgb_get(t, r, CGB_TIP_RGB) 264 let wlen: i64 = bodyl*cgb_get(t, r, CGB_WING_LEN)/CGB_PERMIL 265 let wth: i64 = bodyr*cgb_get(t, r, CGB_WING_THICK)/CGB_PERMIL 266 let wh: i64 = bodyr*cgb_get(t, r, CGB_WING_H)/CGB_PERMIL 267 let tail: i64 = bodyl*cgb_get(t, r, CGB_TAIL_LEN)/CGB_PERMIL 268 let legr: i64 = cgb_get(t, r, CGB_LEG_R) 269 let frx: i64 = cgb_get(t, r, CGB_FOOT_RX) 270 let fry: i64 = cgb_get(t, r, CGB_FOOT_RY) 271 let frz: i64 = cgb_get(t, r, CGB_FOOT_RZ) 272 let bodyY: i64 = 0 - 40 273 let footY: i64 = bodyY - bodyr - legl 274 let headY: i64 = bodyY + bodyr + headr*6/10 275 let headZ: i64 = 0 - bodyl*7/10 276 let hipY: i64 = bodyY - bodyr*8/10 277 let legx: i64 = bodyr*55/100 278 var i: i64 = 0 279 i = as_ellip(P, i, 0, bodyY, 0, bodyr, bodyr*9/10, bodyl, AS_BONE) 280 i = as_color_last(P, i, body_rgb) 281 i = as_fuzz_last(P, i) 282 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) 283 i = as_color_last(P, i, body_rgb) 284 i = as_fuzz_last(P, i) 285 i = as_caps(P, i, 0, bodyY + bodyr*6/10, headZ*8/10, 0, headY, headZ, headr*5/10, AS_BONE) 286 i = as_color_last(P, i, head_rgb) 287 i = as_ellip(P, i, 0, headY, headZ, headr, headr, headr*11/10, AS_BONE) 288 i = as_color_last(P, i, head_rgb) 289 i = as_fuzz_last(P, i) 290 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) 291 i = as_feature_last(P, i, beak_rgb + AS_GLOSS) 292 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) 293 i = as_feature_last(P, i, CGB_EYE + AS_GLOSS) 294 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) 295 i = as_feature_last(P, i, CGB_EYE + AS_GLOSS) 296 i = as_ellip(P, i, 0-bodyr*95/100, bodyY + bodyr*15/100, bodyl*5/100, wth, wh, wlen, AS_MUSCLE) 297 i = as_color_last(P, i, wing_rgb) 298 i = as_fuzz_last(P, i) 299 i = as_ellip(P, i, bodyr*95/100, bodyY + bodyr*15/100, bodyl*5/100, wth, wh, wlen, AS_MUSCLE) 300 i = as_color_last(P, i, wing_rgb) 301 i = as_fuzz_last(P, i) 302 if tip_rgb != CGB_RGB_NONE { 303 let tipz: i64 = bodyl*5/100 + wlen*CGB_TIP_AT/CGB_PERMIL 304 let tipx: i64 = bodyr*CGB_TIP_X/CGB_PERMIL 305 i = as_ellip(P, i, 0-tipx, bodyY + bodyr*15/100, tipz, wth, wh*CGB_TIP_H/CGB_PERMIL, wlen*CGB_TIP_LEN/CGB_PERMIL, AS_MUSCLE) 306 i = as_feature_last(P, i, tip_rgb + AS_MATTE) 307 i = as_ellip(P, i, tipx, bodyY + bodyr*15/100, tipz, wth, wh*CGB_TIP_H/CGB_PERMIL, wlen*CGB_TIP_LEN/CGB_PERMIL, AS_MUSCLE) 308 i = as_feature_last(P, i, tip_rgb + AS_MATTE) 309 } 310 i = as_ellip(P, i, 0, bodyY + bodyr*2/10, bodyl*115/100, bodyr*55/100, bodyr*25/100, tail, AS_MUSCLE) 311 i = as_color_last(P, i, body_rgb) 312 i = as_fuzz_last(P, i) 313 if (pose as i64) == 0 { 314 i = as_caps(P, i, 0-legx, hipY, 0, 0-legx, footY, 0, legr, AS_BONE) 315 i = as_color_last(P, i, leg_rgb) 316 i = as_ellip(P, i, 0-legx, footY, 0-CGB_TOE_Z, frx, fry, frz, AS_BONE) 317 i = as_feature_last(P, i, leg_rgb) 318 i = as_caps(P, i, legx, hipY, 0, legx, footY, 0, legr, AS_BONE) 319 i = as_color_last(P, i, leg_rgb) 320 i = as_ellip(P, i, legx, footY, 0-CGB_TOE_Z, frx, fry, frz, AS_BONE) 321 i = as_feature_last(P, i, leg_rgb) 322 } else { 323 let total: i64 = hipY - footY 324 let L1: i64 = total*CGB_TIB/CGB_PERMIL 325 let L2: i64 = total - L1 326 i = cgb_leg_fk(P, i, 0-legx, hipY, pose[0], pose[1], L1, L2, t, r) 327 i = cgb_leg_fk(P, i, legx, hipY, pose[2], pose[3], L1, L2, t, r) 328 } 329 return i / AS_STRIDE 330} 331func cg_bird_row(P: *i64, seed: i64, t: *i64, nrows: i64, kind: i64) -> i64 { return cg_bird_row_posed(P, seed, t, nrows, kind, 0 as *i64) } 332// ★PG37 THE FIRST ANIMAL, HONESTLY A GULL: the gull ROW of the bird canon -- white-grey palette, longer folded wings 333// with dark tips, stilt legs, webbed feet, standing on the ground (cg_shorebird_posed walks it through the FK 334// legs). EXPLICITLY NOT FLYING: this plan carries no wing pose, and that is the named ceiling. A crab is refused 335// by name until a radial eight-leg plan exists. 336func cg_shorebird(P: *i64, seed: i64) -> i64 { return cg_bird_row(P, seed, cg_bird_canon(), CGB_ROWS, CGB_KIND_GULL) } 337func cg_shorebird_posed(P: *i64, seed: i64, pose: *i64) -> i64 { return cg_bird_row_posed(P, seed, cg_bird_canon(), CGB_ROWS, CGB_KIND_GULL, pose) } 338 339// FISH: fusiform body, tail fin, dorsal fin, pectoral fins, gloss eye. No legs; renders mid-frame (as if swimming). 340func cg_build_fish(P: *i64, seed: i64) -> i64 { 341 let st: *i64 = sys_mmap(16) as *i64 342 st[0] = seed*K_MAGIC_2654435761 + K_MAGIC_90001; cg_next(st); cg_next(st) 343 let bl: i64 = cg_range(st, 330, 430) // body half-length 344 let br: i64 = cg_range(st, 95, 140) // body radius 345 let finr: i64 = cg_range(st, 80, 130) 346 var i: i64 = 0 347 // fusiform body: main + tapered snout + tapered rear 348 i = as_ellip(P, i, 0, 0, 0, br, br*88/100, bl, AS_BONE) 349 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 350 i = as_ellip(P, i, 0, 0, bl*75/100, br*45/100, br*40/100, bl*40/100, AS_BONE) // rear taper 351 // TAIL FIN: thin vertical wedge (crisp so it stays a blade) 352 i = as_ellip(P, i, 0, 0, bl*128/100, br*8/100, finr*13/10, finr*9/10, AS_MUSCLE) 353 i = as_feature_last(P, i, 0) 354 // DORSAL FIN 355 i = as_ellip(P, i, 0, br*95/100, 0-bl*5/100, br*7/100, finr*75/100, bl*42/100, AS_MUSCLE) 356 i = as_feature_last(P, i, 0) 357 // PECTORAL fins 358 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) 359 i = as_feature_last(P, i, 0) 360 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) 361 i = as_feature_last(P, i, 0) 362 // eyes (gloss) 363 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) 364 i = as_feature_last(P, i, 22 + 20*256 + 18*K_MAGIC_65536 + AS_GLOSS) 365 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) 366 i = as_feature_last(P, i, 22 + 20*256 + 18*K_MAGIC_65536 + AS_GLOSS) 367 // belly 368 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) 369 return i / AS_STRIDE 370} 371 372// ★R9 POSED quadruped: the same seed's body with 4 FK-driven legs placed from a POSE (8 angles: FL/FR/BL/BR 373// x thigh/shin, it4096). Rest pose = all zeros = standing. A walk cycle = animate the angles. Returns part count. 374func creaturegen_build_posed(P: *i64, seed: i64, pose: *i64) -> i64 { 375 let st: *i64 = sys_mmap(16) as *i64 376 st[0] = seed*K_MAGIC_2654435761 + K_MAGIC_1013904223; cg_next(st); cg_next(st) 377 let bodylen: i64 = cg_range(st, 360, 500) 378 let build: i64 = cg_range(st, 90, 118) 379 let sZ: i64 = 0 - bodylen/2 380 let hZ: i64 = bodylen/2 381 let backY: i64 = 160 382 let L1: i64 = 132 // upper-leg length 383 let L2: i64 = 120 // lower-leg length 384 let hipY: i64 = backY - 40 385 let headZ: i64 = sZ - 150 386 let headY: i64 = backY + 130 387 var i: i64 = 0 388 // body barrel (fuzzy), chest, neck, head, snout, tail 389 i = as_ellip(P, i, 0, backY-70, 0, 150*build/100, 128, bodylen/2, AS_BONE); i = as_fuzz_last(P, i) 390 i = as_ellip(P, i, 0, backY-40, sZ+40, 150*build/100, 150, 175, AS_BONE); i = as_fuzz_last(P, i) 391 i = as_caps(P, i, 0, backY, sZ, 0, headY, headZ, 54*build/100, AS_BONE); i = as_fuzz_last(P, i) 392 i = as_ellip(P, i, 0, headY, headZ, 118, 106, 130, AS_BONE); i = as_fuzz_last(P, i) 393 i = as_ellip(P, i, 0, headY-48, headZ-108, 72, 60, 84, AS_BONE) 394 i = as_caps(P, i, 0, backY, hZ, 0, backY-100, hZ+300, 28, AS_BONE); i = as_fuzz_last(P, i) 395 // 4 FK legs from the pose 396 i = cg_leg_posed(P, i, 0-108, hipY, sZ+34, pose[0], pose[1], L1, L2, 40) 397 i = cg_leg_posed(P, i, 108, hipY, sZ+34, pose[2], pose[3], L1, L2, 40) 398 i = cg_leg_posed(P, i, 0-114, hipY, hZ-16, pose[4], pose[5], L1, L2, 44) 399 i = cg_leg_posed(P, i, 114, hipY, hZ-16, pose[6], pose[7], L1, L2, 44) 400 // eyes 401 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) 402 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) 403 return i / AS_STRIDE 404} 405 406// build a QUADRUPED from a seed (plan 0; the original). Returns the part count. 407func creaturegen_build(P: *i64, seed: i64) -> i64 { 408 let st: *i64 = sys_mmap(16) as *i64 409 st[0] = seed*K_MAGIC_2654435761 + K_MAGIC_1013904223; cg_next(st); cg_next(st) 410 let bodylen: i64 = cg_range(st, 360, 500) 411 let leglen: i64 = cg_range(st, 360, 560) 412 let necklen: i64 = cg_range(st, 170, 440) 413 let headsz: i64 = cg_range(st, 96, 148) 414 let taillen: i64 = cg_range(st, 130, 420) 415 let build: i64 = cg_range(st, 85, 122) 416 let sZ: i64 = 0 - bodylen/2 // shoulder z (front) 417 let hZ: i64 = bodylen/2 // hip z (back) 418 let backY: i64 = 160 419 let footY: i64 = backY - leglen // ground 420 let headY: i64 = backY + necklen*7/10 421 let headZ: i64 = sZ - necklen*7/10 422 var i: i64 = 0 423 // --- SKELETON (body masses are FUZZY = fur displacement in the geometry) --- 424 i = as_ellip(P, i, 0, backY-40, sZ+40, 150*build/100, 152*build/100, 185, AS_BONE) // ribcage 425 i = as_fuzz_last(P, i) 426 i = as_ellip(P, i, 0, backY-28, hZ-30, 140*build/100, 142, 150, AS_BONE) // pelvis 427 i = as_fuzz_last(P, i) 428 i = as_caps(P, i, 0, backY, sZ, 0, backY, hZ, 58, AS_BONE) // spine 429 i = as_fuzz_last(P, i) 430 i = as_caps(P, i, 0, backY, sZ, 0, headY, headZ, 54*build/100, AS_BONE) // neck 431 i = as_fuzz_last(P, i) 432 i = as_ellip(P, i, 0, headY, headZ, headsz, headsz*9/10, headsz*11/10, AS_BONE) // skull 433 i = as_fuzz_last(P, i) 434 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 435 i = as_caps(P, i, 0, backY, hZ, 0, backY-taillen/3, hZ+taillen, 28, AS_BONE) // tail 436 i = as_fuzz_last(P, i) 437 let hoof: i64 = 52 + 44*256 + 38*K_MAGIC_65536 + AS_GLOSS 438 i = cg_leg(P, i, 0-108, sZ+34, backY-58, footY, 40) // front-left 439 i = as_color_last(P, i, hoof) 440 i = cg_leg(P, i, 108, sZ+34, backY-58, footY, 40) // front-right 441 i = as_color_last(P, i, hoof) 442 i = cg_leg(P, i, 0-114, hZ-16, backY-70, footY, 44) // back-left 443 i = as_color_last(P, i, hoof) 444 i = cg_leg(P, i, 114, hZ-16, backY-70, footY, 44) // back-right 445 i = as_color_last(P, i, hoof) 446 // --- MUSCLE (fuzzy too) --- 447 i = as_ellip(P, i, 0-100, backY-64, sZ+24, 100, 132, 122, AS_MUSCLE) // L shoulder 448 i = as_fuzz_last(P, i) 449 i = as_ellip(P, i, 100, backY-64, sZ+24, 100, 132, 122, AS_MUSCLE) // R shoulder 450 i = as_fuzz_last(P, i) 451 i = as_ellip(P, i, 0-104, backY-86, hZ-22, 116, 150, 132, AS_MUSCLE) // L haunch (thigh) 452 i = as_fuzz_last(P, i) 453 i = as_ellip(P, i, 104, backY-86, hZ-22, 116, 150, 132, AS_MUSCLE) // R haunch 454 i = as_fuzz_last(P, i) 455 i = as_ellip(P, i, 0, backY-120, 0, 150*build/100, 120, bodylen/2, AS_MUSCLE) // belly/barrel 456 i = as_fuzz_last(P, i) 457 i = as_caps(P, i, 0, backY+8, sZ, 0, headY-18, headZ+28, 60, AS_MUSCLE) // neck muscle 458 i = as_fuzz_last(P, i) 459 // --- FEATURES (Phase-1: ears, eyes, nose leather, tail tuft; crisp + low-inflate so they stay sharp) --- 460 let er: i64 = headsz*30/100 461 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) 462 i = as_feature_last(P, i, 0) // L ear (skin, crisp) 463 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) 464 i = as_feature_last(P, i, 0) // R ear 465 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) 466 i = as_feature_last(P, i, 24 + 20*256 + 18*K_MAGIC_65536 + AS_GLOSS) // L eye (dark, glint) 467 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) 468 i = as_feature_last(P, i, 24 + 20*256 + 18*K_MAGIC_65536 + AS_GLOSS) // R eye (glint) 469 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) 470 i = as_feature_last(P, i, 56 + 44*256 + 40*K_MAGIC_65536 + AS_GLOSS) // nose leather (moist gloss) 471 i = as_ellip(P, i, 0, backY-taillen/3, hZ+taillen, 40, 40, 52, AS_MUSCLE) 472 i = as_color_last(P, i, 88 + 66*256 + 48*K_MAGIC_65536 + AS_MATTE) // tail tuft (darker, matte) 473 return i / AS_STRIDE 474}