From 2d8c6e5be255b6b795cbff9d2492b351800dc36f Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Sat, 11 May 2024 10:20:51 +1200 Subject: [PATCH] skinning WIP --- .../src/linkage/stage-renderlet_vertex.spv | Bin 54416 -> 85676 bytes .../tutorial-tutorial_slabbed_renderlet.spv | Bin 28152 -> 28152 bytes .../tutorial-tutorial_slabbed_vertices.spv | Bin 9800 -> 9800 bytes ...-tutorial_slabbed_vertices_no_instance.spv | Bin 8796 -> 8796 bytes crates/renderling/src/pbr/light.rs | 2 +- crates/renderling/src/stage.rs | 79 +++++++---- crates/renderling/src/stage/cpu.rs | 3 +- crates/renderling/src/stage/gltf_support.rs | 20 ++- .../src/stage/gltf_support/anime.rs | 4 +- crates/renderling/src/tutorial.rs | 6 +- gltf/SimpleSkin.gltf | 131 ++++++++++++++++++ 11 files changed, 208 insertions(+), 37 deletions(-) create mode 100644 gltf/SimpleSkin.gltf diff --git a/crates/renderling/src/linkage/stage-renderlet_vertex.spv b/crates/renderling/src/linkage/stage-renderlet_vertex.spv index 203c1d72a6afc5eae01aea3ba00fc3331bd46242..5679c8f0c9fe7d31209f1bb9d9927e8a451385bb 100644 GIT binary patch literal 85676 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 Oa`EAL=ACD&jDG>}oC7%k literal 54416 zcmZwQ1=wd**){Nip>yc&kS+z45D*nmPz(?QWTZp~kP=aW0T~d3vIRs;5L>}+6fDH< zZZJS;1-|tg&f?t{*LU7`v)6sEd#}CDKKq=1JkLDNTyTR$XDqzHj2SbQow4b1>2fSL zW5F3R`roZMW5$v*7MUOKxzE%0+3JK758LVy+i#<8nHe*6^Z&c-j8*631@qq%PMm$@ z;XCel{NcwOcKGpg4nOgEFFE}96Ayps{JMq0FPyeW+M;QTr7fPeMB0*ROQkKHwoKZx zX|vMU+H=N2`M(EhHk)F3V;uN{($iJ9XJ$J%JwJP8M%b~z1KoU{53Y@c*L#qAAYOlp zjo*609p9XFk~62={Dqlv=^o6r&iS;CH)GcwaxUtAa?a^_ z>Hlv%7MgL$Lt=ATzs=Lst6eXRcH^#r^>n>l7aY8Hngi!LmVd8h6~N#4`SEHd2XNHF|LPP*TdZEc2JaKtdnb9uY+9IZQWoV>_2l_4>9jz z=Pb4_#pV*z5<9n*63u z{1;ny?EHAfu5``q9yI@2`LFwr&$WXOPA}&1xb*I8Ipf5xryN~lPDpd8KPkPnmM?#D zur=B&+Wei8ruJp&>5R26PrN|drc>=Jg00=D>76^j#-27|`Lz?f$LVMbq)I$Dtsc${ zzCTCfS0>(I;Li%CU4CA$b#HujuszfGoM7J9&Q5c`yM|-qLH<=~9dmB*1N-fPX9Hey z4(dG{UY)i@R*=?f(&nVO-fiVxJLN{c-0Oz=^5xDOIGT7IALpl;lQs>tTjc!syCAI| z^zN05(yyDgK-!v#J+rL8wG$tb{?I9Q&E62aXxbrZ;x|sQaoy{#0ln@u_wiC`UBkBp z+ke)}ToJ&l)3(;I(in(^)r&$o_0Jb1~6#C+lHKhH6H zPUB5{Sz6cqUBTn}!Cm)v2jj<9k5?rBz;pJ2=b~$2Z*vUDHYue^q+$&3` z@!HsPag3LJNIYwbt1NOJ#=0g zkMj2WcalFpy@qf74auuhFW>d}Zu0g-;~Nw6*7$pgUFXI>O1$I{|2VO=DF2hhvHoEE z)5O-I{Ld0EH^e_ry!;UVBJs*Ye1GBkRP{iPs(CB@?eV#7iY!KXI?^(uqAwU0*r- ze3|6rwH=Z>Dml-4hu5;Z68$;7y=U*tN^{M`_SP~(>>2U5wDNBZzG;egN&W2LThi>^ z#-BNLVCQ1J>GhmvCXcI! zg@SqTT3Zi38pzkfBEb$GaEqobmS#>p4{F4?dRRQT9_ZD>62Z87SSFZDIr)0nHrT-fZo9OHrJTjPvv(xI~QOU{I!=r;8 zJm7Xr+bPYQdLGn>arLlsa6Qnghh2hk^{{I&4_=$tXj`2M@T%rtOhtPCXB5 z#JGBRTyQ>}msE56hldp%pgB?8Jo|yKeG;`{CP$S0G!#=_FK(8M5 z4aS`nc6M|R3ihmaU)0yZ$*IFNH#=B!r+otb8wo{kzZuGitL zU>dy+^Mb2`J3H;1G~@Ji)QEAt4zCLCb)e@u$hkjy9nMXRv!6yCdR?d21goR%I+(N9 zVOG|br|~-Uob3kr)gAVS4X&*{6PESXT7}x9Y;b0oQ4j&1w z4(_9AA4@Y%Pe+Xy*X!`{;9duMu7jNC?KsBRuIutyD|3wNT95j!>(#+(jaBP>s>Sn5q3gPTF}=feSM#N`FQ?Jd(^DhHxh_7NZ8Txuv1~tK zpSvF){Ql{+@2kNprun>Ru4{uG=E8j~?dxf@^>XT_1dF>efha+&9uYjKh61?OSQa z>3g5v5NtkU`8H0C`Z1QbF0)g2V=#YejHg#0yXFfX?~UB|d_2JyJ~{Zn?Vh$91Y z>%ID;U~}?9=f}YgI=G*t{WQ%uJsmY-T<_JN1^4|Py}sZ3c`$AqXMETCm%(aic}AL} z_u-1Uw|E%u!=8h_Yx1jLwRF`w-|GK5*c>>|4P5nC${1s-FF!jqD^Gc2dE(tZb5dWZEk{x4~NO*5C?Tx!I)?!%jcX)cjQ=jQa) z!Tmk$A8E$v`+oah!Iz}a*xn-z6t_lO$f&CxyepJ06V)NR2I z=ZL#K?T$2a=*^)I+9GK@ z=y_5j#?{lJ!SzJ1o)!zn)zjj^a`m)iFi&S?&aTr^$;sE#(!ma%aLc4Eo5q8lCpBVR zJuIH62T!<_(^g62LC=#KF|M9g4X!78 z^|V?ruAWv8maC^Vf_WN0d#;(Bd_AodTu->Q)7DAjLC=#KF|MB04X!78^|W3vuAbHp zmaC@?f_WOh%h@nF`Fh$YxSntur#&o<2R%<}#JGCeB)FdF)zhZIxO&5&Et8Y4->rh{7q@lVHfj9n`Bfvv)$g{!^-HgQw+qJA@56)T z>gf@|Je{3MyVtf)PQIRY2(BmGBhwz0#)FcKZhN zDPNyY4(8L(e0q(alAL^f?iXC2xTmH)EsZZdpK8Ro`h0qDebTGXX9VNwbN^tudO9GO zr*krCJv}oy`Fc7qxSnv&N_%!14|<-|h;jAwoZxz*S5MCk#?{k7!E*I2;m%VvvCORV6+VP63*CT^@ z^>ey6GAl z!o4i*xo`Hof?d*r_+Mv>gn`gp8O28p5`VeUr%QQ*Awo{v{$C_ zpyx@A7*|hc1=kb3dYTuEtEaPrAm0f+PZ&!0PW}L&iDNIyl~*|Nxt0v58*Bw zxHTTa?J;n_i+(k?&V1)b-_PvLcR?ENjv4v=jtQq^zSq|$=2idHtljM7-w&3zJU89b@ zG_idB?HA89-#*o;ANAc*n|XI~ zYOTe4ruzS8Zu$34@%z#nb47aRtMB&dLVocf$NbM2!3(D? zl15AK+|`J2y|)$(?!85?_ts*;xX!nDu=(d@4)ZOM*kL~0l4(n&(bt<#jTqPaYw2M3 zA1(Kf*j!`1ab5pqgWr)_8gny_c0cE@lF!@b?&tjR9Gxo-KYN%Jtd_3tR;)+$mkTxr zj(*q5b>iK1u_k^W=E`8+dtKh2*z?8jg*d-U!(Ek}-)XRqouBwc!R0?N@qNCCNB)Bo z-{*^Xv@%+-K50n?_&XXT+C-ANqVTR-G}uuAdL4KR#c+m{`94`h5A)RHxoGsGh!i z>?^^>o5OgX%6&DM297^m&;8n9yra3VO}X*;^7Z7@T8rzZde0a6>!5chjdgrU} z`TlE(e2<%$cJKFFl9TWA<PS)smR! zY5e|jwdCaMY4zZG!mW|EW*QHAp45nO^|V%SJ<+SDwS#f>v`(;GKOe3eZ0&f()$4k} zyq*;^UBC5{ldsneg6kExVcJG%yyy?WX@7*|i*1k2Uaw!u7&-)nA{oP0e!Jh+~4 zk4W1-jR!qXYQ(sD+99}}=+)CBgK_ors9?EzdUP;P6TN!cH5gYs8_e(cz2+Xt$=C1Wg6kLe__Qaa z@u%lkjTl$Idj{7pz53lN7+1f02g}vd6N7m=JCk<*KPfr+dfF$ro^bo7JvogBJx^-H zxO#d@a6Qqhr~QI)_4L$Wxq5n9Fi+!mm`_hmzMh^DTu-?D(+)`ELC=#KF|MAT8C*~F z>gm8>Ts=K2Sgy~HX9rt5UUBk%Fa0^eo-MAsnsHw9d)-lYP_SBFu1w5h-vg|c*LCMG zz6a=f>igPtaIjjsUc0P)^`94P4jlbnm+lpPbq)!pMVpR&Rh`+vv~YB~=X#ImtMmL| zTD0l7pQ>|cFfAON-fO-8_0>5nm=dXnIMVrow6UWcd!L)F6aQrNho{qjc#{|=&O=qczqjPL9EgT&jokh~q(O2iV zU|O{8*~KP~&hf#taQ@8(&iktq(mTArGXBK0lhSDG&80?+^V!7rx-ZImF`5oJpFihJ zxjZ5stUG$j<*nxYoS*d`lbl+Iv2w>wxsH{4@su0K9yjG?hCgE(dwg;YICcu({3E+$*NsIQG;jXY5k>mu1f5v|#78U0UZd$15if zrw7lO>N;lbFvfYAgZAmUPBed+YiRz~pAp}+Dud!)2N%?%1B2bFcqj#~ZEI zpF7ldE;Z#}J@EASw-0(fUK2bg^Q)`B*9P-J8_!?&?&}iU=Z^DoP2CIUCAQ|c)}0@$ z&bhSig2c`p*SZUX)!Fy0yC^XaxYoTs*nQ||?hRAU9L>FP%F*ljyeT>3)#K-c8}D`Z zyyuE@c}l+b@!gW=fpMM#ugkyq0sx9rMyW%ifjP;aP@zd)lRG#_64(8ZoY)SuYQ+PCv80GdZ8F zapO4S`@DU3usT|v+vecohZZ^qA8LM-_{WofJv}vi;QIdVC&A|Id#Rr$t`6>JX+KXh zPESXT7}xhwzXaOeLwfBVEp(Q_1DSC*TZju>jC%MwBMzfQ_q7MF|Hnd zA6yUf=gC^kj?f>H$JN7Mf_WG}lm0b1`Fi+Ua6RB|O1nADoO&MAh;jAs_uzV%KhNah zAIanD;h(`goRvv>E&i39d_CL}To1Tg)Bc@iPCXB5#JGC+PjEfVpJ(!LTk^R5!ul@t z_jx|KKGvtXKP1PiTDk30_s8Va;>J16ZC|RnH&`7XmnG(}_tqM@xA-6Lt*)KEd;7j% zwRG)m>sh$LIe4RTzUyVIAc$IeP>VbX_0owMnq?<}jY8a+?Oz!10Icxo;MXcQm*8l(QZ_)B2g=7Rjl#7F$mB zzSEcAYKpf`Z_GC7ov;2QS$E(0UL8z#UNDVof*sZq_sO(Rr5UGpo@&Inet*7V_KCep z%WKA=(fCZT{3oWlKATw1`yX?CF4$o%+~?E2kVaeo)O;SdH@+C`{&EglU&FtYocZwd zzMS4c5BHU{ucpz{SMS>3>Z$MV#(pjNa}(3-e)xK@dYp4N2R+(jEbqGVdwuYk>D3r- z?t1=uUemoUn1|=@BzEwOyFTr@G;`?9p+=1B`;Kn~SEuhgzMY)8apO4Sd2_vQ2%cY; z-m}mge0($G9DJzxR^o4`nO9FwjTqPc^POOG_O6gJgjqgi-l~}%>ejQv-xZkAxHjM{8Pin-tdiq^(J<+SD-v{IB=?}qj z_4LPJp3cgoy>@>}EMHH54z4HMU()`X#)Fi0jvxca>u!E*IIPvb$)lNvFuo|Xu%Cwld?WH7FtmI{{ZURyfY^|XHc;_G*rV1Cbzq23$ICMRFN zvx4gvw_MutY5eK=RU^jL?+U^7ORs)c493;(O2KmVv~n;{iC#Ue8H}r^wSwj9Y3*R1#^3o}Cpr0gS~s|!aOipCpBVR zJ#7$NPxR_(!(d!JZ4@k5Pa6mGH2!|?!;+J)r%i(E3Abt5W@$X=c~T?B)zjv|^+d0p zwg|@6)0V+<-D_I~yPnpMUwr*;9n9}JG1R@bO>*+}yKQj&;hmt+bN9)Jx^-HxO&<-xSr_M(=Nfd zdU^~lt)6xb=4t#L-`$dvuczIE>k0SRv^~;z(DS55jH{=|1=kb3dU|{?uAZI{ELTr^ z2JGbxb+Hrn9yf0Myv|#l-y(%%U{oKE1KF>Or@pFIIRp0lPPY+g0*LzFX zp!&}UHV2M=uTS@kzB>B{)1pns{;JLa!L)F6y7ziN=&SS0U|O{4xOb{^U@$Elo!(b{ z4(O}%tYBKS>3C*T=h?xuaCC6ic-{1_vA#Ob38qDxj^|-@o*PUHN2kxqRTI4{$o#zG9qD^P{iKBB!FfAM%9Gyke)6rLFb}%j4bQYgD zI?oTLg`Kq!57Hv8Uq{q=YESMIK4vtRWOX;g~csN?L>3H8&ogIVyFuXw&)Yp!34yY2oPLoLArb>#Osk z)X}0%$LEClnUg#%9G!lK=;s=Jb&gIQE!uQ^2CB|6$F1+cE z>by94S~xoW?AOnb`sy5)I$E?nV|?DM&hg39!ks^HKChmToWti;<4;UGDb3#0TSGNs zoG~Y-@0hEj_tM0tOf`CA)EI;F-G+Y)uu{Im@SWV|8Pn(T%frj}JB3#yUN*dA{Ep(( z8f?U)qi8KIdHBi&U(Em zy~BDL|K_x}q&Y7=ziPy|UjN&&w$|#3G&=uH?4X0YBklGyk%$J<+SD_Xp$Z>8fD4dip>xPviGdA51J?Pag`dC)|hAK9a_Ro+mY8Ts?g>xSr_M z)5n5w_4M&zx&H3eCxWdVuef@>I+)k9Vy4&hn#A(;`pMvW#eFL6(`mfvc~v9E)$3=1 z>y=);el{3aub&H+tEbNg^E7Yp^o7Lo_4LKydcu7v?aOIA=y_5j#?{kTg6oN1J$*G8 zS5Mal%hl7@f_WOhi~4$E`Fgr8xSnv=r+p)h2R%<}#JGC;W^g^xtEX=TCeGDjo(H6C9!-x z{WZ9raDPj?DUAm`Pin-tdb&Bdp6J!n--B`W^p9Y;V_73|sKx~m!I zHNV##zteVWuv%XHZXAz&onAYyz0P5Lo$h+-``Y#IV6}9;c3J!C|0mcSIQqRV-7EU) z+!joWHXZw_I=2VY!qMrT>ph~c&K<$DXwz{&Rp(B4;^_2V>;12<&RxN@Xw&hmsLtKN zv~YBA*0|3$eRb{$rbU~M=U{dI8%zsFr_abwCbmcP)%jmAE!uQGJ#nt%y}`6_ba4E9 zC_Np0b?ytMMVpS-wfea~m==ysU-RCZn2x?WHY_dLbgq~oZmrMV#@j4)4C<6Tz;Z3KX+*QrIJ(YP$#$al;YX&DVoz4_Jj z^>5w8=Ao;0{N2qzr;c{D)(alB%&n&U`VZl)$#^~+Bz8XPI%dORj5XlTn%3V&!R9qq z?fAQ!8z&z980*}-7JrF1TAk}*Lw)B`Q+|_yw^sby2fZGf2J^43{x%EdgEoHr-ObGt z+vkq+rh8$F#MT_wJ-%hII_J{5tr9zTTDszt+P# z@mGGmfwwkzzRIsZ@YV^>Px%c7-kRb0=y`7xY|X~C-8iv5;b`3^Q*K<_&8FNqc8e+J zyz61B&aeM!)G;j z8F>31&u96^47_^)&u3o`b`9oBzW4cV!RDoHyc!^_z zDaqN-xaOW3Z10Y_rzf^g$K3vj?Mb zJ9;j!oO0tHnwOkCgzFwUC)geubLS?uhsNA%65B&^J-62ecWvw;KFm@6bpvk?;mue6 zyn(le@a8Um{=nNqcs_cL7X~};aSy#MaXr~XYWS??#RG2-;rT3o$-vt~cs|QtI`H-o zp3i!^ESRTp4_%SCp6nqtd{*tmlNAVay_@N1b1!hAwJAe z{;LCT58=&M{@Q`Jhw$bu|Fwa)hwyy#9Ip#@-s2v+F>yWFLu&Y}=Jy8P9>Vik{`&)O z58?SN|AT?IhwyyX(~p9A8u!qz6W5bHq=wIG{$}9qAv~Yue>?E@5T4KOq2C4bCEq>t z`(X3ZHeOBNPyQj;Yu#sJvbjGd_UsySe@bjGj=4W4rY+~3y*B?ocAVn-EihFXU_W)+n+e|CLfqdOz1aG~9Ni2{y3IK&wrO-b@ZISd3;y&nDh=_)a;tJTbjA`^wfxP z^|E_#y||z2<#Ea5>ZN1#_44>&b@X^K4=+zh@8Ctvo@slfnOo0`8ZoY3_71L>zz4nT zlK@vQ9jmXGeS_7}ZF=eKlfS^`8}7{c#UGH+fvowPW=?*Mox9(Q~fmajplackrU-d1;5FnOo0` z8ZoY3W(U{HxCahP9#=0NtFM>CgVoXF#XP(mk>0_Jnj_O*kY;W@FKWcNdO0e%UIHIn z_c;l0_0qBWdO12+9X(z;Pp_}OwZ{ajH(ss1!1uA~9ek^KaoTZdeCqjDBgWPD3Bi0@ zKS%e=OOnHNznmQGppScL+9_%D^z_w;an*lWaP`Oia%%Fpu1m-2d#@HIH+BM|uY@YA#QEXPUY7yr>c5>g8R*^)l|4_a=|4myXrf%lm@W z(c{HDyj+pq!Hb$J)83zEZapt*#JGC7D!5((AKWh=N`R}Ej@8%8hlAD8O>-}5DQG`Gf- zvlp6MbIQ3U&8;=%3^(_d0laLLevIXB&;Mep&l3JktAFEqO>)NbDK@4x{%xy&>#D}Q zYQ$rWf8*-kysF_>jd-l_Z(aS{S2fO4jkq;O$IpU!uV>BWydPB~HijQHGlv?S8t*Mz zvvqPSCpR}e9laXwFYN7-wxq?n}x0cf&YqI&z06_V0#q*0P*6St#DDot!mM!`qG7 zAkIPG`JbFQ{oM$EM}p7M_kW`6??&MG9J#k7@9#$7_#C;N6Ynx{e3s+wrK#sn&fkwP z-u-k+dWW@D^Rl#;r}3-jUyT@NpC6j~9hc7g=*;10Zl@{NdqmyNQ?B=j+%8itRvsL? zTXN3LQN7)#+^F~1DL3lvG37?RCnRSbN4-6#+^DzLlpFQ-o^qq!KFPUequ#z#Zq$47 zlpFP)GUe#?d#R@;XCC$aS>Io0<=hkZdy%IF)Aq9&KIy2b#xoMr;G-IU3ol=d{e!FF z{AsAE#xoPs9yM+XFJFxVgGUXX)l}oziTSWb^>K4}`D#2TxEihvA8M*`P+~qtjlYMN zug1Z_qXr*ps&PnS=QwKoBfNYyW(SWN&Rb124oz&2S+}0cKf}vcp2xqV zFJFz929F-Bx0>=V8+hx^gE7_nPij4rTK|gR>fwy%v+pra&2vyq-(#MZ*x?z9J3Vb~ znrEi|3wdT99sbPVj`O|Rp~aS#n!57u9eCG4Gp79e2i{)M zjH$n?CZ0dF_44sx_q|rFPfWF*ot`(Ey7HeIc+VZpnDU<+c+WP?n0opA#Pg!Izq9v+ zVC%)JnomyG{!3Hdo@wqYQ{9-mb{Z$w?_Sr-x*M;4+-`p|9ereN1|%>6w%*GcYk)4Bd5Sibk-KZ70475A^SThg4XzSnn|MgMQF z+Qa-fhw{q~eCM<_op)Av8l88!V262e%crf7W?sGT@7?d~1k*OQduiQZ_l>=T?>es+ zd~9;~KC5oa^T^uN=lauF``rEHJk)d@HwdqWRyA%9@7h#j!$G6hK}|I_3a@6=xFfu4 zS&fYc4bLpsTun6|7G4dF<~9j-zH=LY%THiyvkH-?Yd9x#rj({yc%OWX0>5V*W2~znAO9pF{ZgSf_ahaHMsL3>$hgO zK0CX9YO1kTcr`S-R%-|IXijse8Q031_4CGN!RoD_HMS?!x?ilT`=s9P%Dm&faBH}F z>%F3;^>+umN4iG;9_n#@Ui9AiPk5TWcWw)IxOZ^3r`?gpm%jJTg7Hk-*xoxclk4@y z_j)fB?0VztYvHNZ_3j$m!(HP=!mBa1xkZEN%2j8v;I7C2Zx1XUUX3wbqkFOr<2|>; zpwW9yP3K)Qyc!z4-b)4Z$dftLxQ5oxT3NT=8+Qgjbgk}6u4{$wTHPINt?-@yo?tb& zp7(!)d*1)Q_4{9VHRG6jhcW-Zd+fgOYK-Yx{Wt3{KI85mG`iku>NOwtXQ-jkwOSxK z=fIOW)QoFo&3bPv9ZtRVv&Qz^cyG8zTDy68^~SrW++%(1-!|B151%P~HtFx{ZV=KGq)@$#t23yv@2yzh8)u)}>#d&jh$()iHxp+<}w zWBIPb&cWtaV=iNTN8oq0cL~Nj`n|zp63aWfM|MjrueEOXV0HF%>-I=2ueI)R!Rmab zZ`~6T%WKW;6MRsLwB9rOCf9pr|Kv4w<)1q6hlkUQ>GSPr6Ysr&+I|LkdN8if&}RfY ztTk@`v;)$tt-kmAp~2qA80&WYoEd3UhG`rzJ` z_WCsEsqgw+9&CM#?fSek*g4^>2QA}hjIn&z=RLvJM~(63=zf|LE$ip#yhkUNw@+Jl zOt3oZ)4F35%iE`|dvUP3EX{*;$0e4xPrLpv5BA=hMsueIdrcp6rzht*E7$8VH@Mfy z`+R=sl|N(Py*A)!mp^mhy$;~bQ~uQh@AZ&>bC!S2!24W)H)r|R4!rjwcyo47zB$+& zbkz3zKa^TIty&*WuIFlurmpzGjQEcZ;P(|>uB!cDQ8`p zyJX7QcU{l-CTEYSZ|;gVdb%_%~?^_Mprf|u|Gm`8Y1R6Eay?gLGkEt=<9P|I)YjU{mool0O&yD-(YssmxpIUd_lpE`=pT>^+?i0IAVY<@>`-%XBBN3Z9N(^y>Rx;HxVo$GtSor@>hYO3**DaS`O z?h7wpjh_Zr!(7f!O}|h4dE&FP2(ER%Puwu?+vHu#@%zNzBV7Xv(_TN=6pSU`>71CBrGfq!OjTqN|SG`hje&js=ZywX@zpGw3d0hWp^(w(~ zb5lJ#^{WP}AOC*EYRSph)9S$v=Z0G&ZOt?u^gO8%S>)|xq4bR zn5XgYSFD$ud_AonTu-#)Qv{`UH;Wkg(B8>+8P>+B#USpX;{?c0H{hzxevyHkjXe zgWv6vlds>02iGs|5oz0}@u%lkjTl$II|SD+z50D*Fs^6TN!cH5gYj}3{+P-N#=y_5j z#?{l4gX@W2Jv}8DS5Nx|%XP0kHQ4pEe*EI=_i4fWo*hHIH=drHeEmKnxPEc_ryY>S zpPpYeVqE<`Gq`@~)$f79xcYrouv|SoJD8{OZ&*AhIr(~eZg4%}4oW*XjR!qXYQ(sD zdR}ln(W|FJf^qdUJ6Nuso*&H96`8c_bZBz&^>kQpJ>d>dJ0gt-Jx^-HxOzG=xSr_M z(+h%e^>kFQTs^%on5XgYslF&V`FffYTu->8(~e2wLC=#KF|MAD4X!78_4MLkTs<8Z zEZ4nue6Z_j{rJV#?+L;Do)be|!xNK}uiuk`>lgQuw3E~L)AOrFjH}<52G=jW`aLBW zSHCX{maC_i2lF)kJ=IqvCtpve2GJ*=gsb@u25PjTl!?uL`awdi8W}Fs`0n9W2*%dQC7- zjgSJ<+SD3xjd>bWyNe_uA`&T~F)BFCMo| zOuQj@o3y8<*^_E}E^iEWF6XAM`|wT4$@g5|9PIGE3HO$?x2Ex~cP?tgxSq?~f_pCX zdM+0S<9aTa1k2UarNKP?ET4<&>FvqM*VARe^@Mvz+U03H=y_5j#?{k1gX@W2J-sU! zS5NN_maC`t1oQOs!P9$_ldq@u1=kbqinJ@!c+m5tMvSYc_XpP#y?VMT7*|gp2$rj- z4+ise|KRCE$;sE#hlA@0_mQ-ZrtzTXNsSm+Pag}eCwlet@nBp%eIi({`|#>u*VFp( zi?82ng87}1&!N4ppG;1^em@mlzqn7QeI|`RJ-=$ixcdEUaQ)J&-_Hf(>i6@(a`p6u zV4fBjJbf`a`Fi?Na6RF^oc5J89`rn^5##FVtHJd|ub!?A#?{l;g5~Pz>%lzzVz{o? zB`04`*9X@V?i*>}Oyfb%lNvFup1u`aPxR{P+rhYc`cAN1J>3w@(}Ke~eK$Gzdb%;V zo^anw`+gb^dY;sXarN|r;CiB0Pd^OC)zgoH<+|5?9PD~pKYsD``;%aPXAXXUnw)(7 z{w%nDaX(M{MH+v4e$|L^_4~`<`lVODzY50H@2`X9>ghMZJS{YM`fYOZ_4K>odcyra z?GI@@=y_5j#?{jwgX@W2J^d*dS5JQqmaC_~1oL!BCha}>*W~2u>2JaHgu5y2<}@Dk zJgE`m>gn&n^+d0p{t=9;r+)^^)ziO%d0Kc_r(2Sfucups>k0R7TpAC0p45nO^>kZs zJ<+SD+kw2mI;QGb=H|>9E{OS2sBgWP5 zy}|WMuYT_f#?|lr!E*JKU+JIkY0<&c0?EnO(}Ln0Ue|Fm(-unOLC=#KF|M8#4z4G9 z^|Xk5T0JcqELTs91zV@Z22YD8CtpuX1lJR8$+V@?c+m5tMvSYcrGx8S>c; zTs>_XELTsP1@pAj;A!*Z89Q|IG?iGD?9u-WBHXZw_I*$&fg`?9w*ZW6bogIT|(Wc{GtIkfr zv~YBKANJXxug=cFv}n^=YT~ThF2S^Lba2+V&pmy09urK9Hl2kgj?S*Zv~YBAboxx! zS7*0yv}n`u{O@_~o*XS4oxV2owM<`~$EJoBZ8~1}sz6a4)=LxB!MVpTIE7jREd0IF+eJ|7ZSNiJgl{#9q>3Ayc z=V_^AZE~=sYWVS~xm5IXI^?b`szG4b+l;HIcMVN9F#mQ9332;Q`6JYSLfi=(V|V~^ogVMyyR)& z=-}v_l%9^hI)|i=7Hv8wPaK`u$Y?|=p3FrEgT&jo#&>fqp!{psiQ@k&cPE$=g8z~;ppJ#JR?0FeRW=t zI$E^p958Woj!K>ujt-8_lhV`CSLcPPqeYv}z7t31Mak2`(ZSK#BRw5`b>^gw7Hv9@ zpEx>4Cr=AU2S;b8^mO#qIVN?qXw%tc;^-WkJS`j@9G!=!r=zdVi&IC7Hl6J!j?Qt( z)56ig(b+6L9es6XZ`ea^wl{rb+l;H*>K|MoRmB*9332; z)zj0_SLY?EqeYv}niEIozKi0i* zs^htJZ%R&HU4Iwl&B5mMZy2nRwd1e+TL#{G;rS~6)`7Qncz(*iZQ!jVo{wI?i-WD> zxZal}wvJ=&(!^>VU9-!k+_>JCPq}gIyQZAAsIT`V*Yl=rPHR#Ay#sF^ytOF*zJWI< z-ddEuV&Kh>w-!C`D}$YP_tc^B_Ws1qd(2&xSgoVy{lO_Wp7)2R+<4v}opR%Oe>}OK zH*IrTi~9b=z?%neEy`a#@aDu@i}KeDy!r9gqUZgoVE6Fo{WFQ>$8)@P%Bk!A{d#il z8(eeO2fIhc+&2@uAI99b6WjZ8_4=LQu7$nNhdIjMF!1(1-hAc1JMi{C-rVJH9C&*l z&quH0_k*3cYt}KpNL)|$r5ZlV|8n5%OFWL#-C7#dnzaDt|63=Hn{Wh4VanJlM zaXr~HYWS??O#^Sw;Q1_n^T69Pcs|Sjec=|75%zeT3%$S?8!~=U~%q^IlJtJ4IGn4CD*fV^Xqx?bxZ_nV(SAOAvw`cI?F2BgY z+cS7RdX9?)JMVGNEH{j?XVman&E*H)p2723euaUzXYhQMUvc2=89bl$v~n;{jZ`7FQwz}qu;KD%c&47O*+XX(bt$vf(On<+Q$neCFZ zXK>v!j|jGB#@r6cdCrWvM(1oJfRnf(*j zlRcw`&uShp@b(Oz&+^Y4czXuVXZZsM-k!np*=u}guxH)kc|Y6S;mLWvjkzO}yZIrx zqmuI+Q`h-km|V}t>+YiA%u)VD1MhVgZ@%(#2Hxu~-rVJn9(b?2cs|O%WZ>P8ONQsE z{K*6Fe#G-s{-p!&e#G-s{*-}tKjL}n?smHwYhs+=5B@+tw;Y}RZONG%Xa0-R zJIs%}B<<2P^Xbj6MvUuuToz2D=kbo<>fkOS+7lax`au7O-(H6i?&N0(wsRe)fD{uv)rmoqzSO2sQ_f zPn`9;GQGq48UOyYtJ0jOo?kU$T(83if~_50Iv-5$po9BR+K1DO)6-ES#`QXUG?+%O z!^eWFgZp^eC(?}5(@`VF^*US~-0MKkb&$I?V!aO6B*xiKqYk~U)2D*f(RLlo+3WDI ztSwLDb?7=e` zUWacb#`QW>N8fe&POv)Ku7f#y9X83@@-$wDo|C@U;f7$fbk#cl>VG%b95`NZ*6+sj z4(n(9_tL(f<~;SzTa6gk>+q9cYe$#PPt!Z-;C`0&^EBi1bkvA(y$-(!rqS#0%i!wZ zewFs?G~@Ji)QEAt4!;TRb)e@u$aT#-Mn8JtX*@^gD(>FXi~CH_i~Ee%i@l!kbm2o{ zdHkt)-Noz0r^KvSFTO5sy2RI~A7lCcEyj!T9h$!@cxyEMO*mu4#U4L&-jlZ|2M%)^&O*58EKAoIi&3&mihM%pI`&hWS zQ;lBD{Zoze{CIfht+#h*ekAx4Q(mv`JyZPNhs5$d_w#dJ`^Wb}(Xdv=ij8T_{>k5y z^H5{0)QHELHIlz8xGC0)kD6k=_>d{qiw~S)y?DPV){FO? zV!e3RDb|a3m}0$nt0~rtH=1I-c&#bci&vUry?E&<){7UKV!il(dB0(u^y1s5STFwb z6zj!boMOFr?+)ynqs|pktx=T@6TRv SK6>$;Q>?!?pB5gK_WuCtr<%F| diff --git a/crates/renderling/src/linkage/tutorial-tutorial_slabbed_renderlet.spv b/crates/renderling/src/linkage/tutorial-tutorial_slabbed_renderlet.spv index 878b75199d3ff7d576ea262426ced67f1eadfc6d..93c9d230984b061b8a971046fec48476c3a1c20a 100644 GIT binary patch literal 28152 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 G;{O2bDnTv) literal 28152 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 diff --git a/crates/renderling/src/linkage/tutorial-tutorial_slabbed_vertices_no_instance.spv b/crates/renderling/src/linkage/tutorial-tutorial_slabbed_vertices_no_instance.spv index dc6b159875b8f7677850b7f33a360776135be377..893b8f14e3f48f900dd74fa8ae492a42af5b3f6b 100644 GIT binary patch delta 114 zcmccPa>r$Z42!7>0|SFC5GydSFgO8eb}*ZPK?cZI1hSQY7$)xwl~r$Z42!4|0|SFC5X&&IFen0P6%c=NA&a!G0+0m~QH5d!pb94-n;j|+;yXk6 o3X=m_lqb(&(P31We3C_)QE~HAmeqWW3Y#Yimoou*oMOQ|07<40-v9sr diff --git a/crates/renderling/src/pbr/light.rs b/crates/renderling/src/pbr/light.rs index 7a4dd5fe..2ee0ab5f 100644 --- a/crates/renderling/src/pbr/light.rs +++ b/crates/renderling/src/pbr/light.rs @@ -1,6 +1,6 @@ //! Stage lighting. use crabslab::{Id, SlabItem}; -use glam::{Vec3, Vec4}; +use glam::{Mat4, Vec3, Vec4}; use crate::transform::Transform; diff --git a/crates/renderling/src/stage.rs b/crates/renderling/src/stage.rs index 9de7ee51..e2fa93f6 100644 --- a/crates/renderling/src/stage.rs +++ b/crates/renderling/src/stage.rs @@ -11,7 +11,7 @@ use spirv_std::{ use crate::{ camera::Camera, - math::IsVector, + math::{IsMatrix, IsVector}, pbr::{Material, PbrConfig}, transform::Transform, }; @@ -45,28 +45,32 @@ pub struct Skin { pub inverse_bind_matrices: Array, } -impl Skin { - pub fn get_transform(&self, vertex: Vertex, slab: &[u32]) -> Mat4 { - let mut mat = Mat4::ZERO; - for i in 0..vertex.joints.len() { - let joint_weight = vertex.weights[i]; - if joint_weight == 0.0 { - continue; - } - let inverse_bind_matrix = slab.read(self.inverse_bind_matrices.at(i)); +impl Skin { + pub fn get_inverse_bind_matrix(&self, i: usize, slab: &[u32]) -> Mat4 { + slab.read(self.inverse_bind_matrices.at(i)) + } - let joint_index = vertex.joints[i] as usize; - let joint_id = slab.read(self.joints.at(joint_index)); - let joint_matrix = Mat4::from(slab.read(joint_id)) * inverse_bind_matrix; + pub fn get_joint_matrix(&self, i: usize, vertex: Vertex, slab: &[u32]) -> Mat4 { + let joint_index = vertex.joints[i] as usize; + let joint_id = slab.read(self.joints.at(joint_index)); + let joint_transform = slab.read(joint_id); + Mat4::from(joint_transform) * self.get_inverse_bind_matrix(i, slab) + } - mat += joint_matrix * joint_weight; - } - if mat == Mat4::ZERO { - Mat4::IDENTITY - } else { - mat - } + pub fn get_transform(&self, vertex: Vertex, slab: &[u32]) -> Transform { + let mat = vertex.weights[0] * self.get_joint_matrix(0, vertex, slab) + + vertex.weights[1] * self.get_joint_matrix(1, vertex, slab) + + vertex.weights[2] * self.get_joint_matrix(2, vertex, slab) + + vertex.weights[3] * self.get_joint_matrix(3, vertex, slab); + + Transform::from( + if mat == Mat4::ZERO { + Mat4::IDENTITY + } else { + mat + }, + ) } } @@ -251,8 +255,6 @@ pub fn renderlet_vertex( out_world_pos: &mut Vec3, #[spirv(position)] out_clip_pos: &mut Vec4, ) { - use crate::math::IsMatrix; - let renderlet = slab.read_unchecked(renderlet_id); let mut vertex_log = RenderletVertexLog::new(renderlet_id, renderlet.debug_index, vertex_index); @@ -274,17 +276,16 @@ pub fn renderlet_vertex( *out_uv0 = vertex.uv0; *out_uv1 = vertex.uv1; - let model_matrix = if renderlet.skin_id.is_some() { + let transform = if renderlet.skin_id.is_some() { let skin = slab.read(renderlet.skin_id); skin.get_transform(vertex, slab) } else { - let t = slab.read(renderlet.transform_id); - Mat4::from(t) + slab.read(renderlet.transform_id) }; - let (scale, _, _) = model_matrix.to_scale_rotation_translation_or_id(); - let scale2 = scale * scale; + let scale2 = transform.scale * transform.scale; let normal = vertex.normal.alt_norm_or_zero(); let tangent = vertex.tangent.xyz().alt_norm_or_zero(); + let model_matrix = Mat4::from(transform); let normal_w: Vec3 = (model_matrix * (normal / scale2).extend(0.0)) .xyz() .alt_norm_or_zero(); @@ -459,3 +460,27 @@ pub fn test_i8_i16_extraction( slab[index] = value as u32; } } + +#[cfg(test)] +mod test { + use glam::{Mat4, Vec3}; + + use crate::transform::Transform; + + #[test] + fn matrix_hierarchy_sanity() { + let a: Mat4 = Transform { + translation: Vec3::new(100.0, 100.0, 0.0), + ..Default::default() + } + .into(); + let b: Mat4 = Transform { + scale: Vec3::splat(0.5), + ..Default::default() + } + .into(); + let c1 = a * b; + let c2 = b * a; + assert_ne!(c1, c2); + } +} diff --git a/crates/renderling/src/stage/cpu.rs b/crates/renderling/src/stage/cpu.rs index e63144da..be8769a3 100644 --- a/crates/renderling/src/stage/cpu.rs +++ b/crates/renderling/src/stage/cpu.rs @@ -18,6 +18,7 @@ use crate::{ stage::Renderlet, texture::{DepthTexture, Texture}, tonemapping::Tonemapping, + transform::Transform, }; use crabslab::{Array, CpuSlab, GrowableSlab, Id, Slab, SlabItem, WgpuBuffer}; use snafu::Snafu; @@ -839,7 +840,7 @@ impl NestedTransform { .as_ref() .map(|parent| parent.get_global_transform()) .unwrap_or_default(); - Transform::from(Mat4::from(parent_transform) * Mat4::from(transform)) + Transform::from(Mat4::from(transform) * Mat4::from(parent_transform)) } pub fn global_transform_id(&self) -> Id { diff --git a/crates/renderling/src/stage/gltf_support.rs b/crates/renderling/src/stage/gltf_support.rs index 6174d233..b5c5ab4b 100644 --- a/crates/renderling/src/stage/gltf_support.rs +++ b/crates/renderling/src/stage/gltf_support.rs @@ -468,9 +468,22 @@ impl GltfPrimitive { let vs = uv1s.zip(vs); let vs = uv0s.into_iter().zip(vs); let vs = positions.into_iter().zip(vs); + let mut logged_not_normalized = false; + let mut unnormalized_weight_vertices_count = 0; let vertices = vs .map( - |(position, (uv0, (uv1, (normal, (tangent, (color, (joints, weights)))))))| { + |(position, (uv0, (uv1, (normal, (tangent, (color, (joints, mut weights)))))))| { + let weight_sum: f32 = weights.iter().sum(); + let are_normalized = 1.0 - weight_sum <= f32::EPSILON; + if !are_normalized { + unnormalized_weight_vertices_count += 1; + if !logged_not_normalized { + log::warn!("weights are not normalized: {weights:?}"); + logged_not_normalized = true; + weights = weights.map(|w| w / weight_sum); + log::warn!(" normalized to {weights:?}"); + } + } Vertex { position, color, @@ -486,6 +499,11 @@ impl GltfPrimitive { .collect::>(); let vertices = stage.new_array(vertices); log::debug!("{} vertices, {:?}", vertices.len(), vertices.array()); + if logged_not_normalized { + log::debug!( + " {unnormalized_weight_vertices_count} of which had unnormalized joint weights" + ); + } let indices = stage.new_array(indices); log::debug!("{} indices, {:?}", indices.len(), indices.array()); let gltf::mesh::Bounds { min, max } = primitive.bounding_box(); diff --git a/crates/renderling/src/stage/gltf_support/anime.rs b/crates/renderling/src/stage/gltf_support/anime.rs index 69631e34..9da1de9d 100644 --- a/crates/renderling/src/stage/gltf_support/anime.rs +++ b/crates/renderling/src/stage/gltf_support/anime.rs @@ -1,8 +1,8 @@ //! Animation helpers for gltf. -use glam::{Quat, Vec3}; +use glam::{Mat4, Quat, Vec3}; use snafu::prelude::*; -use crate::stage::NestedTransform; +use crate::{math::IsMatrix, stage::NestedTransform}; #[derive(Debug, Snafu)] pub enum InterpolationError { diff --git a/crates/renderling/src/tutorial.rs b/crates/renderling/src/tutorial.rs index 52363b60..b32b7215 100644 --- a/crates/renderling/src/tutorial.rs +++ b/crates/renderling/src/tutorial.rs @@ -103,11 +103,7 @@ pub fn tutorial_slabbed_renderlet( *out_color = vertex.color; let transform = slab.read(renderlet.transform_id); - let model = Mat4::from_scale_rotation_translation( - transform.scale, - transform.rotation, - transform.translation, - ); + let model = Mat4::from(transform); let camera = slab.read(renderlet.camera_id); *clip_pos = camera.projection * camera.view * model * vertex.position.extend(1.0); } diff --git a/gltf/SimpleSkin.gltf b/gltf/SimpleSkin.gltf new file mode 100644 index 00000000..cb6795bb --- /dev/null +++ b/gltf/SimpleSkin.gltf @@ -0,0 +1,131 @@ +{ + "scene" : 0, + "scenes" : [ { + "nodes" : [ 0, 1 ] + } ], + + "nodes" : [ { + "skin" : 0, + "mesh" : 0 + }, { + "children" : [ 2 ] + }, { + "translation" : [ 0.0, 1.0, 0.0 ], + "rotation" : [ 0.0, 0.0, 0.0, 1.0 ] + } ], + + "meshes" : [ { + "primitives" : [ { + "attributes" : { + "POSITION" : 1, + "JOINTS_0" : 2, + "WEIGHTS_0" : 3 + }, + "indices" : 0 + } ] + } ], + + "skins" : [ { + "inverseBindMatrices" : 4, + "joints" : [ 1, 2 ] + } ], + + "animations" : [ { + "channels" : [ { + "sampler" : 0, + "target" : { + "node" : 2, + "path" : "rotation" + } + } ], + "samplers" : [ { + "input" : 5, + "interpolation" : "LINEAR", + "output" : 6 + } ] + } ], + + "buffers" : [ { + "uri" : "data:application/gltf-buffer;base64,AAABAAMAAAADAAIAAgADAAUAAgAFAAQABAAFAAcABAAHAAYABgAHAAkABgAJAAgAAAAAvwAAAAAAAAAAAAAAPwAAAAAAAAAAAAAAvwAAAD8AAAAAAAAAPwAAAD8AAAAAAAAAvwAAgD8AAAAAAAAAPwAAgD8AAAAAAAAAvwAAwD8AAAAAAAAAPwAAwD8AAAAAAAAAvwAAAEAAAAAAAAAAPwAAAEAAAAAA", + "byteLength" : 168 + }, { + "uri" : "data:application/gltf-buffer;base64,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAABAPwAAgD4AAAAAAAAAAAAAQD8AAIA+AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAgD4AAEA/AAAAAAAAAAAAAIA+AABAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAA=", + "byteLength" : 320 + }, { + "uri" : "data:application/gltf-buffer;base64,AACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAgD8=", + "byteLength" : 128 + }, { + "uri" : "data:application/gltf-buffer;base64,AAAAAAAAAD8AAIA/AADAPwAAAEAAACBAAABAQAAAYEAAAIBAAACQQAAAoEAAALBAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAkxjEPkSLbD8AAAAAAAAAAPT9ND/0/TQ/AAAAAAAAAAD0/TQ/9P00PwAAAAAAAAAAkxjEPkSLbD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAkxjEvkSLbD8AAAAAAAAAAPT9NL/0/TQ/AAAAAAAAAAD0/TS/9P00PwAAAAAAAAAAkxjEvkSLbD8AAAAAAAAAAAAAAAAAAIA/", + "byteLength" : 240 + } ], + + "bufferViews" : [ { + "buffer" : 0, + "byteLength" : 48, + "target" : 34963 + }, { + "buffer" : 0, + "byteOffset" : 48, + "byteLength" : 120, + "target" : 34962 + }, { + "buffer" : 1, + "byteLength" : 320, + "byteStride" : 16 + }, { + "buffer" : 2, + "byteLength" : 128 + }, { + "buffer" : 3, + "byteLength" : 240 + } ], + + "accessors" : [ { + "bufferView" : 0, + "componentType" : 5123, + "count" : 24, + "type" : "SCALAR" + }, { + "bufferView" : 1, + "componentType" : 5126, + "count" : 10, + "type" : "VEC3", + "max" : [ 0.5, 2.0, 0.0 ], + "min" : [ -0.5, 0.0, 0.0 ] + }, { + "bufferView" : 2, + "componentType" : 5123, + "count" : 10, + "type" : "VEC4" + }, { + "bufferView" : 2, + "byteOffset" : 160, + "componentType" : 5126, + "count" : 10, + "type" : "VEC4" + }, { + "bufferView" : 3, + "componentType" : 5126, + "count" : 2, + "type" : "MAT4" + }, { + "bufferView" : 4, + "componentType" : 5126, + "count" : 12, + "type" : "SCALAR", + "max" : [ 5.5 ], + "min" : [ 0.0 ] + }, { + "bufferView" : 4, + "byteOffset" : 48, + "componentType" : 5126, + "count" : 12, + "type" : "VEC4", + "max" : [ 0.0, 0.0, 0.707, 1.0 ], + "min" : [ 0.0, 0.0, -0.707, 0.707 ] + } ], + + "asset" : { + "version" : "2.0" + } +} \ No newline at end of file