code wiki / _hdl_build / nx_ng_avatar_rig.nx
nx_ng_avatar_rig.nx source
↩ module page · 174 lines · 10398 B
1// nx_ng_avatar_rig.nx -- CAP-NEURAL-AVATAR RUNG-2: the SKELETAL RIG. Extends nx_ng_avatar's 1-DOF single-
2// gaussian deform to a multi-gaussian character driven by a multi-BONE skeleton via LINEAR BLEND SKINNING
3// (LBS) -- the exact deformation math a DAZ Genesis figure / Unreal MetaHuman rig uses: each gaussian k's
4// posed center = mu0[k] + SUM_b w[k][b]*pose[b] (a learned per-gaussian skinning weight w binds it to the
5// bones). The KEY S-class rung toward beating DAZ/Unreal characters (shared primitive behind offline + real-
6// time). Honest gated proof, Q16 no-float, reuses the gaussian-splat + GD-fit spine from nx_ng_avatar:
7// T1 LEARNED-RIG: fit the skinning weights from posed frames -> loss->~0 AND w recovers the true binding.
8// T2 NOVEL-POSE: an untrained skeleton pose renders correctly (LBS is linear = generalizes, not memorized).
9// T3 NEG-CONTROL: a RIGID rig (all gaussians share one bone) CANNOT match a pose where the bones differ =
10// the skeleton is load-bearing. T4 BIT-EXACT.
11// HONEST: 1D positions, 2 bones, 2 gaussians, translation-LBS (no rotation), linear skinning. Full production
12// = 3D + rotational LBS + blendshapes (expression) + many bones/gaussians = the follow-on rungs. Sovereign:
13// nx_nofloat_autograd + syscalls. license_tier: ORIGINAL expect_exit: 0
14import "nx_nofloat_autograd.nx"
15import "nx_syscalls.nx"
16const K_MAGIC_1500: i64 = 1500
17const K_MAGIC_22938: i64 = 22938
18const K_MAGIC_42598: i64 = 42598
19const K_MAGIC_19661: i64 = 19661
20const K_MAGIC_32768: i64 = 32768
21const K_MAGIC_8192: i64 = 8192
22const K_MAGIC_26214: i64 = 26214
23const K_MAGIC_3000: i64 = 3000
24
25const RLOG: *u8 = "knowledge/status/ng_avatar_rig.log"
26const Q16: i64 = 65536
27const NP: i64 = 16
28const INV2S2: i64 = 2275555 // 1/(2 sigma^2) Q16, sigma=0.12
29const EPOCHS: i64 = 6000
30const LRQ: i64 = 48
31const NB: i64 = 2 // bones
32const NK: i64 = 2 // gaussians (character parts)
33const NPOSE: i64 = 4 // training skeleton poses
34
35func ap(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
36func apn(v: i64) -> i64 { let b: *u8=sys_mmap(28); var x: i64=v; if x<0{b[0]=45;sys_write(1,b,1);x=0-x} if x==0{b[0]=48;sys_write(1,b,1);return 0} var d: i64=0; var y: i64=x; while y>0{d=d+1;y=y/10} var i: i64=d-1; y=x; while i>=0{b[i]=(48+(y%10)) as u8; y=y/10; i=i-1} sys_write(1,b,d); return 0 }
37func a_abs(v: i64) -> i64 { if v<0 { return 0-v } return v }
38func aqm(a: i64, b: i64) -> i64 { return (a*b)>>16 }
39func rl_ws(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 }
40func rl_wn(fd: i64, v: i64) -> i64 { let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(fd,"-" as *u8,1);m=0-m} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(fd,b,k); return 0 }
41
42// single gaussian value at pixel p for a given center.
43func gval(center: i64, p: i64) -> i64 {
44 let pos: i64 = p*(Q16/NP) + (Q16/(2*NP))
45 let dlt: i64 = pos - center
46 let d2: i64 = aqm(dlt, dlt)
47 return nfa_fxexp(0 - aqm(d2, INV2S2))
48}
49// LBS posed center of gaussian k: mu0[k] + sum_b w[k*NB+b]*pose[b].
50func rig_center(mu0: *i64, w: *i64, pose: *i64, k: i64) -> i64 {
51 var c: i64 = mu0[k]
52 var b: i64 = 0
53 while b < NB { c = c + aqm(w[k*NB+b], pose[b]); b = b + 1 }
54 return c
55}
56// render the whole rig (sum of NK gaussians at their posed centers) into out[NP].
57func render_rig(mu0: *i64, w: *i64, pose: *i64, out: *i64) -> i64 {
58 var p: i64 = 0
59 while p < NP { out[p] = 0; p = p + 1 }
60 var k: i64 = 0
61 while k < NK {
62 let c: i64 = rig_center(mu0, w, pose, k)
63 var p2: i64 = 0
64 while p2 < NP { out[p2] = out[p2] + gval(c, p2); p2 = p2 + 1 }
65 k = k + 1
66 }
67 return 0
68}
69func sse(a: *i64, b: *i64) -> i64 { var s: i64=0; var p: i64=0; while p<NP { let d: i64=a[p]-b[p]; s=s+aqm(d,d); p=p+1 } return s }
70
71// GD-fit the skinning weights w (NK*NB) so render_rig matches the posed frames. Analytic LBS gradient
72// (chain through gaussian k: dg_k/dcenter_k = g_k*(x-center)/sigma^2 ; dcenter_k/dw[k][b] = pose[b]).
73func fit_skin(mu0: *i64, poses: *i64, frames: *i64, w: *i64, lf: *i64, ll: *i64) -> i64 {
74 let cur: *i64 = sys_mmap(NP*8) as *i64
75 let g: *i64 = sys_mmap(NK*NB*8) as *i64
76 var ep: i64 = 0
77 while ep < EPOCHS {
78 var gi: i64 = 0; while gi < NK*NB { g[gi] = 0; gi = gi + 1 }
79 var loss: i64 = 0
80 var f: i64 = 0
81 while f < NPOSE {
82 let pose_f: *i64 = ((poses as i64) + f*NB*8) as *i64
83 render_rig(mu0, w, pose_f, cur)
84 let fr: i64 = f*NP
85 var p0: i64 = 0
86 while p0 < NP { let resid0: i64 = cur[p0] - frames[fr+p0]; loss = loss + aqm(resid0, resid0); p0 = p0 + 1 }
87 var k: i64 = 0
88 while k < NK {
89 let c: i64 = rig_center(mu0, w, pose_f, k)
90 var p: i64 = 0
91 while p < NP {
92 let resid: i64 = cur[p] - frames[fr+p]
93 let gk: i64 = gval(c, p)
94 let pos: i64 = p*(Q16/NP) + (Q16/(2*NP))
95 let dxc: i64 = pos - c
96 let drdc: i64 = aqm(gk, aqm(dxc, 2 * INV2S2))
97 var b: i64 = 0
98 while b < NB { g[k*NB+b] = g[k*NB+b] + aqm(aqm(2 * resid, drdc), pose_f[b]); b = b + 1 }
99 p = p + 1
100 }
101 k = k + 1
102 }
103 f = f + 1
104 }
105 if ep == 0 { *lf = loss }
106 *ll = loss
107 if ep % K_MAGIC_1500 == 0 { ap(" fit ep " as *u8); apn(ep); ap(" loss=" as *u8); apn(loss); ap(" w=[" as *u8); apn(w[0]); ap(" " as *u8); apn(w[1]); ap(" | " as *u8); apn(w[2]); ap(" " as *u8); apn(w[3]); ap("]\n" as *u8) }
108 var wi: i64 = 0; while wi < NK*NB { w[wi] = w[wi] - aqm(LRQ, g[wi]); wi = wi + 1 }
109 ep = ep + 1
110 }
111 return 0
112}
113
114func main() -> i64 {
115 ap("nx_ng_avatar_rig: CAP-NEURAL-AVATAR rung-2 -- SKELETAL RIG (multi-bone linear blend skinning)\n" as *u8)
116 let mu0: *i64 = sys_mmap(NK*8) as *i64
117 mu0[0] = K_MAGIC_22938; mu0[1] = K_MAGIC_42598 // two gaussians at 0.35 and 0.65
118 // TRUE skinning: gaussian0 bound to bone0, gaussian1 to bone1.
119 let wt: *i64 = sys_mmap(NK*NB*8) as *i64
120 wt[0]=Q16; wt[1]=0; wt[2]=0; wt[3]=Q16
121 // training skeleton poses (bone translations, Q16): exercise each bone independently + together.
122 let poses: *i64 = sys_mmap(NPOSE*NB*8) as *i64
123 poses[0]=0; poses[1]=0
124 poses[2]=K_MAGIC_19661; poses[3]=0 // ( 0.3, 0.0)
125 poses[4]=0; poses[5]=K_MAGIC_19661 // ( 0.0, 0.3)
126 poses[6]=K_MAGIC_19661; poses[7]=0-K_MAGIC_19661 // ( 0.3,-0.3)
127 let frames: *i64 = sys_mmap(NPOSE*NP*8) as *i64
128 var f: i64=0
129 while f<NPOSE { let pf: *i64=((poses as i64)+f*NB*8) as *i64; let tmp: *i64=sys_mmap(NP*8) as *i64; render_rig(mu0, wt, pf, tmp); var p: i64=0; while p<NP { frames[f*NP+p]=tmp[p]; p=p+1 } f=f+1 }
130
131 // T1: FIT the skinning weights from posed frames (init uniform 0.5).
132 let w: *i64 = sys_mmap(NK*NB*8) as *i64
133 w[0]=K_MAGIC_32768; w[1]=K_MAGIC_32768; w[2]=K_MAGIC_32768; w[3]=K_MAGIC_32768
134 let lf: *i64=sys_mmap(8) as *i64; let ll: *i64=sys_mmap(8) as *i64
135 fit_skin(mu0, poses, frames, w, lf, ll)
136 var t1: i64=0
137 if (*ll)*50 < (*lf) { if a_abs(w[0]-Q16)<K_MAGIC_8192 { if a_abs(w[1])<K_MAGIC_8192 { if a_abs(w[2])<K_MAGIC_8192 { if a_abs(w[3]-Q16)<K_MAGIC_8192 { t1=1 } } } } }
138
139 // T2: NOVEL skeleton pose (-0.4, 0.4), NOT trained -> learned rig matches the true rig (LBS generalizes).
140 let np2: *i64=sys_mmap(NB*8) as *i64; np2[0]=0-K_MAGIC_26214; np2[1]=K_MAGIC_26214
141 let gen: *i64=sys_mmap(NP*8) as *i64; let refn: *i64=sys_mmap(NP*8) as *i64
142 render_rig(mu0, w, np2, gen); render_rig(mu0, wt, np2, refn)
143 let novel_err: i64 = sse(gen, refn)
144 var t2: i64=0; if novel_err < K_MAGIC_3000 { t2=1 }
145
146 // T3: NEG-CONTROL -- a RIGID rig (both gaussians share bone0) can't match a pose where bone1 moves.
147 let wr: *i64=sys_mmap(NK*NB*8) as *i64; wr[0]=Q16; wr[1]=0; wr[2]=Q16; wr[3]=0
148 let rigid: *i64=sys_mmap(NP*8) as *i64
149 var rigid_loss: i64=0
150 f=0; while f<NPOSE { let pf: *i64=((poses as i64)+f*NB*8) as *i64; render_rig(mu0, wr, pf, rigid); var p: i64=0; while p<NP { let d: i64=rigid[p]-frames[f*NP+p]; rigid_loss=rigid_loss+aqm(d,d); p=p+1 } f=f+1 }
151 var t3: i64=0; if rigid_loss > (*ll)*20 { t3=1 }
152
153 // T4: BIT-EXACT (re-fit -> same weights)
154 let w2: *i64=sys_mmap(NK*NB*8) as *i64; w2[0]=K_MAGIC_32768; w2[1]=K_MAGIC_32768; w2[2]=K_MAGIC_32768; w2[3]=K_MAGIC_32768
155 let lf2: *i64=sys_mmap(8) as *i64; let ll2: *i64=sys_mmap(8) as *i64
156 fit_skin(mu0, poses, frames, w2, lf2, ll2)
157 var t4: i64=0; if w2[0]==w[0] { if w2[3]==w[3] { t4=1 } }
158
159 ap(" T1 LEARNED-RIG: fit loss " as *u8); apn(*lf); ap("->" as *u8); apn(*ll); ap(" w=[" as *u8); apn(w[0]); ap(" " as *u8); apn(w[1]); ap(" | " as *u8); apn(w[2]); ap(" " as *u8); apn(w[3]); ap("] vs true[65536 0|0 65536] ok=" as *u8); apn(t1); ap("\n" as *u8)
160 ap(" T2 NOVEL-POSE(-0.4,0.4 untrained): err vs true rig=" as *u8); apn(novel_err); ap(" generalizes=" as *u8); apn(t2); ap("\n" as *u8)
161 ap(" T3 NEG-CONTROL rigid(shared-bone) loss=" as *u8); apn(rigid_loss); ap(" >> fitted " as *u8); apn(*ll); ap(" skeleton-load-bearing=" as *u8); apn(t3); ap("\n" as *u8)
162 ap(" T4 bit-exact=" as *u8); apn(t4); ap("\n" as *u8)
163 var ok: i64=1
164 if t1!=1 { ok=0 }
165 if t2!=1 { ok=0 }
166 if t3!=1 { ok=0 }
167 if t4!=1 { ok=0 }
168 let logf: i64=sys_openat_append(RLOG, 420)
169 if logf>=0 { rl_ws(logf,"NGRIG authored=organ skeletal-LBS t1=" as *u8); rl_wn(logf,t1); rl_ws(logf," t2_novel=" as *u8); rl_wn(logf,t2); rl_ws(logf," t3_negctl=" as *u8); rl_wn(logf,t3); rl_ws(logf," t4=" as *u8); rl_wn(logf,t4); if ok==1 { rl_ws(logf," verdict=GREEN\n" as *u8) } else { rl_ws(logf," verdict=RED\n" as *u8) } sys_close(logf) }
170 ap(" verdict=" as *u8)
171 if ok==1 { ap("GREEN (a multi-bone skeleton deforms a multi-gaussian character via learned LBS; generalizes to novel poses; skeleton load-bearing = the DAZ/MetaHuman rig primitive, sovereign no-float)\n" as *u8); sys_exit(0); return 0 }
172 ap("RED\n" as *u8)
173 sys_exit(1); return 1
174}