code wiki / _hdl_build / nx_char_identity.nx

nx_char_identity.nx source

↩ module page · 280 lines · 13733 B

1// nx_char_identity.nx -- THE IDENTITY VECTOR: "a LoRA, but for riggable models" (operator 2026-07-27: 2// "daz like models or whatever powers lust goddesses or nikke ... an emitter or proc generator but 3// wireable, making CONSISTENT beauties almost like a lora on a diffusion but for riggable models"). 4// 5// WHAT A LoRA ACTUALLY IS, mechanically: a SMALL reproducible DELTA applied to a big frozen base, such 6// that the same delta yields the same identity every time, under any prompt. The riggable equivalent is 7// exactly the DAZ Genesis architecture: ONE base topology + a MORPH-DIAL VECTOR + a shared rig. Same 8// dials => same woman, in any pose, any outfit, any art style. This organ is that dial vector. 9// 10// ★THE LAW IT ENFORCES (already written in nx_scene_contract.nx:9-13, now made GATE-ABLE): 11// identity = f(seed) ONLY. STYLE transforms proportions and shading; it must NEVER touch identity. 12// That single invariant is what "consistent beauties" means operationally, and T2 of the gate proves it. 13// 14// ★WHAT IT REUSES (check-before-build; none of this is rebuilt here): 15// nx_morph.nx -- mo_begin/mo_add_delta/mo_apply: 32 dials x 0..256 weights, ADDITIVE and 16// COMMUTATIVE, applied to the bind-pose mesh before skinning (industry standard). 17// THE dial primitive. This organ emits weights FOR it. 18// nx_body_proc.nx -- seed + {sex,build,musc,noise,stylize,eyecol} -> canon.dat, already deterministic 19// and already carrying a realistic<->ANIME stylize axis (0..1000). 20// nx_scene_contract -- the per-style proportion tables (anime head-ratio 205 vs realistic 137). 21// nx_bodyatlas -- the base body + the 9-bone FK rig that glTF export already skins against. 22// nx_canon_cid.nx -- the DURABLE character id (nxc1-<sha256>) at publish time. `idv_key` below is a 23// fast in-memory dedup key ONLY, deliberately a different thing, not a rival CID. 24// 25// ★★WHAT IT REFUSES TO DO, AND WHY (the honest boundary): 26// It does NOT score beauty. [[reference-beauty-canon-and-layered-anatomy-2026-07-26]]: Versluys 2018 found 27// the aesthetic optimum FLIPS with stimulus realism -- silhouettes optimise BELOW baseline, detailed CG 28// ABOVE. We render at clay fidelity, so a beauty judge calibrated here would teach the WRONG target and 29// actively make the models worse. What IS honestly gate-able is CONSISTENCY, DIVERSITY, and conformance 30// to MEASURED anthropometry -- so that is all this gates. Aesthetic judgement belongs to the high-fidelity 31// lane, at the fidelity it will be used at. 32// ★★AND IT HARD-REFUSES PHI: the golden ratio is ACTIVELY REFUTED for human proportion (Naini 2024; 33// Burusapat 2019 measured 32 Miss Universe winners: "statistically significantly invalid"). WHR 0.7 is 34// dead too -- our own ANSUR II parse found 0.0% of 1,986 women reach it. The gate carries a REGRESSION 35// TOOTH so nobody can quietly reintroduce either. 36// All integer, deterministic. LIB, no main. license_tier: ORIGINAL 37import "nx_syscalls.nx" 38import "nx_game_genetics.nx" 39 40// ---- the identity record: 24 i64 slots ---- 41const IDV_SLOTS: i64 = 24 42// IDENTITY FIELDS (0..19) -- these define WHO she is. Style/pose/outfit may never write them. 43const IDV_SEED: i64 = 0 // the individual 44const IDV_SEX: i64 = 1 // 0..1000 body dimorphism (nx_body_proc scale) 45const IDV_BUILD: i64 = 2 // 0..1000 lean..heavy 46const IDV_MUSC: i64 = 3 // 0..1000 soft..muscular 47const IDV_STATURE:i64 = 4 // mm 48const IDV_LBR: i64 = 5 // leg-to-body ratio, PER-MILLE (measured canon: 491 +- 15) 49const IDV_SHIP: i64 = 6 // shoulder:hip x100 50const IDV_D0: i64 = 7 // ---- 8 FACE/BODY MORPH DIALS, each 0..256 = nx_morph's weight range ---- 51const IDV_D1: i64 = 8 52const IDV_D2: i64 = 9 53const IDV_D3: i64 = 10 54const IDV_D4: i64 = 11 55const IDV_D5: i64 = 12 56const IDV_D6: i64 = 13 57const IDV_D7: i64 = 14 58const IDV_SKIN: i64 = 15 // packed r|g<<8|b<<16 59const IDV_HAIR: i64 = 16 60const IDV_EYE: i64 = 17 61const IDV_HAIRSTYLE: i64 = 18 62const IDV_ARCH: i64 = 19 // temperament/archetype, derived -- drives expression defaults 63// ---- NON-IDENTITY (20..23): presentation state. Free to change without changing WHO she is. ---- 64const IDV_STYLE: i64 = 20 // 0 realistic 1 anime 2 cartoon 3 VN 65const IDV_POSE: i64 = 21 66const IDV_OUTFIT: i64 = 22 67const IDV_EXPR: i64 = 23 68const IDV_NIDENT: i64 = 20 // slots [0, IDV_NIDENT) are the identity half -- the gate asserts on this 69 70const IDV_NDIAL: i64 = 8 71const IDV_DIALMAX: i64 = 256 // nx_morph weight range 72 73// measured canon targets (NOT phi, NOT WHR 0.7 -- see the header) 74const IDV_LBR_MEAN: i64 = 491 // Versluys 2018, leg-to-body ratio 75const IDV_LBR_SD: i64 = 15 76const IDV_SHIP_LO: i64 = 113 // Aich 2026 male shoulder:hip 1.13..1.45 77const IDV_SHIP_HI: i64 = 145 78 79func idv_rng(s: *i64) -> i64 { 80 var x: i64 = s[0] 81 x = x ^ (x << 13); x = x ^ (x >> 7); x = x ^ (x << 17) 82 s[0] = x 83 if x < 0 { return 0 - x } 84 return x 85} 86func idv_clamp(v: i64, lo: i64, hi: i64) -> i64 { 87 if v < lo { return lo } 88 if v > hi { return hi } 89 return v 90} 91 92// ---- THE GENERATOR: seed -> a complete, reproducible individual ---- 93// Everything derives from ONE integer, so an identity is as portable as its seed. 94func idv_from_seed(idv: *i64, seed: i64) -> i64 { 95 let s: *i64 = sys_mmap(16) as *i64 96 s[0] = seed * 2654435761 + 1013904223 97 var warm: i64 = 0 98 while warm < 8 { idv_rng(s); warm = warm + 1 } 99 idv[IDV_SEED] = seed 100 idv[IDV_SEX] = 700 + (idv_rng(s) % 301) // this lane authors women: 700..1000 101 idv[IDV_BUILD] = 180 + (idv_rng(s) % 380) 102 idv[IDV_MUSC] = 250 + (idv_rng(s) % 400) 103 idv[IDV_STATURE] = 1560 + (idv_rng(s) % 190) // mm, real adult female range 104 // ★LBR drawn around the MEASURED mean with the MEASURED SD, biased +0.5SD to the measured optimum. 105 // This is the one place an aesthetic preference enters, and it is a published number, not a taste. 106 idv[IDV_LBR] = IDV_LBR_MEAN + IDV_LBR_SD/2 + (idv_rng(s) % (IDV_LBR_SD*2+1)) - IDV_LBR_SD 107 idv[IDV_SHIP] = IDV_SHIP_LO + (idv_rng(s) % (IDV_SHIP_HI - IDV_SHIP_LO + 1)) 108 var d: i64 = 0 109 while d < IDV_NDIAL { 110 idv[IDV_D0 + d] = idv_rng(s) % (IDV_DIALMAX + 1) 111 d = d + 1 112 } 113 let sr: i64 = 150 + (idv_rng(s) % 105) 114 let sg: i64 = 110 + (idv_rng(s) % 100) 115 let sb: i64 = 95 + (idv_rng(s) % 95) 116 idv[IDV_SKIN] = (sr & 255) | ((sg & 255) << 8) | ((sb & 255) << 16) 117 idv[IDV_HAIR] = (idv_rng(s) % 256) | ((idv_rng(s) % 256) << 8) | ((idv_rng(s) % 256) << 16) 118 idv[IDV_EYE] = (idv_rng(s) % 256) | ((idv_rng(s) % 256) << 8) | ((idv_rng(s) % 256) << 16) 119 idv[IDV_HAIRSTYLE] = 1 + (idv_rng(s) % 4) 120 idv[IDV_ARCH] = idv_rng(s) % 4 121 idv[IDV_STYLE] = 1 // anime by default; presentation, not identity 122 idv[IDV_POSE] = 0 123 idv[IDV_OUTFIT] = 0 124 idv[IDV_EXPR] = 0 125 return 0 126} 127 128// ★★THE GAMEPLAY WIRE -- the whole point of doing this in THIS lane. 129// A companion you bred has a GENOME (nx_game_genetics). Her appearance must be that genome expressed, so 130// the creature you earned is literally the woman you see, and two sisters differ because their ALLELES 131// differ. Identical genomes therefore produce identical twins -- gate-proven (T7). 132// The genome supplies the HERITABLE traits; the per-individual seed supplies everything genetics does not 133// specify (exact dial noise), and that seed is itself derived from the genome so it stays reproducible. 134func idv_from_companion(idv: *i64, geno: i64, poly: i64, sexg: i64, epi: i64, nick: i64) -> i64 { 135 idv_from_seed(idv, geno * 2654435761 + poly * 40503 + sexg * 69061 + nick) 136 // ---- heritable overrides: these come from ALLELES, not from the seed ---- 137 // polygenic dose -> stature (a continuous, bell-curved trait, exactly as in life) 138 let dose: i64 = gx_poly_dose(poly) 139 idv[IDV_STATURE] = 1500 + dose * 22 140 // coat locus (incomplete dominance) -> hair colour, the trait a player can SEE segregating 141 let coat: i64 = gx_expressed(geno, epi, GX_COAT) 142 if coat == 2 { idv[IDV_HAIR] = (190) | (40 << 8) | (55 << 16) } // crimson 143 if coat == 1 { idv[IDV_HAIR] = (235) | (150 << 8) | (170 << 16) } // rose blend 144 if coat == 0 { idv[IDV_HAIR] = (238) | (234 << 8) | (240 << 16) } // white 145 // ABO affinity -> eye colour, with AB expressing BOTH (heterochromia = codominance you can point at) 146 let el: i64 = gx_expressed(geno, epi, GX_ELEM) 147 if el == 1 { idv[IDV_EYE] = (255) | (150 << 8) | (60 << 16) } 148 if el == 2 { idv[IDV_EYE] = (90) | (170 << 8) | (255 << 16) } 149 if el == 3 { idv[IDV_EYE] = (255) | (150 << 8) | (255 << 16) } 150 if el == 0 { idv[IDV_EYE] = (120) | (120 << 8) | (130 << 16) } 151 // horn locus -> the hairstyle slot (a visible dominant/recessive split) 152 if gx_expressed(geno, epi, GX_HORN) == 1 { idv[IDV_HAIRSTYLE] = 2 } 153 if gx_expressed(geno, epi, GX_HORN) == 0 { idv[IDV_HAIRSTYLE] = 1 } 154 // ZW sex gene -> body dimorphism 155 if gx_sex(sexg) == GX_SEX_F { idv[IDV_SEX] = 820 } 156 if gx_sex(sexg) == GX_SEX_M { idv[IDV_SEX] = 240 } 157 return 0 158} 159 160// ---- THE DIAL VECTOR: what you actually hand to nx_morph's mo_apply(weights) ---- 161// One definition of "how this identity deforms the base", in nx_morph's own 0..256 weight units. 162func idv_dials(idv: *i64, weights: *i64) -> i64 { 163 var d: i64 = 0 164 while d < IDV_NDIAL { 165 weights[d] = idv_clamp(idv[IDV_D0 + d], 0, IDV_DIALMAX) 166 d = d + 1 167 } 168 return IDV_NDIAL 169} 170 171// ---- STYLE: transforms PROPORTIONS ONLY. Mirrors nx_scene_contract's table so the two lanes agree. 172// out[0]=head_ratio_q10 out[1]=outline out[2]=big_eyes out[3]=stature_mm (style-adjusted) 173// ★It reads idv and writes only `out` -- it CANNOT touch identity by construction, which is what makes 174// the same woman recognisable in realistic render, anime render, and VN portrait. 175func idv_style_params(idv: *i64, style: i64, out: *i64) -> i64 { 176 var hr: i64 = 137 // realistic 177 if style == 1 { hr = 205 } // anime 178 if style == 2 { hr = 341 } // cartoon 179 if style == 3 { hr = 228 } // VN portrait 180 out[0] = hr 181 var ol: i64 = 0 182 if style == 2 { ol = 1 } 183 out[1] = ol 184 var be: i64 = 0 185 if style == 1 { be = 1 } 186 if style == 3 { be = 1 } 187 out[2] = be 188 out[3] = idv[IDV_STATURE] 189 return 0 190} 191 192// ---- the nx_body_proc argv this identity corresponds to (the EMITTER wire) ---- 193// out: [sex, build, musc, noise, seed, stylize, eyecol] -- exactly nx_body_proc's 7 knobs. 194func idv_bodyproc_args(idv: *i64, style: i64, out: *i64) -> i64 { 195 out[0] = idv[IDV_SEX] 196 out[1] = idv[IDV_BUILD] 197 out[2] = idv[IDV_MUSC] 198 out[3] = 120 // per-mille individual variation 199 out[4] = idv[IDV_SEED] 200 var sty: i64 = 0 201 if style == 1 { sty = 850 } // anime 202 if style == 2 { sty = 1000 } 203 if style == 3 { sty = 700 } 204 out[5] = sty 205 out[6] = 0 206 return 7 207} 208 209// ---- in-memory dedup KEY over the IDENTITY HALF ONLY (slots 0..IDV_NIDENT). 210// ⚠Deliberately NOT a rival to nx_canon_cid's durable nxc1-<sha256> CID: this is a fast collision key for 211// "have I seen this woman before", the CID is the publishable name. Different jobs, no duplication. 212func idv_key(idv: *i64) -> i64 { 213 var k: i64 = 1469598103934665603 214 var i: i64 = 0 215 while i < IDV_NIDENT { 216 k = ((k ^ idv[i]) * 1099511628211) & 4611686018427387903 217 i = i + 1 218 } 219 return k 220} 221 222// ---- identity DISTANCE: how different are two women? Used for the diversity floor (the "every LoRA 223// output looks like the same girl" failure) and for "is this the same person" checks. 224func idv_distance(a: *i64, b: *i64) -> i64 { 225 var d: i64 = 0 226 var i: i64 = 0 227 while i < IDV_NDIAL { 228 var t: i64 = a[IDV_D0 + i] - b[IDV_D0 + i] 229 if t < 0 { t = 0 - t } 230 d = d + t 231 i = i + 1 232 } 233 var st: i64 = a[IDV_STATURE] - b[IDV_STATURE] 234 if st < 0 { st = 0 - st } 235 d = d + st / 4 236 var bu: i64 = a[IDV_BUILD] - b[IDV_BUILD] 237 if bu < 0 { bu = 0 - bu } 238 d = d + bu / 4 239 return d 240} 241// same woman? (identity half byte-identical) 242func idv_same(a: *i64, b: *i64) -> i64 { 243 var i: i64 = 0 244 while i < IDV_NIDENT { 245 if a[i] != b[i] { return 0 } 246 i = i + 1 247 } 248 return 1 249} 250 251// ---- serialization: rides gs_save with everything else ---- 252func idv_serialize(idv: *i64, S: *i64) -> i64 { 253 var i: i64 = 0 254 while i < IDV_SLOTS { S[i] = idv[i]; i = i + 1 } 255 return IDV_SLOTS 256} 257func idv_restore(idv: *i64, S: *i64) -> i64 { 258 var i: i64 = 0 259 while i < IDV_SLOTS { idv[i] = S[i]; i = i + 1 } 260 return IDV_SLOTS 261} 262 263// ---- canon conformance against MEASURED anthropometry (never phi, never WHR 0.7) ---- 264// returns 1 if this identity's proportions sit inside the measured bands. 265func idv_canon_ok(idv: *i64) -> i64 { 266 var d: i64 = idv[IDV_LBR] - IDV_LBR_MEAN 267 if d < 0 { d = 0 - d } 268 if d > IDV_LBR_SD * 3 { return 0 } // within 3 SD of the measured mean 269 if idv[IDV_SHIP] < IDV_SHIP_LO { return 0 } 270 if idv[IDV_SHIP] > IDV_SHIP_HI { return 0 } 271 if idv[IDV_STATURE] < 1400 { return 0 } 272 if idv[IDV_STATURE] > 1900 { return 0 } 273 return 1 274} 275func idv_style_name(s: i64) -> *u8 { 276 if s == 1 { return "anime" as *u8 } 277 if s == 2 { return "cartoon" as *u8 } 278 if s == 3 { return "VN" as *u8 } 279 return "realistic" 280}