code wiki / (root) / nx_gltf_quaternion_witness_t181.nx

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}