code wiki / (root) / nx_fbx_clip.nx

nx_fbx_clip.nx source

↩ module page · 122 lines · 5652 B

1// Authored AnimationStack reachability for the existing NXA animation importer. 2// Selects object identities only. Does not evaluate, retarget or claim affine fidelity. 3import "nx_fbx_bind.nx" 4const FC_BAD:i64=0-40 5const FC_MISSING:i64=0-41 6const FC_AMBIGUOUS:i64=0-42 7const FC_CAPACITY:i64=0-43 8const FC_STACK:i64=1 9const FC_LAYER:i64=2 10const FC_NODE:i64=3 11const FC_CURVE:i64=4 12const FC_MODEL:i64=5 13struct FbxClipObject { id:i64,kind:i64,offset:i64,name_offset:i64,name_bytes:i64,selected:i64, } 14struct FbxClipLink { src:i64,dst:i64,offset:i64,kind:i64,scale:i64, } 15struct FbxClipGraph { objects:*FbxClipObject,count:i64,links:*FbxClipLink,link_count:i64, } 16struct FbxClipSelection { stack_id:i64,layers:i64,nodes:i64,curves:i64,scale_nodes:i64, } 17func fc_object(g:*FbxClipGraph,i:i64)->*FbxClipObject{return ((g.objects as i64)+i*__size_of(FbxClipObject)) as *FbxClipObject} 18func fc_link(g:*FbxClipGraph,i:i64)->*FbxClipLink{return ((g.links as i64)+i*__size_of(FbxClipLink)) as *FbxClipLink} 19func fc_find(g:*FbxClipGraph,id:i64)->i64 { 20 var found:i64=FC_MISSING;var i:i64=0 21 while i<g.count{let o:*FbxClipObject=fc_object(g,i);if o.id==id{if found>=0{return FC_AMBIGUOUS};found=i};i=i+1} 22 return found 23} 24func fc_load(b:*u8,n:i64,g:*FbxClipGraph)->i64 { 25 let version:i64=fbxc_version(b,n);if version<0{return FC_BAD} 26 let big:i64=fbxc_big(version) 27 let h:*i64=sys_mmap(FBXC_OUTN*8) as *i64 28 if fbb_find_child(b,n,FBXC_TOPOFF,n,big,"Objects" as *u8,h)!=1{return FC_BAD} 29 var p:i64=h[FBXC_PROPSOFF]+h[FBXC_PLEN];let end:i64=h[FBXC_END] 30 let count:i64=fbb_sibling_count(b,n,p,end,big);if count<=0{return FC_BAD} 31 g.objects=sys_mmap(count*__size_of(FbxClipObject)) as *FbxClipObject;g.count=count 32 var i:i64=0 33 while i<count{ 34 if fbb_node(b,n,p,end,big,h)!=1{return FC_BAD} 35 let o:*FbxClipObject=fc_object(g,i);o.offset=p 36 let po:i64=h[FBXC_PROPSOFF];let pe:i64=po+h[FBXC_PLEN] 37 if fbb_property_size(b,po,pe)!=9||b[po]!=(76 as u8){return FC_BAD} 38 o.id=fbxc_i64le(b,po+1) 39 let ns:i64=fbb_property_size(b,po+9,pe) 40 if ns<5||b[po+9]!=(83 as u8){return FC_BAD} 41 o.name_offset=po+14;o.name_bytes=ns-5 42 if fbxc_name_is(b,h[FBXC_NAMEOFF],h[FBXC_NAMELEN],"AnimationStack" as *u8)==1{o.kind=FC_STACK} 43 if fbxc_name_is(b,h[FBXC_NAMEOFF],h[FBXC_NAMELEN],"AnimationLayer" as *u8)==1{o.kind=FC_LAYER} 44 if fbxc_name_is(b,h[FBXC_NAMEOFF],h[FBXC_NAMELEN],"AnimationCurveNode" as *u8)==1{o.kind=FC_NODE} 45 if fbxc_name_is(b,h[FBXC_NAMEOFF],h[FBXC_NAMELEN],"AnimationCurve" as *u8)==1{o.kind=FC_CURVE} 46 if fbxc_name_is(b,h[FBXC_NAMEOFF],h[FBXC_NAMELEN],"Model" as *u8)==1{o.kind=FC_MODEL} 47 p=h[FBXC_END];i=i+1 48 } 49 if fbb_find_child(b,n,FBXC_TOPOFF,n,big,"Connections" as *u8,h)!=1{return FC_BAD} 50 p=h[FBXC_PROPSOFF]+h[FBXC_PLEN];let ce:i64=h[FBXC_END] 51 let links:i64=fbb_sibling_count(b,n,p,ce,big);if links<0{return FC_BAD} 52 g.links=sys_mmap((links+1)*__size_of(FbxClipLink)) as *FbxClipLink;g.link_count=0 53 i=0 54 while i<links{ 55 if fbb_node(b,n,p,ce,big,h)!=1{return FC_BAD} 56 let po:i64=h[FBXC_PROPSOFF];let pe:i64=po+h[FBXC_PLEN] 57 if fbb_string(b,po,pe,"OO" as *u8)==1||fbb_string(b,po,pe,"OP" as *u8)==1{ 58 let a:i64=po+fbb_property_size(b,po,pe) 59 if fbb_property_size(b,a,pe)!=9||fbb_property_size(b,a+9,pe)!=9||b[a]!=(76 as u8)||b[a+9]!=(76 as u8){return FC_BAD} 60 let l:*FbxClipLink=fc_link(g,g.link_count);l.src=fbxc_i64le(b,a+1);l.dst=fbxc_i64le(b,a+10);l.offset=p;l.kind=1 61 if fbb_string(b,po,pe,"OP" as *u8)==1{l.kind=2} 62 if l.kind==2{if fbb_string(b,a+18,pe,"Lcl Scaling" as *u8)==1{l.scale=1}} 63 g.link_count=g.link_count+1 64 } 65 p=h[FBXC_END];i=i+1 66 } 67 sys_munmap(h as *u8,FBXC_OUTN*8);return 0 68} 69// Exactly one parent at the previous animation level prevents mixing stack/layer ownership. 70func fc_select(g:*FbxClipGraph,id:i64,max_nodes:i64,max_curves:i64,s:*FbxClipSelection)->i64 { 71 s.stack_id=id;s.layers=0;s.nodes=0;s.curves=0;s.scale_nodes=0 72 var i:i64=0;while i<g.count{let o:*FbxClipObject=fc_object(g,i);o.selected=0;i=i+1} 73 let selected:i64=fc_find(g,id);if selected<0{return selected} 74 let stack:*FbxClipObject=fc_object(g,selected);if stack.kind!=FC_STACK{return FC_MISSING};stack.selected=1 75 var kind:i64=FC_LAYER 76 while kind<=FC_CURVE{ 77 i=0 78 while i<g.count{ 79 let o:*FbxClipObject=fc_object(g,i) 80 if o.kind==kind{ 81 var j:i64=0;var parents:i64=0;var chosen:i64=0 82 while j<g.link_count{ 83 let l:*FbxClipLink=fc_link(g,j) 84 if l.src==o.id{ 85 let parent:i64=fc_find(g,l.dst) 86 if parent==FC_AMBIGUOUS{return FC_AMBIGUOUS} 87 if parent>=0{let p:*FbxClipObject=fc_object(g,parent);if p.kind==kind-1{if kind==FC_CURVE{if l.kind!=2{return FC_BAD}}else{if l.kind!=1{return FC_BAD}};parents=parents+1;if p.selected==1{chosen=chosen+1}}} 88 } 89 j=j+1 90 } 91 if chosen>0{ 92 if parents!=1||chosen!=1||fc_find(g,o.id)!=i{return FC_AMBIGUOUS} 93 o.selected=1 94 if kind==FC_LAYER{s.layers=s.layers+1} 95 if kind==FC_NODE{s.nodes=s.nodes+1;if s.nodes>max_nodes{return FC_CAPACITY}} 96 if kind==FC_CURVE{s.curves=s.curves+1;if s.curves>max_curves{return FC_CAPACITY}} 97 } 98 } 99 i=i+1 100 } 101 kind=kind+1 102 } 103 i=0 104 while i<g.count{ 105 let o:*FbxClipObject=fc_object(g,i) 106 if o.kind==FC_NODE&&o.selected==1{ 107 var j:i64=0;var models:i64=0 108 while j<g.link_count{ 109 let l:*FbxClipLink=fc_link(g,j) 110 if l.src==o.id&&l.kind==2{ 111 let m:i64=fc_find(g,l.dst);if m==FC_AMBIGUOUS{return FC_AMBIGUOUS} 112 if m>=0{let model:*FbxClipObject=fc_object(g,m);if model.kind==FC_MODEL{models=models+1;if l.scale==1{s.scale_nodes=s.scale_nodes+1}}} 113 } 114 j=j+1 115 } 116 if models!=1{return FC_AMBIGUOUS} 117 } 118 i=i+1 119 } 120 if s.layers==0||s.nodes==0||s.curves==0{return FC_MISSING} 121 return 0 122}