code wiki / (root) / nx_gltf_clip_pack_t321.nx

nx_gltf_clip_pack_t321.nx source

↩ module page · 88 lines · 6377 B

1// Full authored glTF tracks, not sampled palettes. Reuses native accessor/pose owners. 2// Caller owns returned storage. ABI GPA1 v1:20headerwords,8words/track; all offsets words. 3import "nx_gltf_render_descriptor_candidate_t181.nx" 4import "nx_atomic_rewrite.nx" 5import "nx_itoa_lib.nx" 6const GCP_HEADER:i64=20 7const GCP_TRACK:i64=8 8const GCP_MAGIC:i64=0x47504131 9func gcp_track(cx:*i64,an:i64,index:i64,row:*i64,iv:*i64,ov:*i64)->i64{ 10 let channel:i64=gld_nth(cx,an,"channels",index);if channel<0{return -1} 11 let sampler:i64=gld_int(cx,channel,"sampler",-1);if sampler<0||gli_member(cx,channel,"target")!=1{return -1} 12 let sp:*i64=cx[4] as *i64;let target:i64=sp[0];let node:i64=gld_int(cx,target,"node",-1);let st:*i64=cx[5] as *i64 13 if node<0||node>=st[5]||gli_member(cx,target,"path")!=1{return -1} 14 let tok:*NxJsonTok=cx[2] as *NxJsonTok;glp_reset(tok,cx[0] as *u8,cx[1],sp[0]);var flag:i64=0;var components:i64=3 15 if glp_eq(tok,"translation")==1{flag=1};if glp_eq(tok,"rotation")==1{flag=2;components=4};if glp_eq(tok,"scale")==1{flag=4} 16 if flag==0{return -2};let nat:i64=gld_nth(cx,0,"nodes",node);if gli_member(cx,nat,"matrix")!=0{return -2} 17 let sa:i64=gld_nth(cx,an,"samplers",sampler);if sa<0{return -1};var mode:i64=0;let ih:i64=gli_member(cx,sa,"interpolation");if ih<0{return -1} 18 if ih==1{glp_reset(tok,cx[0] as *u8,cx[1],sp[0]);if glp_eq(tok,"STEP")==1{mode=1}else{if glp_eq(tok,"LINEAR")!=1{return -2}}} 19 let input:i64=gld_int(cx,sa,"input",-1);let output:i64=gld_int(cx,sa,"output",-1) 20 if gltf_accessor_view(cx,input,st[2],iv)!=0||gltf_accessor_view(cx,output,st[2],ov)!=0{return -1} 21 if iv[3]!=5126||iv[5]!=1||iv[1]<1||ov[3]!=5126||ov[5]!=components||iv[1]!=ov[1]{return -1} 22 row[0]=node;row[1]=flag;row[2]=mode;row[3]=iv[1];row[4]=input;row[5]=output;row[6]=components;row[7]=0;return 0 23} 24func gltf_clip_pack(cx:*i64,animation:i64,skin:i64,result:*i64)->i64{ 25 result[0]=0;result[1]=0 26 let st:*i64=cx[5] as *i64;let nodes:i64=st[5];let sk:i64=gld_nth(cx,0,"skins",skin);let an:i64=gld_nth(cx,0,"animations",animation) 27 if sk<0||an<0||nodes<1{return -1};let joints:i64=gli_array(cx,sk,"joints",0);let tracks:i64=gli_array(cx,an,"channels",0) 28 let max:i64=GLD_I64_MAX/8 29 if joints<1||joints>nodes||tracks<1||nodes>(max-GCP_HEADER)/28{return -1} 30 var words:i64=GCP_HEADER+nodes*28 31 if joints>(max-words)/17{return -1};words=words+joints*17 32 if tracks>(max-words)/GCP_TRACK{return -1};words=words+tracks*GCP_TRACK 33 let scratchBytes:i64=(GLD_VIEW_WORDS*2+GCP_TRACK+8+nodes)*8 34 let scratch:*u8=sys_mmap_try(scratchBytes);if (scratch as i64)==0{return -7} 35 let iv:*i64=scratch as *i64;let ov:*i64=(scratch as i64+GLD_VIEW_WORDS*8) as *i64 36 let row:*i64=(ov as i64+GLD_VIEW_WORDS*8) as *i64;let val:*i64=(row as i64+GCP_TRACK*8) as *i64 37 let masks:*i64=(val as i64+64) as *i64 38 var i:i64=0;var rc:i64=0;while i<nodes{masks[i]=0;i=i+1} 39 i=0;while i<tracks&&rc==0{ 40 rc=gcp_track(cx,an,i,row,iv,ov);if rc!=0{break} 41 if (masks[row[0]]&row[1])!=0{rc=-1;break};masks[row[0]]=masks[row[0]]|row[1] 42 if row[3]>(max-words)/(row[6]+1){rc=-1;break};words=words+row[3]*(row[6]+1);i=i+1 43 } 44 if rc!=0{sys_munmap_direct(scratch,scratchBytes);return rc} 45 let p:*i64=sys_mmap_try(words*8) as *i64;if (p as i64)==0{sys_munmap_direct(scratch,scratchBytes);return -7} 46 p[0]=GCP_MAGIC;p[1]=1;p[2]=words;p[3]=nodes;p[4]=joints;p[5]=tracks;p[6]=0;p[7]=FBB_Q;p[8]=VM_Q30 47 p[9]=GCP_HEADER;p[10]=p[9]+nodes;p[11]=p[10]+nodes*10;p[12]=p[11]+nodes*16;p[13]=p[12]+nodes;p[14]=p[13]+joints;p[15]=p[14]+joints*16;p[16]=p[15]+tracks*GCP_TRACK;p[17]=animation;p[18]=skin;p[19]=0 48 let parents:*i64=(p as i64+p[9]*8) as *i64;let trs:*i64=(p as i64+p[10]*8) as *i64;let matrices:*i64=(p as i64+p[11]*8) as *i64;let flags:*i64=(p as i64+p[12]*8) as *i64 49 rc=gld_parents(cx,nodes,parents);i=0 50 while i<nodes&&rc==0{let f:i64=gld_node_trs(cx,i,(trs as i64+i*80) as *i64,(matrices as i64+i*128) as *i64);if f<0{rc=f;break};flags[i]=f;i=i+1} 51 let ib:i64=gld_int(cx,sk,"inverseBindMatrices",-1) 52 if rc==0{if ib<0{rc=-2}else{rc=gltf_accessor_view(cx,ib,st[2],iv)}} 53 if rc==0{if iv[3]!=5126||iv[5]!=16||iv[1]!=joints{rc=-1}} 54 i=0;while i<nodes{masks[i]=0;i=i+1};i=0 55 while i<joints&&rc==0{ 56 let at:i64=gld_nth(cx,sk,"joints",i);let tok:*NxJsonTok=cx[2] as *NxJsonTok 57 if at<0{rc=-1;break};glp_reset(tok,cx[0] as *u8,cx[1],at);let node:i64=gld_uint(tok) 58 if node<0||node>=nodes||masks[node]!=0{rc=-1;break};masks[node]=1;p[p[13]+i]=node 59 var k:i64=0;while k<16{rc=gld_view_float(cx,iv,i,k,FBB_Q,(p as i64+(p[14]+i*16+k)*8) as *i64);if rc!=0{break};k=k+1};i=i+1 60 } 61 var cursor:i64=p[16];i=0 62 while i<tracks&&rc==0{ 63 rc=gcp_track(cx,an,i,row,iv,ov);if rc!=0{break} 64 let rec:i64=p[15]+i*GCP_TRACK;var k:i64=0;while k<GCP_TRACK{p[rec+k]=row[k];k=k+1} 65 p[rec+4]=cursor;p[rec+5]=cursor+row[3];cursor=cursor+row[3]*(row[6]+1) 66 var last:i64=-1;k=0 67 while k<row[3]&&rc==0{ 68 rc=gld_view_float(cx,iv,k,0,VM_Q30,val);if rc!=0{break};if val[0]<0||val[0]<=last{rc=-1;break};last=val[0];p[p[rec+4]+k]=last;if last>p[6]{p[6]=last} 69 var q:i64=FBB_Q;if row[1]==2{q=VM_Q30};var c:i64=0 70 while c<row[6]{rc=gld_view_float(cx,ov,k,c,q,(p as i64+(p[rec+5]+k*row[6]+c)*8) as *i64);if rc!=0{break};c=c+1} 71 if row[1]==2&&rc==0{rc=vm_q_norm_q30((p as i64+(p[rec+5]+k*4)*8) as *i64,val,1024)} 72 k=k+1 73 };i=i+1 74 } 75 sys_munmap_direct(scratch,scratchBytes) 76 if rc!=0||cursor!=words||p[6]<=0{sys_munmap_direct(p as *u8,words*8);if rc==0{return -1};return rc} 77 result[0]=p as i64;result[1]=words;return 0 78} 79func gcp_s(s:*u8)->i64{return sys_write(1,s,gll_slen(s))} 80func main(argc:i64,argv:*i64)->i64{ 81 if argc!=3{return 2};let ln:*i64=sys_mmap(8) as *i64;let src:*u8=sys_read_file(argv[1] as *u8,ln);if (src as i64)==0{return 3} 82 let cx:*i64=sys_mmap(GLD_CONTEXT_WORDS*8) as *i64;if gltf_view_open(src,ln[0],cx)!=0{return 4} 83 let result:*i64=sys_mmap(16) as *i64;let rc:i64=gltf_clip_pack(cx,0,0,result) 84 if rc!=0{gcp_s("clip_pack_failed\n" as *u8);return 5} 85 let p:*i64=result[0] as *i64;let written:i64=atomic_rewrite_checked(argv[2] as *u8,p as *u8,result[1]*8) 86 if written!=0{return 6};gcp_s("FULL_CLIP_PACK_OK nodes=" as *u8);nxi_out(p[3]);gcp_s(" joints=" as *u8);nxi_out(p[4]);gcp_s(" tracks=" as *u8);nxi_out(p[5]);gcp_s(" durationQ30=" as *u8);nxi_out(p[6]);gcp_s(" words=" as *u8);nxi_out(p[2]);gcp_s("\n" as *u8) 87 sys_munmap_direct(p as *u8,result[1]*8);gltf_view_close(cx);sys_free_file(src,ln[0]);return 0 88}