code wiki / _hdl_build / nx_retarget_emit.nx
nx_retarget_emit.nx source
↩ module page · 92 lines · 5600 B
1// nx_retarget_emit.nx -- R3 APPLICATION LEG (debt 1785900608/1785900993): export the being as a SKINNED, WALKING .glb. Mesh the skin, bind each vertex to its nearest
2// part's deepest FK bone, export with a walk-cycle animation, self-verify the container + names. Writes nishi_being_walk.glb.
3// license_tier: ORIGINAL expect_exit: 0
4import "nx_syscalls.nx"
5import "nx_trimesh.nx"
6import "nx_isosurf.nx"
7import "nx_bodyatlas.nx"
8import "nx_gltf_anim.nx"
9const K_MAGIC_1231: i64 = 1231
10const K_MAGIC_1403: i64 = 1403
11const K_MAGIC_1067: i64 = 1067
12const K_MEASURED_CALF_1179: i64 = 1179 // theirs/ours fx1024, derived frame-cancelling via the CONVERGED thigh: (their shin->foot 0.38811 / their hip->knee 0.34247) / (our knee->ankle 400 / our hip->knee 390) * 1067
13const K_MAGIC_65536: i64 = 65536
14const K_MAGIC_8388608: i64 = 8388608
15
16func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
17func pn(v: i64) -> i64 { let b: *u8=sys_mmap(32) as *u8; var x: i64=v; var ng: i64=0; if x<0{ng=1;x=0-x} var i: i64=31; if x==0{b[i]=48 as u8;i=i-1} while x>0{b[i]=(48+x%10) as u8;x=x/10;i=i-1} if ng==1{b[i]=45 as u8;i=i-1} sys_write(1,(b as i64+i+1) as *u8,31-i); return 0 }
18func 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) }
19func 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 }
20
21const GX: i64 = 32
22const GY: i64 = 110
23const GZ: i64 = 20
24const GC: i64 = 18
25const OX: i64 = 0-288
26const OY: i64 = 0-990
27const OZ: i64 = 0-180
28
29func main() -> i64 {
30 hw("=== nx_retarget_emit -- being in SEED-SAN proportions -> .glb ===\n" as *u8)
31 var fails: i64 = 0
32 ba_set_axes(363, K_MAGIC_1231, K_MAGIC_1403, K_MAGIC_1067, K_MEASURED_CALF_1179) // MEASURED Seed-san retarget vector fx1024 (shw/hipw/arm/thigh/calf; calf expressible since the 11-joint ankle-landmark rig)
33 atlas_build(0)
34 let grid: *i64 = sys_mmap((GX+1)*(GY+1)*(GZ+1)*8) as *i64
35 var i: i64 = 0
36 while i <= GX { var jj: i64=0; while jj<=GY { var k: i64=0; while k<=GZ { grid[(i*(GY+1)+jj)*(GZ+1)+k] = ba_sdf(OX+i*GC, OY+jj*GC, OZ+k*GC, 1); k=k+1 } jj=jj+1 } i=i+1 }
37 tm_reset()
38 surface_nets(grid, GX, GY, GZ, OX, OY, OZ, GC, 0, 216+172*256+152*K_MAGIC_65536)
39 let NV: i64 = tm_nv()
40 // per-vertex joint + colour, from nearest part
41 let jarr: *i64 = sys_mmap(NV*8) as *i64
42 let vp: *i64 = sys_mmap(24) as *i64
43 let jc: *i64 = sys_mmap(9*8) as *i64
44 var b: i64 = 0
45 while b < 9 { jc[b]=0; b=b+1 }
46 i = 0
47 while i < NV {
48 tm_vpos(i, vp)
49 let kk: i64 = ba_nearest(vp[0], vp[1], vp[2], 1)
50 var jt: i64 = 0
51 if kk >= 0 { jt = ba_part_bone(kk); tm_vcol(i, ba_part_color(kk)) } else { tm_vcol(i, 216+172*256+152*K_MAGIC_65536) }
52 jarr[i] = jt
53 jc[jt] = jc[jt] + 1
54 i = i + 1
55 }
56 hw(" verts="); pn(NV); hw(" joint spread root="); pn(jc[0]); hw(" Lsh="); pn(jc[1]); hw(" Lel="); pn(jc[2]); hw(" Rsh="); pn(jc[3]); hw(" Lhip="); pn(jc[5]); hw(" Lkn="); pn(jc[6]); hw("\n" as *u8)
57 var t0: i64 = 0
58 if jc[1] > 20 { if jc[5] > 20 { if jc[6] > 20 { t0 = 1 } } } // limbs actually got bound to bones
59 if t0 == 1 { hw("T0 PASS vertices bound across the FK bones (arms + legs rigged)\n" as *u8) } else { fails=fails+1; hw("T0 FAIL binding\n" as *u8) }
60
61 let out: *u8 = sys_mmap(K_MAGIC_8388608)
62 let total: i64 = gltf_anim_export(out, jarr)
63 hw(" glb bytes="); pn(total); hw("\n" as *u8)
64 // self-verify container + rigging/animation presence
65 var t1: i64 = 0
66 if (out[0] as i64)==103 { if ru32(out,8)==total { t1=1 } }
67 if t1 == 1 { hw("T1 PASS glTF header + length\n" as *u8) } else { fails=fails+1; hw("T1 FAIL\n" as *u8) }
68 let jsonLen: i64 = ru32(out,12)
69 let binLenPos: i64 = 20+jsonLen
70 let binLen: i64 = ru32(out,binLenPos)
71 var t2: i64 = 0
72 if (12+8+jsonLen+8+binLen)==total { if (out[binLenPos+4] as i64)==66 { t2=1 } }
73 if t2 == 1 { hw("T2 PASS chunk arithmetic + BIN type\n" as *u8) } else { fails=fails+1; hw("T2 FAIL\n" as *u8) }
74 var t3: i64 = 0
75 if hasstr(out,20+jsonLen,"animations"as *u8)==1 { if hasstr(out,20+jsonLen,"skins"as *u8)==1 { if hasstr(out,20+jsonLen,"JOINTS_0"as *u8)==1 { if hasstr(out,20+jsonLen,"\"walk\""as *u8)==1 { t3=1 } } } }
76 if t3 == 1 { hw("T3 PASS JSON declares skin + JOINTS_0 + a 'walk' animation\n" as *u8) } else { fails=fails+1; hw("T3 FAIL\n" as *u8) }
77
78 let fd: i64 = sys_openat_wr("knowledge/nishi_being_seedsan.glb\x00" as *u8, 0x1a4)
79 sys_write(fd, out, total)
80 sys_close(fd)
81 hw("wrote knowledge/nishi_being_seedsan.glb ("); pn(total); hw(" bytes)\n" as *u8)
82 // publish where consumers look (the /exceed/vrm T2 slot serves this exact path)
83 let fd2: i64 = sys_openat_wr("sites/nishifamily/exceed/vrm/nishi-in-seedsan-proportions.glb\x00" as *u8, 0x1a4)
84 sys_write(fd2, out, total)
85 sys_close(fd2)
86 hw("wrote sites/nishifamily/exceed/vrm/nishi-in-seedsan-proportions.glb ("); pn(total); hw(" bytes)\n" as *u8)
87
88 if fails == 0 { hw("GLTF-ANIM-GATE GREEN -- the being exports as a SKINNED, WALKING .glb (11-joint rig: 9 FK bones + 2 ankle calf-landmarks, walk-cycle quaternion keyframes). Plays in any glTF viewer. Residual: skinning in our own web viewer (next).\n" as *u8); sys_exit(0); return 0 }
89 hw("GLTF-ANIM-GATE RED fails="); pn(fails); hw("\n" as *u8)
90 sys_exit(1)
91 return 1
92}