code wiki / (root) / nx_nxa_affine_palette_t34.nx

nx_nxa_affine_palette_t34.nx source

↩ module page · 36 lines · 2820 B

1// Private existing-animation consumer contract: W(t)*inverse(authored BindPose). 2import "nx_fbx_affine_t32.nx" 3import "nx_linalg_affine_t34.nx" 4const AF_Q20_TO_Q30:i64=1024 5func af_promote_q30(input:*i64,out:*i64)->i64{ 6 var i:i64=0;while i<16{if input[i]<=0-LA_AFFINE_MAX/AF_Q20_TO_Q30||input[i]>=LA_AFFINE_MAX/AF_Q20_TO_Q30{return LA_AFFINE_RANGE};i=i+1} 7 i=0;while i<16{out[i]=input[i]*AF_Q20_TO_Q30;i=i+1};return 0 8} 9func af_inverse_bind(bind:*i64,out:*i64,residual_budget:i64,report:*i64)->i64{ 10 if bind[3]!=0||bind[7]!=0||bind[11]!=0||bind[15]!=FBB_Q{return FBB_BAD} 11 let full:*i64=sys_mmap(128) as *i64;let linear:*i64=sys_mmap(128) as *i64;let translation:*i64=sys_mmap(128) as *i64 12 let a:*Mat=nx_mat_new(3,3);let inverse:*Mat=nx_mat_new(3,3) 13 var rc:i64=af_promote_q30(bind,full) 14 if rc==0{var r:i64=0;while r<3{var c:i64=0;while c<3{nx_mat_set(a,r,c,full[c*4+r]);c=c+1};r=r+1};rc=la_inverse3_q30(a,inverse,residual_budget,report)} 15 if rc==0{var r:i64=0;while r<3{var c:i64=0;while c<3{linear[c*4+r]=nx_mat_get(inverse,r,c);c=c+1};r=r+1};linear[15]=FQ_ONE 16 translation[0]=FQ_ONE;translation[5]=FQ_ONE;translation[10]=FQ_ONE;translation[15]=FQ_ONE;translation[12]=0-full[12];translation[13]=0-full[13];translation[14]=0-full[14] 17 rc=la_affine_compose_q30(linear,translation,out) 18 } 19 sys_munmap(full as *u8,128);sys_munmap(linear as *u8,128);sys_munmap(translation as *u8,128);sys_munmap(a.data as *u8,72);sys_munmap(a as *u8,NX_MAT_BYTES);sys_munmap(inverse.data as *u8,72);sys_munmap(inverse as *u8,NX_MAT_BYTES);return rc 20} 21func af_palette_matrix(world:*i64,inverse_bind:*i64,out:*i64)->i64{ 22 let promoted:*i64=sys_mmap(128) as *i64;let delta:*i64=sys_mmap(128) as *i64 23 var rc:i64=af_promote_q30(world,promoted) 24 if rc==0{rc=la_affine_compose_q30(promoted,inverse_bind,delta)} 25 if rc==0{var i:i64=0;while i<16{out[i]=delta[i]/AF_Q20_TO_Q30;i=i+1}} 26 sys_munmap(promoted as *u8,128);sys_munmap(delta as *u8,128);return rc 27} 28// Inverse transpose of the blended vertex linear transform, not a blend of inverse transposes. 29// Caller normalizes the resulting normal; singular blends explicitly refuse. 30func af_normal_matrix(blended:*i64,out:*i64,residual_budget:i64,report:*i64)->i64{ 31 let a:*Mat=nx_mat_new(3,3);let inverse:*Mat=nx_mat_new(3,3);var r:i64=0;var rc:i64=0 32 while r<3&&rc==0{var c:i64=0;while c<3&&rc==0{let value:i64=blended[c*4+r];if value<=0-LA_AFFINE_MAX/AF_Q20_TO_Q30||value>=LA_AFFINE_MAX/AF_Q20_TO_Q30{rc=LA_AFFINE_RANGE}else{nx_mat_set(a,r,c,value*AF_Q20_TO_Q30)};c=c+1};r=r+1} 33 if rc==0{rc=la_inverse3_q30(a,inverse,residual_budget,report)} 34 if rc==0{r=0;while r<3{var c:i64=0;while c<3{out[c*3+r]=nx_mat_get(inverse,c,r);c=c+1};r=r+1}} 35 sys_munmap(a.data as *u8,72);sys_munmap(a as *u8,NX_MAT_BYTES);sys_munmap(inverse.data as *u8,72);sys_munmap(inverse as *u8,NX_MAT_BYTES);return rc 36}