code wiki / (root) / nx_dance_emit.nx

nx_dance_emit.nx source

↩ module page · 1415 lines · 69317 B

1// nx_dance_emit.nx -- DANCE-MOTION KEYSTONE v2: the being DANCES from REAL third-party mocap (ws=dance-motion 2026-08-10). 2// 3// v2 (operator saw v1 live: "tearing and junky"): the two roots were (1) LOCAL-Euler rotation transfer -- 4// with the mocap's collar/spine frames dropped, absolute limb poses were wrong; (2) rigid one-joint 5// binding -- triangles spanning a joint tore into spikes at real dance angles. v2 replaces both: 6// RETARGET BY POSITION: FK the mocap skeleton per key (world quats+positions from the clip's own 7// channels), take each segment's WORLD direction (shoulder->elbow, elbow->wrist, hip->knee, 8// knee->ankle), de-yaw by the dancer's hip axis (torso-relative dance, stable body), mirror X into 9// our rig's handedness, and drive each bone as the minimal rotation from its rest (-Y) to that 10// direction. Correct poses BY CONSTRUCTION -- no local-frame luck. 11// SMOOTH TWO-BONE SKIN: per-vertex second joint + Q14 weight, blending BOTH sides of every joint 12// pivot over a 150-unit band (child side toward parent, parent side toward child) -- kills the tears. 13// Plus: ONE skin tone (per-part colours read as patches -- the showcase organ measured this first). 14// 15// usage: nx_dance_emit [file.bvh] default knowledge/fixture_mocapbank.bvh; writes 16// nx_dance_emit --kat selftest incl neg-control + exact quat values 17// exit 0 ok | 1 teeth RED | 2 unreadable | 3 usage | 4 REFUSED (parse or joint-map) 18// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 19import "nx_syscalls.nx" 20import "nx_trimesh.nx" 21import "nx_isosurf.nx" 22import "nx_bodyatlas.nx" 23import "nx_gltf_anim.nx" 24import "nx_bvh_lib.nx" 25import "nx_nxa.nx" 26import "nx_clipcap_lib.nx" 27const XD_MAGIC_33333: i64 = 33333 28const XD_MAGIC_1900: i64 = 1900 29const XD_MAGIC_225000000: i64 = 225000000 30const XD_MAGIC_4000: i64 = 4000 31const XD_MAGIC_8000: i64 = 8000 32const XD_MAGIC_3900: i64 = 3900 33const XD_MAGIC_8192: i64 = 8192 34const XD_MAGIC_16384: i64 = 16384 35const XD_MAGIC_116324: i64 = 116324 36const XD_MAGIC_21008: i64 = 21008 37const XD_MAGIC_42008: i64 = 42008 38const XD_MAGIC_16777215: i64 = 16777215 39const XD_MAGIC_4278190080: i64 = 4278190080 40const XD_MAGIC_49008: i64 = 49008 41const XD_MAGIC_56008: i64 = 56008 42const XD_MAGIC_63008: i64 = 63008 43const XD_MAGIC_70008: i64 = 70008 44const XD_MAGIC_112008: i64 = 112008 45const XD_MAGIC_112009: i64 = 112009 46const XD_MAGIC_112010: i64 = 112010 47const XD_MAGIC_112011: i64 = 112011 48const XD_MAGIC_112012: i64 = 112012 49const XD_MAGIC_112013: i64 = 112013 50const XD_MAGIC_112014: i64 = 112014 51const XD_MAGIC_112015: i64 = 112015 52const XD_MAGIC_112016: i64 = 112016 53const XD_MAGIC_112017: i64 = 112017 54const XD_MAGIC_112018: i64 = 112018 55const XD_MAGIC_112019: i64 = 112019 56const XD_MAGIC_112052: i64 = 112052 57const XD_MAGIC_112228: i64 = 112228 58const XD_MAGIC_90000: i64 = 90000 59const XD_MAGIC_2880: i64 = 2880 60const XD_MAGIC_2912: i64 = 2912 61const XD_MAGIC_30000: i64 = 30000 62const XD_MAGIC_40000: i64 = 40000 63const XD_MAGIC_4096: i64 = 4096 64const XD_MAGIC_1231: i64 = 1231 65const XD_MAGIC_1403: i64 = 1403 66const XD_MAGIC_1067: i64 = 1067 67const XD_MAGIC_1179: i64 = 1179 68 69const XD_KEY_US: i64 = 125000 // 1/8 s -- the writer's exact-f32 time grid 70const XD_MAXK: i64 = 128 // key cap == the .nxdv wire format's DV_MAXK (16 s at 8 Hz); hitting it is REPORTED, never silent -- 240 here once overran the track region and the viewer refused the blob 71const XD_CIRCLE: i64 = 25736 // it_* integer-trig full circle (2*PI*4096) 72const XD_MDEG2: i64 = 720000 // millidegrees in a full circle, x2 (half-angle divisor) 73const XD_FX12: i64 = 4096 74const XD_NORM_LO: i64 = 3850 // |q|^2/4096 tolerance band 75const XD_NORM_HI: i64 = 4350 76const XD_AXIS_TH: i64 = 50 // 3-axis content threshold (fx12) 77const XD_MOVE_TH: i64 = 100 // motion threshold vs key 0 (fx12) 78const XD_GLBCAP: i64 = 8388608 79const XD_BAND: i64 = 180 // smooth-skin blend band around a joint pivot, model units 80const XD_SKIN: i64 = 11583466 // uniform skin albedo 234 + 192<<8 + 170<<16 81 82// dense being grid -- SAME extents/cell as nx_retarget_emit (the proven export) 83const XD_GX: i64 = 32 84const XD_GY: i64 = 110 85const XD_GZ: i64 = 20 86const XD_GC: i64 = 18 87const XD_OX: i64 = 0-288 88const XD_OY: i64 = 0-990 89const XD_OZ: i64 = 0-180 90const XD_C65536: i64 = 65536 91 92func xd_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 93func xd_num(v: i64) -> i64 { 94 let b: *u8 = sys_mmap(32) 95 var x: i64 = v; var ng: i64 = 0 96 if x < 0 { ng = 1; x = 0-x } 97 var i: i64 = 31 98 if x == 0 { b[i]=48 as u8; i=i-1 } 99 while x > 0 { b[i]=(48+x%10) as u8; x=x/10; i=i-1 } 100 if ng == 1 { b[i]=45 as u8; i=i-1 } 101 sys_write(1,(b as i64+i+1) as *u8,31-i) 102 return 0 103} 104func xd_ru32(buf: *u8, at: i64) -> i64 { return (buf[at] as i64) + ((buf[at+1] as i64)<<8) + ((buf[at+2] as i64)<<16) + ((buf[at+3] as i64)<<24) } 105func xd_hasstr(buf: *u8, n: i64, needle: *u8) -> i64 { var m: i64=0; while needle[m]!=(0 as u8){m=m+1} var i: i64=0; while i+m<=n { var k: i64=0; while k<m { if buf[i+k]!=needle[k] {k=m+9} else {k=k+1} } if k==m {return 1} i=i+1 } return 0 } 106 107// integer floor-sqrt (Newton), for distances and quaternion norms 108func xd_isqrt(n: i64) -> i64 { 109 if n <= 0 { return 0 } 110 var x: i64 = n 111 var y: i64 = (x + 1) / 2 112 var it: i64 = 0 113 while y < x { 114 if it > 64 { y = x } 115 else { x = y; y = (x + n/x) / 2; it = it + 1 } 116 } 117 return x 118} 119 120// joint lookup BY NAME in the parsed skeleton (names = B_NAMEW-strided NUL-terminated rows). -1 = absent. 121func xd_findjoint(names: *u8, nj: i64, want: *u8) -> i64 { 122 var j: i64 = 0 123 while j < nj { 124 let row: *u8 = ((names as i64) + j * B_NAMEW) as *u8 125 var i: i64 = 0 126 var same: i64 = 1 127 var stop: i64 = 0 128 while stop == 0 { 129 if row[i] != want[i] { same = 0; stop = 1 } 130 else { if want[i] == (0 as u8) { stop = 1 } else { i = i + 1 } } 131 } 132 if same == 1 { return j } 133 j = j + 1 134 } 135 return 0 - 1 136} 137 138// axis quaternion from a millidegree angle, fx12 components into o[0..3] (x,y,z,w) 139func xd_qaxis(chcode: i64, mdeg: i64, o: *i64) -> i64 { 140 let half_it: i64 = mdeg * XD_CIRCLE / XD_MDEG2 141 let s: i64 = it_sin4096(half_it) 142 let c: i64 = it_cos4096(half_it) 143 o[0]=0; o[1]=0; o[2]=0; o[3]=c 144 if chcode == B_CH_XROT { o[0]=s } 145 if chcode == B_CH_YROT { o[1]=s } 146 if chcode == B_CH_ZROT { o[2]=s } 147 return 0 148} 149 150// Hamilton product o = a * b, all fx12 151func xd_qmul(a: *i64, b: *i64, o: *i64) -> i64 { 152 let x: i64 = ( a[3]*b[0] + a[0]*b[3] + a[1]*b[2] - a[2]*b[1] ) / XD_FX12 153 let y: i64 = ( a[3]*b[1] - a[0]*b[2] + a[1]*b[3] + a[2]*b[0] ) / XD_FX12 154 let z: i64 = ( a[3]*b[2] + a[0]*b[1] - a[1]*b[0] + a[2]*b[3] ) / XD_FX12 155 let w: i64 = ( a[3]*b[3] - a[0]*b[0] - a[1]*b[1] - a[2]*b[2] ) / XD_FX12 156 o[0]=x; o[1]=y; o[2]=z; o[3]=w 157 return 0 158} 159 160// rotate a vector (any integer units) by an fx12 quaternion: r = q (x) (v,0) (x) conj(q). Unit-preserving. 161func xd_qrotv(q: *i64, vx: i64, vy: i64, vz: i64, o: *i64, s1: *i64, s2: *i64, s3: *i64) -> i64 { 162 s1[0]=vx; s1[1]=vy; s1[2]=vz; s1[3]=0 163 xd_qmul(q, s1, s2) 164 s3[0]=0-q[0]; s3[1]=0-q[1]; s3[2]=0-q[2]; s3[3]=q[3] 165 xd_qmul(s2, s3, s1) 166 o[0]=s1[0]; o[1]=s1[1]; o[2]=s1[2] 167 return 0 168} 169 170// minimal rotation taking rest (0,-1,0) to a NORMALIZED fx12 direction. q_raw = (-dz, 0, dx, 4096-dy), 171// renormalized. Degenerate straight-up dir -> 180deg about X. 172func xd_qfromdir(dx: i64, dy: i64, dz: i64, o: *i64) -> i64 { 173 o[0] = 0 - dz 174 o[1] = 0 175 o[2] = dx 176 o[3] = XD_FX12 - dy 177 let n2: i64 = o[0]*o[0] + o[1]*o[1] + o[2]*o[2] + o[3]*o[3] 178 if n2 < 16 { o[0]=XD_FX12; o[1]=0; o[2]=0; o[3]=0; return 0 } 179 let nn: i64 = xd_isqrt(n2) 180 o[0]=o[0]*XD_FX12/nn; o[1]=o[1]*XD_FX12/nn; o[2]=o[2]*XD_FX12/nn; o[3]=o[3]*XD_FX12/nn 181 return 0 182} 183 184// compose one joint's local rotation at one frame from its channels IN FILE ORDER -> fx12 quat in q 185func xd_joint_quat(fv: *i64, chan0j: i64, nchanj: i64, chtype: *i64, q: *i64, qa: *i64, qt: *i64) -> i64 { 186 q[0]=0; q[1]=0; q[2]=0; q[3]=XD_FX12 187 var c: i64 = 0 188 while c < nchanj { 189 let ci: i64 = chan0j + c 190 let t: i64 = chtype[ci] 191 var isrot: i64 = 0 192 if t == B_CH_XROT { isrot = 1 } 193 if t == B_CH_YROT { isrot = 1 } 194 if t == B_CH_ZROT { isrot = 1 } 195 if isrot == 1 { 196 xd_qaxis(t, fv[ci], qa) 197 xd_qmul(q, qa, qt) 198 q[0]=qt[0]; q[1]=qt[1]; q[2]=qt[2]; q[3]=qt[3] 199 } 200 c = c + 1 201 } 202 return 0 203} 204 205// ===== KAT ===== 206func xd_cat(b: *u8, o: i64, s: *u8) -> i64 { let n: i64 = b_slen(s); var i: i64 = 0; while i < n { b[o+i]=s[i]; i=i+1 } return o+n } 207func xd_kat() -> i64 { 208 var red: i64 = 0 209 // T1: axis-quat exact value -- Zrot 90000 mdeg -> half 45 deg -> sin=cos=2896 fx12 210 let qa: *i64 = sys_mmap(32) as *i64 211 xd_qaxis(B_CH_ZROT, XD_MAGIC_90000, qa) 212 xd_w("T1 qaxis Z90: qz=" as *u8); xd_num(qa[2]); xd_w(" qw=" as *u8); xd_num(qa[3]) 213 var t1: i64 = 0 214 if qa[2] > XD_MAGIC_2880 { if qa[2] < XD_MAGIC_2912 { if qa[3] > XD_MAGIC_2880 { if qa[3] < XD_MAGIC_2912 { if qa[0] == 0 { if qa[1] == 0 { t1 = 1 } } } } } } 215 if t1 == 1 { xd_w(" GREEN\n" as *u8) } else { xd_w(" RED\n" as *u8); red = red + 1 } 216 // T2: identity * q == q (qmul sanity) 217 let qi: *i64 = sys_mmap(32) as *i64 218 let qo: *i64 = sys_mmap(32) as *i64 219 qi[0]=0; qi[1]=0; qi[2]=0; qi[3]=XD_FX12 220 xd_qmul(qi, qa, qo) 221 var t2: i64 = 0 222 if qo[2] == qa[2] { if qo[3] == qa[3] { t2 = 1 } } 223 if t2 == 1 { xd_w("T2 GREEN qmul-identity\n" as *u8) } else { xd_w("T2 RED qmul-identity\n" as *u8); red = red + 1 } 224 // T3: norm preserved through a 3-rotation composition 225 let qb: *i64 = sys_mmap(32) as *i64 226 let qc: *i64 = sys_mmap(32) as *i64 227 xd_qaxis(B_CH_ZROT, XD_MAGIC_30000, qb) 228 xd_qmul(qa, qb, qc) 229 xd_qaxis(B_CH_XROT, XD_MAGIC_40000, qb) 230 xd_qmul(qc, qb, qo) 231 let n2: i64 = (qo[0]*qo[0] + qo[1]*qo[1] + qo[2]*qo[2] + qo[3]*qo[3]) / XD_FX12 232 xd_w("T3 norm2/4096=" as *u8); xd_num(n2) 233 var t3: i64 = 0 234 if n2 > XD_NORM_LO { if n2 < XD_NORM_HI { t3 = 1 } } 235 if t3 == 1 { xd_w(" GREEN\n" as *u8) } else { xd_w(" RED\n" as *u8); red = red + 1 } 236 // T4 neg-control-missing-joint: a 2-joint fixture WITHOUT the required names must map to -1 237 let fb: *u8 = sys_mmap(XD_MAGIC_4096) 238 var o: i64 = 0 239 o = xd_cat(fb, o, "HIERARCHY\nROOT Hips\n{\nOFFSET 0.0 0.0 0.0\nCHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation\nJOINT Chest\n{\nOFFSET 0.0 5.0 0.0\nCHANNELS 3 Zrotation Xrotation Yrotation\nEnd Site\n{\nOFFSET 0.0 5.0 0.0\n}\n}\n}\nMOTION\nFrames: 1\nFrame Time: 0.033333\n0.0 10.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0\n" as *u8) 240 fb[o] = 0 as u8 241 let H: *i64 = sys_mmap(B_H_WORDS * 8) as *i64 242 let names: *u8 = sys_mmap(B_MAX_JOINTS * B_NAMEW) 243 let parent: *i64 = sys_mmap(B_MAX_JOINTS * 8) as *i64 244 let nchan: *i64 = sys_mmap(B_MAX_JOINTS * 8) as *i64 245 let chan0: *i64 = sys_mmap(B_MAX_JOINTS * 8) as *i64 246 let joff: *i64 = sys_mmap(B_MAX_JOINTS * 24) as *i64 247 let chtype: *i64 = sys_mmap(B_MAX_CHAN * 8) as *i64 248 let pr: i64 = b_parse(fb, o, H, names, parent, nchan, chan0, joff, chtype) 249 var t4: i64 = 0 250 if pr == 0 { 251 let wantL: *u8 = "LeftShoulder" as *u8 252 if xd_findjoint(names, H[B_H_NJOINT], wantL) == 0 - 1 { t4 = 1 } 253 } 254 if t4 == 1 { xd_w("T4 GREEN neg-control-missing-joint maps to -1 (caller REFUSES)\n" as *u8) } else { xd_w("T4 RED neg-control\n" as *u8); red = red + 1 } 255 // T5: findjoint positive control on the same fixture 256 let wantH: *u8 = "Chest" as *u8 257 if xd_findjoint(names, H[B_H_NJOINT], wantH) == 1 { xd_w("T5 GREEN findjoint positive (Chest=1)\n" as *u8) } else { xd_w("T5 RED findjoint\n" as *u8); red = red + 1 } 258 // T6: qfromdir on straight-down rest dir -> identity rotation 259 xd_qfromdir(0, 0-XD_FX12, 0, qo) 260 var t6: i64 = 0 261 if qo[0] == 0 { if qo[1] == 0 { if qo[2] == 0 { if qo[3] == XD_FX12 { t6 = 1 } } } } 262 if t6 == 1 { xd_w("T6 GREEN qfromdir(down)=identity\n" as *u8) } else { xd_w("T6 RED qfromdir(down): " as *u8); xd_num(qo[0]); xd_w(","as *u8); xd_num(qo[3]); xd_w("\n" as *u8); red = red + 1 } 263 // T7: qfromdir(+X) rotates rest(-Y) onto +X (round-trip through xd_qrotv) 264 xd_qfromdir(XD_FX12, 0, 0, qo) 265 let s1: *i64 = sys_mmap(32) as *i64 266 let s2: *i64 = sys_mmap(32) as *i64 267 let s3: *i64 = sys_mmap(32) as *i64 268 let rv: *i64 = sys_mmap(32) as *i64 269 xd_qrotv(qo, 0, 0-XD_FX12, 0, rv, s1, s2, s3) 270 xd_w("T7 qrotv(rest by qfromdir(+X)) = " as *u8); xd_num(rv[0]); xd_w(","as *u8); xd_num(rv[1]); xd_w(","as *u8); xd_num(rv[2]) 271 var t7: i64 = 0 272 if rv[0] > XD_MAGIC_3900 { if rv[1] > 0-300 { if rv[1] < 300 { if rv[2] > 0-300 { if rv[2] < 300 { t7 = 1 } } } } } 273 if t7 == 1 { xd_w(" GREEN\n" as *u8) } else { xd_w(" RED\n" as *u8); red = red + 1 } 274 if red > 0 { xd_w("nx_dance_emit KAT RED teeth_failed=" as *u8); xd_num(red); xd_w("\n" as *u8); return 1 } 275 xd_w("nx_dance_emit KAT GREEN 7/7\n" as *u8) 276 return 0 277} 278 279// minimal rotation taking unit vector a to unit vector b (both fx12). Output q fx12. Antiparallel 280// falls back to 180deg about a deterministic perpendicular of a (smallest-component axis). 281func xd_qfromto(ax: i64, ay: i64, az: i64, bx: i64, by: i64, bz: i64, qo: *i64) -> i64 { 282 let cx: i64 = (ay*bz - az*by)/XD_FX12 283 let cy: i64 = (az*bx - ax*bz)/XD_FX12 284 let cz: i64 = (ax*by - ay*bx)/XD_FX12 285 var w: i64 = XD_FX12 + (ax*bx + ay*by + az*bz)/XD_FX12 286 if w < 41 { 287 var px: i64 = 0 - az 288 var py: i64 = 0 289 var pz: i64 = ax 290 var aax: i64 = ax 291 if aax < 0 { aax = 0 - aax } 292 var aay: i64 = ay 293 if aay < 0 { aay = 0 - aay } 294 var aaz: i64 = az 295 if aaz < 0 { aaz = 0 - aaz } 296 if aax <= aay { if aax <= aaz { px = 0; py = 0 - az; pz = ay } } 297 let pn: i64 = xd_isqrt(px*px + py*py + pz*pz) 298 if pn < 1 { qo[0]=0; qo[1]=0; qo[2]=0; qo[3]=XD_FX12; return 0 } 299 qo[0]=px*XD_FX12/pn; qo[1]=py*XD_FX12/pn; qo[2]=pz*XD_FX12/pn; qo[3]=0 300 return 0 301 } 302 let n: i64 = xd_isqrt(cx*cx + cy*cy + cz*cz + w*w) 303 if n < 1 { qo[0]=0; qo[1]=0; qo[2]=0; qo[3]=XD_FX12; return 0 } 304 qo[0]=cx*XD_FX12/n; qo[1]=cy*XD_FX12/n; qo[2]=cz*XD_FX12/n; qo[3]=w*XD_FX12/n 305 return 0 306} 307// bind segment dir joint(cj) minus joint(pj), fx12-normalized, NXA frame. SKEL row = 8 words 308// [parent, x, y, z, ...] at word sow+1+j*8 (the ntx_apply-verified layout). 309func xd_nxa_seg(W: *i64, sow: i64, cj: i64, pj: i64, o: *i64) -> i64 { 310 let ax: i64 = W[sow+1+cj*8+1] - W[sow+1+pj*8+1] 311 let ay: i64 = W[sow+1+cj*8+2] - W[sow+1+pj*8+2] 312 let az: i64 = W[sow+1+cj*8+3] - W[sow+1+pj*8+3] 313 var n: i64 = xd_isqrt(ax*ax + ay*ay + az*az) 314 if n < 1 { n = 1 } 315 o[0] = ax*XD_FX12/n 316 o[1] = ay*XD_FX12/n 317 o[2] = az*XD_FX12/n 318 return 0 319} 320// ---- M1 ADOPTION: retargeted mocap -> chn-2 ANIM section spliced into the RIGGED NXA body ---- 321// dtrk = 8 limb-segment WORLD dirs per key (fx12, dance frame: X lateral with mocap-left already 322// mirrored to -X, Y up, Z fwd). NXA frame is X lateral / Y BACK (chest DYNA at -y) / Z up, so 323// dance->NXA = (x, -z, y). Wire (decoded from the game player, the working consumer): chn==2, 324// 16B/key LE = u16 t_ms, i16 q[4] (WORLD rotation; scale free -- the player nlerp-normalizes; 325// we pack fx12), i16 d[3] = 0 (in-place BY THE LANE'S DESIGN: the FK zeroes root translation, 326// the organ owns where she is). Wrists carry the forearm D and ankles the shin D (hand/foot 327// continue their parent segment; the player's own hand-collapse + ankle fix ride on top). 328// 12 tracks; every untracked joint holds bind pose, which is correct stillness not a gap. 329// Role resolution is MEASURED-data-driven (probe 2026-08-12): fingertip = argmax side.x; wrist = 330// first ancestor whose parent-segment exceeds 15cm (forearm; finger segments are 2-4cm); elbow/ 331// shoulder = its ancestors (this also dodges the twist-helper duplicates, which are SIBLINGS not 332// ancestors); ankle = the unique off-midline joint in the shank band with its parent above the 333// knee line; knee/hip = its ancestors. Every chain is ordering-asserted; ambiguity REFUSES. 334// DECLARED ASSUMPTION (eye-verify on first render): mocap-left maps to the NXA -x side. 335func xd_nxa_apply(inp: *u8, outp: *u8, dtrk: *i64, nk: i64, keyus: i64, ttrk: *i64, atrk: *i64) -> i64 { 336 let lp: *i64 = sys_mmap(16) as *i64 337 let b: *u8 = sys_read_file(inp, lp) 338 if (b as i64) == 0 { xd_w("NXA-ANIM REFUSED: cannot read input NXA\n" as *u8); return 4 } 339 let flen: i64 = lp[0] 340 let W: *i64 = b as *i64 341 let sow: i64 = nxa_find(b, flen, nxa_tag4("SKEL" as *u8)) 342 if sow < 1 { xd_w("NXA-ANIM REFUSED: SKEL missing or corrupt\n" as *u8); return 4 } 343 let ns: i64 = W[2] 344 if ns > 62 { xd_w("NXA-ANIM REFUSED: section table full\n" as *u8); return 4 } 345 let nj: i64 = W[sow] 346 if nj < 12 { xd_w("NXA-ANIM REFUSED: too few joints\n" as *u8); return 4 } 347 var zmn: i64 = W[sow+1+3] 348 var jz: i64 = 0 349 while jz < nj { 350 if W[sow+1+jz*8+3] < zmn { zmn = W[sow+1+jz*8+3] } 351 jz = jz + 1 352 } 353 let R: *i64 = sys_mmap(16*8) as *i64 354 var sdi: i64 = 0 355 while sdi < 2 { 356 var sgn: i64 = 1 357 if sdi == 1 { sgn = 0 - 1 } 358 var ft: i64 = 0 - 1 359 var ftx: i64 = 0 360 var j2: i64 = 0 361 while j2 < nj { 362 let xv: i64 = W[sow+1+j2*8+1]*sgn 363 if xv > ftx { ftx = xv; ft = j2 } 364 j2 = j2 + 1 365 } 366 if ft < 0 { xd_w("NXA-ANIM REFUSED: no joints on one side\n" as *u8); return 4 } 367 var wr: i64 = 0 - 1 368 var cu: i64 = ft 369 var guard: i64 = 0 370 while guard < 64 { 371 let pj: i64 = W[sow+1+cu*8] 372 if pj < 0 { guard = 64 } else { 373 let dx: i64 = W[sow+1+cu*8+1] - W[sow+1+pj*8+1] 374 let dy: i64 = W[sow+1+cu*8+2] - W[sow+1+pj*8+2] 375 let dz: i64 = W[sow+1+cu*8+3] - W[sow+1+pj*8+3] 376 if dx*dx + dy*dy + dz*dz > XD_MAGIC_225000000 { wr = cu; guard = 64 } else { cu = pj; guard = guard + 1 } 377 } 378 } 379 if wr < 1 { xd_w("NXA-ANIM REFUSED: wrist not found (no 15cm segment above the fingertip)\n" as *u8); return 4 } 380 let el: i64 = W[sow+1+wr*8] 381 if el < 0 { xd_w("NXA-ANIM REFUSED: wrist has no parent\n" as *u8); return 4 } 382 let sh: i64 = W[sow+1+el*8] 383 if sh < 0 { xd_w("NXA-ANIM REFUSED: elbow has no parent\n" as *u8); return 4 } 384 var an: i64 = 0 - 1 385 var anc: i64 = 0 386 var j3: i64 = 0 387 while j3 < nj { 388 let xr: i64 = W[sow+1+j3*8+1]*sgn 389 let zr: i64 = W[sow+1+j3*8+3] - zmn 390 let pj3: i64 = W[sow+1+j3*8] 391 if xr > XD_MAGIC_4000 { if zr > XD_MAGIC_8000 { if zr < XD_MAGIC_30000 { if pj3 >= 0 { 392 if W[sow+1+pj3*8+3] - zmn > XD_MAGIC_40000 { an = j3; anc = anc + 1 } 393 } } } } 394 j3 = j3 + 1 395 } 396 if anc != 1 { xd_w("NXA-ANIM REFUSED: ankle ambiguous count=" as *u8); xd_num(anc); xd_w("\n" as *u8); return 4 } 397 let kn: i64 = W[sow+1+an*8] 398 let hp: i64 = W[sow+1+kn*8] 399 if hp < 0 { xd_w("NXA-ANIM REFUSED: knee has no parent\n" as *u8); return 4 } 400 if W[sow+1+sh*8+3] <= W[sow+1+el*8+3] { xd_w("NXA-ANIM REFUSED: arm chain z-order wrong\n" as *u8); return 4 } 401 if W[sow+1+el*8+3] <= W[sow+1+wr*8+3] { xd_w("NXA-ANIM REFUSED: forearm z-order wrong\n" as *u8); return 4 } 402 if W[sow+1+hp*8+3] <= W[sow+1+kn*8+3] { xd_w("NXA-ANIM REFUSED: leg chain z-order wrong\n" as *u8); return 4 } 403 R[sdi*6]=sh; R[sdi*6+1]=el; R[sdi*6+2]=wr; R[sdi*6+3]=hp; R[sdi*6+4]=kn; R[sdi*6+5]=an 404 sdi = sdi + 1 405 } 406 xd_w("NXA-ANIM roles +x sh/el/wr/hp/kn/an=" as *u8) 407 xd_num(R[0]); xd_w("/" as *u8); xd_num(R[1]); xd_w("/" as *u8); xd_num(R[2]); xd_w("/" as *u8) 408 xd_num(R[3]); xd_w("/" as *u8); xd_num(R[4]); xd_w("/" as *u8); xd_num(R[5]) 409 xd_w(" -x=" as *u8) 410 xd_num(R[6]); xd_w("/" as *u8); xd_num(R[7]); xd_w("/" as *u8); xd_num(R[8]); xd_w("/" as *u8) 411 xd_num(R[9]); xd_w("/" as *u8); xd_num(R[10]); xd_w("/" as *u8); xd_num(R[11]); xd_w("\n" as *u8) 412 // ---- ZOMBIE-ARMS FIX (operator RED 2026-08-12, "crazy arms"): the player has NO runtime 413 // hierarchy, and its OWN load comment documents this exact class -- "forearms pinned at T-pose 414 // pivots because their world displacement was dropped at apply time". The first emit set d=0 on 415 // every track and reproduced it verbatim. Each chain therefore PROPAGATES its pivots: the mid 416 // joint rides the rotated upper segment about the proximal pivot, the distal joint rides the 417 // rotated lower segment about the MOVED mid pivot; the dt lanes carry pivot_new - pivot_bind 418 // (stored /100: binds are 0.01mm units, the wire is integer mm, the player multiplies x100). 419 // Per chain: proximal track = upper D, dt 0 (its pivot rides the untracked torso/pelvis = bind); 420 // mid + distal tracks = lower D with propagated dt. dance bones: 1 L-upper 2 L-fore 3 R-upper 421 // 4 R-fore 5 L-thigh 6 L-shin 7 R-thigh 8 R-shin; mocap-left rides -x roles, mocap-right +x. 422 // ---- SUBTREE-COMPLETE TRACKS (operator RED #2, "still a mess", 2026-08-12): the rig weights 423 // flesh to TWIST HELPERS (mid-upper-arm 75, elbow twists 55/57, forearm twist chains, mid-thigh 424 // 20, mid-shin 17...) -- the estate's own 07-29 note names the result of leaving them behind: 425 // "ribbon forearms". Three role tracks per limb can NEVER drive this rig; EVERY joint in each 426 // limb subtree must ride its segment rigidly. Lane by ancestor walk: in subtree(elbow/knee) -> 427 // LOWER lane (forearm/shin D about the MOVED mid pivot); else in subtree(shoulder/hip) -> UPPER 428 // lane (thigh/upper-arm D about the proximal pivot). One uniform row per joint g: 429 // dt_g = pivotNew + rot(qLane, b_g - laneBindBase) - b_g, so fingers, toes and every helper 430 // land exactly where their segment carries them (the player's hand-collapse then agrees). 431 let CU: *i64 = sys_mmap(4*8) as *i64 432 let CL: *i64 = sys_mmap(4*8) as *i64 433 let CP: *i64 = sys_mmap(4*8) as *i64 434 let CM: *i64 = sys_mmap(4*8) as *i64 435 CU[0]=1; CL[0]=2; CP[0]=R[6]; CM[0]=R[7] 436 CU[1]=3; CL[1]=4; CP[1]=R[0]; CM[1]=R[1] 437 CU[2]=5; CL[2]=6; CP[2]=R[9]; CM[2]=R[10] 438 CU[3]=7; CL[3]=8; CP[3]=R[3]; CM[3]=R[4] 439 let LN: *i64 = sys_mmap(nj*8 + 64) as *i64 440 var lg: i64 = 0 441 while lg < nj { 442 LN[lg] = 0 - 1 443 var c2: i64 = 0 444 while c2 < 4 { 445 var cu2: i64 = lg 446 var gd: i64 = 0 447 var lane: i64 = 0 - 1 448 while gd < 64 { 449 if cu2 == CM[c2] { lane = c2*2 + 1; gd = 64 } 450 else { if cu2 == CP[c2] { lane = c2*2; gd = 64 } 451 else { cu2 = W[sow+1+cu2*8] 452 if cu2 < 0 { gd = 64 } else { gd = gd + 1 } } } 453 } 454 if lane >= 0 { LN[lg] = lane; c2 = 4 } else { c2 = c2 + 1 } 455 } 456 lg = lg + 1 457 } 458 // ---- M1-TORSO (debt 1786598036): the torso is TRACKED, not bind-held. qT per key = minimal 459 // rotation from the NXA's OWN bind spine (hip-centre -> shoulder-centre) to the captured, 460 // de-yawed mocap spine. LEAN-ONLY v1: shoulder-axis twist deliberately deferred (declared). 461 let hcx: i64 = (W[sow+1+R[3]*8+1] + W[sow+1+R[9]*8+1])/2 462 let hcy: i64 = (W[sow+1+R[3]*8+2] + W[sow+1+R[9]*8+2])/2 463 let hcz: i64 = (W[sow+1+R[3]*8+3] + W[sow+1+R[9]*8+3])/2 464 var tdx: i64 = (W[sow+1+R[0]*8+1] + W[sow+1+R[6]*8+1])/2 - hcx 465 var tdy: i64 = (W[sow+1+R[0]*8+2] + W[sow+1+R[6]*8+2])/2 - hcy 466 var tdz: i64 = (W[sow+1+R[0]*8+3] + W[sow+1+R[6]*8+3])/2 - hcz 467 var tdn: i64 = xd_isqrt(tdx*tdx + tdy*tdy + tdz*tdz) 468 if tdn < 1 { tdn = 1 } 469 tdx = tdx*XD_FX12/tdn 470 tdy = tdy*XD_FX12/tdn 471 tdz = tdz*XD_FX12/tdn 472 // NXA bind shoulder axis (-x-side shoulder minus +x-side: mocap-left rides -x roles) 473 var bax: i64 = W[sow+1+R[6]*8+1] - W[sow+1+R[0]*8+1] 474 var bay: i64 = W[sow+1+R[6]*8+2] - W[sow+1+R[0]*8+2] 475 var baz: i64 = W[sow+1+R[6]*8+3] - W[sow+1+R[0]*8+3] 476 var ban: i64 = xd_isqrt(bax*bax + bay*bay + baz*baz) 477 if ban < 1 { ban = 1 } 478 bax = bax*XD_FX12/ban 479 bay = bay*XD_FX12/ban 480 baz = baz*XD_FX12/ban 481 // TWO-VECTOR chest frame per key: q1 aligns the spine (LEAN), q2 then aligns the shoulder 482 // axis (TWIST -- its residual axis ~ the leaned spine, second-order error only); qT = q2*q1. 483 // The twist is what gives a crossing arm its forward clearance (probe-proven at key 78). 484 let qTc: *i64 = sys_mmap(nk*4*8 + 64) as *i64 485 let q1T: *i64 = sys_mmap(32) as *i64 486 let q2T: *i64 = sys_mmap(32) as *i64 487 let rvT: *i64 = sys_mmap(32) as *i64 488 let s1T: *i64 = sys_mmap(32) as *i64 489 let s2T: *i64 = sys_mmap(32) as *i64 490 let s3T: *i64 = sys_mmap(32) as *i64 491 var kT: i64 = 0 492 while kT < nk { 493 xd_qfromto(tdx, tdy, tdz, ttrk[kT*6], 0 - ttrk[kT*6+2], ttrk[kT*6+1], q1T) 494 xd_qrotv(q1T, bax, bay, baz, rvT, s1T, s2T, s3T) 495 xd_qfromto(rvT[0], rvT[1], rvT[2], ttrk[kT*6+3], 0 - ttrk[kT*6+5], ttrk[kT*6+4], q2T) 496 xd_qmul(q2T, q1T, ((qTc as i64) + kT*32) as *i64) 497 kT = kT + 1 498 } 499 let TF: *i64 = sys_mmap(nj*8 + 64) as *i64 500 var tf2: i64 = 0 501 while tf2 < nj { 502 TF[tf2] = 0 503 if LN[tf2] < 0 { if W[sow+1+tf2*8+3] >= hcz { TF[tf2] = 1 } } 504 tf2 = tf2 + 1 505 } 506 var ntr: i64 = 0 507 var ntor: i64 = 0 508 var g2: i64 = 0 509 while g2 < nj { 510 if LN[g2] >= 0 { ntr = ntr + 1 } else { if TF[g2] == 1 { ntr = ntr + 1; ntor = ntor + 1 } } 511 g2 = g2 + 1 512 } 513 xd_w("NXA-ANIM subtree tracks=" as *u8); xd_num(ntr); xd_w(" of " as *u8); xd_num(nj) 514 xd_w(" joints (torso tracked=" as *u8); xd_num(ntor); xd_w(")\n" as *u8) 515 // per-chain per-key quats + moved mid pivots, precomputed once 516 let sdU: *i64 = sys_mmap(32) as *i64 517 let sdL: *i64 = sys_mmap(32) as *i64 518 let rv2: *i64 = sys_mmap(32) as *i64 519 let t1: *i64 = sys_mmap(32) as *i64 520 let t2: *i64 = sys_mmap(32) as *i64 521 let t3: *i64 = sys_mmap(32) as *i64 522 let qUc: *i64 = sys_mmap(4*nk*4*8) as *i64 523 let qLc: *i64 = sys_mmap(4*nk*4*8) as *i64 524 let mNc: *i64 = sys_mmap(4*nk*3*8) as *i64 525 let pPc: *i64 = sys_mmap(4*nk*3*8 + 64) as *i64 // per-chain per-key PROXIMAL pivot (torso-rebased for arms) 526 var ikfb9: i64 = 0 // M1-ARM-IK: keys that fell back to the direction lane 527 var ch: i64 = 0 528 while ch < 4 { 529 let jP: i64 = CP[ch] 530 let jM: i64 = CM[ch] 531 // lower-lane bind dir needs the distal role: reuse the resolver's R rows (wr/an sit at +2/+5) 532 var jD: i64 = 0 533 if ch == 0 { jD = R[8] } 534 if ch == 1 { jD = R[2] } 535 if ch == 2 { jD = R[11] } 536 if ch == 3 { jD = R[5] } 537 xd_nxa_seg(W, sow, jM, jP, sdU) 538 xd_nxa_seg(W, sow, jD, jM, sdL) 539 // M1-ARM-IK: OUR bind segment lengths (W units) for the two-bone solve 540 let uax9: i64 = W[sow+1+jM*8+1] - W[sow+1+jP*8+1] 541 let uay9: i64 = W[sow+1+jM*8+2] - W[sow+1+jP*8+2] 542 let uaz9: i64 = W[sow+1+jM*8+3] - W[sow+1+jP*8+3] 543 var aU9: i64 = xd_isqrt(uax9*uax9 + uay9*uay9 + uaz9*uaz9) 544 if aU9 < 1 { aU9 = 1 } 545 let lbx9: i64 = W[sow+1+jD*8+1] - W[sow+1+jM*8+1] 546 let lby9: i64 = W[sow+1+jD*8+2] - W[sow+1+jM*8+2] 547 let lbz9: i64 = W[sow+1+jD*8+3] - W[sow+1+jM*8+3] 548 var bL9: i64 = xd_isqrt(lbx9*lbx9 + lby9*lby9 + lbz9*lbz9) 549 if bL9 < 1 { bL9 = 1 } 550 var k4: i64 = 0 551 while k4 < nk { 552 let dbU: i64 = ((CU[ch]-1)*nk + k4)*3 553 let dbL: i64 = ((CL[ch]-1)*nk + k4)*3 554 let qb: i64 = (ch*nk + k4)*4 555 // pivot FIRST (moved above the IK, which needs it): ARM chains (0,1) ride the TRACKED 556 // torso -- the clearance mechanism; LEG chains keep the bind pivot (pelvis residual 557 // ~ identity post-de-yaw) 558 var bpx9: i64 = W[sow+1+jP*8+1] 559 var bpy9: i64 = W[sow+1+jP*8+2] 560 var bpz9: i64 = W[sow+1+jP*8+3] 561 if ch < 2 { 562 xd_qrotv(((qTc as i64) + k4*32) as *i64, bpx9 - hcx, bpy9 - hcy, bpz9 - hcz, rv2, t1, t2, t3) 563 bpx9 = hcx + rv2[0] 564 bpy9 = hcy + rv2[1] 565 bpz9 = hcz + rv2[2] 566 } 567 var ikok: i64 = 0 568 if ch < 2 { 569 // M1-ARM-IK v2 (debt 1786598036): shoulder-relative retarget CANNOT preserve torso 570 // clearance when the shoulder-to-axis distance differs between bodies (measured at 571 // the worst key: source wrist 201mm from its axis; the shoulder-relative solve put 572 // ours at 40mm, no better than direction-copy). So the wrist is retargeted in the 573 // TORSO frame: offset from the HIP CENTRE, scaled by the spine-length ratio 574 // (tdn/sn9 -- the same stature-class bridge the clipcheck ruler uses), then a 575 // two-bone solve from OUR tracked shoulder pivot with the mocap bend-plane hint. 576 // Axis clearance is inherited from the data BY CONSTRUCTION; arm shape adapts. 577 // dance->NXA map (x,-z,y) on the RAW atrk offsets, matching the dtrk convention. 578 let ab8: i64 = k4*20 + 1 + ch*9 579 let sn8: i64 = atrk[k4*20] 580 // slots ab8+0..2 = the mocap SHOULDER hip-offset (banked for the future twist lane) 581 let emx: i64 = atrk[ab8+3] 582 let emy: i64 = 0 - atrk[ab8+5] 583 let emz: i64 = atrk[ab8+4] 584 let wmx: i64 = atrk[ab8+6] 585 let wmy: i64 = 0 - atrk[ab8+8] 586 let wmz: i64 = atrk[ab8+7] 587 if sn8 > 0 { 588 let sc9: i64 = tdn*XD_FX12/sn8 589 let twx: i64 = hcx + wmx*sc9/XD_FX12 590 let twy: i64 = hcy + wmy*sc9/XD_FX12 591 let twz: i64 = hcz + wmz*sc9/XD_FX12 592 let cx9: i64 = twx - bpx9 593 let cy9: i64 = twy - bpy9 594 let cz9: i64 = twz - bpz9 595 var cn9: i64 = xd_isqrt(cx9*cx9 + cy9*cy9 + cz9*cz9) 596 if cn9 < 1 { cn9 = 1 } 597 let lr9: i64 = aU9 + bL9 598 var dmin9: i64 = aU9 - bL9 599 if dmin9 < 0 { dmin9 = 0 - dmin9 } 600 dmin9 = dmin9 + 1 601 var d9: i64 = cn9 602 if d9 < dmin9 { d9 = dmin9 } 603 if d9 > lr9 - 1 { d9 = lr9 - 1 } 604 let ux9: i64 = cx9*XD_FX12/cn9 605 let uy9: i64 = cy9*XD_FX12/cn9 606 let uz9: i64 = cz9*XD_FX12/cn9 607 // bend hint v2b: OUR pivot -> the SCALED mocap elbow position (hip frame). Its 608 // perp about OUR chord steers the elbow toward the mocap elbow's ABSOLUTE 609 // torso-frame position (clean in the source), not merely its bend plane -- 610 // measured: plane-only left the elbow at 68mm from the axis (worst 71mm). 611 // (x64 scale keeps angular resolution in integers) 612 let hbx: i64 = hcx + emx*sc9/XD_FX12 - bpx9 613 let hby: i64 = hcy + emy*sc9/XD_FX12 - bpy9 614 let hbz: i64 = hcz + emz*sc9/XD_FX12 - bpz9 615 let hdu: i64 = (hbx*ux9 + hby*uy9 + hbz*uz9)/XD_FX12 616 let px9: i64 = hbx*64 - hdu*ux9/64 617 let py9: i64 = hby*64 - hdu*uy9/64 618 let pz9: i64 = hbz*64 - hdu*uz9/64 619 let pn9: i64 = xd_isqrt(px9*px9 + py9*py9 + pz9*pz9) 620 var x9: i64 = (aU9*aU9 - bL9*bL9 + d9*d9)/(2*d9) 621 if x9 > aU9 { x9 = aU9 } 622 if x9 < 0 - bL9 { x9 = 0 - bL9 } 623 var y29: i64 = aU9*aU9 - x9*x9 624 if y29 < 0 { y29 = 0 } 625 var y9: i64 = xd_isqrt(y29) 626 if pn9 < 1 { y9 = 0 } 627 var ex9: i64 = ux9*x9/XD_FX12 628 var ey9: i64 = uy9*x9/XD_FX12 629 var ez9: i64 = uz9*x9/XD_FX12 630 if y9 > 0 { 631 ex9 = ex9 + px9*y9/pn9 632 ey9 = ey9 + py9*y9/pn9 633 ez9 = ez9 + pz9*y9/pn9 634 } 635 let tx9: i64 = ux9*d9/XD_FX12 636 let ty9: i64 = uy9*d9/XD_FX12 637 let tz9: i64 = uz9*d9/XD_FX12 638 var en9: i64 = xd_isqrt(ex9*ex9 + ey9*ey9 + ez9*ez9) 639 if en9 < 1 { en9 = 1 } 640 var fx9: i64 = tx9 - ex9 641 var fy9: i64 = ty9 - ey9 642 var fz9: i64 = tz9 - ez9 643 var fn9: i64 = xd_isqrt(fx9*fx9 + fy9*fy9 + fz9*fz9) 644 if fn9 < 1 { fn9 = 1 } 645 xd_qfromto(sdU[0], sdU[1], sdU[2], ex9*XD_FX12/en9, ey9*XD_FX12/en9, ez9*XD_FX12/en9, ((qUc as i64) + qb*8) as *i64) 646 xd_qfromto(sdL[0], sdL[1], sdL[2], fx9*XD_FX12/fn9, fy9*XD_FX12/fn9, fz9*XD_FX12/fn9, ((qLc as i64) + qb*8) as *i64) 647 ikok = 1 648 } 649 if ikok == 0 { ikfb9 = ikfb9 + 1 } 650 } 651 if ikok == 0 { 652 xd_qfromto(sdU[0], sdU[1], sdU[2], dtrk[dbU], 0 - dtrk[dbU+2], dtrk[dbU+1], ((qUc as i64) + qb*8) as *i64) 653 xd_qfromto(sdL[0], sdL[1], sdL[2], dtrk[dbL], 0 - dtrk[dbL+2], dtrk[dbL+1], ((qLc as i64) + qb*8) as *i64) 654 } 655 let pb8: i64 = (ch*nk + k4)*3 656 pPc[pb8] = bpx9 657 pPc[pb8+1] = bpy9 658 pPc[pb8+2] = bpz9 659 xd_qrotv(((qUc as i64) + qb*8) as *i64, W[sow+1+jM*8+1] - W[sow+1+jP*8+1], W[sow+1+jM*8+2] - W[sow+1+jP*8+2], W[sow+1+jM*8+3] - W[sow+1+jP*8+3], rv2, t1, t2, t3) 660 let mb: i64 = (ch*nk + k4)*3 661 mNc[mb] = bpx9 + rv2[0] 662 mNc[mb+1] = bpy9 + rv2[1] 663 mNc[mb+2] = bpz9 + rv2[2] 664 k4 = k4 + 1 665 } 666 ch = ch + 1 667 } 668 xd_w("NXA-ANIM arm-ik keys=" as *u8); xd_num(nk*2 - ikfb9) 669 xd_w(" fallback=" as *u8); xd_num(ikfb9); xd_w("\n" as *u8) 670 let kw: i64 = nk*2 671 let aw: i64 = 1 + ntr*(3 + kw) 672 let AP: *i64 = sys_mmap(aw*8 + 64) as *i64 673 AP[0] = ntr 674 var ap: i64 = 1 675 var tg: i64 = 0 676 while tg < nj { 677 if LN[tg] >= 0 { 678 let c3: i64 = LN[tg]/2 679 let low: i64 = LN[tg] - (LN[tg]/2)*2 680 AP[ap] = tg 681 AP[ap+1] = 2 682 AP[ap+2] = nk 683 ap = ap + 3 684 let bgx: i64 = W[sow+1+tg*8+1] 685 let bgy: i64 = W[sow+1+tg*8+2] 686 let bgz: i64 = W[sow+1+tg*8+3] 687 var basej: i64 = CP[c3] 688 if low == 1 { basej = CM[c3] } 689 let bbx: i64 = W[sow+1+basej*8+1] 690 let bby: i64 = W[sow+1+basej*8+2] 691 let bbz: i64 = W[sow+1+basej*8+3] 692 var k5: i64 = 0 693 while k5 < nk { 694 let qb2: i64 = (c3*nk + k5)*4 695 var qq: *i64 = ((qUc as i64) + qb2*8) as *i64 696 if low == 1 { qq = ((qLc as i64) + qb2*8) as *i64 } 697 let pb9: i64 = (c3*nk + k5)*3 698 var pvx: i64 = pPc[pb9] 699 var pvy: i64 = pPc[pb9+1] 700 var pvz: i64 = pPc[pb9+2] 701 if low == 1 { 702 let mb2: i64 = (c3*nk + k5)*3 703 pvx = mNc[mb2] 704 pvy = mNc[mb2+1] 705 pvz = mNc[mb2+2] 706 } 707 xd_qrotv(qq, bgx - bbx, bgy - bby, bgz - bbz, rv2, t1, t2, t3) 708 let dgx: i64 = (pvx + rv2[0] - bgx)/100 709 let dgy: i64 = (pvy + rv2[1] - bgy)/100 710 let dgz: i64 = (pvz + rv2[2] - bgz)/100 711 let tms: i64 = k5*keyus/1000 712 AP[ap + k5*2] = (tms & 0xffff) | ((qq[0] & 0xffff) << 16) | ((qq[1] & 0xffff) << 32) | ((qq[2] & 0xffff) << 48) 713 AP[ap + k5*2 + 1] = (qq[3] & 0xffff) | ((dgx & 0xffff) << 16) | ((dgy & 0xffff) << 32) | ((dgz & 0xffff) << 48) 714 k5 = k5 + 1 715 } 716 ap = ap + kw 717 } else { if TF[tg] == 1 { 718 // TORSO track: the joint rides the tracked chest rigidly about the hip centre 719 AP[ap] = tg 720 AP[ap+1] = 2 721 AP[ap+2] = nk 722 ap = ap + 3 723 let bgx2: i64 = W[sow+1+tg*8+1] 724 let bgy2: i64 = W[sow+1+tg*8+2] 725 let bgz2: i64 = W[sow+1+tg*8+3] 726 var k6: i64 = 0 727 while k6 < nk { 728 let qq2: *i64 = ((qTc as i64) + k6*32) as *i64 729 xd_qrotv(qq2, bgx2 - hcx, bgy2 - hcy, bgz2 - hcz, rv2, t1, t2, t3) 730 let dgx2: i64 = (hcx + rv2[0] - bgx2)/100 731 let dgy2: i64 = (hcy + rv2[1] - bgy2)/100 732 let dgz2: i64 = (hcz + rv2[2] - bgz2)/100 733 let tms2: i64 = k6*keyus/1000 734 AP[ap + k6*2] = (tms2 & 0xffff) | ((qq2[0] & 0xffff) << 16) | ((qq2[1] & 0xffff) << 32) | ((qq2[2] & 0xffff) << 48) 735 AP[ap + k6*2 + 1] = (qq2[3] & 0xffff) | ((dgx2 & 0xffff) << 16) | ((dgy2 & 0xffff) << 32) | ((dgz2 & 0xffff) << 48) 736 k6 = k6 + 1 737 } 738 ap = ap + kw 739 } } 740 tg = tg + 1 741 } 742 // splice: keep every section except an old ANIM, append ours, RECOMPUTE every checksum 743 // (a copied checksum validates its own bug -- the ntx_apply law) 744 var ani: i64 = 0 - 1 745 var s4: i64 = 0 746 while s4 < ns { 747 if W[4+s4*4] == nxa_tag4("ANIM" as *u8) { ani = s4 } 748 s4 = s4 + 1 749 } 750 var nsec: i64 = ns 751 if ani < 0 { nsec = ns + 1 } 752 var total: i64 = (4 + nsec*4)*8 753 var s5: i64 = 0 754 while s5 < ns { 755 if s5 != ani { total = total + W[4+s5*4+2]*8 } 756 s5 = s5 + 1 757 } 758 total = total + aw*8 759 let nb: *u8 = sys_mmap(total + XD_MAGIC_4096) 760 if (nb as i64) == 0 { xd_w("NXA-ANIM REFUSED: cannot allocate output\n" as *u8); return 4 } 761 let NW: *i64 = nb as *i64 762 NW[0] = nxa_magic() 763 NW[1] = 1 764 NW[2] = nsec 765 var wo: i64 = (4 + nsec*4)*8 766 var ti3: i64 = 0 767 var s6: i64 = 0 768 while s6 < ns { 769 if s6 != ani { 770 let oldoff: i64 = W[4+s6*4+1] 771 let wl: i64 = W[4+s6*4+2] 772 NW[4+ti3*4] = W[4+s6*4] 773 NW[4+ti3*4+1] = wo 774 NW[4+ti3*4+2] = wl 775 var cb: i64 = 0 776 while cb < wl*8 { nb[wo+cb] = b[oldoff+cb]; cb = cb + 1 } 777 let pw: *i64 = ((nb as i64) + wo) as *i64 778 NW[4+ti3*4+3] = nxa_check2(1, pw, wl) 779 wo = wo + wl*8 780 ti3 = ti3 + 1 781 } 782 s6 = s6 + 1 783 } 784 NW[4+ti3*4] = nxa_tag4("ANIM" as *u8) 785 NW[4+ti3*4+1] = wo 786 NW[4+ti3*4+2] = aw 787 let dstw: *i64 = ((nb as i64) + wo) as *i64 788 var cw: i64 = 0 789 while cw < aw { dstw[cw] = AP[cw]; cw = cw + 1 } 790 NW[4+ti3*4+3] = nxa_check2(1, dstw, aw) 791 wo = wo + aw*8 792 let tb2: *i64 = ((nb as i64) + 32) as *i64 793 NW[3] = nxa_check2(1, tb2, nsec*4) 794 let fd: i64 = sys_openat_wr(outp, 0x1a4) 795 if fd < 0 { xd_w("NXA-ANIM REFUSED: cannot open output\n" as *u8); return 4 } 796 sys_write(fd, nb, wo) 797 sys_close(fd) 798 xd_w("NXA-ANIM-OK ntr=" as *u8); xd_num(ntr); xd_w(" nk=" as *u8); xd_num(nk) 799 xd_w(" sections=" as *u8); xd_num(nsec) 800 xd_w(" out_bytes=" as *u8); xd_num(wo); xd_w("\n" as *u8) 801 return 0 802} 803func xd_streq(a: *u8, b: *u8) -> i64 { 804 var i: i64=0; var go: i64=1; var eq: i64=1 805 while go==1 { if a[i]!=b[i] { eq=0; go=0 } else { if a[i]==(0 as u8) { go=0 } else { i=i+1 } } } 806 return eq 807} 808// M1 ADOPTION (2026-08-12): dump the NXA SKEL so the 12-role resolver is designed against 809// MEASURED binds, never armchair anatomy. Output: nj, then per joint: idx parent x y z. 810func xd_nxa_probe(inp: *u8) -> i64 { 811 let lp: *i64 = sys_mmap(16) as *i64 812 let b: *u8 = sys_read_file(inp, lp) 813 if (b as i64) == 0 { xd_w("NXA-PROBE REFUSED: cannot read input\n" as *u8); return 2 } 814 let flen: i64 = lp[0] 815 let sow: i64 = nxa_find(b, flen, nxa_tag4("SKEL" as *u8)) 816 if sow < 0 { xd_w("NXA-PROBE REFUSED: SKEL missing/corrupt code=" as *u8); xd_num(sow); xd_w("\n" as *u8); return 2 } 817 let W: *i64 = b as *i64 818 let nj: i64 = W[sow] 819 xd_w("NXA-PROBE nj=" as *u8); xd_num(nj); xd_w(" rows: idx parent x y z\n" as *u8) 820 var j: i64 = 0 821 while j < nj { 822 let base: i64 = sow + 1 + j*8 823 xd_num(j); xd_w(" " as *u8); xd_num(W[base]); xd_w(" " as *u8) 824 xd_num(W[base+1]); xd_w(" " as *u8); xd_num(W[base+2]); xd_w(" " as *u8); xd_num(W[base+3]); xd_w("\n" as *u8) 825 j = j + 1 826 } 827 return 0 828} 829// M1-ARM-IK: de-yawed + mirrored offset of joint j from the mocap hip centre, RAW units -> o[ob..ob+2] 830// (the same de-yaw+mirror pipeline as dtrk/ttrk; un-normalized because POSITION is the payload) 831func xd_hipoff(wp: *i64, j: i64, hx: i64, hy: i64, hz: i64, cr: i64, sr: i64, o: *i64, ob: i64) -> i64 { 832 let dx0: i64 = wp[j*3] - hx 833 let dy0: i64 = wp[j*3+1] - hy 834 let dz0: i64 = wp[j*3+2] - hz 835 o[ob] = 0 - ((dx0*cr + dz0*sr) / XD_FX12) 836 o[ob+1] = dy0 837 o[ob+2] = ((0-dx0)*sr + dz0*cr) / XD_FX12 838 return 0 839} 840func main(argc: i64, argv: *i64) -> i64 { 841 var donxa: i64 = 0 842 if argc > 1 { 843 let a1: *u8 = argv[1] as *u8 844 if a1[0] == (45 as u8) { return xd_kat() } 845 if xd_streq(a1, "nxa" as *u8) == 1 { 846 if argc >= 3 { if xd_streq(argv[2] as *u8, "probe" as *u8) == 1 { 847 if argc < 4 { xd_w("usage: nx_dance_emit nxa probe <in.nxa>\n" as *u8); return 3 } 848 return xd_nxa_probe(argv[3] as *u8) 849 } } 850 if argc < 5 { xd_w("usage: nx_dance_emit nxa <in.nxa> <clip.bvh> <out.nxa>\n" as *u8); return 3 } 851 donxa = 1 852 } 853 } 854 xd_w("=== nx_dance_emit v2 -- REAL mocap -> position-retargeted, smooth-skinned being ===\n" as *u8) 855 var path: *u8 = "knowledge/fixture_mocapbank.bvh" as *u8 856 if argc > 1 { path = argv[1] as *u8 } 857 if donxa == 1 { path = argv[3] as *u8 } 858 859 let lenp: *i64 = sys_mmap(16) as *i64 860 let buf: *u8 = sys_read_file(path, lenp) 861 if (buf as i64) == 0 { xd_w("nx_dance_emit unreadable\n" as *u8); return 2 } 862 let len: i64 = lenp[0] 863 864 let H: *i64 = sys_mmap(B_H_WORDS * 8) as *i64 865 let names: *u8 = sys_mmap(B_MAX_JOINTS * B_NAMEW) 866 let parent: *i64 = sys_mmap(B_MAX_JOINTS * 8) as *i64 867 let nchan: *i64 = sys_mmap(B_MAX_JOINTS * 8) as *i64 868 let chan0: *i64 = sys_mmap(B_MAX_JOINTS * 8) as *i64 869 let joff: *i64 = sys_mmap(B_MAX_JOINTS * 24) as *i64 870 let chtype: *i64 = sys_mmap(B_MAX_CHAN * 8) as *i64 871 let r: i64 = b_parse(buf, len, H, names, parent, nchan, chan0, joff, chtype) 872 if r < 0 { return b_refuse(r) } 873 xd_w("clip joints=" as *u8); xd_num(H[B_H_NJOINT]) 874 xd_w(" frames=" as *u8); xd_num(H[B_H_NFRAME]) 875 xd_w(" ftime_us=" as *u8); xd_num(H[B_H_FTIME]) 876 xd_w("\n" as *u8) 877 878 // ---- resolve 12 skeleton joints BY NAME, CMU/cgspeed aliases FIRST (that skeleton also carries a 879 // "LeftShoulder" CLAVICLE, so the mocapbank name must be the FALLBACK, never the first try); 880 // a missing role REFUSES (proven by KAT T4) ---- 881 let map: *i64 = sys_mmap(13*8) as *i64 882 let aLsh: *u8 = "LeftArm" as *u8 883 let nLsh: *u8 = "LeftShoulder" as *u8 884 let aLel: *u8 = "LeftForeArm" as *u8 885 let nLel: *u8 = "LeftElbow" as *u8 886 let aRsh: *u8 = "RightArm" as *u8 887 let nRsh: *u8 = "RightShoulder" as *u8 888 let aRel: *u8 = "RightForeArm" as *u8 889 let nRel: *u8 = "RightElbow" as *u8 890 let aLhp: *u8 = "LeftUpLeg" as *u8 891 let nLhp: *u8 = "LeftHip" as *u8 892 let aLkn: *u8 = "LeftLeg" as *u8 893 let nLkn: *u8 = "LeftKnee" as *u8 894 let aRhp: *u8 = "RightUpLeg" as *u8 895 let nRhp: *u8 = "RightHip" as *u8 896 let aRkn: *u8 = "RightLeg" as *u8 897 let nRkn: *u8 = "RightKnee" as *u8 898 let aLwr: *u8 = "LeftHand" as *u8 899 let nLwr: *u8 = "LeftWrist" as *u8 900 let aRwr: *u8 = "RightHand" as *u8 901 let nRwr: *u8 = "RightWrist" as *u8 902 let aLan: *u8 = "LeftFoot" as *u8 903 let nLan: *u8 = "LeftAnkle" as *u8 904 let aRan: *u8 = "RightFoot" as *u8 905 let nRan: *u8 = "RightAnkle" as *u8 906 let nj: i64 = H[B_H_NJOINT] 907 map[1] = xd_findjoint(names, nj, aLsh) 908 if map[1] < 0 { map[1] = xd_findjoint(names, nj, nLsh) } 909 map[2] = xd_findjoint(names, nj, aLel) 910 if map[2] < 0 { map[2] = xd_findjoint(names, nj, nLel) } 911 map[3] = xd_findjoint(names, nj, aRsh) 912 if map[3] < 0 { map[3] = xd_findjoint(names, nj, nRsh) } 913 map[4] = xd_findjoint(names, nj, aRel) 914 if map[4] < 0 { map[4] = xd_findjoint(names, nj, nRel) } 915 map[5] = xd_findjoint(names, nj, aLhp) 916 if map[5] < 0 { map[5] = xd_findjoint(names, nj, nLhp) } 917 map[6] = xd_findjoint(names, nj, aLkn) 918 if map[6] < 0 { map[6] = xd_findjoint(names, nj, nLkn) } 919 map[7] = xd_findjoint(names, nj, aRhp) 920 if map[7] < 0 { map[7] = xd_findjoint(names, nj, nRhp) } 921 map[8] = xd_findjoint(names, nj, aRkn) 922 if map[8] < 0 { map[8] = xd_findjoint(names, nj, nRkn) } 923 map[9] = xd_findjoint(names, nj, aLwr) 924 if map[9] < 0 { map[9] = xd_findjoint(names, nj, nLwr) } 925 map[10] = xd_findjoint(names, nj, aRwr) 926 if map[10] < 0 { map[10] = xd_findjoint(names, nj, nRwr) } 927 map[11] = xd_findjoint(names, nj, aLan) 928 if map[11] < 0 { map[11] = xd_findjoint(names, nj, nLan) } 929 map[12] = xd_findjoint(names, nj, aRan) 930 if map[12] < 0 { map[12] = xd_findjoint(names, nj, nRan) } 931 var bi: i64 = 1 932 var missing: i64 = 0 933 while bi <= 12 { if map[bi] < 0 { missing = missing + 1 } bi = bi + 1 } 934 if missing > 0 { 935 xd_w("DANCE-EMIT REFUSED: required joints missing from clip=" as *u8); xd_num(missing); xd_w(" of 12\n" as *u8) 936 return 4 937 } 938 xd_w("joint map 12/12 by name\n" as *u8) 939 940 // ---- keys: nearest frame on the 8 Hz exact-f32 grid ---- 941 let dur_us: i64 = H[B_H_NFRAME] * H[B_H_FTIME] 942 // M1 FLUIDITY (operator: "movements aren't fluid"): the 8 Hz grid was the BLOB wire's DV_MAXK 943 // constraint, not a choice -- 125ms nlerp gaps read as non-fluid on fast choreography. The NXA 944 // lane samples at the clip's NATIVE rate (floored at 30 Hz); its wire has no 128-key cap 945 // (u16 ms ceils at 65s, guarded at 1900 keys). 946 var keyus: i64 = XD_KEY_US 947 if donxa == 1 { 948 keyus = H[B_H_FTIME] 949 if keyus < XD_MAGIC_33333 { keyus = XD_MAGIC_33333 } 950 } 951 var nk: i64 = dur_us / keyus 952 var capped: i64 = 0 953 if donxa == 0 { if nk > XD_MAXK { nk = XD_MAXK; capped = 1 } } 954 if donxa == 1 { if nk > XD_MAGIC_1900 { nk = XD_MAGIC_1900; capped = 1 } } 955 if nk < 2 { xd_w("DANCE-EMIT REFUSED: clip shorter than 2 keys\n" as *u8); return 4 } 956 xd_w("keys=" as *u8); xd_num(nk) 957 xd_w(" key_us=" as *u8); xd_num(keyus) 958 xd_w(" over " as *u8); xd_num(dur_us/1000); xd_w(" ms" as *u8) 959 if capped == 1 { xd_w(" (CAPPED at XD_MAXK)" as *u8) } 960 xd_w("\n" as *u8) 961 962 // ---- POSITION-BASED RETARGET: FK the whole mocap skeleton per key, drive bones by world dirs ---- 963 let qtrk: *i64 = sys_mmap(8*nk*4*8) as *i64 964 let fv: *i64 = sys_mmap(B_MAX_CHAN*8) as *i64 965 let q: *i64 = sys_mmap(32) as *i64 966 let qa: *i64 = sys_mmap(32) as *i64 967 let qt: *i64 = sys_mmap(32) as *i64 968 let s1: *i64 = sys_mmap(32) as *i64 969 let s2: *i64 = sys_mmap(32) as *i64 970 let s3: *i64 = sys_mmap(32) as *i64 971 let rv: *i64 = sys_mmap(32) as *i64 972 let wq: *i64 = sys_mmap(B_MAX_JOINTS*4*8) as *i64 // mocap world quats, fx12 973 let wp: *i64 = sys_mmap(B_MAX_JOINTS*3*8) as *i64 // mocap world positions, file units 974 let qwb: *i64 = sys_mmap(9*4*8) as *i64 // OUR bones' world quats this key 975 let dtrk: *i64 = sys_mmap(8*nk*3*8 + 64) as *i64 // M1: per-key WORLD segment dirs (fx12, dance frame) for the NXA lane 976 let ttrk: *i64 = sys_mmap(nk*6*8 + 64) as *i64 // M1-TORSO: per-key de-yawed mocap SPINE dir + SHOULDER-AXIS dir (fx12, 6/key) 977 let atrk: *i64 = sys_mmap(nk*20*8 + 64) as *i64 // M1-ARM-IK (debt 1786598036): per key = [mocap spine len, then per arm RAW de-yawed+mirrored sh/el/wr offsets from the HIP CENTRE (9)] = 20/key, mocap units 978 let pa: *i64 = sys_mmap(9*8) as *i64 // per-bone segment: parent joint (map index) 979 let pc: *i64 = sys_mmap(9*8) as *i64 // child joint (map index) 980 pa[1]=1; pc[1]=2 981 pa[2]=2; pc[2]=9 982 pa[3]=3; pc[3]=4 983 pa[4]=4; pc[4]=10 984 pa[5]=5; pc[5]=6 985 pa[6]=6; pc[6]=11 986 pa[7]=7; pc[7]=8 987 pa[8]=8; pc[8]=12 988 var k: i64 = 0 989 while k < nk { 990 var f: i64 = k * keyus / H[B_H_FTIME] 991 if f >= H[B_H_NFRAME] { f = H[B_H_NFRAME] - 1 } 992 if b_frame_values(buf, len, H, f, fv) != 0 { xd_w("DANCE-EMIT REFUSED: frame read failed\n" as *u8); return 4 } 993 // FK: BVH file order is parent-before-child 994 var mj: i64 = 0 995 while mj < nj { 996 xd_joint_quat(fv, chan0[mj], nchan[mj], chtype, q, qa, qt) 997 let pj: i64 = parent[mj] 998 if pj < 0 { 999 wq[mj*4]=q[0]; wq[mj*4+1]=q[1]; wq[mj*4+2]=q[2]; wq[mj*4+3]=q[3] 1000 wp[mj*3]=0; wp[mj*3+1]=0; wp[mj*3+2]=0 1001 } else { 1002 xd_qmul(((wq as i64) + pj*32) as *i64, q, ((wq as i64) + mj*32) as *i64) 1003 xd_qrotv(((wq as i64) + pj*32) as *i64, joff[mj*3], joff[mj*3+1], joff[mj*3+2], rv, s1, s2, s3) 1004 wp[mj*3] = wp[pj*3] + rv[0] 1005 wp[mj*3+1] = wp[pj*3+1] + rv[1] 1006 wp[mj*3+2] = wp[pj*3+2] + rv[2] 1007 } 1008 mj = mj + 1 1009 } 1010 // hip-axis yaw frame (torso-relative dance; stable body facing) 1011 let hl: i64 = map[5] 1012 let hr: i64 = map[7] 1013 let hx: i64 = wp[hl*3] - wp[hr*3] 1014 let hz: i64 = wp[hl*3+2] - wp[hr*3+2] 1015 var hn: i64 = xd_isqrt(hx*hx + hz*hz) 1016 if hn < 1 { hn = 1 } 1017 let cr: i64 = hx*XD_FX12/hn 1018 let sr: i64 = hz*XD_FX12/hn 1019 // M1-TORSO (debt 1786598036): capture the de-yawed, mirrored SPINE direction per key -- 1020 // real choreography clears the chest by torso lean; bind-holding it was the proven root 1021 // cause of the 138mm arm-through-chest clip (clipcheck probe key78 joint86) 1022 let ls9: i64 = map[1] 1023 let rs9: i64 = map[3] 1024 let sx0: i64 = (wp[ls9*3] + wp[rs9*3])/2 - (wp[hl*3] + wp[hr*3])/2 1025 let sy0: i64 = (wp[ls9*3+1] + wp[rs9*3+1])/2 - (wp[hl*3+1] + wp[hr*3+1])/2 1026 let sz0: i64 = (wp[ls9*3+2] + wp[rs9*3+2])/2 - (wp[hl*3+2] + wp[hr*3+2])/2 1027 let sx1: i64 = (sx0*cr + sz0*sr) / XD_FX12 1028 let sz1: i64 = ((0-sx0)*sr + sz0*cr) / XD_FX12 1029 let sx2: i64 = 0 - sx1 1030 var sn9: i64 = xd_isqrt(sx2*sx2 + sy0*sy0 + sz1*sz1) 1031 if sn9 < 1 { sn9 = 1 } 1032 ttrk[k*6] = sx2*XD_FX12/sn9 1033 ttrk[k*6+1] = sy0*XD_FX12/sn9 1034 ttrk[k*6+2] = sz1*XD_FX12/sn9 1035 // shoulder-axis dir (Lsh - Rsh), same de-yaw + mirror pipeline: carries the chest TWIST 1036 let ax0: i64 = wp[ls9*3] - wp[rs9*3] 1037 let ay0: i64 = wp[ls9*3+1] - wp[rs9*3+1] 1038 let az0: i64 = wp[ls9*3+2] - wp[rs9*3+2] 1039 let ax1: i64 = (ax0*cr + az0*sr) / XD_FX12 1040 let az1: i64 = ((0-ax0)*sr + az0*cr) / XD_FX12 1041 let ax2: i64 = 0 - ax1 1042 var an9: i64 = xd_isqrt(ax2*ax2 + ay0*ay0 + az1*az1) 1043 if an9 < 1 { an9 = 1 } 1044 ttrk[k*6+3] = ax2*XD_FX12/an9 1045 ttrk[k*6+4] = ay0*XD_FX12/an9 1046 ttrk[k*6+5] = az1*XD_FX12/an9 1047 // M1-ARM-IK v2: RAW sh/el/wr offsets from the MOCAP HIP CENTRE, de-yawed + mirrored like 1048 // dtrk. HIP-relative, not shoulder-relative: shoulder-relative fidelity cannot preserve 1049 // torso clearance when the shoulder-to-axis distance differs between bodies (measured: 1050 // source wrist 201mm from its axis; shoulder-relative retarget placed ours at 40mm). 1051 // atrk[k*20] additionally banks the mocap spine length sn9 = the scale bridge. 1052 let hcmx9: i64 = (wp[hl*3] + wp[hr*3])/2 1053 let hcmy9: i64 = (wp[hl*3+1] + wp[hr*3+1])/2 1054 let hcmz9: i64 = (wp[hl*3+2] + wp[hr*3+2])/2 1055 atrk[k*20] = sn9 1056 var ar9: i64 = 0 1057 while ar9 < 2 { 1058 let ab9: i64 = k*20 + 1 + ar9*9 1059 xd_hipoff(wp, map[1 + ar9*2], hcmx9, hcmy9, hcmz9, cr, sr, atrk, ab9) 1060 xd_hipoff(wp, map[2 + ar9*2], hcmx9, hcmy9, hcmz9, cr, sr, atrk, ab9+3) 1061 xd_hipoff(wp, map[9 + ar9], hcmx9, hcmy9, hcmz9, cr, sr, atrk, ab9+6) 1062 ar9 = ar9 + 1 1063 } 1064 // per bone: world dir -> de-yaw -> mirror X -> normalize -> quat; local = conj(parentBone) x world 1065 var bn: i64 = 1 1066 while bn <= 8 { 1067 let ja: i64 = map[pa[bn]] 1068 let jc: i64 = map[pc[bn]] 1069 let dx0: i64 = wp[jc*3] - wp[ja*3] 1070 let dy0: i64 = wp[jc*3+1] - wp[ja*3+1] 1071 let dz0: i64 = wp[jc*3+2] - wp[ja*3+2] 1072 let dx1: i64 = (dx0*cr + dz0*sr) / XD_FX12 1073 let dz1: i64 = ((0-dx0)*sr + dz0*cr) / XD_FX12 1074 let dx2: i64 = 0 - dx1 1075 var dn: i64 = xd_isqrt(dx2*dx2 + dy0*dy0 + dz1*dz1) 1076 if dn < 1 { dn = 1 } 1077 let dbi: i64 = ((bn-1)*nk + k)*3 1078 dtrk[dbi] = dx2*XD_FX12/dn 1079 dtrk[dbi+1] = dy0*XD_FX12/dn 1080 dtrk[dbi+2] = dz1*XD_FX12/dn 1081 xd_qfromdir(dtrk[dbi], dtrk[dbi+1], dtrk[dbi+2], q) 1082 qwb[bn*4]=q[0]; qwb[bn*4+1]=q[1]; qwb[bn*4+2]=q[2]; qwb[bn*4+3]=q[3] 1083 let qb: i64 = ((bn-1)*nk + k)*4 1084 if bn == 2 { s3[0]=0-qwb[4]; s3[1]=0-qwb[5]; s3[2]=0-qwb[6]; s3[3]=qwb[7]; xd_qmul(s3, q, qt); qtrk[qb]=qt[0]; qtrk[qb+1]=qt[1]; qtrk[qb+2]=qt[2]; qtrk[qb+3]=qt[3] } 1085 else { if bn == 4 { s3[0]=0-qwb[12]; s3[1]=0-qwb[13]; s3[2]=0-qwb[14]; s3[3]=qwb[15]; xd_qmul(s3, q, qt); qtrk[qb]=qt[0]; qtrk[qb+1]=qt[1]; qtrk[qb+2]=qt[2]; qtrk[qb+3]=qt[3] } 1086 else { if bn == 6 { s3[0]=0-qwb[20]; s3[1]=0-qwb[21]; s3[2]=0-qwb[22]; s3[3]=qwb[23]; xd_qmul(s3, q, qt); qtrk[qb]=qt[0]; qtrk[qb+1]=qt[1]; qtrk[qb+2]=qt[2]; qtrk[qb+3]=qt[3] } 1087 else { if bn == 8 { s3[0]=0-qwb[28]; s3[1]=0-qwb[29]; s3[2]=0-qwb[30]; s3[3]=qwb[31]; xd_qmul(s3, q, qt); qtrk[qb]=qt[0]; qtrk[qb+1]=qt[1]; qtrk[qb+2]=qt[2]; qtrk[qb+3]=qt[3] } 1088 else { qtrk[qb]=q[0]; qtrk[qb+1]=q[1]; qtrk[qb+2]=q[2]; qtrk[qb+3]=q[3] } } } } 1089 bn = bn + 1 1090 } 1091 k = k + 1 1092 } 1093 1094 if donxa == 1 { return xd_nxa_apply(argv[2] as *u8, argv[4] as *u8, dtrk, nk, keyus, ttrk, atrk) } 1095 // ---- track teeth (values, not booleans) ---- 1096 var fails: i64 = 0 1097 var normbad: i64 = 0 1098 var worstn2: i64 = XD_FX12 1099 var axis3: i64 = 0 1100 var moved: i64 = 0 1101 var bn2: i64 = 1 1102 while bn2 <= 8 { 1103 var k2: i64 = 0 1104 while k2 < nk { 1105 let qb2: i64 = ((bn2-1)*nk + k2)*4 1106 let n2: i64 = (qtrk[qb2]*qtrk[qb2] + qtrk[qb2+1]*qtrk[qb2+1] + qtrk[qb2+2]*qtrk[qb2+2] + qtrk[qb2+3]*qtrk[qb2+3]) / XD_FX12 1107 if n2 < XD_NORM_LO { normbad = normbad + 1 } 1108 if n2 > XD_NORM_HI { normbad = normbad + 1 } 1109 var dv: i64 = n2 - XD_FX12 1110 if dv < 0 { dv = 0 - dv } 1111 var dw: i64 = worstn2 - XD_FX12 1112 if dw < 0 { dw = 0 - dw } 1113 if dv > dw { worstn2 = n2 } 1114 var ay: i64 = qtrk[qb2+1] 1115 if ay < 0 { ay = 0 - ay } 1116 var az: i64 = qtrk[qb2+2] 1117 if az < 0 { az = 0 - az } 1118 if ay > XD_AXIS_TH { axis3 = axis3 + 1 } 1119 if az > XD_AXIS_TH { axis3 = axis3 + 1 } 1120 let q0: i64 = ((bn2-1)*nk)*4 1121 var c3: i64 = 0 1122 while c3 < 4 { 1123 var d3: i64 = qtrk[qb2+c3] - qtrk[q0+c3] 1124 if d3 < 0 { d3 = 0 - d3 } 1125 if d3 > XD_MOVE_TH { moved = moved + 1 } 1126 c3 = c3 + 1 1127 } 1128 k2 = k2 + 1 1129 } 1130 bn2 = bn2 + 1 1131 } 1132 xd_w("T-norm worst |q|^2/4096=" as *u8); xd_num(worstn2); xd_w(" band=[" as *u8); xd_num(XD_NORM_LO); xd_w(","as *u8); xd_num(XD_NORM_HI); xd_w("] violations=" as *u8); xd_num(normbad) 1133 if normbad == 0 { xd_w(" PASS\n" as *u8) } else { xd_w(" FAIL\n" as *u8); fails = fails + 1 } 1134 xd_w("T-3axis |qy|/|qz|>50 count=" as *u8); xd_num(axis3) 1135 if axis3 > 0 { xd_w(" PASS\n" as *u8) } else { xd_w(" FAIL flat\n" as *u8); fails = fails + 1 } 1136 xd_w("T-moves keys-departing-key0 count=" as *u8); xd_num(moved) 1137 if moved > 0 { xd_w(" PASS\n" as *u8) } else { xd_w(" FAIL constant-pose\n" as *u8); fails = fails + 1 } 1138 1139 // ---- build the being (SEED-SAN proportions) + bind, ONE skin tone ---- 1140 ba_set_axes(363, XD_MAGIC_1231, XD_MAGIC_1403, XD_MAGIC_1067, XD_MAGIC_1179) 1141 atlas_build(0) 1142 let grid: *i64 = sys_mmap((XD_GX+1)*(XD_GY+1)*(XD_GZ+1)*8) as *i64 1143 var gi: i64 = 0 1144 while gi <= XD_GX { var gj: i64=0; while gj <= XD_GY { var gk: i64=0; while gk <= XD_GZ { grid[(gi*(XD_GY+1)+gj)*(XD_GZ+1)+gk] = ba_sdf(XD_OX+gi*XD_GC, XD_OY+gj*XD_GC, XD_OZ+gk*XD_GC, 1); gk=gk+1 } gj=gj+1 } gi=gi+1 } 1145 tm_reset() 1146 surface_nets(grid, XD_GX, XD_GY, XD_GZ, XD_OX, XD_OY, XD_OZ, XD_GC, 0, XD_SKIN) 1147 let NV: i64 = tm_nv() 1148 let jarr: *i64 = sys_mmap(NV*8) as *i64 1149 let vp: *i64 = sys_mmap(24) as *i64 1150 let jc9: *i64 = sys_mmap(9*8) as *i64 1151 var b9: i64 = 0 1152 while b9 < 9 { jc9[b9]=0; b9=b9+1 } 1153 var vi: i64 = 0 1154 while vi < NV { 1155 tm_vpos(vi, vp) 1156 let kk: i64 = ba_nearest(vp[0], vp[1], vp[2], 1) 1157 var jt: i64 = 0 1158 if kk >= 0 { jt = ba_part_bone(kk) } 1159 tm_vcol(vi, XD_SKIN) 1160 jarr[vi] = jt 1161 jc9[jt] = jc9[jt] + 1 1162 vi = vi + 1 1163 } 1164 xd_w("verts=" as *u8); xd_num(NV) 1165 xd_w(" bound: Lsh=" as *u8); xd_num(jc9[1]); xd_w(" Lel=" as *u8); xd_num(jc9[2]); xd_w(" Lhip=" as *u8); xd_num(jc9[5]); xd_w(" Lkn=" as *u8); xd_num(jc9[6]); xd_w("\n" as *u8) 1166 var t0: i64 = 0 1167 if jc9[1] > 20 { if jc9[5] > 20 { if jc9[6] > 20 { t0 = 1 } } } 1168 if t0 == 1 { xd_w("T-bind PASS limbs rigged\n" as *u8) } else { fails=fails+1; xd_w("T-bind FAIL\n" as *u8) } 1169 1170 // ---- smooth two-bone weights, CONTINUOUS across every seam (v2.2) ---- 1171 // The v2.1 ownership-anchored scheme was discontinuous: adjacent verts across a seam flipped 1172 // PRIMARY bone while each kept majority weight -- the seam still tore 8-10x (measured). Correct 1173 // scheme: near any joint pivot the blend is a pure function of GEOMETRY -- signed height relative 1174 // to the pivot (all rest bones hang -Y): w_child = 1/2 + (pivY - vy)/(2*BAND), clamped. Adjacent 1175 // verts get near-identical mixes whichever side owns them, so the seam deforms instead of tearing. 1176 let j1arr: *i64 = sys_mmap(NV*8) as *i64 1177 let j2arr: *i64 = sys_mmap(NV*8) as *i64 1178 let wtarr: *i64 = sys_mmap(NV*8) as *i64 1179 let pb: *i64 = sys_mmap(9*8) as *i64 1180 pb[0]=0; pb[1]=0; pb[2]=1; pb[3]=0; pb[4]=3; pb[5]=0; pb[6]=5; pb[7]=0; pb[8]=7 1181 // OWNERSHIP-GATED seams (v2.3): a vert participates only in seams its own chain forms -- own 1182 // pivot (seam with parent) and child pivots (seam with that child). An ungated nearest-pivot 1183 // capture let the ELBOW pivot grab belly/chest verts (seedsan arms hang against the torso; 1184 // measured 25x tears). Weight stays PURELY GEOMETRIC (signed height vs the seam pivot, all rest 1185 // bones hang -Y), so the two sides of a seam get continuous, matching blends. 1186 let cA: *i64 = sys_mmap(9*8) as *i64 1187 let cB: *i64 = sys_mmap(9*8) as *i64 1188 let cC: *i64 = sys_mmap(9*8) as *i64 1189 let cD: *i64 = sys_mmap(9*8) as *i64 1190 var ci9: i64 = 0 1191 while ci9 < 9 { cA[ci9]=0-1; cB[ci9]=0-1; cC[ci9]=0-1; cD[ci9]=0-1; ci9=ci9+1 } 1192 cA[0]=1; cB[0]=3; cC[0]=5; cD[0]=7 1193 cA[1]=2; cA[3]=4; cA[5]=6; cA[7]=8 1194 vi = 0 1195 while vi < NV { 1196 tm_vpos(vi, vp) 1197 let own: i64 = jarr[vi] 1198 var sc: i64 = 0 - 1 1199 var nd: i64 = XD_BAND + 1 1200 // own pivot = seam (own <-> parent) 1201 if own > 0 { 1202 let ox2: i64 = vp[0] - ga_piv(own,0) 1203 let oy2: i64 = vp[1] - ga_piv(own,1) 1204 let oz2: i64 = vp[2] - ga_piv(own,2) 1205 let od: i64 = xd_isqrt(ox2*ox2 + oy2*oy2 + oz2*oz2) 1206 if od < nd { nd = od; sc = own } 1207 } 1208 // child pivots = seams (child <-> own) 1209 var cslot: i64 = 0 1210 while cslot < 4 { 1211 var cb2: i64 = 0 - 1 1212 if cslot == 0 { cb2 = cA[own] } 1213 if cslot == 1 { cb2 = cB[own] } 1214 if cslot == 2 { cb2 = cC[own] } 1215 if cslot == 3 { cb2 = cD[own] } 1216 if cb2 > 0 { 1217 let cx: i64 = vp[0] - ga_piv(cb2,0) 1218 let cy2: i64 = vp[1] - ga_piv(cb2,1) 1219 let cz: i64 = vp[2] - ga_piv(cb2,2) 1220 let dd: i64 = xd_isqrt(cx*cx + cy2*cy2 + cz*cz) 1221 if dd < nd { nd = dd; sc = cb2 } 1222 } 1223 cslot = cslot + 1 1224 } 1225 if sc > 0 { 1226 let sup: i64 = ga_piv(sc,1) - vp[1] 1227 var w: i64 = XD_MAGIC_8192 + XD_MAGIC_8192*sup/XD_BAND 1228 if w < 0 { w = 0 } 1229 if w > XD_MAGIC_16384 { w = XD_MAGIC_16384 } 1230 j1arr[vi] = sc 1231 j2arr[vi] = pb[sc] 1232 wtarr[vi] = w 1233 } else { 1234 j1arr[vi] = own 1235 j2arr[vi] = own 1236 wtarr[vi] = XD_MAGIC_16384 1237 } 1238 vi = vi + 1 1239 } 1240 1241 // ---- export the glb through the shared writer (gets the v2 retargeted track too) ---- 1242 let out: *u8 = sys_mmap(XD_GLBCAP) 1243 let aname: *u8 = "dance" as *u8 1244 let total: i64 = gltf_anim_export_qtrack(out, jarr, qtrk, nk, aname) 1245 xd_w("glb bytes=" as *u8); xd_num(total); xd_w("\n" as *u8) 1246 var t1: i64 = 0 1247 if (out[0] as i64)==103 { if xd_ru32(out,8)==total { t1=1 } } 1248 if t1 == 1 { xd_w("T-glb PASS header + length\n" as *u8) } else { fails=fails+1; xd_w("T-glb FAIL\n" as *u8) } 1249 let jsonLen: i64 = xd_ru32(out,12) 1250 var t2: i64 = 0 1251 let ndance: *u8 = "\"dance\"" as *u8 1252 let nwalk: *u8 = "\"walk\"" as *u8 1253 if xd_hasstr(out,20+jsonLen,ndance)==1 { if xd_hasstr(out,20+jsonLen,nwalk)==0 { t2=1 } } 1254 if t2 == 1 { xd_w("T-name PASS animation is 'dance', not 'walk'\n" as *u8) } else { fails=fails+1; xd_w("T-name FAIL\n" as *u8) } 1255 1256 let p1: *u8 = "knowledge/nishi_being_dance.glb\x00" as *u8 1257 let fd: i64 = sys_openat_wr(p1, 0x1a4) 1258 sys_write(fd, out, total) 1259 sys_close(fd) 1260 xd_w("artifact:ADDED knowledge/nishi_being_dance.glb bytes=" as *u8); xd_num(total); xd_w("\n" as *u8) 1261 let p2: *u8 = "sites/nishifamily/exceed/vrm/nishi-being-dance.glb\x00" as *u8 1262 let fd2: i64 = sys_openat_wr(p2, 0x1a4) 1263 sys_write(fd2, out, total) 1264 sys_close(fd2) 1265 xd_w("artifact:ADDED sites/nishifamily/exceed/vrm/nishi-being-dance.glb bytes=" as *u8); xd_num(total); xd_w("\n" as *u8) 1266 1267 // ---- .nxdv v2 blob: the sovereign viewer's wasm-memory IMAGE (wire format = O_D* in 1268 // nx_meshview_wasm.nx v2). Units: verts/translations Q14 = units*16384/600 (trunc); normals fx12*4; 1269 // quats fx12*4; weights Q14. Cross-checked byte-identical vs the Node oracle (build_blob.js). 1270 let XB_TOT: i64 = XD_MAGIC_116324 1271 let bb: *i64 = sys_mmap(XB_TOT*8) as *i64 1272 bb[0] = 0x3256584E 1273 bb[1] = NV 1274 bb[2] = tm_nt() 1275 bb[3] = nk 1276 bb[4] = 125 1277 bb[5] = 11 1278 bb[6] = 0 1279 bb[7] = 0 1280 var xk: i64 = 0 1281 while xk < NV { 1282 tm_vpos(xk, vp) 1283 bb[8 + xk*3] = vp[0]*XD_MAGIC_16384/600 1284 bb[8 + xk*3 + 1] = vp[1]*XD_MAGIC_16384/600 1285 bb[8 + xk*3 + 2] = vp[2]*XD_MAGIC_16384/600 1286 tm_vnorm(xk, vp) 1287 bb[XD_MAGIC_21008 + xk*3] = vp[0]*4 1288 bb[XD_MAGIC_21008 + xk*3 + 1] = vp[1]*4 1289 bb[XD_MAGIC_21008 + xk*3 + 2] = vp[2]*4 1290 bb[XD_MAGIC_42008 + xk] = (tm_getvcol(xk) & XD_MAGIC_16777215) + XD_MAGIC_4278190080 1291 bb[XD_MAGIC_49008 + xk] = j1arr[xk] 1292 bb[XD_MAGIC_56008 + xk] = j2arr[xk] 1293 bb[XD_MAGIC_63008 + xk] = wtarr[xk] 1294 xk = xk + 1 1295 } 1296 // BRIDGE FILTER (v2.1): the rest-pose SDF fuses surfaces that merely TOUCH (hanging forearms 1297 // against thighs, inner thighs against each other) -- surface_nets bridges them into one skin, and 1298 // any correct dance tears those triangles 50x (measured: worst edge stretch 58x, all offenders 1299 // arm-bone<->leg-bone pairs). A triangle spanning two different LIMBS, or torso<->forearm, has no 1300 // anatomical joint -- DROP it from the viewer blob. Legit seams stay: torso<->shoulder, torso<->hip, 1301 // chain links. Dropped count is PRINTED, never silent. 1302 let lg: *i64 = sys_mmap(9*8) as *i64 1303 lg[0]=0; lg[1]=1; lg[2]=1; lg[3]=2; lg[4]=2; lg[5]=3; lg[6]=3; lg[7]=4; lg[8]=4 1304 let NT2: i64 = tm_nt() 1305 var xt: i64 = 0 1306 var kept: i64 = 0 1307 var dropped: i64 = 0 1308 let tv: *i64 = sys_mmap(24) as *i64 1309 while xt < NT2 { 1310 tm_tget(xt, tv) 1311 let ga: i64 = lg[jarr[tv[0]]] 1312 let gb: i64 = lg[jarr[tv[1]]] 1313 let gc: i64 = lg[jarr[tv[2]]] 1314 var lo: i64 = 9 1315 var hi: i64 = 0 1316 if ga > 0 { if ga < lo { lo = ga } if ga > hi { hi = ga } } 1317 if gb > 0 { if gb < lo { lo = gb } if gb > hi { hi = gb } } 1318 if gc > 0 { if gc < lo { lo = gc } if gc > hi { hi = gc } } 1319 var drop: i64 = 0 1320 if hi > 0 { if lo < hi { drop = 1 } } 1321 var hastorso: i64 = 0 1322 if ga == 0 { hastorso = 1 } 1323 if gb == 0 { hastorso = 1 } 1324 if gc == 0 { hastorso = 1 } 1325 // mixed torso+limb is legit ONLY at the limb's ROOT joint: every vert of the triangle must sit 1326 // within 170 units of that pivot (shoulder/hip). The SDF fuses the whole inner arm to the chest 1327 // (and inner thighs to the crotch) -- those strips are contact, not anatomy, and they tear. 1328 if drop == 0 { if hastorso == 1 { if hi > 0 { 1329 var rootb: i64 = 1 1330 if hi == 2 { rootb = 3 } 1331 if hi == 3 { rootb = 5 } 1332 if hi == 4 { rootb = 7 } 1333 let rpx: i64 = ga_piv(rootb, 0) 1334 let rpy: i64 = ga_piv(rootb, 1) 1335 let rpz: i64 = ga_piv(rootb, 2) 1336 var vv: i64 = 0 1337 while vv < 3 { 1338 tm_vpos(tv[vv], vp) 1339 let ddx: i64 = vp[0] - rpx 1340 let ddy: i64 = vp[1] - rpy 1341 let ddz: i64 = vp[2] - rpz 1342 if xd_isqrt(ddx*ddx + ddy*ddy + ddz*ddz) > 170 { drop = 1 } 1343 vv = vv + 1 1344 } 1345 } } } 1346 if drop == 0 { 1347 bb[XD_MAGIC_70008 + kept*3] = tv[0] 1348 bb[XD_MAGIC_70008 + kept*3 + 1] = tv[1] 1349 bb[XD_MAGIC_70008 + kept*3 + 2] = tv[2] 1350 kept = kept + 1 1351 } else { dropped = dropped + 1 } 1352 xt = xt + 1 1353 } 1354 bb[2] = kept 1355 xd_w("bridge filter: kept=" as *u8); xd_num(kept); xd_w(" dropped=" as *u8); xd_num(dropped); xd_w(" (fused rest-pose contact patches)\n" as *u8) 1356 // joint slots 0..10 = the glb skin order = ga_piv indices; parents fixed by the rig 1357 bb[XD_MAGIC_112008] = 0-1 1358 bb[XD_MAGIC_112009] = 0 1359 bb[XD_MAGIC_112010] = 1 1360 bb[XD_MAGIC_112011] = 0 1361 bb[XD_MAGIC_112012] = 3 1362 bb[XD_MAGIC_112013] = 0 1363 bb[XD_MAGIC_112014] = 5 1364 bb[XD_MAGIC_112015] = 0 1365 bb[XD_MAGIC_112016] = 7 1366 bb[XD_MAGIC_112017] = 6 1367 bb[XD_MAGIC_112018] = 8 1368 var xs: i64 = 0 1369 while xs < 11 { 1370 var xpar: i64 = bb[XD_MAGIC_112008 + xs] 1371 var xax: i64 = 0 1372 while xax < 3 { 1373 var tloc: i64 = ga_piv(xs, xax) 1374 if xpar >= 0 { tloc = tloc - ga_piv(xpar, xax) } 1375 bb[XD_MAGIC_112019 + xs*3 + xax] = tloc*XD_MAGIC_16384/600 1376 xax = xax + 1 1377 } 1378 var xc: i64 = 0 1379 while xc < 16 { bb[XD_MAGIC_112052 + xs*16 + xc] = 0; xc = xc + 1 } 1380 bb[XD_MAGIC_112052 + xs*16] = XD_MAGIC_16384 1381 bb[XD_MAGIC_112052 + xs*16 + 5] = XD_MAGIC_16384 1382 bb[XD_MAGIC_112052 + xs*16 + 10] = XD_MAGIC_16384 1383 bb[XD_MAGIC_112052 + xs*16 + 15] = XD_MAGIC_16384 1384 bb[XD_MAGIC_112052 + xs*16 + 3] = (0 - ga_piv(xs, 0))*XD_MAGIC_16384/600 1385 bb[XD_MAGIC_112052 + xs*16 + 7] = (0 - ga_piv(xs, 1))*XD_MAGIC_16384/600 1386 bb[XD_MAGIC_112052 + xs*16 + 11] = (0 - ga_piv(xs, 2))*XD_MAGIC_16384/600 1387 xs = xs + 1 1388 } 1389 var xbn: i64 = 0 1390 while xbn < 8 { 1391 var xkk: i64 = 0 1392 while xkk < nk { 1393 let src: i64 = (xbn*nk + xkk)*4 1394 let dst: i64 = XD_MAGIC_112228 + (xkk*8 + xbn)*4 1395 bb[dst] = qtrk[src]*4 1396 bb[dst + 1] = qtrk[src + 1]*4 1397 bb[dst + 2] = qtrk[src + 2]*4 1398 bb[dst + 3] = qtrk[src + 3]*4 1399 xkk = xkk + 1 1400 } 1401 xbn = xbn + 1 1402 } 1403 let p3: *u8 = "sites/nishifamily/exceed/vrm/being-dance.nxdv\x00" as *u8 1404 let fd3: i64 = sys_openat_wr(p3, 0x1a4) 1405 sys_write(fd3, bb as *u8, XB_TOT*8) 1406 sys_close(fd3) 1407 xd_w("artifact:ADDED sites/nishifamily/exceed/vrm/being-dance.nxdv bytes=" as *u8); xd_num(XB_TOT*8); xd_w(" (v2: position-retargeted + smooth 2-bone skin)\n" as *u8) 1408 1409 if fails == 0 { 1410 xd_w("DANCE-EMIT v2 GREEN -- position-retargeted mocap + smooth skin. Residual: bone twist, root motion, spine/head bones, VMD-corpus clip.\n" as *u8) 1411 return 0 1412 } 1413 xd_w("DANCE-EMIT RED fails=" as *u8); xd_num(fails); xd_w("\n" as *u8) 1414 return 1 1415}