nx_gltf_render_descriptor_before_material_t218.nx source
↩ module page · 100 lines · 10061 B
1import "nx_gltf_pose_candidate_t181.nx"
2import "nx_sha256.nx"
3func gpd_source_identity(w:*i64,cx:*i64)->i64{
4 let digest:*u8=sys_mmap_try(32);if (digest as i64)==0{return -7};sha256_digest(cx[6] as *u8,cx[7],digest);let hex:*u8="0123456789abcdef";gpd_s(w,"\"sourceSha256\":\"");var i:i64=0;while i<32{let b:i64=digest[i] as i64;gpd_put(w,(hex as i64+b/16) as *u8,1);gpd_put(w,(hex as i64+b%16) as *u8,1);i=i+1};gpd_s(w,"\",");sys_munmap_direct(digest,32);return 0
5}
6
7// Native render descriptor over retained GLB bytes. No geometry or image transcoding.
8// Writer state: output, capacity, position, failure. A null output performs sizing.
9func gpd_put(w:*i64,s:*u8,n:i64)->i64{
10 if w[3]!=0{return -1};if n<0||w[2]>GLD_I64_MAX-n{w[3]=-1;return -1}
11 if w[0]>0{if n>w[1]-w[2]{w[3]=-1;return -1};let b:*u8=w[0] as *u8;var i:i64=0;while i<n{b[w[2]+i]=s[i];i=i+1}}
12 w[2]=w[2]+n;return 0
13}
14func gpd_s(w:*i64,s:*u8)->i64{return gpd_put(w,s,gll_slen(s))}
15func gpd_n(w:*i64,n:i64)->i64{
16 if n<0{w[3]=-1;return -1};var d:i64=1;while d<=n/10{d=d*10};var left:i64=n
17 while d>0{let digit:i64=48+left/d;let chars:*u8="0123456789";if gpd_put(w,(chars as i64+digit-48) as *u8,1)!=0{return -1};left=left%d;d=d/10};return 0
18}
19func gpd_raw(w:*i64,cx:*i64,parent:i64,key:*u8,fallback:*u8)->i64{
20 let h:i64=gli_member(cx,parent,key);if h<0{return -1};if h==0{return gpd_s(w,fallback)}
21 let sp:*i64=cx[4] as *i64;return gpd_put(w,(cx[0]+sp[0]) as *u8,sp[1]-sp[0])
22}
23func gpd_view(w:*i64,cx:*i64,accessor:i64,v:*i64)->i64{
24 let st:*i64=cx[5] as *i64;if gltf_accessor_view(cx,accessor,st[2],v)!=0{return -1}
25 gpd_s(w,"[");gpd_n(w,accessor);var i:i64=0;while i<GLD_VIEW_WORDS{gpd_s(w,",");gpd_n(w,v[i]);i=i+1};return gpd_s(w,"]")
26}
27func gpd_alpha(cx:*i64,mat:i64)->i64{
28 let have:i64=gli_member(cx,mat,"alphaMode");if have<0{return -1};if have==0{return 0}
29 let t:*NxJsonTok=cx[2] as *NxJsonTok;let sp:*i64=cx[4] as *i64;glp_reset(t,cx[0] as *u8,cx[1],sp[0])
30 if glp_eq(t,"OPAQUE")==1{return 0};if glp_eq(t,"MASK")==1{return 1};if glp_eq(t,"BLEND")==1{return 2};return -1
31}
32func gpd_image(w:*i64,cx:*i64,texture:i64)->i64{
33 let tx:i64=gld_nth(cx,0,"textures",texture);if tx<0||gli_member(cx,tx,"extensions")!=0{return -1}
34 let image:i64=gld_int(cx,tx,"source",-1);let im:i64=gld_nth(cx,0,"images",image);if im<0||gli_member(cx,im,"uri")!=0{return -1}
35 let vi:i64=gld_int(cx,im,"bufferView",-1);let view:i64=gld_nth(cx,0,"bufferViews",vi);if view<0||gld_int(cx,view,"buffer",-1)!=0||gli_member(cx,view,"extensions")!=0{return -1}
36 let off:i64=gld_int(cx,view,"byteOffset",0);let len:i64=gld_int(cx,view,"byteLength",-1);let bf:i64=gld_nth(cx,0,"buffers",0);let declared:i64=gld_int(cx,bf,"byteLength",-1)
37 if off<0||len<=0||off>declared||len>declared-off{return -1}
38 gpd_s(w,"{\"image\":");gpd_n(w,image);gpd_s(w,",\"offset\":");gpd_n(w,cx[8]-cx[6]+off);gpd_s(w,",\"bytes\":");gpd_n(w,len);gpd_s(w,",\"mime\":");if gpd_raw(w,cx,im,"mimeType","null")!=0{return -1}
39 let si:i64=gld_int(cx,tx,"sampler",-1);var sampler:i64=-1;if si>=0{sampler=gld_nth(cx,0,"samplers",si);if sampler<0{return -1}}
40 gpd_s(w,",\"sampler\":{");var mag:i64=9729;var min:i64=9987;var ws:i64=10497;var wt:i64=10497
41 if sampler>=0{mag=gld_int(cx,sampler,"magFilter",9729);min=gld_int(cx,sampler,"minFilter",9987);ws=gld_int(cx,sampler,"wrapS",10497);wt=gld_int(cx,sampler,"wrapT",10497)}
42 if mag!=9728&&mag!=9729{return -1};if min!=9728&&min!=9729&&min!=9984&&min!=9985&&min!=9986&&min!=9987{return -1}
43 if ws!=10497&&ws!=33071&&ws!=33648{return -1};if wt!=10497&&wt!=33071&&wt!=33648{return -1}
44 gpd_s(w,"\"mag\":");gpd_n(w,mag);gpd_s(w,",\"min\":");gpd_n(w,min);gpd_s(w,",\"wrapS\":");gpd_n(w,ws);gpd_s(w,",\"wrapT\":");gpd_n(w,wt);return gpd_s(w,"}}")
45}
46func gpd_material(w:*i64,cx:*i64,index:i64)->i64{
47 let mat:i64=gld_nth(cx,0,"materials",index);if mat<0||gli_member(cx,mat,"extensions")!=0{return -1}
48 let mode:i64=gpd_alpha(cx,mat);if mode<0{return -1}
49 gpd_s(w,"{\"index\":");gpd_n(w,index);gpd_s(w,",\"alpha\":");gpd_n(w,mode);gpd_s(w,",\"cutoff\":");if gpd_raw(w,cx,mat,"alphaCutoff","0.5")!=0{return -1}
50 gpd_s(w,",\"doubleSided\":");if gpd_raw(w,cx,mat,"doubleSided","false")!=0{return -1}
51 var h:i64=gli_member(cx,mat,"pbrMetallicRoughness");if h<0{return -1};let sp:*i64=cx[4] as *i64;var pbr:i64=-1;if h==1{pbr=sp[0]}
52 gpd_s(w,",\"factor\":");if pbr<0{gpd_s(w,"[1,1,1,1]")}else{if gpd_raw(w,cx,pbr,"baseColorFactor","[1,1,1,1]")!=0{return -1}}
53 gpd_s(w,",\"baseColor\":");var texture:i64=-1
54 if pbr>=0{h=gli_member(cx,pbr,"baseColorTexture");if h<0{return -1};if h==1{let bt:i64=sp[0];if gli_member(cx,bt,"extensions")!=0||gld_int(cx,bt,"texCoord",0)!=0{return -1};texture=gld_int(cx,bt,"index",-1);if texture<0{return -1}}}
55 if texture<0{gpd_s(w,"null")}else{if gpd_image(w,cx,texture)!=0{return -1}}
56 return gpd_s(w,"}")
57}
58func gltf_render_descriptor(cx:*i64,mesh:i64,skin:i64,w:*i64)->i64{
59 if (cx as i64)<=0||(w as i64)<=0{return -1};let st:*i64=cx[5] as *i64
60 let m:i64=gld_nth(cx,0,"meshes",mesh);let sk:i64=gld_nth(cx,0,"skins",skin);if m<0||sk<0{return -1}
61 if gli_member(cx,m,"extensions")!=0||gli_member(cx,m,"weights")!=0{return -2}
62 let n:i64=gli_array(cx,m,"primitives",0);if n<=0{return -1};let joints:i64=gli_array(cx,sk,"joints",0);if joints<=0{return -1}
63 let v:*i64=sys_mmap_try(GLD_VIEW_WORDS*8) as *i64;if (v as i64)==0{return -7};var rc:i64=0
64 gpd_s(w,"{");if gpd_source_identity(w,cx)!=0{sys_munmap_direct(v as *u8,GLD_VIEW_WORDS*8);return -7};gpd_s(w,"\"schema\":\"nishi-authored-render/1\",\"scope\":\"source-albedo-and-discrete-native-pose\",\"basis\":\"gltf-Y-up\",\"physicalScale\":null,\"sourceBytes\":");gpd_n(w,cx[7]);gpd_s(w,",\"binOffset\":");gpd_n(w,cx[8]-cx[6]);gpd_s(w,",\"mesh\":");gpd_n(w,mesh);gpd_s(w,",\"skin\":");gpd_n(w,skin);gpd_s(w,",\"joints\":");gpd_n(w,joints);gpd_s(w,",\"parts\":[")
65 var i:i64=0
66 while i<n{
67 let p:i64=gld_nth(cx,m,"primitives",i);if p<0||gli_member(cx,p,"extensions")!=0||gli_member(cx,p,"targets")!=0||gld_int(cx,p,"mode",4)!=4{rc=-2;break}
68 let h:i64=gli_member(cx,p,"attributes");let sp:*i64=cx[4] as *i64;if h!=1{rc=-1;break};let a:i64=sp[0]
69 if i>0{gpd_s(w,",")};gpd_s(w,"{\"attributes\":{");var j:i64=0
70 while j<6{var key:*u8="POSITION";if j==1{key="JOINTS_0"};if j==2{key="WEIGHTS_0"};if j==3{key="TEXCOORD_0"};if j==4{key="NORMAL"};if j==5{key="TANGENT"}
71 let ai:i64=gld_int(cx,a,key,-1);if ai<0{rc=-2;break};if j>0{gpd_s(w,",")};gpd_s(w,"\"");gpd_s(w,key);gpd_s(w,"\":");if gpd_view(w,cx,ai,v)!=0{rc=-2;break};j=j+1
72 };if rc!=0{break};gpd_s(w,"},\"indices\":");let ix:i64=gld_int(cx,p,"indices",-1);if ix<0||gpd_view(w,cx,ix,v)!=0{rc=-2;break};if v[5]!=1||v[6]!=0||(v[3]!=5121&&v[3]!=5123&&v[3]!=5125)||v[1]%3!=0{rc=-2;break}
73 gpd_s(w,",\"material\":");let ma:i64=gld_int(cx,p,"material",-1);if ma<0||gpd_material(w,cx,ma)!=0{rc=-2;break};gpd_s(w,"}");i=i+1
74 }
75 gpd_s(w,"]}");sys_munmap_direct(v as *u8,GLD_VIEW_WORDS*8);if w[3]!=0{return -3};return rc
76}
77
78func gpd_i(w:*i64,n:i64)->i64{if n==0-GLD_I64_MAX-1{return -1};if n<0{gpd_s(w,"-");return gpd_n(w,0-n)};return gpd_n(w,n)}
79// Caller selects exact native sample times; no baked matrix interpolation.
80func gltf_render_poses(cx:*i64,animation:i64,skin:i64,position:i64,jointattr:i64,weightattr:i64,times:*i64,samples:i64,w:*i64)->i64{
81 if samples<=0||(times as i64)<=0{return -1};let st:*i64=cx[5] as *i64;let count:i64=st[5];let sk:i64=gld_nth(cx,0,"skins",skin);if sk<0{return -1};let joints:i64=gli_array(cx,sk,"joints",0)
82 if count<=0||joints<=0||count>GLD_I64_MAX/368||joints>GLD_I64_MAX/128{return -1}
83 let need:i64=count*368;if joints*128>GLD_I64_MAX-need-GLD_VIEW_WORDS*24-72{return -1};let bytes:i64=need+joints*128+GLD_VIEW_WORDS*24+72
84 let mem:*u8=sys_mmap_try(bytes);if (mem as i64)==0{return -7};let parents:*i64=mem as *i64;let local:*i64=(mem as i64+count*8) as *i64;let world:*i64=(local as i64+count*128) as *i64;let done:*i64=(world as i64+count*128) as *i64;let trs:*i64=(done as i64+count*8) as *i64;let flags:*i64=(trs as i64+count*80) as *i64;let masks:*i64=(flags as i64+count*8) as *i64;let palette:*i64=(masks as i64+count*8) as *i64;let pv:*i64=(palette as i64+joints*128) as *i64;let jv:*i64=(pv as i64+GLD_VIEW_WORDS*8) as *i64;let wv:*i64=(jv as i64+GLD_VIEW_WORDS*8) as *i64;let vertex:*i64=(wv as i64+GLD_VIEW_WORDS*8) as *i64;let bounds:*i64=(vertex as i64+24) as *i64
85 var rc:i64=0
86 if gltf_accessor_view(cx,position,st[2],pv)!=0||gltf_accessor_view(cx,jointattr,st[2],jv)!=0||gltf_accessor_view(cx,weightattr,st[2],wv)!=0||gld_parents(cx,count,parents)!=0{rc=-2}
87 gpd_s(w,"{");if gpd_source_identity(w,cx)!=0{sys_munmap_direct(mem,bytes);return -7};gpd_s(w,"\"schema\":\"nishi-native-discrete-lbs/1\",\"q\":");gpd_n(w,FBB_Q);gpd_s(w,",\"timeQ\":");gpd_n(w,VM_Q30);gpd_s(w,",\"animation\":");gpd_n(w,animation);gpd_s(w,",\"skin\":");gpd_n(w,skin);gpd_s(w,",\"samples\":[")
88 var sample:i64=0
89 while sample<samples&&rc==0{
90 var i:i64=0;while i<count{flags[i]=gld_node_trs(cx,i,(trs as i64+i*80) as *i64,(local as i64+i*128) as *i64);if flags[i]<0{rc=-2;break};i=i+1};if rc!=0{break}
91 let channels:i64=gld_animate(cx,animation,times[sample],trs,count,masks);if channels<0{rc=-3;break}
92 i=0;while i<count{if flags[i]==0{if gld_trs_matrix((trs as i64+i*80) as *i64,(local as i64+i*128) as *i64)!=0{rc=-4;break}};i=i+1};if rc!=0{break}
93 if gld_world_matrices(count,parents,local,world,done)!=0||gld_skin_palette(cx,skin,world,count,palette,joints)!=joints{rc=-5;break}
94 if sample>0{gpd_s(w,",")};gpd_s(w,"{\"time\":");gpd_i(w,times[sample]);gpd_s(w,",\"channels\":");gpd_n(w,channels);gpd_s(w,",\"palette\":[");i=0
95 while i<joints*16{if i>0{gpd_s(w,",")};gpd_i(w,palette[i]);i=i+1};gpd_s(w,"],\"bounds\":[")
96 i=0;while i<pv[1]{if gld_skin_vertex(cx,pv,jv,wv,i,palette,joints,vertex)!=0{rc=-6;break};var k:i64=0;while k<3{if i==0||vertex[k]<bounds[k]{bounds[k]=vertex[k]};if i==0||vertex[k]>bounds[k+3]{bounds[k+3]=vertex[k]};k=k+1};i=i+1};if rc!=0{break}
97 i=0;while i<6{if i>0{gpd_s(w,",")};gpd_i(w,bounds[i]);i=i+1};gpd_s(w,"]}");sample=sample+1
98 }
99 gpd_s(w,"]}");sys_munmap_direct(mem,bytes);if w[3]!=0{return -3};return rc
100}