code wiki / (root) / nx_nxa_morph.nx

nx_nxa_morph.nx source

↩ module page · 244 lines · 10375 B

1// nx_nxa_morph.nx -- FIGURE CANON morph at BAKE level (SOTA rung 2): applies the operator's 2// proportion canon (bust-dominant hourglass: bust +25pct teardrop volume front-side, waist 3// -8pct, hips UNCHANGED -- never enlarge glutes, no surgery-look hard edges) directly to the 4// NXA VERT section so EVERY consumer (viewers, games, skinning) inherits it. Smooth quartic 5// falloff bumps (integer, no exp); face side found from head-region depth extremes; face and 6// head untouched. Run BEFORE nx_nxa_skin so auto-skin sees the final shape. 7// usage: nx_nxa_morph <in.nxa> <out.nxa> 8// rc: 0 ok, 2 usage, 5 bad nxa, 9 io 9// license_tier: ORIGINAL 10import "nx_syscalls.nx" 11import "nx_nxa.nx" 12const K_MAGIC_4096: i64 = 4096 13const K_MAGIC_4611686018427387903: i64 = 4611686018427387903 14 15func mw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 16func mn(v: i64) -> i64 { 17 let t: *u8 = sys_mmap(32) as *u8 18 var m: i64 = v; var w: i64 = 0 19 if m<0 { t[w]=45 as u8; w=w+1; m=0-m } 20 if m==0 { t[0]=48 as u8; sys_write(1,t,1); return 0 } 21 let d: *u8 = sys_mmap(32) as *u8 22 var k: i64=0 23 while m>0 { d[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } 24 var j: i64=0 25 while j<k { t[w]=d[k-1-j]; w=w+1; j=j+1 } 26 sys_write(1,t,w); return 0 27} 28// smooth bump: 4096 * (1 - ((y-c)/w)^2)^2 for |y-c|<w else 0 -- quartic, no trig/exp 29func m_bump(y: i64, c: i64, w: i64) -> i64 { 30 var d: i64 = y - c 31 if d < 0 { d = 0 - d } 32 if d >= w { return 0 } 33 let t: i64 = K_MAGIC_4096 - d*K_MAGIC_4096/w 34 // (1-(d/w)^2)^2 ~ use (2t - t^2/4096) form of 1-(1-t)^2 twice: compute u = 1-(d/w)^2 35 let dw: i64 = d*K_MAGIC_4096/w 36 let u: i64 = K_MAGIC_4096 - dw*dw/K_MAGIC_4096 37 return u*u/K_MAGIC_4096 38} 39 40func main(argc: i64, argv: *i64) -> i64 { 41 if argc < 3 { mw("usage: nx_nxa_morph <in.nxa> <out.nxa>\n" as *u8); return 2 } 42 let lp: *i64 = sys_mmap(16) as *i64 43 let b: *u8 = sys_map_file(argv[1] as *u8, lp) 44 let flen: i64 = lp[0] 45 let vwo: i64 = nxa_find(b, flen, nxa_tag4("VERT" as *u8)) 46 if vwo < 0 { mw("bad nxa\n" as *u8); return 5 } 47 let h: *i64 = b as *i64 48 let nv: i64 = h[vwo] 49 // copy VERT payload to a mutable buffer 50 let vwl: i64 = 1 + nv*3 51 let vp: *i64 = sys_mmap(vwl*8 + 64) as *i64 52 var c0: i64 = 0 53 while c0 < vwl { vp[c0] = h[vwo + c0]; c0 = c0 + 1 } 54 let vx: *i64 = ((vp as i64) + 8) as *i64 55 // axes: up = largest extent; lat = larger of the rest; face sign from head-region depth 56 let mnv: *i64 = sys_mmap(64) as *i64 57 let mxv: *i64 = sys_mmap(64) as *i64 58 var a0: i64 = 0 59 while a0 < 3 { mnv[a0] = K_MAGIC_4611686018427387903; mxv[a0] = 0 - K_MAGIC_4611686018427387903; a0 = a0 + 1 } 60 var i0: i64 = 0 61 while i0 < nv { 62 var a1: i64 = 0 63 while a1 < 3 { 64 let v: i64 = vx[i0*3 + a1] 65 if v < mnv[a1] { mnv[a1] = v } 66 if v > mxv[a1] { mxv[a1] = v } 67 a1 = a1 + 1 68 } 69 i0 = i0 + 1 70 } 71 var up: i64 = 0 72 if mxv[1]-mnv[1] > mxv[up]-mnv[up] { up = 1 } 73 if mxv[2]-mnv[2] > mxv[up]-mnv[up] { up = 2 } 74 var lat: i64 = 0 75 if up == 0 { lat = 1 } 76 let o3: i64 = 3 - up - lat 77 var oth: i64 = o3 78 if mxv[o3]-mnv[o3] > mxv[lat]-mnv[lat] { oth = lat; lat = o3 } 79 let H: i64 = mxv[up] - mnv[up] 80 let clat: i64 = (mnv[lat] + mxv[lat]) / 2 81 let coth: i64 = (mnv[oth] + mxv[oth]) / 2 82 // face sign: head band = top 12pct; farthest depth extreme sign 83 var fs: i64 = 1 84 var fm: i64 = 0 85 var i1: i64 = 0 86 while i1 < nv { 87 let y01: i64 = (vx[i1*3 + up] - mnv[up])*1000/H 88 if y01 > 880 { 89 var dz: i64 = vx[i1*3 + oth] - coth 90 var ad: i64 = dz 91 if ad < 0 { ad = 0 - ad } 92 if ad > fm { fm = ad; fs = 1; if dz < 0 { fs = 0 - 1 } } 93 } 94 i1 = i1 + 1 95 } 96 // morph: bust two-lobe teardrop (front only, arms excluded), waist -8pct radial 97 var i2: i64 = 0 98 var moved: i64 = 0 99 while i2 < nv { 100 let y01: i64 = (vx[i2*3 + up] - mnv[up])*1000/H 101 let lx: i64 = vx[i2*3 + lat] - clat 102 let dz: i64 = vx[i2*3 + oth] - coth 103 // waist: radial shrink about the body axis, band c=585 w=90 104 let gw: i64 = m_bump(y01, 585, 90) 105 if gw > 0 { 106 let s: i64 = K_MAGIC_4096 - gw*328/K_MAGIC_4096 107 vx[i2*3 + lat] = clat + lx*s/K_MAGIC_4096 108 vx[i2*3 + oth] = coth + dz*s/K_MAGIC_4096 109 moved = moved + 1 110 } 111 // hips/glutes: the BASE scan is fuller than the benchmark canon (operator: butt huge 112 // vs Emily) -- reduce radially -10pct in the glute band c=465 w=120 113 let gh: i64 = m_bump(y01, 465, 120) 114 if gh > 0 { 115 let sh9: i64 = K_MAGIC_4096 - gh*410/K_MAGIC_4096 116 vx[i2*3 + lat] = clat + (vx[i2*3 + lat] - clat)*sh9/K_MAGIC_4096 117 vx[i2*3 + oth] = coth + (vx[i2*3 + oth] - coth)*sh9/K_MAGIC_4096 118 moved = moved + 1 119 } 120 // bust: front side only, |lat| < .15H; lower lobe c=668 w=110 amp .28, upper lobe 121 // c=715 w=70 amp .10 -- teardrop: full lower pole, gentle upper slope 122 var al: i64 = lx 123 if al < 0 { al = 0 - al } 124 let fr0: i64 = dz*fs 125 if fr0 > 0 { if al < H*150/1000 { 126 var gb: i64 = m_bump(y01, 668, 110)*287/1000 + m_bump(y01, 715, 70)*102/1000 127 if gb > 0 { 128 var fr: i64 = fr0*K_MAGIC_4096/(H*50/1000) 129 if fr > K_MAGIC_4096 { fr = K_MAGIC_4096 } 130 let s2: i64 = K_MAGIC_4096 + gb*fr/K_MAGIC_4096 131 // scale depth about the chest wall (offset .005H toward face) + slight lateral 132 let z0: i64 = coth + fs*H*5/1000 133 let dz2: i64 = vx[i2*3 + oth] - z0 134 vx[i2*3 + oth] = z0 + dz2*s2/K_MAGIC_4096 135 let s3: i64 = K_MAGIC_4096 + gb*fr/K_MAGIC_4096/4 136 vx[i2*3 + lat] = clat + (vx[i2*3 + lat] - clat)*s3/K_MAGIC_4096 137 // teardrop droop: slight downward shift proportional to bump 138 vx[i2*3 + up] = vx[i2*3 + up] - gb*fr/K_MAGIC_4096*(H*12/1000)/K_MAGIC_4096 139 moved = moved + 1 140 } 141 } } 142 i2 = i2 + 1 143 } 144 // CLUS bounds were computed on the unmorphed verts -- recompute per-cluster bbox + 145 // Chebyshev max edge or fsck rightly refuses (RED vertex below cluster bounds) 146 let two: i64 = nxa_find(b, flen, nxa_tag4("TRIS" as *u8)) 147 let cwo: i64 = nxa_find(b, flen, nxa_tag4("CLUS" as *u8)) 148 var clw: i64 = 0 149 var cpb: *i64 = 0 as *i64 150 if cwo >= 0 { if two >= 0 { 151 let ncl: i64 = h[cwo] 152 clw = 1 + ncl*10 153 cpb = sys_mmap(clw*8 + 64) as *i64 154 var cc0: i64 = 0 155 while cc0 < clw { cpb[cc0] = h[cwo + cc0]; cc0 = cc0 + 1 } 156 let tr: *i64 = ((b as i64) + two*8 + 8) as *i64 157 var cl0: i64 = 0 158 while cl0 < ncl { 159 let cb: i64 = 1 + cl0*10 160 let ts: i64 = cpb[cb] 161 let tc: i64 = cpb[cb+1] 162 var bmn0: i64 = K_MAGIC_4611686018427387903 163 var bmn1: i64 = K_MAGIC_4611686018427387903 164 var bmn2: i64 = K_MAGIC_4611686018427387903 165 var bmx0: i64 = 0 - K_MAGIC_4611686018427387903 166 var bmx1: i64 = 0 - K_MAGIC_4611686018427387903 167 var bmx2: i64 = 0 - K_MAGIC_4611686018427387903 168 var med: i64 = 0 169 var q0: i64 = 0 170 while q0 < tc { 171 var e0: i64 = 0 172 while e0 < 3 { 173 let vi9: i64 = tr[(ts+q0)*3 + e0] 174 var vj9: i64 = tr[(ts+q0)*3] 175 if e0 < 2 { vj9 = tr[(ts+q0)*3 + e0 + 1] } 176 let x9: i64 = vx[vi9*3] 177 let y9: i64 = vx[vi9*3+1] 178 let z9: i64 = vx[vi9*3+2] 179 if x9 < bmn0 { bmn0 = x9 } 180 if y9 < bmn1 { bmn1 = y9 } 181 if z9 < bmn2 { bmn2 = z9 } 182 if x9 > bmx0 { bmx0 = x9 } 183 if y9 > bmx1 { bmx1 = y9 } 184 if z9 > bmx2 { bmx2 = z9 } 185 var ch0: i64 = vx[vi9*3] - vx[vj9*3] 186 if ch0 < 0 { ch0 = 0 - ch0 } 187 var ch1: i64 = vx[vi9*3+1] - vx[vj9*3+1] 188 if ch1 < 0 { ch1 = 0 - ch1 } 189 var ch2: i64 = vx[vi9*3+2] - vx[vj9*3+2] 190 if ch2 < 0 { ch2 = 0 - ch2 } 191 if ch1 > ch0 { ch0 = ch1 } 192 if ch2 > ch0 { ch0 = ch2 } 193 if ch0 > med { med = ch0 } 194 e0 = e0 + 1 195 } 196 q0 = q0 + 1 197 } 198 cpb[cb+2] = bmn0 199 cpb[cb+3] = bmn1 200 cpb[cb+4] = bmn2 201 cpb[cb+5] = bmx0 202 cpb[cb+6] = bmx1 203 cpb[cb+7] = bmx2 204 cpb[cb+9] = med 205 cl0 = cl0 + 1 206 } 207 } } 208 mw("morph verts_touched=" as *u8); mn(moved) 209 mw(" H=" as *u8); mn(H) 210 mw(" up=" as *u8); mn(up) 211 mw(" facesign=" as *u8); mn(fs); mw("\n" as *u8) 212 // write out: same TOC layout; VERT payload replaced + its check and the TOC check redone 213 let ns: i64 = h[2] 214 let otoc: *i64 = ((b as i64) + 32) as *i64 215 let toc: *i64 = sys_mmap(ns*32 + 64) as *i64 216 var t0: i64 = 0 217 while t0 < ns*4 { toc[t0] = otoc[t0]; t0 = t0 + 1 } 218 var ti: i64 = 0 219 while ti < ns { 220 if toc[ti*4] == nxa_tag4("VERT" as *u8) { toc[ti*4+3] = nxa_check2(1, vp, vwl) } 221 if toc[ti*4] == nxa_tag4("CLUS" as *u8) { if clw > 0 { toc[ti*4+3] = nxa_check2(1, cpb, clw) } } 222 ti = ti + 1 223 } 224 let hdr: *i64 = sys_mmap(64) as *i64 225 hdr[0] = h[0] 226 hdr[1] = h[1] 227 hdr[2] = ns 228 hdr[3] = nxa_check2(1, toc, ns*4) 229 let fd: i64 = sys_openat_wr(argv[2] as *u8, 0x1a4) 230 if fd < 0 { mw("open out failed\n" as *u8); return 9 } 231 sys_write(fd, hdr as *u8, 32) 232 sys_write(fd, toc as *u8, ns*32) 233 var ci: i64 = 0 234 while ci < ns { 235 var done9: i64 = 0 236 if toc[ci*4] == nxa_tag4("VERT" as *u8) { sys_write(fd, vp as *u8, vwl*8); done9 = 1 } 237 if toc[ci*4] == nxa_tag4("CLUS" as *u8) { if clw > 0 { sys_write(fd, cpb as *u8, clw*8); done9 = 1 } } 238 if done9 == 0 { sys_write(fd, ((b as i64) + toc[ci*4+1]) as *u8, toc[ci*4+2]*8) } 239 ci = ci + 1 240 } 241 sys_close(fd) 242 mw("MORPHED nxa written\n" as *u8) 243 return 0 244}