nx_persongen.nx source
↩ module page · 79 lines · 4535 B
1// nx_persongen.nx -- ★GENERATIVE PERSON FACTORY (operator north star 2026-07-08: "generate a model from the
2// bones up ... a daz-like photoreal model WITHOUT a photo reference as a NEW generative person"). A SEED grows a
3// UNIQUE novel human FACE, built bones-up (nx_faceanat = skull landmarks + tissue-depth), by driving the
4// anatomical morphs + skin tone from a deterministic PRNG. NO photo input -- a person who never existed. Same
5// seed -> same person (a reproducible identity); different seed -> a different person. This is the DAZ-equivalent
6// GENERATION (parametric identity), sovereign. (Photoreal skin micro-detail = the texture-synthesis rung on top;
7// this rung owns the IDENTITY generation bones-up.) license_tier: ORIGINAL
8import "nx_faceanat.nx"
9const K_MAGIC_6364136223846793005: i64 = 6364136223846793005
10const K_MAGIC_1442695040888963407: i64 = 1442695040888963407
11const K_MAGIC_2147483647: i64 = 2147483647
12const K_MAGIC_2654435761: i64 = 2654435761
13const K_MAGIC_1013904223: i64 = 1013904223
14
15// deterministic LCG PRNG (Knuth MMIX constants); i64 wraps on overflow = the generator. Reproducible => identity.
16func pg_next(st: *i64) -> i64 {
17 var h: i64 = st[0]
18 h = h * K_MAGIC_6364136223846793005 + K_MAGIC_1442695040888963407
19 st[0] = h
20 return (h >> 33) & K_MAGIC_2147483647 // 31 positive bits
21}
22func pg_seed(st: *i64, seed: i64) -> i64 {
23 st[0] = seed * K_MAGIC_2654435761 + K_MAGIC_1013904223
24 pg_next(st); pg_next(st); pg_next(st) // warm up (decorrelate low seeds)
25 return 0
26}
27func pg_range(st: *i64, lo: i64, hi: i64) -> i64 { return lo + pg_next(st) % (hi - lo + 1) }
28func pg_clamp(v: i64, lo: i64, hi: i64) -> i64 { if v < lo { return lo } if v > hi { return hi } return v }
29
30// grow a novel person from a seed. Fills the sdf arena `base` with a unique face (bones-up morphs) and returns
31// its skin tone in skinout[0..2]. Also fills idout[0..7] with the identity parameter vector (for inspection).
32// egout receives the six eye genes (FA_EG_*); persongen_build below keeps the older four-argument door for every caller
33func persongen_build_eye(base: i64, seed: i64, skinout: *i64, idout: *i64, egout: *i64) -> i64 {
34 let st: *i64 = sys_mmap(16) as *i64
35 pg_seed(st, seed)
36
37 // bones-up anatomical identity: morph the skull-derived geometry. ★pct is a MULTIPLIER in percent (100 =
38 // identity, 120 = x1.2); ranges centred on 100 -> valid, distinct faces (never near-zero radius).
39 let mw: i64 = pg_range(st, 85, 118) // face width
40 let ml: i64 = pg_range(st, 88, 114) // face length
41 let mj: i64 = pg_range(st, 80, 126) // jaw
42 let me: i64 = pg_range(st, 85, 120) // eyes
43 let mp: i64 = pg_range(st, 78, 132) // lips
44 let mn: i64 = pg_range(st, 84, 122) // nose
45 let mc: i64 = pg_range(st, 82, 128) // cheek
46 faceanat_build(base)
47 faceanat_morph_width(base, mw)
48 faceanat_morph_length(base, ml)
49 faceanat_morph_jaw(base, mj)
50 faceanat_morph_eyes(base, me)
51 faceanat_morph_lips(base, mp)
52 faceanat_morph_nose(base, mn)
53 faceanat_morph_cheek(base, mc)
54 idout[0]=mw; idout[1]=ml; idout[2]=mj; idout[3]=me; idout[4]=mp; idout[5]=mn; idout[6]=mc
55
56 // skin tone: pick a realistic tone family + per-person jitter (no photo -- synthesized)
57 let fam: i64 = pg_range(st, 0, 4)
58 var sr: i64 = 232; var sg: i64 = 196; var sb: i64 = 166
59 if fam == 0 { sr=246; sg=226; sb=208 } // light
60 if fam == 1 { sr=232; sg=196; sb=166 } // fair-medium
61 if fam == 2 { sr=206; sg=162; sb=126 } // olive / tan
62 if fam == 3 { sr=168; sg=122; sb=90 } // brown
63 if fam == 4 { sr=124; sg=86; sb=62 } // deep
64 sr = pg_clamp(sr + pg_range(st, 0-12, 12), 40, 255)
65 sg = pg_clamp(sg + pg_range(st, 0-12, 12), 30, 255)
66 sb = pg_clamp(sb + pg_range(st, 0-12, 12), 25, 255)
67 skinout[0]=sr; skinout[1]=sg; skinout[2]=sb; idout[7]=fam
68
69 // THE EYE UNIT'S GENES (AT39), drawn AFTER every earlier draw so each existing seed keeps its seven morphs and its tone:
70 // an identity is a PRNG stream, and a new gene inserted mid-stream would silently turn every person into someone else
71 var ek: i64 = 0
72 while ek < FA_EG_N { egout[ek] = pg_range(st, fa_eye_gene_lo(ek), fa_eye_gene_hi(ek)); ek = ek + 1 }
73 faceanat_eye_genes(base, egout)
74 return 0
75}
76func persongen_build(base: i64, seed: i64, skinout: *i64, idout: *i64) -> i64 {
77 let eg: *i64 = sys_mmap(FA_EG_N * 8) as *i64
78 return persongen_build_eye(base, seed, skinout, idout, eg)
79}