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}