nx_gltf_quaternion_witness_t181.nx source
↩ module page · 57 lines · 3651 B
1import "nx_gltf_accessor_candidate_t181.nx"
2
3// High-precision geodesic quaternion interpolation. Repeated normalized midpoints
4// bisect the short great-circle arc; binary fraction selection avoids low-Q12 angles.
5const VM_Q30:i64=1073741824
6const VM_Q30_BITS:i64=30
7func vm_q_norm_q30(a:*i64,out:*i64,tolerance:i64)->i64 {
8 if tolerance<0||tolerance>VM_Q30{return -1}
9 var sum:i64=0;var i:i64=0
10 while i<4{if a[i]<0-VM_Q30||a[i]>VM_Q30{return -1};sum=sum+a[i]*a[i];i=i+1}
11 let length:i64=vm_isqrt(sum);if length<=0||vm_abs(length-VM_Q30)>tolerance{return -2}
12 i=0;while i<4{out[i]=a[i]*VM_Q30/length;i=i+1};return 0
13}
14func vm_q_slerp_q30(a:*i64,b:*i64,t:i64,tolerance:i64,out:*i64,scratch:*i64)->i64 {
15 if t<0||t>VM_Q30{return -1}
16 let lo:*i64=scratch;let hi:*i64=(scratch as i64+32) as *i64;let mid:*i64=(scratch as i64+64) as *i64
17 let lowrc:i64=vm_q_norm_q30(a,lo,tolerance);if lowrc!=0{return lowrc}
18 let highrc:i64=vm_q_norm_q30(b,hi,tolerance);if highrc!=0{return highrc}
19 var dot:i64=0;var i:i64=0;while i<4{dot=dot+lo[i]*hi[i];i=i+1}
20 if dot<0{i=0;while i<4{hi[i]=0-hi[i];i=i+1}}
21 var left:i64=0;var right:i64=VM_Q30;var step:i64=0
22 while step<VM_Q30_BITS{
23 if t==left{i=0;while i<4{out[i]=lo[i];i=i+1};return 0}
24 if t==right{i=0;while i<4{out[i]=hi[i];i=i+1};return 0}
25 i=0;var sum:i64=0;while i<4{mid[i]=(lo[i]+hi[i])/2;sum=sum+mid[i]*mid[i];i=i+1}
26 let length:i64=vm_isqrt(sum);if length<=0{return -2}
27 i=0;while i<4{mid[i]=mid[i]*VM_Q30/length;i=i+1}
28 let center:i64=(left+right)/2
29 if t==center{i=0;while i<4{out[i]=mid[i];i=i+1};return 0}
30 if t<center{i=0;while i<4{hi[i]=mid[i];i=i+1};right=center}else{i=0;while i<4{lo[i]=mid[i];i=i+1};left=center}
31 step=step+1
32 };return -3
33}
34
35func gp(s:*u8)->i64{sys_write(1,s,gll_slen(s));return 0}
36func gn(v:i64)->i64{let b:*u8=sys_mmap(32);var x:i64=v;var i:i64=31;if x<0{gp("-");x=0-x};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};sys_write(1,(b as i64+i+1) as *u8,31-i);sys_munmap(b,32);return 0}
37
38func main()->i64{
39 let ln:*i64=sys_mmap(16) as *i64;let src:*u8=sys_read_file("../knowledge/fetched/rigmodels-tifa-catwalk-143925f3.glb",ln)
40 let cx:*i64=sys_mmap(GLD_CONTEXT_WORDS*8) as *i64;let view:*i64=sys_mmap(GLD_VIEW_WORDS*8) as *i64
41 let rc:i64=gltf_view_open(src,ln[0],cx);if rc!=0{return 1}
42 let st:*i64=cx[5] as *i64;let a:*i64=sys_mmap(32) as *i64;let b:*i64=sys_mmap(32) as *i64;let out:*i64=sys_mmap(32) as *i64;let scratch:*i64=sys_mmap(96) as *i64
43 var ai:i64=24;var pass:i64=0
44 while ai<=124{
45 if gltf_accessor_view(cx,ai,st[2],view)!=0{return 2};if view[3]!=5126||view[5]!=4||view[1]<2{return 3}
46 gp("INPUT_ACCESSOR ");gn(ai-1);gp(" time_bits=");if gltf_accessor_view(cx,ai-1,st[2],view)!=0{return 5};if view[3]!=5126||view[5]!=1||view[1]<2{return 6};gn(gll_ru32(cx[8] as *u8,view[0]));gp(",");gn(gll_ru32(cx[8] as *u8,view[0]+view[2]));gp("\n");if gltf_accessor_view(cx,ai,st[2],view)!=0{return 7};gp("ACCESSOR ");gn(ai);gp(" first_two_bits=")
47 var k:i64=0;while k<4{let raw:i64=gll_ru32(cx[8] as *u8,view[0]+k*4);a[k]=vm_f32_to_int(raw,VM_Q30);gn(raw);gp(",");k=k+1}
48 k=0;while k<4{let raw:i64=gll_ru32(cx[8] as *u8,view[0]+view[2]+k*4);b[k]=vm_f32_to_int(raw,VM_Q30);gn(raw);gp(",");k=k+1};gp("
49")
50 var ti:i64=0;while ti<4{var t:i64=0;if ti==1{t=VM_Q30/3};if ti==2{t=VM_Q30/2};if ti==3{t=VM_Q30}
51 let qr:i64=vm_q_slerp_q30(a,b,t,1024,out,scratch);gp("sample fraction_q30=");gn(t);gp(" rc=");gn(qr);gp(" quaternion_q30=");k=0;while k<4{gn(out[k]);gp(",");k=k+1};gp("
52");if qr!=0{return 4};ti=ti+1}
53 pass=pass+1;if ai==24{ai=28}else{if ai==28{ai=124}else{break}}
54 }
55 gp("ACTUAL_QUATERNION_ACCESSORS=");gn(pass);gp("
56");return 0
57}