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}