From ad79393e1ff65ad4e559b735d8c42c6ca8ce6610 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 24 Sep 2019 17:52:21 -0700 Subject: [PATCH 01/15] Implement point at directional blend and API --- .../animations/emote_point01_aimoffsets.fbx | Bin 0 -> 1013072 bytes .../sitting_emote_point_aimoffsets.fbx | Bin 0 -> 1013104 bytes interface/src/avatar/MyAvatar.cpp | 103 ++++++++++++------ interface/src/avatar/MyAvatar.h | 11 ++ .../simplifiedEmote/simplifiedEmote.js | 26 ++++- 5 files changed, 103 insertions(+), 37 deletions(-) create mode 100644 interface/resources/avatar/animations/emote_point01_aimoffsets.fbx create mode 100644 interface/resources/avatar/animations/sitting_emote_point_aimoffsets.fbx diff --git a/interface/resources/avatar/animations/emote_point01_aimoffsets.fbx b/interface/resources/avatar/animations/emote_point01_aimoffsets.fbx new file mode 100644 index 0000000000000000000000000000000000000000..84524168e7376865d49c342202686e9d0562f1ae GIT binary patch literal 1013072 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
+XudEKtMOKkj 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 G|Nj9pxY>dL literal 0 HcmV?d00001 diff --git a/interface/resources/avatar/animations/sitting_emote_point_aimoffsets.fbx b/interface/resources/avatar/animations/sitting_emote_point_aimoffsets.fbx new file mode 100644 index 0000000000000000000000000000000000000000..eb31091a9470baf1c847d4eaaa6d1f5bc2e0bc4b GIT binary patch literal 1013104 zcmeF42UrtJ*T)x8v4Oo_^~Hj{AofNAtSAD?6)aeZ5G7KAA*fif_ueb0*WT;3C)mqX zv3JGZD|)S0zh|>&H6~kTLih|mv(J0pPR0(QCNs3yTgZjP|@b>J`La7K-YMS-aDx+gn>gdiCMcGjlm5rjPeBX=PDK$)? z&r^Gf>St6Vm$zpJu8eU$$EeJyS#+o-K1QojM+e2nD1DfyLmAhw<@eGk6^2q(lrm7O zh>AIF)Y^e_`^cW6?i&?k4OS{NK6f1`>Wk6QZ2szKZMYB9xBPZLdSFj0;(eH|R5Uu6 zwS_uPmjgJQ^L)Fn?KKUq$(i$Dl?XQZARK>D|dyM*J z*q8&%v5FK$IT$*s)&!QND2llvfwXT;W*-n4*HaZ8>)eMOU1vAfS`BNs&CfwmS)ggo zz))qh(kHryIVx*3Z=}5 zd>`O2=7jCxqEHl-!(XXYFuuA9)s8bN$QGp1Mk)iDhLemAI|Rmc@1+dY8VZ&h6=e5_ z(}t@xhU0pp<2ihl@qN{ruvkOMRpXL2%04P4`wS&%MkNkj>ZmAXG#linZIV%v=LyiL zW0V@LN*P<}X@bPc$?H$-GD6mG4 z?)?g6WkbiXp`94Fn$Z8R=yX_uuI!qZGaTEMCVf_^o@YhNa zr4;bSoWH*!UQs<8JCYu(r#}Qd!5u`vS$2w|++1rlaIH56-1)Qa7@=`PGmutjmCXIA zTXX*)LvOePMx885QIu=lnyw9MG6HsXb8A$$UZYy|YSgJyJA3w@u6cfA*WRi~rATM3 zkZ}#Ov)9~(?O0BVqWl!G+CW7gWthN49|tGw^du@#!j_VQ#TBEu?94g>cKnTX}2s`#WkLIl1-7o|>!6qG^E^L2H!$L3WLMp_L3P)<&b8{Y;%ii=PMrW~RNt7vZb%Gv?jEO#3~O4yma<;M z?qPMqwlQ~W*qm4j2PzFW{MZo?{kw?-YU6%Wchgp7uk zu53%@vEoNd$+*epalO=PO_+FGW}Ls7$NkY#GOl}WcBpExXU$v)?v9Q!(nFznUAB1v z^X8Iga0Fa1Pm^{5fy~2Z+h~L4^zi=k5n4|Y!w&P9WFP`X4)%R z;XG_VP0+yS$g z2MC70{^~HL0R+nExTqgDM;~So%RBz0C#GLalK_ocs}5C1@-<^pyDKyUQ81S%Fj^7Q zI@(*K5Dv(UMk2JV%?>2fWy2gMMiCvTRcN$^!Sgj7V%TN)gK6i-URR2`1rC^-kzK&| zGiDvAV}#pRuGz66MNuwJY>$ny%PTHctBx|9dK-n7O)2s0(gi!Qj|UalvtVv0%&Gb- zG!aTJ8%!Sx=R@Q=Y#Zi*#w$*vQATTxnlew$ytlD$-@bk0#=v}g!dwE_a&phbv3H!< zTR)SK*}T+o(OSdZ@J3#C(!xAO=HM#(CGB;}Il+#i*bHHs7^X>^jXeK!EAE{4ry*cc zC(uB+*6i$sNiX$}iHyPRvb^lzH)e;RAR{9~>Uu=0q5`#w&NCiIEjO*~p^8>9 z^X^z#z8^#T({!+%Q2~s3FMEpm3l1|~&c%+9VT#GzUw?+;Y;y;uGh}L90X90HH)bde zvkSv`-skr=2plj;m=7j-@j=R{m`Fwd%(e9H-tYTGiD7Qzu>F(+%KYs0tjb&$mmM#QtUyP%r&=A;?c^*#hi2gAADq@cr7O zg%1S}M)xoy4+y7#xHT_~aFzWO@k-4JxSU2pXKvGtz=7mdHaMxyJW0a#(^YO+kR7oq z>~J%}Zm(4J4A+{%H;_qG4**`UJRaIHPw;jD>|7*H%d)7uS`EtsOhf}3R+?82R7a`} z?RctRGOzBZ4vi41UZD_6aA55ZMl-h+1Fd<`J#Q|vJ(ijO(XkLaCIA2?1wA8`(P2Wc zWqP>~+Q73BbNg+h)*7_x5gHm76&GpvTg=4`Z~^pVu9)Gu2(`U)VfM7)6qtMa_tW-_ zk5Rt5%stxt4#nJQyu0@cj8H}@wd&~Q%mfs+pHjDE5vyMH_C?s?gLwq=gc7LgkMP70 zET0Qa;kIMAzGMF z&T)XMkJ@6t!_ECNYE(t{OyBul1;5Owz%wrRP1orbDb8M>8mwD}3PBo0bS!(@VIRbV zZlCJnX4l53t-mVT(ra^6+_9pcrH-?dV0&vcNBQ}TI|%i)iB!vAp_YB5T6Pp_xlz2O zqMzW|K9OoEc(&#L5FH^!Kf$x@3@zb_z*tbNHDOAPp_e=gPl9&!*bHP=G&vy##wbFS z-fE4XDoUko9UU1jG*XYj2h1TDzI^wgRrTl*t&ENBAaFxv?lRx+6K*Bh?u$7JMsYL% z!BIyPM?1k0JQXwdTxPk)PZ=%Uy1YDZDORGeM!_I5K%@LVHq3L51^3P#;MM3}6rhgP zrq^v^DR%H-=3soU7rzm`Gw&sLF6p=n`Ia^tyYF5tzXc5|&2|!2D;ctW_o@=U|LhcP zCMf4uqRj-gT=9RxCn<8<=_=Yx@FZu7HWNI_6VR*@d*fho+b23)sZp`BXn_X`duO(5 zMz<;8sCbTbaAvciIU9|6l7e>WNU?RoPSG;#mF)YY;P*f7LJy6`<;R%{BBOX2c3gN{ z30}I^Vyy(P+(_Y8BH6WDtd-yyz7}gGc!mLG*{l60d$pO>)#gfdlv1lvg&I9ESb76p z3+~}n8S~Wj-92|Vu++ChIrh}y^(!-1`tBR@0L3+5X8D$5a|BS$Al_dUO)H{e+9;xX zDv<~~S=;|bvT1huZo!ZUghP^;ooytAjhRIDO9E<$I5)SXrp+4X*a2J^(`r&dRJXu0KM!!xSsivK8R z1qf#DP;Fz_$57FB+u)Rq)(!*1)qVLU1~&|BOT9HpWq-lB^-}W& zeywRwbw9rIWTr6RDzUeHKnk;p=NB63Yz!;DV@%VZmS~M8L*HjbZ7Z|Bjox%JzQ2=- zd5Hb#0Fu{L;MJQQ6XyAial$dm^uNt~@)7EBW%g>pauf5E)=m|x>aL1ZY2!`*lgDF| zDs1~^>^U(@h(Fpp!{enQI#elEWbn)UpZQA~;jLL!c8QL8DQ&z&$INBFzrOK`)AUg? z>uoDxVa{m1j<%zy2H=FrQuFmXMriN~=ewh-%w!9;pBC;)S7oJLiX90?P(mMaLfo!b zV|&P~aU1uLd12+Hj*MhpSgWI(^$U%Ri&gbej)%S&b&)xV)8K`9Bs1?Klj7dp`_Zb{ zm`Fvu;T6VyX0ZphpL$rn8k^NtTKx~K#-f-}~+2K%C!x%oT(wCL}b)b!R=!`o)&DpGbo6&fB{ znZbWyVcoifUy?8W;L_9G9L-~u@$VrjtTRGo0EAb>m8}+8EZHP?)Act z%FJgwg*z3}60uXGF=OVaDL9a+RS;u-#*8^oBxXg#nChB%WBW=tW=Lhkn0GN_hPeuk zt+NaeqI)diF!RxV8-;TCD_lTs)+rR)xztiUN~k*IAY8#m@(_P3HH-D2r*_w zH@tqX6popS8go8o%#yVQ`?aa4 z1Tkhr9lWu9CLA*)7%}E8%$Ol{1;;id0x@P_UA%st7mk^vK#X|=GiHl=g8fWYBgSl8 z53iqlgky#bLX5cqGp1{O!G0#iAjT|LAFrQ(3CDCs)#q%?n8g|h_cIK!pSc_0^>c!7 zOlJ*Z%psUDndLd=6QMj0(5V9uW2Rxo)C$K;ibssuvmxHtJ`#!91~KL}%$S`U36E_g zV$9Z!@cNk|9Mc)~dLF=xNjDbkXHqA`e%5b{*UufoF+&m%W3IuBS*?j+KU4oijQPJN zc>PQgjv3M!G3Ip4n1z}O_p=LPOoyg;{Tw44Go(9W%mJ7&zlg-_jTrMKX3Q9O!Ld#1 ziWoE09dB&!3CDCsy`GmaV|I`U_R|@4?%*rK>*qfrF;VZgI?R}IxnMt&dLdrV+H$;p zZWW2y6EWrr%$Sutg!>tV81oMgynZeaiP;u0=48y6`8);t8PX0hroAU#KSv11bVlV$ zU(A>vgky$8BlhztX3R)0;j!(87_*xf-q@xJ$4nZ681o!v%ph8@pU$Xr!R9nxKaYyU zY>(K_-Iy_(G!yJ+D(ZZtW;48gZWNB06pPr;rI<0xdkgl{ITSHwQE$9{&Jl@;x;``> zGv@RbY(JToc-ageB?|Ml@B3GfC_6*xPj69PKrrTY&iAjYJz_r7!@TE( z?Wfl(^5*R86|4_vGH;0bKtrPsmq~n7k7;$HIs1Z+=OcG$pN`{um;DJ&1>rRvGX(M$ zY?m#6{m+f$_bs#qn^?@Zu^a-!6=ACAo?gMD;3)I%%fTxylKIAf;e|E)-MUAQ?;euBGKRHePpvikPMq)a6nw{+K@DWCwntUwC4EwEr`kID+qZAJauLCD=8tdl3x1UC z2Ioc}s{ZLS75pEv0Jq$QqnCP|PdxVMjXT|L)3;ks+`M#Oz^&026MLv4qq?j68Gc2I zX1~=N&U^yKaGuP^W<9F5Z4pdS!P%Jqx%;w12VYWR-n&PtLnC~mdql=D-;HIz_7`ht z==uE{e9Q`!N7c6G*{|^B%l;8?6gB&&v|_WL`8_De{*9ab*&81-P=PV3Xx^LNT?k~B z{wHvR&ZZqV(VP`q`Jzd&Tthrh%)9ZFux%AMKvy($z^z{AHiPt;Olzw3SuUKcp33 z`VWVr$m#zloBm8{LHbW|g_}R~nFT}o*W$bV--Sr#`OkdRnK%DiTblpS5HtT^;==2=7jC)`|F2J%1KrM-WFbBh!80rb&I&nY>B_!6}m97Rpk`t8l0 z(vun*J*Br&hDPwE={SgEmZq=UL5?!N+-3YrjMsxKOw$5w*@k#&+Ous2r0F_1mGn)v za3fOCs((|+^k+&ulXteoywGhx7} zL4{;=-IHf$9F+O!mVjG}v;ST@_9|K_`yJZzWq%boikkg5gUzx(wTn^qGryI~m;GZP zj#>842^PrytL-h!{(K!Q$$n*r49Na9a4PA`{v5&S&i-2yL+-3T(n3eS`t~hxl3O`B zotL6Q?*9E+<^#?xPSf$hR!!6O!F*|Y29Bbp>DbO}nlhiLfT!tKJs?dPA8nZ5wP_a5 zJD;rGkv#*mRP|zh`5CsKZqy??T9~T4p&{OlI$x&@NY!?o*gm8$Rky&YrEfXKdBij) z_QAK2y11NKU~%4ivaI|qIJY=e>vgtjss?xFOVxpJ6g5?AcVknP`Sv)s?%@fkYWVh* zvWHNn-hfbMnfkmdm!~F=6g9h8n5jx=h?l9mx@176QeCZ)sa?9J`=-i_@sOoXh6mnM zKPFR|BLz;Cl`jJ47H4WI^wCP}x9`T6sTJTTYNk%^&Som}!!nSm&ch&6nXj5KnHm_b zj*ARaYWSW3CO|y1boDX%G2EYSte?BF7s-;}y7i8>(`il7%X#1nxo zBm+c{O<@fYbXTNX1ojk_)c8prIUVrqo9ssG@^U)0iDN?DgcrJ<;M}6;YEAvLA{CC> z>1qAgroqiyB+KYiUGI1=7*s?53EWz&ttQ>sp|g^n&?w-~VL3mFqiNJX;^KWP*dCY3UiGbd#1LqcrVBy;uc~5_S<4zAR@waBxhV?SK zXuEOwm-o)9qr%y9wpaw7;Z_xaGMrBYW8f&N2xdpHA~2e^=8FdrFg_R&v`|FzuCP3T zSY`_NGeSTCO;i>tKm!f&6mUe90Sa*JWeo-N>SZMb6lzMp{r2sD$`%bd1+-|I49+c5 zK-|aiz1{Qem(e>WbvijAds#WXB=W%O&x?xavqYp*0d#~_70@$+PXXiLD5?Syqge$o zzm3OXV2w{l!^fYPpFrRg5ELF4)t&cs=o^S=rh{OkFL?j-I7CNUsDu8{5KjlEBQrn; zg`=#Y15H%Ab&wF*;^VuAdD}hMZ3O zQ{f)%`9C>rKcn51Jgb|?b49092Y%63)qy&iPY2WBD5?%t^fuE$Ot6p+cwdWtf{121 zQ1lkyfuGt!9SnnpcsjVG&Hx>him`?c`p2YO2UOSTS1u_|>gax}@}7+=l$+tfKi-!+ z%5`VJxkWl?U37Z>=W$i!^tz2{J3T+0kkIiuws_PLn#8X$(J{h2{;eD*3u2eX+bi6EEn|k2% zxK&y8bohhROWTT+l+#p)eUXD29Fx`W%l6wMbv?Y($+u5@3pqWle)c|FmgJJt$Iskp z9i&au^#ivS&%1Z^wW_*q^yO0*^Dpo+UpGKiSHu7_b>-VFq%Pj4t#F8FMj4j@0_wWd z&vJDg$#*rUy5(jWeS-UgJCZNnLUnmVLp*iOkIw*g-G)<1->Yc%{_LrxLtP1-dwsgO zeVUF=*_*vv%9QMKno3AGl_xDmHxry&q^?45E6#ei?N2$a@0!r%M3<6sy7khnO?RAg z)?Wm-7OSh+0IRC2@c=$`b%mp->WUp~rmiU(A$9RS!ySf*X6mXwSU_FH23n|tR?rYn z2TKQLfDRtRsiaQ_-h*$1fk9SvIm_<%gJ5~%FbtPQ45S&}2gIw3Q z?f9dJubghYuW8Q5uk*?2MJ>w4Z97v?e-qqVtOMu4R@H&mU_Kr6fTO577&w&G0rSt= zaqrI$f({J-v@Wdf`m4giBKbe-e;PuX38CIl0U?wbVxbV)Lqj|vtR0d8LU;qGl0G4{ zPDr;9hSjm_JtgI#j_%MU>|k>5(sG&#phu25m8@G1&Mgwc+2yk;<{RZJr)TF}yR`Mu z|8(>k`t{n;yPV|@!L7wYs65oFLhu{PCj>PdMHRxx5oSVgJt-&z-si2$5YkKtvJnD8 zs4~n#A%s9fJRxiwmH|Te45yMlA#@m?ZXqPhn@A-GtR>#Zte7^oW5WG;GFXwCG>P~vjtOPN0yMk0=E_m!EJ<9h0t~cpAh=NQB)yJ z8f_+o1eKr=cpr^!Lr60rv=}WQgxVu56oLvG;t65j$P5rd)=_L9(kBGPsB{Z~O0IBo z@67+o|tL&a+=b6{~6@dMz;f;TOeLZasp4 zW-@3!PCy2Y##ktW7-)zmgF|C7KnA(TT0;imW792z8h7u!8|(Z`M(=3U&Dm>FDLGA* z-1vT3(`20voLeM=haq)tyKQbIr&p}ATfM!flb+t3YeePn%a!ERIQE<^mVxIutI9w* zj!y<-;3%pL7ECmgfqtTZ40s=lUP3@K8MK=yAOnx_7RsP6G{lp^KjSk%1_dTqLk8*z z>6QWIT+Ffl{XsICYQC-QrrvhU%Z{mY56z9x9R}wX$zbT#+kbTZ{HL6Lb}y<*L*Ej5 z+G~#{W_|loa)*iOl!4DgtI8m9BA*NEPPb4A4QDY1Yue;A!dB z!Kv3fSG}8QFQ*@k_WE$Xz#np&%KAsCoXtoR@K3P>3lj^1V>SIuw|B+4pI|^bin&qlzj$!9%ed-nkArv z4l^v&!6ayir-QpQGC&8FXIeuCqh_XC2h{L0hdQoaCZnD2bZfKzD#HV+PSz&U3VXxTciVrIZKD@!vf@Vg;_?b} z)2V~-xmMM|__=&KSPw^0bx>@f+4O+gY&1PEe7Rrji>QU?3CQ5=0s$F}n8yyJB_D+{ z{UYj*pLE(g&q8sfK|?%owV0m);+izy8sd5ir8F-{+grGd7X~_SZk7Fncg+z!@;e^OHhXvSXEq) z7VwEH_d@n4s<=udvEnlN3R1`;5EtXaATEI~;YC3#v&XFSi2}OPEwoSp@1P-`0$MK0 z00m50WDNy8hf_<30@yJwwwJl%+}i8@{hO%HP3gpRD4^QiI)}G2-$ZS>@JiKUJ5yxz zs+1D9=l8Cm9|>+PR=|-&t1940BA)^rlkgPayp&ad(a#*jyaoj@KXYJEfXG)-VI$fTLyzlz$RY0D+)P{G+p zr*98AmPJPQ@36ksq9N;bbe)__x{kVIryCD$EmpzFC013zt0jCYD7X|)1?85rDlqyT z@`O*I0>kf+GryoD^j*|G5X?*hH%bO_;MDF^4~v+ebC$mrrBeey92uvERFPHRrc+O1575IPq- zx%qS-FFF0klNX6yqMYUQlsLzmE2`V;XMYr1RfX_nC7%%fw+c@Pb=R5+VT%0= z_Dgu?Lf~D29RnfFgz$2WfDo>(vQP;5R$C$jX;8?B^M(~zib`2n*1a1zw`g)aT-Mg*ZcLDzp44UY`Mw3p$>}E5QU=ybcGf3> zTZ@HoXN^^bkZmoW5Guh@)XA~?1~Va~x(W(`cL{bXgftVvhxGzNxVzRuArxO{i4daK zWq=U2!l|TB2>I8iUkK-?{I_x7G98`p?@oRE3uXzHq7pi}mv;{b=N1X!QK90q&v^#P zX*=EGQ;+^GC#MU(cKoPMDyd%uZY>tV)Ad#rg3|^*A=HASs6z1G%nHHi)wFY45CZdR z`un4i;0N~RLPRqiP@4sG@N|QPIw-Tz5*_r}m;pN21E-Qc9TeY`ZXMj}_bsuG%QGFF zlvtd)GN1Xt-m9mB>s{09V!*jYI#_c1MxVicUUItktEQ?|e%bW&-$``e=_&{LCU9%9 z4$?MRRR={j^XZ@=97WYZt8HdFc-2ry2fPnPiy@+!4svW0&_UW}3w2O=izPZ3yd?v4 za1c%^V_KAKlqHp>CAn6MGbu)ULRDKX7i54yv7eIHv<0Ag5!N z_tLEt%8VV zI>@&}KnI_UQFNn@mKP5VnbZ*`2ubxS zx+j2hi*&HvKYN{t6WYq@!M6kCd3KbN)5?#*$ETgkuTKWI7VE%%hgEe@VF#ZMeBdam z4nlUbI&k~(J%)UKpo5~u&qX5N@!SG2&6H4Lw}29|?X*w{jiDjln$eV<8K8uVa4P9j zLhW7YRzky=b!X?LJe1M$3MHuvk<52IllGndR%*X)95}Z~3Da`!e0eC;OHM}*IN7aA z-{N}u^Ela*nAcAF6X4cjB{=T3suEmx^C=+^j-o1|*FG~PY%DCS1m0((y%5t(3FY?* zC?W423zg6e8saHo-kuClLMog}`jpUgZ@QI06+5})dCes@Ru$Fl<)*jC4EY0u1~iTQUm33 z=X(crw7gEYRL9B8w>&8->BagA?u)>=MM@}{V^o&l)otap+bq|bPu2P5^bYruYNs+; zA$);TNuLmc52srQ)T}Sx?p+uo zqZ0zNQE`)*p9W(#`J$#9!MR03*wx%KIr2?zIoS!24))2SS<&!RNSu5b7MYPzb%CA)XL)M>9YO z*^aS&NS_e8A4|6oLaJv=D*j}HjMithr#8-mg(Hd@)pRE~w@3)PbMHDh>&a&seLD2- zQN`^x%jk1`A5<$In@j%*+*&MzCdaKRgl@)37zhpVgmC6m1_+_(X=?~Udpg}h zpw75a-5pNK=ueNbCBZM>QxtXm!rl|$+#(^!Cqx#S`@f=cy1DoDQGXwLC!=rbmwR<8 zR8*fQC7nWOm10#P^iJUu!VEZyDumVN%!H5-A}9pjN2C8Bq?r)H&It&i^%)C=FcKQ# z3E}FQ3=o3zS!)Pk(Ao40A?xQ@V9!MX3A8zHp#;W2Lp%xGIG+I$D0jgc5=gj^ZV7ZL z?tOa%^E;`|Sscn1K3ZH)U#xL=Z|(dab(g@oMG|OprithK8e3)bUlT*O4w$$_N6)DK zS5#cz9`b4ze;Ur*On!t$ItPX-B302n&HkIofxs*jMR`=E|LM;BbIY$}G}R6MIBn0A zzmi3PQ;VOpHe9r-uFhWM)73jTimEI7tE{e!{^4oYgP<$!AD$LaRl7?9s@i)+KvgR* zS*WU;&=5~mwJ-ma2DzBa%%*_9qF-PRilW*nL$zv6Z8|Xf_x~_t1G|nxQ9OUdU$%y- zF2bp$=hNI&YTYN@&+MbWolIWRY)La_@oDa*nNw5Tt6yRJZIP;?#F&SNCd7j5L$NZ-|3~nvfRgN20)m7CSe7b4{M^SaPJ(bm!(Ld$;DiL(W{Zqa{ zYNe+lR>>!=EfCJ^ku4@wKw4#QS}rYRi-eGx#l3i>)#;{%(wYhl@uc+tI?D7yeF zA*^WO3tx+MC^#8%ye$B&V|N9V)$O*08kh+U@ig${Hha;mssYzK*3iJjJL%WJvR9?=#FW<4 zDI?D*LYT?W^TT&bZE^gly9drK(m?kGUuS;nx=Tja>$+jToosKUzs(Ck@oipuC&(C~#O zf!Rc(U@i|5F}VXErqYzBOcZ4^AyzPi?NbrX4@yPIrG@ z<8>rE8*-lP{qU4~;|FZNEt1vftW)QEr8(+p{qU`KyJw%PqqCK*RzJMoZQVd{Yq0|M zJ+P_*Za?5tK-PzN3h4EORe;elTg)R+!1o{g5SkA4gkWY8DE~x20v8{$*T$0RQ0-6E zsx;ljHyz6R$Um^RH`rY9AfEce=J6J00rh znK$U{z8T=$B4IrXZkDh1*}{7I&hoz-Rf|8NqfbummHMF4SJ?${Yq7A3KC!B>8a?3? zRu?#mik8FASz#Ido|JwB2H%Jww49v>-X8vH@_)(Q>c5Fyd)FNnXG}vvFJ(L<{ zbf^-^f$*01U$)1kf9kPUoTiV`kNWqV-2^*|GCb+CJv9^uz z`!Zq$C}cX8-B%gkPO0%(m6xIpzhN6qu%{>oUu8Vg)yT!nkWdsg#Ga!1*|{9<9WXsx z$9d|zPoZh=YeHU%9=ZDYS&eQ71$T~Zwxm@4$ zBK3Nc11>iipD>U|#JbJpE%+FbL#rEKKQ zPMe(1x9?y6X^T@Qy^1`#x%89cll8LW0~Yx``LZyjZrrod=U>#QaeMmMHLH3ih4u_D zyt-nes^^Z)*&bQ!>V_QWx;Y1*^eZ)?YoAG8oqXbEB?NWtJ}G%j|5{nr4ITQWs88^p zdrOU~S>@}9S?hcok0^ile~(9(+5WLxclFptT2hhU! zI%r|a!7e*`v@BB-3svniheO9-GeOEq=`n$z}n~P7Esee}M*uQG<$7_Fm zeQ@>Cl)(HS?00SWTereF?tY1ieyv{5S{(8IuNsrjx4PQYb<>t%Ys!}@xTNFCuc>{g z!|UHFqboe0H@tb7#x?fZEp>Tc_~n%CzKaS51V`@6UC!=8pTer@9X~o9AN=n(`vaXi z$&Od7{`F3oqlK2gzUAVzv`oP|MYUZ<-I?mPJR#3&w~k4weh-QiigaIg)$`M-_IPrp9nQ{w>Yn@E!zYRIR;_OC^SmQ_Q@u@O?{};er)HrjM@F}b$T+2Uq*|fv z!KjqkMli28sRS7@G6ugg2j)YnGRu^Ce3kJYTCK)AQqeP3#ju3g7?$QxP}BveS&E{l zd{C2CXccT;GqsqFnUiu`Hpgs^%->o5W#z!c$O|poD0_IRCu878J=wn}EJWVUL1v(^7) zW%VgBTP+=Y!c+gP6EQLdzbprQAXTNYIvi@^V|AlZ47}NDp*+G^rNppWFdM5tUaVGy zLQ|}s$U(45W~*ejYOAx=KDm*wn!4bqtoqfzcM>CG@T+nl2~t%Wt5=~WK2{y_uyVkk ztwt0S#%f5iqO;(;)m{*i7pudd&=jj>^AW5PtP-r+DppSxK*H*;e5XcYlXtpI4!nm{ zmBwnVf^1UbW3?-^#K-FX62e$@){9^@8A9@6^$HZ4Vl}=f!79Nj!K$rdwR{PJRf4Td z@#xYDQdJtOW1uEJR<{|&z*__^URD^ZDRmok5uB|S`-4>=FIHWl&=jjFr3qFERtZ*Z z6{`cv5UdicW(uq>gH)Bq>Mf{=kJUV7Svla(R%0p)V>O?f2v*e)k{7F^q0kho6)O;| z608!e+A3DhRzk!oMg9FWJee37gI|>cUm#Vbv0AS(o7DJN4TYBYSUut@jMbQ0B3L~P zA$hTS6ADeSI=DK)D#0qjs;y$RvMUl+{k><`uR8eVZenB%epLz^Vim}X)w)ntrYUfjseFS!xV5@v$0i6a#Oz`j59TR^^T@rwC&81cc

Rl)_#p-Y`f>nZ5f>m3^Y7K9KRf5b+f#VL4s?xL7X;2d%t2(0?cvvmhN(8GpM6g=6 zIjcZktTuu|Q>Q)Y1gjOhunOeGstgKEv3e_nV3lB% zVAWQ!IxZ9mtMScd|4l2O$)v1y+pTgGlk&rr=j%L4hhkiPsr{mM+2klD<%cUT<q z&=ji^)dZ^qs|2gIiq!@hB&?G6kD25B?WcRi&|-1~u`q>fE1|1O6iL zh@m1_wG+YWa0tnZ)%j3piq*!0304VK307?ts}B+gRtZ)!1y=J7{ee93Mc|fD6CbO6 zjbh-tSm0*=%)mE|EbPT~N!D^DlUH zsELo&Q${iHu>tPzUj%LqHSw`J&?pApY&CU}Fjk!@5v<;Vki1xZ4~3>!ojspmm0*=%)mE|U zxd;iXJyyMJ__ELAeNr~!z&ss_N%`T*&wiG&uD;ZM#EVpS6qEA9m2W)JR)%6s{YXev>DlUXsELo&b4D@n zuv&k)FjifcHJ&W^Q~UK2Sq1W9wG|YaV)exmf>nZ5f>m3^>fB{WSS9ZtGspYK-}yQn zfK-*n>VHrZAFEZCvvR;+1fH}`7^_qM62a<32+51pWl(5})n=;+RtZ)KR&5oluhtT* z5@coy9G6)419{?$z(G(GAFD%+V&KhI?{5{x>c%A^SiJ`!d9nHh3Qe)PU=zVA!79P3 ztzxzLR)ST6)l7la-jJ%&v(+_F6CbOWjbh+owaFe~tiD<)g4M>`SOxN8H4q9-v6{An zV3lB%VAWQ!x@b4SD#2=|!0J&*RcWkd*~2C^K2~c&OZ-LP=?8?d>Y5~i)oBot7ptqG z&=jjJ^#rQ~s|2gIiq&`f5wS{9E!K9BOWEjFbCFES4_7`Yvm{=<%cUj>{V5VVqATxeSeo;c~C9>uu&Qv2{qjb$h%<%cU@?-?&gF{b`W zNL6X9I-F&b8Xv25pe6ny@SH2cSWOXI1fC5cd9k_y3Qe)v`Xa$9!79P3tzz}lWkjrI zj`wfmJ?ZazoyuQfQ&k$PU7;pER>vE~z?-eUOclZEYLP|Y7Z8#ctJ$xzeKy7F@*4!J z1giwAwu;q1QwdgoV-)>PeH#F&Dvi}`P!k`kcZ_1-Vb%MQFjixhi(s|cZB~K2SnUFZ zrda*&9>FTXD#5C)Vs+(1f>namOo89CkgC#H&GU#&YJ99VgqHY=zzbgrV|B`U5v(qN zki1yk3WcUv4SGhfO0Y_>YO7fN_JUxQU^P=jgk-fZ>lzrt8e z_~tW3@W%_&AS5qVbH8HyY>L%2X#}eTs|2gIiq&@iB4Kq%*PAFllDiIT}E#?_bFJB2+( zGATb?dGoG+%214{p8%;Ujn!RH6CbM&jbh+o)%U9~R#W~FnXR^b&nl1?tKFf{6suW2 z6RZ-f60F)PR@eQ9gw;CFmNv*e{f@ho^?KjL1I48LaODww8}3IjuD;Yh-|jp}Cgq1K z&+#;CGKz8arS``^Dm+k3$`4mwwR6j46yxek?e#l%dZ3t;AFjMd+QVcNW9namRF%eR z{;zCO<73qwTH-GPFUgjLvZpAjG(}NP9?_~Og;u4G_KMT=QTlB>CW6()5RwVY}DPz7D3ll{hN z*S*Q>5ta5ftKZtUVKVt< z%H^xiuCnok_et5(FCFzLCgq1KFTLtdIf`-hrS{rlvvepX<%cU@JR_eD#kl%X`<*l1 zBAJvQt~_rSoessg`cnH*Z#pNVn3Nx`T=)0^k}>sbK&nb(H5_W>c*S|t7NuHW~;V3TkVtw39ID&W9E4O_&Z;xk&vp=Sk*yI ze5^h*ih+mKfI`Aposukq)z*%z0(r686ADeS>X4scm0*=%)mE{(xgfzRL1w1F@pVX5 zX{;70#3nU9R=uDl{vz;-KZLOwa9jkd%ONB$R`)@nDOS4{BUmL^C0MmptmgcKV3lAs zQ((0=q^dMlqo5`}R_7VTz?-dpEh~)GdtK%S5rLlStYT{${wNVT_thTKpf>p7PECrQg708R#NGLSLYMzP&s|2eA ztG0^OzbhkRm7@CAt}2(Zn+GrJP)y1XS1y0wN`_)weW`t*gEkq(r2KH@jqMhApcq$Q zYVUHjQZkB3`Qgf67pSa9F|NMUe*e5tNG9cnE6=hl&;!Mo`nMrfrLp=)6*j5yvDyM! z;x7WPttE_A*CQgc)in^37pn)L&=jkoH3(J-RtZ*Z6{}9Qkg*zZ@rzE%-n2{eKrtyl zTzTZYg~=$!)tB0zw;PFMQhvDdPXqTN8CPFwU!=_h4-}K~!>KGtd@X6Q>^Z) zOR!3?O0a6HSXDMa#%iv;z2#C?bAKHqlk&rr=WTOBhhkiPsr}2Tb&*WU4_6-E`U;Y9 z^`-W{!S`h-Cgq1K|8vLx^eD#Fm)h@eysAerDL-8Koof$eD8|&E45=!O)niZ-AFKZw z#lXXAN4YRoH;TPm4Q?oc)!tBOiq-s0304VK307?tt9xXKSj`;o-^hE?-}gE_fK-*n zsP zeQOG-Dvi~?P!k`ke;LKVo2}+(EsWI^v3IKuEm#HeV)cJeXo^*xFTpCoD#5C)VzpN* zf>namOo87SkgC#HJq0!KvHIC41|C+swG+mw>wb~hYS-2xSnUIardTZ!NU%zZ+KXoOlp;D#0qjs;y#G9Y(N9woI|jg;bTs>N%*1k5x*^$^n128Wt&x)qL|suo?;> zd9gYG3Qe*4hl*g8V3lCiRN;0swwhndDv%eem7&lStH=5htP-petlBD8wfzZJe`6H=PJLShsVa@t%TN;^ ztJwyya=@Rhs)h+;HD!?qR>L7AFIE$v&=jlALkLz0RtZ*Z6{{zP608!eW(xeigH)Bq zYRzG6QsZN_Gql9Vs(!2pR>fwkIta;&)k{!liq*cO2v!MJ307?tt7XR$tP-qd3at7; zs!C&Z6x77W>K3CIc#FVArwU^=W~Rt&wa7SDfxK9)0fnYmJvEVFm0*=%)mE_@KLru1 zWFyQ4o?Bt0SS%6ss;X304VK307?t zt0}VyR>_trwoj0%(parChfQjHtSX=-K2{GU3S)KSR1vHmgpj;gy$*$@SRJ^4V3lB% zVAWQ!S}~Dem28<}`x8=C8mr@>CO%eo7{$O_1TMKk7^^Y!M6mit601O7tk#A?Q>>m_ zO0Y_>O0a6HSRK3^5v!Tw{Tq2t`ukp|m5{2^SiJ)^@v)kB1uF;q*=p>1VXOw|MSc@l z10i{_It~g=v07yf!79Nj!K$rd^};%W)!!IJzf<47L8?k)wc&a;sqwMe16tx^_4qbn ztjZle3jZeXF$l?v)!R^Liq)Z;304VK307?ttJSs=njp2ql75=k2Tld9m663Qe(kc_+at!79P3tzvcf9)eYZ)l7lab&#skSbYdJ z@v&NHFDnQ9*=oOo!dOkpErQj)5Rwtc+w*elkmWRP`u1ilO%B>*(8Z6hrmrsB_h!7^**O*GqfOWpeT2!iI3F?qZoLz)zc@0u^N(B1gobYBrjGUK%psC zM;#?tC0Hd`wNg-pM4AtL2 zx8_KO>d)HsD&MY;WK7&nkgC$N)tOKeAFKO~V&Gx5!Z~5ACfSK#)#V>nfxK943WcUv zy>Xggm0*=%)mE`O<}4Cc?>vi5PThMUkT90H*+|7`x(pY^4HSw`p{2VI>{6*kFSB0^fD)y13fe?}xt23a` z6svVE5v&rd60F)PR&QNF!YXh$Ud^28T` zTR=^Gti~C|z?-dJc`uCB)I1_sy$m6FvHA)MO|d%VEx{_mD#5C)Vzu#mB&=$3ILIf? z9PcS*<#vunGATb?`Oz=akc_J@wXbz*GLlL8;mTufPewAXzSMr)`{76?<%cV;kvtN~ zxcXB2)areaOv(>ezB6eGk}>s_kgC$N)kLU?kJW#SV&Gxb^_wtOopXv{wdMy_fxK94 z4uz&zefXJRm0*=%)mE`O?JE*iyVe`EFW)yRS<0M?L?M}!AFh1Xgf)5;l9nF|NMUzR02kB$M*Pl~-<-Lyuxi{XLMX z(pdc$YT{$H+&5MZ_=~`!v)fbl6h)P$D9XtrS{0?xs?^b5ahg6#zl0njSRDl+d9k_( z3Qe)6H08!zi+`|$DI#6r}r*U-$h&O`QbCS^RzlLvd)faF4s4`NWI?VfXj_dX@?u` z7;|Im_JR$IR&=Y=dvx<^PI0|<7wLO+*tt)GHatu`ec<+&#NBagbFCOKaA2Vdx=JVe zjnl4slh-3E?QK@SwQs{@{*5L*y0*A~!?eD|A{Ny2EA!m9=YTQ;E`O*$;p@yaMHN-V znB9xrUikZ$EBDSnd-$M@_sh<>ux{+4G6&udR*fhU`ngcpi#>^-s}=t=;*#CT-0h1d z?Ks@^pv&;I0j)gF4L(z@(j0oQv>f>yzKBs1(C`Vsqd^<&CoYFf|tqK1*s~H)xV%7K32~d#lXXA-NGVR zoz`9Wr}pbOu?pnHsvi`ZV)a>mf>nZ5f>m3^>g+-Us|1;u0>{aas?u2f3^nnwTB$HA z2mD3g2_=QG>N;HntK%UgFIJaAp($3qiW967tP-r+Dpp_oL9j}&nkleatmF^miGLEf z4b;TP>JXzCc(c{J<%F@CZ>9)V??6aitbT$*Q>@N&CRim{C0MmptTro0uu8C+DX^-B zRF$5su7aBQSiNWz0}rc>stRLu;}j9BHZ0F7kQb|eLZK;EUsohpC0Hd`wN&ucK31zkOZ-LPscynpjaeju z)hQ5?7pp6w&=jjJY7(pxtP-r+Dpu2KAz{^TP+Zfz1189&ti=5HNG9cnD}S4{6OwWD zrS^RfJwY-lKU{f(YoCyet1q?B_If{(N%`T*>nxfjLou$t)V{!jU>S-@`Qgex99bhn zF{XYgH#SwJvDzML;$wA$Q4GA<>Z69jSPhsjg4Kr*k{7GrpwJYniS-Cp304VKZ5696 z8zNz~*2HoQhvDdoi(Q;8CPFwKdRF( zB$M*Pm0$U19+GkOrS^-b&P6gQKU{hA+KEWU)Yn3)N@I0B)WpZ?HKQ1KSe1DQWA)Wk z5v;m5Vim}X)pk&5iq(Ic608!e60F)PRu{{Wuu9%PW{&rdzw>oE0jVmD)odPYQsZOQ z4O-$a0?%q8jMV@!tj>gxyjWcag{D~bZ$_|6uu8CMt62TeoM4q8GgIKWYzsD3rLo!> zYT{#ctWgZS+3NGw!dQJJwg~(TLh@oYs}I{}Q>^~wN3cq;O0a6HSZ&>!V3lAsQ(!e7 zQdJtOTc9RBR#S~);9-?+FN{^!g(8cUlP~W>F)2S>dC}YX_n{b9Uuyp{@2Pz#Cgq1K4@rpIhhkiP zseS%{8gdkq^23#Pc)wbYVqATx{kPW(^e86fhbuqv;&>AjW9nDz%BHF`RuxbaAFGp$ zV&KhI-zbH#nleWOtFIv>FIIDQWBY81)m7aIRtZ)KR&5olK}sa7_NbH3Bjn4yWGS0} z{3()2`QgeR-F}K>Tz#qivWw4e9_sxR$+-Gb`wCB}{U|2ohbtdm_&Abr^`-W6 ziXTNXDL-6!lm9(KGN%4uNL6X9?tq&3SiNr)0}rb{QNmc=_>TxyTl8QR$cxnwC^W?? z)r(-2V3lCiRy z`U~_rhGeMzc2w|9Mln=>gLW=JGE{#(-8Se@jPZ8?QdJtOd862*#>Z+CXoZ`LNSWSeGyjcAk3Qe)vzBj=t!79P3tztEc77455{bS~M|M)v!r)rR@(pc>QHSw`J z-6#g$Z1w#BVXVfS5W(ud5RwW1O=^6sdO%D3Mc`%Qgs~cPK?JLRK}cS#?twy6tactvuu8B>uxhJVbr?sm zO0b$Kuv!aJRT`@iP!k`kbBto(%~rom6~=17brGz7hLF5iEjXT)rzuvqOd?n%SS47s zRjhWMiiFj2XJb8xkums{IWPuNRT``Np(Z|7UmC^0!)oAMVXUSc62WSlX{-WyvDym? zO|hD57QrgPD#5C)Vs+abB&=!*ev%U-WAH0;;1;B+G**kxWs@2otKQHOe-U_fk}y{D zT@=CUDhSDo)nq6%#j0W}>W;q%RtZ)KR&5olp(~KEO5Q(aj`xqh^L3gC zsVa@tBTy3`t8a~B;9<4H24Sq`+b@FE_A5oOs)j;Stma)yuu8B>uxhJV-L;-zl^`=y z;P@V-sx($hZ(x%eAFIC55`PhR!**e;x?T~%>Us#tJ6k;rg{D~Tv4vojV3lCiR2ASS45` zShZEGhVLap#L+4LB)+)h!T` zceZ*03Qe&Zag1PBI zyf9W>Pm5qR*GX1^yjU#@g{D~DpF*%ouu8CMt5}UXhlJI4--42fkums{IWQYiRT`^j zpe8<6zZ%8B!)o_y!dT5Gwg{{^FM`#0C^W@t@yi6O1giwAwu;q*SCOzv-alrJ_m98x zb$S7*Dvi}j*Vv@S$7)+>iN6TE^Nui90}hDHR(C*1-q~sj6q;f+<`%&!!79P3tzz|$ zI|Qo)nVAB|%^+2!u{s25;$wBKQ4GAHR>1|#cJsn z1giwA1go}+)nl&+RtZ)!1y<7_Ri&|7{WY7^_*m@-E%C9s?}IQ_UB$4v7eex4^#T-{ zVm0m^!79Nj!K$rd)%gPwR{xI6t0zXr;8*5AOGs5|td4-1_*mU!6a#M&xGtwuTsV>RHY2v#E?BrjHnL!l{F%VlNH zbAmlZIru8$gH%z<$i)<8IQb#=6xGkp<#6wS>Dfw-eqA`AQ@xJmZj1}Ac_n;8i7ol} zEjaAB^MU8|-UaHrXp22ReCBqZR!2tG*)h%K`lc7D*P9%0xv?qjaKjyAZfxCNuwl`P zZgqN(ZeGnPuGj7&eUA=1_i50Ehl!^T-2RfdJ8o^R6$1tiEL1^P>14lg+I4U8dPJqY z&FZ)IZJ5lz(WFP$7WZ$M*0)&1f|`D1p8NJ3P-ej85A`Q}otdVnqKX)^d$HRKfB$mj z-uY(_AGGm)*%=qsja^jc!27|f5k*2j7Yci^C-HN&;-5xbvOAf(ebJ;Hhr1qh8J;$v zmB+ckXUbKYL$FG)YO`29m7Ue+)GQR`=&Ouxr-+PGdPk}i+8&HbnQcTCifY?zXfiP} z2EQ@~K0vBUW7W-pO=^6sc7vAqi@*n*gt0nhwg^`DLr7k%UWGzatoF}Muu5jDWVULn zvsD)-B&?G6kD25B?R*UCl708R#T2N?; z)iVVMRtZ)KR&5ol0}B(Z5@coy9507dmBwl+)WpZCV-Z#k__NjCrG&BiO6wf0DOM|$AXp_>C0Mmptez`Luu8C+DX{tz87a8Xv1+&=Mc3N6QOiRj>ax zb%Gs51?Fa6s@O3fXfk}3DUkWkBM_1otGA%g6stqZ5Udic60F)PR;!dJSS47^6j%*{ zRF%f+B&dmx)!jxh@D_ppS4|kJNjpTaTH1wGATL(yL7^#DFIFO0C0Hd`wNP<$yn1?NeJAt09L)uo?#;d9gYX3Qe(E-IZXK zV3lCiRnZ5f>m3^YRyJSSY5JYzK$3f zgI}2g!H}xbv(@QP6CbO3qZoKtE$=Ce)sSQntd?ucDv%eejiJyKtJmBKRtZ)KR&5ol zqdbtXO5Q(aj`xqh^L5$?sVa@tCr}d~t3^FoIp8k>5AYGjDz!xftNkG)FIJ~Pp($3~ zya`qbRtZ*Z6{|N|5UdhpW(piT`20Yg_#&_e)WpYXv{4Ma+3MKt6d>grDv;ipe8<64;jV4!)oOY!dRvL5y5Ju zKUoFxVpR@>rdUl4B3LC@C0Mmptd4I_uu8C+DX_W?QdJtOFQFzrR!eqZ<$%8koX|}e ztEoptusQ@n@?v#16q;hSerJMJf>nZ5TgB>~u1Hv2w_&0uF){|fG6(W>`++?1MPP5J ziI3G-qZoLz)k{5uv6>_{TfGP&d9nHe3Qe&(DU@K9V3lCiRT#nOcv!6wEsRxazsPL0dQVn?yjX1pg{D}&--}?CV3lCiRbp(Xu#p(hmG{tHY z4Z$kGD#5C)V)daG39ID&W9E4O_&Z;x{Bb{!C%y>m3pMev+RrEk-fZ>yKw+#p?-s%8 zH3-Rz)ifwH#p?8Uf>nZ5f>m3^s{25KRf5b+f#YyURq5I45~zuf)zd~X@UU8YgfLc< z#1?_w2C)j{#cE3^G{x$Z1cFt9Rf1Jp#p=xA1giwAnF6aiNL6X9euSF%SgkOEl>`1F z@VN29SWP%6GFu%BA$hU77z$0X>M@33m0*=%)mE|kY#hNV!D^JN!vH5EegV)X+Qnqqa%WP(+KRf1Jp#j4jdB&^=t*uj$+8G~P$ z15uEw(zDeSP!k`k=Z#|EVYR_LVXRVnMX*|bI;%ilthR?z6MX*Y+O0a6HSe-W) z39Bt8kCqc7WAH0;;2@-`G*-VtO?<3YoyW=ne-U`{VqvU0Zx_MpBnZii)#XrVidFAL z1giwA1go}+)z?W#SY11Dk)9YCgI}2ge=PoiJn==~wonrvtHX?9;LTPatQ5woUhI>= z_aP)NR{w)SQ>-prMzBh-O0a6HSZ%Qq39ID&W9E4O_&Z-G4Wz2{Y;`Tv#K-CtqZoKt zZMsnytEu}$W~)tBu?pnHY7i8fV)gA>f>nZ5f>m3^YT^chRf5b+f#YM4s?u1s-^eC4 zK2}|!CH^AtjK4*&dQt?d(;*};R@XqGDOP>A608!e60F)PR{z~juu8C+DX{ANH=C-` zSnUWk@v%DEC19c-UXvASe8!79Nj!K$rd)qfwsD#2=| zz-nJeRcWklf|~ePy=fE!538PsMX;(DnXP*0SOxN8H5dv_vHEd8!79Nj!K$rd^{+!n zSRLxx*^?LTrtfvnf_roFP~xSS47sRjjr-kA&5x=d*bb zBV+I@b6_B(sx(%&Lrr|F-ZhGWht=lSg|X_qHS09N*{b&iR)M@&?FxmaSp9mLV3lB% zVAWQ!y6PGdR>}Lv%<=y5cfL;NAXTNY>Uf<^YJ99Vf|mG;z>Dq*V^uGP)rAm}7pvQ# z&=jj}QwdfHRtZ*Z6|2-;f>nadOo8JnkgC#H4TGBaSee`0{s|2eAtG0^O_D={_305-&R)<2WN@I05)WpZ?Bcm92SoM1&j8$rr z2v&WcvI^wIYA6(%V%7fT|FL%;P*ogX1Hc!tD~Jud0TDGu12HyiJkVGI7!*tFprWE6 zqM#z8sHmvK*n0#tw#0%RMdcxiy=$x}Cb1+&f}*iTzeD!E&;9S2ncd;QdApvw=gi^D zH?!})ow+x^%;!Af2vLpgy=$ou+I9T5gX2dIdfnJq^dHj zMi|M@>SIX^K32OFr?YC<%V5>pLaaa{tHYpE&T8=@;!UxZf>6xEKfGH&kbhuq!RFTT zWJ^I9Z{e68;=Qm)^_fp9diQDC+aY6iFQ@CnVyo^fduUa<)xP`g3q#5^a}2HgIQ_!i z(w&b@Z=AHi@z(aN%v-I}95c4(q`M@=WbE2g-lbCAMvX&ec4%N7HayvO-0`WGUPo?w z5O*%^?%TNJu+1emL`@hULKH}QTX0h)U=lInR7!i}4&?w8x%faEfSJ7dSiT7$Py0T@~YWuVolLDe` z2fe80M_;u#Q>tgB_@wmyM;xc+M09q$H0gpvy=BNMvZ`5DcNSB{>JOh? zHeka!FlP>AK&mRUTB*30)cmZrgFE>Tfj5?+v+8?Rb^JI*A$bQpVdxqC;uVv7Dqa(hExWtn;|5T z)g#a;XLWEbWEELOR<+7%8AoIlS=9xrE|99qtd4<^{H(@HV({%&3pb>*D(qpfYFS6D zKq9Nvpi|Cj@~6luvWl!~mDM2)RIzG%tg$;boC9;_z&uD*WmZqZNPbpdNMi7@+NUv{ zRo}A=R(m&OusRw#<*b(b0$D{?kyWj-dhknCtR4(AreMQ4FlP=tfK*jx)xNQq)cmY= zhCBHWfp@f|vznRCV0Al$B<@yEK&PD5fab_5vWl!~mDLI@Rk7OY*)StEoC9;_KpRL^ zWmd<-NPbq=Nn-HrR!g*{vuc;dV6}KFu>y&#+CitBRii7iimW25T4i;FyDC=k{i8nK zKYq;Xv=~xVnbmVJlAqPLk{Eof`hHDkHQvZzbwFDNtK*- zBvTh0{{^Y4%xayl#iZtE)d%k6KLp;}h0dyxwOic-A&I-yv(PDLb!2B`67p$&;R8?m6GK}PB)uNYJ4*a`Se_uMQ!bt|JgCQi5)rrt4XSI4iWEELO zR<+9Nu>q=BT{=I^9UIPpIdk9%q^dHjpZSVO&Clw$a3?>j2ZqvFjXK6)H5oz@S-k|E za#qI-MpltkWL2xI)*Pye)!nVf7_s3Tm@@}DLaHjWIu%Cpv${8wU2zMmg!AqYODgxtSr+-+n)P}{K4WBq+{|FO~}u>y&#IzgwL z)pJvjRb&-e)heqKqLEc(RTr%O2&t;f>TMXw&uXdZVma{dR)b^dtlAxC>{drYNFu8< zpi|Cjomt2#vWl!~mDLM#kX2+=7p%U4R8?lRNvxRE{HzXyJNa2nUr1*))3V3{>TdNY zge0<>0iAMIBj+Kj$SSg`RaWaQRK@C(8{fNQ!#OZ#4s?Z7Rc197M)I?|PZERg5V*!l zI;*}f7`xT#i^K{fvf3Cr<*Z&_imW25$f{OZoxDO7t0#J0G-AU!FlP>If>c#z^*0#F z&#KKzu^jk!tD$S?ti~5&>{iD>NFu9qpi|E3XK~0XvWl!~mDOJoRIwU*@J|CaoC9;_ zfUxERd8Ix4!`(tdN4F338#*SyBKLp#BM3raK@f`j2|^1P$Zwh1R_#hM zSUm|LiLCw#opM&Eu18jpRb*AGtTx=FidB67sE_xLAM-l(gj7}Dt&1v=%dUf+VOBCE)%R#}ZsL{^bZU2wb=QdODNhcJ?#)r#B2 za^OD%4o{-9YW#=6>UaoAWOW{N%2{>ZjjST8$f{OZy}1`zMOJmeYLTQ5&{s#R7Sr68-wsxDaV3#qESTU`Pp z`B_bq#NcDK?lC&6QPzxit96WG1rk|p1D$eKZ>J%v$SSg`RaR%Et73I{tI6)za1P9w z13MvAm05iZBl%gadQ2<_{zKqNXX&gOSbuIc5<(JLT@0OaR-2qcR*_X?RjaIKo>9fB zMc6zeHk<=<=0M4_AIM`L0=I*a{H%sZV({%&uUuiUTAZ<4y$m6Vto{X^a#mw6BCE(M zvZ_^9n_W@G>VXr34cKrF%$WmzkgCeN)s--kpVi}%7<{ZY$e^?8`;_r+^|N2Z3M8`H z7CPmu{&pQ%MOKkjt+G1zmMT{9{i8nKKYq;Xlmw}&%<5AZ$Vo4kzkeW)eF)qMM)I>dRuY46w|e6d zoz={DjNR&W2uWo133SR?o&OM7MOKkjt+Lwc5weP`>VnlFkgCeN)p!`m&*~XT3_e!B z$YHShiovS$Ut$FkS?vg&a#kPyjjST8$f{OZUHBAPMOJme>On|VWmaFnNPbpp=ZNLN ze+V4&n$Bu`F~%YAObAJ2H4ZxEth&BHR*_X?RjaK2`AQY5vpx-W$A)uY&K#)l`U83F zL*ULZlAqNGNesT->K%)sf~6n`H3dPi&i#wZ{XzqRNB;M>m3#UYWw3f1LK0d12Rh}f zE_sKnBCE)%R#|nkC@SRsrtdVz+k`7Aqnsc%%cklLaUH?BQ~4^ zbLPMZNLA(C>N*(7&+0`<3_ezymY}mL{L455Zc<3BKq9MN&?#s2aS`#RSW7`D=HVaS zEg;B0Ft=cHYk9JzAdI(gOb_v1Sfu*QCl$T>H0|w>F}s)3^^kEmv;AUTyogvk{co>POMNTrQVtGvqQH$E#nrH^Q^Gv=4XRly;{tD zcr#&wOU}5;BUU+i+CTOf8et!C?PasrcZ+lU>IaO7Nls{#<>lqz@Z78Du*k%FwH963 zGHbPc+KWj6(YAx$R2ZCfAnr|rDzBrjTAV4>vr>FgdjBJi({ds@yIq=e!J*zVWEEM} zEUU|kt70{x;XpTRI0xp;fy0oh%B;SHk^HQFT0$%b{zKsJZ0M{SS$~5~EQBPo`XhA8 zS#4*9tm1AJcdJ_6t^Qp`6|4CEQ6KLgKjw9+V)KDK_93tjjO1rEN)m%_xB7b}I;(bN z7>B^WK}aI2Z=h4o>dFepDzb{KYL(UYm5@~=Qx_bMf>c%Bt^Ncf`B}XxiNVKe%TE}r zK4BaJx2P;uAd%Is&?#s2X*FaOSw&X0%IXg_kyT_>7pxwGR8?lx;uA5c`C0uO?&LoN zUQmb5YJ3iZ)%g&T$m%BOl(X8&0a-;>kyWj-`pgkoMOJmeYRx)gsw%VkEsW%6b-E-5 z-){AfhICdltr&;E4m#ekDzd6oRy`W3VztKa%iOWy9GEi)!XQ*rzx5?SpDopM%Re1WVYtH`QWSzXgu6|42SmQ2Nl zb70OKI1Q<)%xcjlVp8+7`X$`Se+ay^6`fVX@%Qs%Ed;@*RPLWyv&j8Zt^fUjR-fE| zTmm79tZs!)IjfyrkX2+AS=B15uUe{N^@~r6yJ5pQFlP=pv=UQQnbm$UlAqPtk{Eou z)vUI3R-@vq7f@M!3?YfE7HKU$vz*m+24odkMOL-Ss&`vetm6AeeY}7CnAd3nq^dHj zyI>?gt9KkyWj-y5VbN70J{E#}^<~ zm02z2Atp6HtIgp~{zKqZUFobwtzfXa5<(JL-3gs?R(-xfR*_X?RjaJN>w>HztGZyd zURNGOIRzVp8+7+8XZUKLkz~MrYNqk-=&_ge0<>1f6nLzx78} zkyT_>tE^fMQ^l&A^Iao0oC9;_Kto7XWmbp6NPboqNn-HrR$m6wS+!fqVD$xrB(hp2 zKrBx=tJ?yRRb&-e)hesKgH^F=>~hk84d=j|IS>u0s?6#k7|GA-BS{QCR=*iXXVtib z!D{DGVg(Xe9Ri(lR*QxrtH>&{s#R9Ek5$DgzJJum`^S%Yoo+&^DzjQ~oS4-7th&RU z{D;8nC(&88i)XO94nh)HJqVq0R{KRDtH>&{s#R8tPeN9aOkHr?2vSv<)j$}@&+2kX z48Gm!zticg8ul_+eG4IptX7yTmZzN6T~m=&WEEM}DysvgBdf@&E?AufsjAFs8jR#; zHCqyckJWD9(OLCfz+ly9hFF0_R!2amoYhjZkyT_BS=B15dt#AQWK|ceW53vWl!~l~t=ns#q=axwWy!w^LJ; zT6yp8Mm0_8b4>jUuI_eK(@f))e*S%CmQhVp`W#b#qg|;6HO(|$>F4${^HbF{rOz?- zzY2*-Rntu4m41HJKHODJQ~DfJ|E#NF1~n~rd^1Q@WmZFABtNUGB{BGRtA$q4SvBrr zuxhbbtUw~GRiIPO>b_;jDzb{KYL(T&D^;;-NO*U!MEYPirFLLIGgVFLb4>mB9EPiE zrtwNYw`TsKswsVrslWN=b_O-gG+ycFl_ED(HKorn_1B4=rmC67EB$P;b^Vgy4Q`I!3&oT8!y8M}L+W( zq~>SU6Yk_c1Wx>k&T1y>*FkK9ki^~UG3b=DI&=fFimW25T4lA|PpVkO_mBE`|M)Sl zQ!7YSWmd<+NPbq=N@DQsR*UVRv+A43I0P>Gvsi&dR%=41oYg~HkyT_BS=B150o##P zBvTh0FN9Q8X7vn=PATnzTIl+<8)Si6Bw+PN);=R$f^T$%2`c2f~+E|$f{OZ z9eGR@t9z`98J17%=BCuFr(H6rX-c1C>hDyhiBU~6jaT~l-Jdpx)ikBgG4%&Kdbq1; zrtwNYAN8x0s-`J@j;Y`I`B9^qW*V>b^IcX^cQsAvb4>kzg$V9yTJHE|kgCe8UWAeS ztiG4T;A3^rIXbJt4-8fZ9%ryR0XpTZRy~cZBCE)%R#`oIRu!wM$EUZkI$Fd{sab^LgbascM?i=a~AF&sA2{OyiY)T3B5&s%c7}W9pyjbFz(^ zW*V>bbK&5#s+!X0nEGw|+8Ncf-0^=ysw%Vk={Yf}`C07&ck&+s@Bf9t>KX>C`yeE7 zw|W6O<*bHWLROJgWL2xIR{up6t9N3@q&nHg9#(4I1COX`N}pru-xg?XP}5A~m3|7J zc&KVhpJVC|v?{EsnZ_&r?0@XAs-|Ksa>tx~R6SKqQ~PomY7~s*XLXAt2H$SA>}@)$Q9m+RwYe%*Ad%I2&?#s2_zh$gSw&X0%IcU5RjlIs zM}541{FvA22S`s<|oz+a%ui769A&IO`hE6%FpZtofBCE)% zR#`pyJF<#o>Vo5EkgCe8etu6(YJOJxz@7Z8ru;=`HGVT=w|WRd5?TEPI_0d6{R3G= zR*_Y$vTFYqvWl$gf>jSlRb^JE!$^KscSvIJ9Rk}vqqAzaj=^fh$6^H%S#1cNa#qh| zBdf?NvZ_^9$LAoc$f_<_T?47A%<3%|$Vz%3w7RLK0bxhE6%F zwO=Bu$SSg`RaVcvR>kUj58LKbbI5Cp!)lt+ z=a~BMjQQN4rkTbo{ajzu>ad!o^f{*fpNq$-YNqi@KaHQ%b5qllKF8F*eQC8eYFh62 zSCFd8tbX}MOlp2sec?`iR*w`aCRhrBP*V^DYqyaBL4KhD!6Vy-jUMaoDQsY{ng$_> ztlor9Ija%xkyT_BS=B15bqW;|ECfNAUq}$FJp99Z_yvafw+{^V3muXmh*xwWL3sLh z%)vFwceyFG^rru+YD%AD>K}f0uc~Gmuk>^F_1^Akn$qW(`YRPJpQ@&r#w-1tbg!km znx^zQrvA6bPpfLC@k&4A`edc3X-c1C>hJQ%&7h{`j`xOCRc3WIjO1r^uOtTFA#k;l zbXE;p7_3&c6f2O(Y9r{BvwE?pcvGyUAQbcP5APNbC*s43r9$J-dwePkHra_h0 z(N`_blP3dz?{Z6}@t7@k4N1WA3n^iTX&oT9%TGUik%N@S~QdODNyD*ZURqK*sIq>gRN0+6unz@|8Y6yfRvN{Vo z<*a^cjjZBs6?dyz-K}1>QN=30f7HkO$B%iP-a)D=v)a6@nAH5N`oo?4te&V$XVrL! z!Rm1cNn|w>I_0cJRYX>iRb*AGtbSG*Sw%8+!Etv;Rb^JchmriO9+1S~I|R0~qq7=s zWU%^46|n+|tTuyAIjdKzBdf?NvZ_^9r+$L0BCEP!bu*-@GOPDtBtNU=?Zk56->r_T zOJ_Ce7=zWZ5R%C1T;)rstZ;v>wX}ww1Jfx9faZgmliLVD*&uZnSVma_10#9sBXVq|k!D*#cQb zR*_Y$vU5 z%kOa)Ztqpq@;h$s=M``Lfjsshuse+8XEj(7gKxKbsU4kFVGo1Vix85?>YvalXLYt4 zvWl!Ct6F8XNjp`n;`>K^ynpy&# zx;$Rb&-e)hes89>^+^sSA$xK&mRUnhhiQS*_tImIMDG@Dv|9tC{HxR-+&! zk=13;DQC60H?oSXBCA?u^|!9bDzd5zR;_$KkjFj*?f@hCSq+uM;M=WU>rH1h>L7#F zs}PdN>fg{QXZ8D@$SSgmtZJ3j7QK;GWK|ce4u(`!-mR{Nk^HQllEmO+)oCD|Ro@c~ zRzL3}Rv?kp_RuM3^?rY36nK&Mx&~D-V#7Hw zXAT5Fsw(eR*TP7CR?kaf@Uhx>Je^hJaR#ejhKLnNWYq&Y<*YsmMOKkjWL2xIE*Yna zReb-bkN1xs^Ew$JRh3zN4I}wktvg;U2mV9gIg{zEMkO&=oed$0tgeAhIjimykyT_B zS=B15k0&9kNTx10t~B`rdF(^rE-;dx)k%^Ve7n_OXV6*AWc`+MQ7!v$}j5 zvWl!Ct6F8X-3(+ES=9xrBOz6lcdHv=BtNTHBr*6{b(u?NRbc(aaLs3m6-Z>&8#?8z zX3s`ekyT_>tE{g44p~K3b;0UUNL6K4-@{0LRvXL}%Ypw8c-~?qiRRimH0xyD)L{>LL zr<_&KjmRppimYmt)fYdhVin&%>f`<6$GlGVKZ~iV%xWJP$S70J{E$KxSYm08^ZBl%gqBZaVT4KML)cmYAg**8V zfmfu`Sv?=jV0Af!B(l04I_0c(IfSettH`QWS$%6nR*_X*uv#ZoOjTu8ePJX&tKUgt z@a&{s#R9E-9uK9OkHq%9a2@9)$;enq~>SU0C(~q0{{4!&g!U93|7}d zNFuAr&?#rN&!5ODvWl!~mDQq;kyT_>7pyu%sw%TO97gi9x>OQ_Z@2p98H3d@2CJ_j zB$3r}Sz>w0S>5pjSw&WnRjsnx?-{a+tm=Z*nUJc=tfs<9epa(2G5A>R`j*bB_c#Wt zU7m{-NMtntI_0dEc!jJYtH`QWS>5$U6|2t%RdvUPb70OKxDBbQ%xdMgVp8+7`W4*C ze+azEvbbO=2trLk5Ug{5nZ93WK=8=_exttU`7R7rH$q4vt48RQv+64p7c2xph_w`i zVjlkC-2#IA0~2z8kG~)YlPv{dyoFZe4$6MR8GH=UV(!D62@_m$##J7%%E{CIvB%H|`-p2Vo5j9coa0wNU_?xELZd7%F9(O`UPXsR zCf=*H=*pH^tL@WXObUp$9rUKc;H(32ZyHp29evf}OsSrg;*-+*A90+P6Vci2(xeLx z^_C&4$f{;pEoCXz=lnu~VCCT--or02%)fnLuwUqq+$znzq6-Ovhktz|Hk<=<=0Foj zRb^I#VI)7Rt0Xb_cB?`uI;)9+3|8MmNFuA13XA0_XLWBeWEFR-xLeigZgpTuRjjV^ zY-zxTb70OKh=o*DW;Go~^0S&FiNVKe&vJBD&ktv?+M|?MfkakELZ_Tn>oUkHvWl!~ zmDPP^Rk4ciANBG6@nc@6-yl_$S*=k{Olp2szlJ;c4}rHTipzBCE)%R#~;Ff~+E$y5P74q^dHjp)iu4)dWclzTIjOdpfI$-!fP&Tve<5woYmnCkX2+AS=B156`fSEdbHM5cWgKZ=F9Dzd6oRs)-=Vs+&09R_ST2jf ziNVLJUmH5B*{oj&;oFSC>Uijsvs$?&vWl!Ct6F6>t+gsvBZ}QIV#7HwXAV4uR8?lR zZW}SF`C07-ck&+sCw)a{)q4=*5O^giNUv9E#pOJb>095tJdws3M8^x2Rh}frguVCkyT_>tE`52 zBCANIE;wEZsjAHC6&T6SY9TMN9Qb#uL%PvfweexF>JK4_tVTkooYfj#kX2+AS=B15 z$9<4hWK|ceK7~|OX0<^#F{$}k?FD!8vwE-(omFRF2CD}kB$3t2&?#p%^jl;VSw&X0 z%IYV5kX2+=7p!)IR8?km8jR#;HBl0S?-01cAUdnr-59Kv?<-ayk=4(jQ_kwC0mv${ zimYmt)v*Iru{wP4W_N5j2jn}tomFRl2CKs%B$3sr z&?#rN)=*>>Sw&X0%IcW_Rjdv)J~m*(IWT7qyns|yX7!8VVp8+7+8^%ZXZ3Ihoz?R! zR#PD)k=5(aDQ7i&B(jREBCA?uwRVUqR+p@rYs7|gV9p%q45_NjY7C6zXLYwE2HzoY zm2f(%&OI2r)ykvA3M8`X44raT&xawa$SSg`RaPU$t6~-3KkDQCmXH?S-k@z z`B^O;E|vrTZgo@?oz?7N3|507B$3sb&?#rNZX~jbtRkygW%c4@WEIKO1;=k8Rh3z7 z8YLz*KdXb_PJUL8&7`wx!}@E?(;+00)!Wc1XLV9EvWl!Ct6F9C)0xOBvZ@PKeIQkp zS^W-1^0T^M5`*s$xaRkCR_Bdm>{e^Uh!sd=wFz{}S-mm`Sw&WnRjslbH5XY$R&~MZ zPmrq0to{xo`B^Rdy;u(XyVbBIbXL9RFjx(RkVIBvp;OLkgN4W{vWl!~mDQ_@Rk7++ zvzj|LoC9;_fW?vz%&2(06SbvRqID{m!Iv+aatbVZxSw&WnRjsmm>t|K0;`>K^ zynpO<(1vl^3#tRkz(s#aP3 zawoEiWa@(BevqolyVa#IlAqNhk{Eof)=Q?dI%+b5)w;XH3M8`X3Y~IR@9afZkyT_> ztE|r6kE|lAx?pt|q^dHjSum2H)oRINIq)9>Pd-d%_53sjtCJukk<}&8DQC553bKl< zBCA?u^=>M%imd8_)l!E)kjFj*{t8C&vpQN5gKxL`%LzKGiBSwzuRus5tB;{m&gysR z$SSgmtZJ3j<|kCKx+i9(J2spHbLPN6NLA(C>M9t?&*}+D3_eyHUZAsTGn>I`gOg$f z5?O5ropM%xKZC3ytH`QWS^fUJDpofMsRnE~2jb42poNl z&g!VS3|6N>NFu8%p;OLk%PYt#vWl!~mDT%KRk6C_eyLP!I0xp;0h?d!M9tzd56ww_7n!IHy|XD)u+%YXLZ3XWEELOR<+7%>pQAg#rKc;c>nk@uhURS zRps4k0*vHm^{gZYAFGWX&{=h6{W^#*GQ|ocvf2qc<*fek8?uV5BCA?ub&{s#R7WJw{fM zRb8-JG3x_)>_gyhU?e}Q6D2YDcB`4s>8vKQSiJ)wiLAbWPC2VfpCYTsDzd6oR^6W? ztH`P@SPg_!Ro<{}C&Y$ZBWkl(U-k3Ry)~kyWj- zy8NvwR*!ex;*JgHz??ad2C1sd>c23OpVj*Risit62t2oN3BghjgqngNSi6l32=WUJ z2p-usZ1h-v&+HitR=NaW|GP6Si>#*U;w&RXZz4SVA+k?1s zX?NeoC5LS;xglcW#0qs%>YW)sJ9Nv_GHyXR&kB2Pem2ZbIe!z&BVLa)hl4A^iE%$WmK3yZ0$%xX6n$b+8Q zRufr&ZuNHvNo4gcbjn#>RUBEx-74-@wYppFP)Zf6V~UqGV8b~uXAXowsw%VkGmPYC z^_nCGAFHj((^<9op0QhPSz4?>BC9^oDQ7jO46=%>BCA?ub#*yatm6AeeY}7CnAhnz zq^dHjh02Rb&CjY6+{u3kys#>r)%Z2m3t}w5oP35%GVg!#=tHxBx;DS^Wt* z<*a^P30Xx}kyWj-`n(FVie&17<4>xJsjAFsFBr+s>I_K?zTN7d_HBrRh3yygpvHLW=LZ2vFi3Ioz=`mjNPiC zmRNyAR=QV?vWOW;K%31xUA+n0BBCA?u^|g~KRv&LlF=E3xFlP?bb{11rnbrO|g#D;TV&K!t< zR8?kmH;m+G^;by@K33bi(pjBn#bEWT=3)gBS?vd%a#sIsiL4^4$f{OZ-PlGIt1&i* zjM#7v%$WlhAyt)GE$u2MH9xB^a3}vE@DJ_jta_Jbu(}FD5?S2^opM&YwMABuRb*AG ztiJzB6|4CEQ6KLgKjwA%w7rZLtv>Ujv+7)f!DZ=uT(#yfuT>uRDtsNMv;& zbjn#R)D>ApR*_Y$vbv=kvWl$gg4L^#s>-aE?Jg!YKdWuvPX0sSHGS!<+LU6jngAh* ztnPzOIjg;TA*;wLvZ_^93-?7-aUz({^p|B}SuW7T^E zoz?8J3|7AxELI?q)uGTSXSLWcWEELOR<+9Nj^V0UZMd@BL2Nh&=FEXxkgCe8+Kv#D znxECSa3}vE@P^TJR?nAUu(}>X5?MV2opM(D2P3PRK84O|HtWx=cAFqpAd%HT=#;ZsdJ?jVtRkyg zWp!^9vWjHtg5$f8s>-ZZn<6GPKdT+#PX0sS%`tRVomsoppCKfX)imgovpQ%xvWl!C zt6F8%ItE!qR&~K@b4XQXR!74~epcfoG5B_?mh-a|EftfRpH(lolm8HS`)WF?+0_`VCPGN! zZuK~H%2^$@5?Mu7kyWj-T7I=ER!k6PC2V7YmilB6RB-+w)W)v?eiXVvy6WEELOR<+7%>Sk4};`>K^ynpTU>0+^wF0PC2VV+mTgd6lt4O9UICh6r zRc3V}jO1r^lOzV;Zq@1loz?Sqt1XDN5Cor6f*=SMZX*MN+J=oD>+h5MkEM5u6-Z>Y zHgw8aJ(7g1BCE)%R#^>BMpltkU9h?wQdODNOE8k3RpEeG4*a{-!D)0>6CW~I9RwkX ztVTemoYiVZWEELOR<+7%`e9@hS=9xr*^sKrtkzExlbWB^o^U5WtH~$nta|4#SltgH ziL73PPC2Wik0GnbDzd6oR%@J8#p>1p>)o*79GEi)IzXx_vpNMv^0T^C5`*s$xZFhs ztA8+9Eqh9=Kq9N3LZ_V76K9cCWEEM}DyyLvRIwUkUpy5X&Ve~|U^S$wGOO2MBtNS~ zE{f&AzgrEsPG>doErZoz5R%Ah6m-g2wfhBGMOKkjt+IORnkrU9UY0qG4d=j|Iq)1( zRhd<%>ta&#v)UK#&{s#R9Q zA0VqprY<;M3#qEiY6gttXSL)*u^jk!t0VuWvzpC%w;BW?iL6eCPC2WNe<7>LDzd6o zR?lZ4tH`P@SbYtts?2KRzs02HXVnkx-bX3M2VhE%Qz+2mamam?9+wOF$UiV4_g6Rx zf-u=q5XM_LriXYhEK+^ulZxJbn)Y_cnBB|i`morlJIfwgm2S1~zWc(Ea?Kn=D?d)Z zaJO{lW78WaEpWWGJuCB8t2D=q?K$Z#Nii9__LO(2RJT#%keMACSceTywjFnT>ZR9_ z+aAQ7OS}6vE;(#-$qf+`CswGFQt!<8*`ZsWmT?Qpc~;nS^RvOOUM=Q6yqPe;C1+ga z5v!a$?H_v#jj)fn_Oe;*yTv(v^#ex4Bqub=^73+Uck zXxl+=Dh$p#5cj4*mDkZ%EzXqcSt&j#z5fx%X*m&{-7ZbK;81TFvWl!~menhT#rm9I zND!<%{KI?r1%~;z4-EDT9gKg{&g0x?r^rq^k06buoeE@x{++?9qk~w1L{?ivr<~P{I>;)rimYmt)tFC_Rb*8ctnPqRRc7@s7|G9SmHJ{i z@E-z4enDq--aQ7Z6Cos#)kV-LXSMO?$SSgmtZJ3jJI<Xh%Ypw8cxnd*tM?hKPJxg_R+mGkoK=^0 z$SSgmtZJ3j-`lHV72iMVy&#c7RSfs}H&&tH>&{s#R7ObVpW^Rb8-p08&+%)qh|lKdTNs#B$(21fJQC&T1m- zw=B(okVIBjL#Le8HocKmWEEM}Dyx6=MOKkjU9eid-v{#8hrnJilAqNHk{Eou)!T#V ztY+shcB>f>lE~_F=#;a%*biAnR*_Y$vT7Ktiq-w&5?a^Jn(K}Y=fGS!FdR}pPSPQq20YPoUMvwLP$^FMR^Ti4zvf2YW<*fd*2w6o|kyWj- zny^$At1X8F8f)A+d>9+ffw^+v6r`#$t3{THNzKn{Be;|Q5O_%(oz=`|h3Tv=hLA*7 zw?L&{s#R9MS+9!Km3vCMzTMd0fDPxsTsaU9 zsjAHCP8iA0YNjLxAFJ)Q(pfb&VzAnFgIIw?R{KDwoYgl!A*;wLvZ_^9*Kbk9D!zZz z$NR^Rd7aKfsw%Tua;uos{H!*EJNXZRSMH{>YOrUpx&lHHS=|Aha#p+UKvt1eWL2xI z{<{lVMKX24aoycwsw%VU2P64eohymKw_AOBfX=F2GX|?qAS9915_`mFmb1EPAF_(9 zBCA?uwc7z?6X-wbKzgtC_6bYR7|O1rk~Hg-$uELMpO~ ztRkygW%cJYWEEM}1*=yeRh3ySb3{yPepXw-o&1Nu@u%plM%7~MR^uQfk=4D>DQC6k zaby))MOL-SYN1oASaq1P#n>ixXDT+F19Rm-14vb6R)@eyepVMsV({%&UtFZKYN*3t z^&bdHWYzk#Se|lLx1K{*kyT_>tE~3AsEXBvue{nE`)i;ZHk<=<<-jyZRb^HW!bpBr z|CGewW3}@QI;#Tf57>BJ5-X6%sy}qfSuJuESw&WnRjsm`cwH5%limJG$?QHp6&uch zxpLqJq^dHj6>f-0&CjYE+{u3kyzVZY)l65$ZuLh9No4f^bjn%ndmC9rR*_Y$vRdq} zDpv9Rqdwk0e$4Ci1*EDnt0Q0}KdZ|mG5B_?Zy(ZG_5GB=>Kh12WVQUSVtLA0-FXjL zMOKkjt+LwxA+m~O>Vo4KNL6K455q`)R{xg7;A7P%o6f4xhQVsrKg0?ovN{|(<*b%` zjI1K7$f{OZ-TgPRimd8_)jN=?%B)t&7L%Hv)%I{F{~_>CFX*fqSckxyAS991ROpnm z>h}y;MOKkjt+HDB1+t2)>Vnm#kgCe8j)IZ=to|U0!M9trcu!|Fp0!&QUWye+WVJGM z%2`c%gRCN}$f{OZ9rR8WtB3t-xs`F6g$?JxY&q~9q^dHj$6zEstIs4c_*nh6Xeq%` z5QLh7AXw-A)o*^G0l_2x`}^NKjjZ3Y)bl-q)nMq9vs%WolwctULae1A6!Y*8?-mf` zADEE)x6TQIFxgTN##=b1hj=e6Qhnx=ir#&i_IAja-OK6vu-K|Q%N|;lZnf{e`@)cN z%^X83KTf}Jw{+)Y(;Fu(aJ;oWEAv*XG{=nXIq5D*F&Vq|ly|9Aw^8GenH?HfhYe4* z9d~@{rPq<$9>kqXyZbgSIc#&u4G|M3R;ZIw@67nwp_>$ zwc0-I#iW2}+d*$C49+?b_ohLW*U?uk&Xnp|DLyH^{}IP&IT4-RE={`NP;VKsimYmu z)%``p`kY@#5Uf1>!+ZDzhWWP-4E75hl3S&@S9Bpk$hwq#XzhvD*l-TamIJ>-sw%Tu zv#6NV{H%Jwo&1Nu+pOrUM%87!TipsFiM!Qw=#;ZMq$IM6yH(t+YIV0-)=Cwt%T6wA z^KI3f*4S_k%#{NzAyt)G4TF*Vtgey7;M=Vhtw?9pw>g8=BGzIB5?QSQopM$WmPJ;P zRb*AGtPZQ7idB67sE_xLAM-jbfK*jx^)!s+XZ4jN1|O^as?%9DI5Sx7Tam$PD0IqM ztxyG7MOKkjt+JX@4OvApb;0o;kgCe8I#d^vnx9o~xRd`7c$Wj6RbO`ot2-eiakqL3 zI_0d6utQdnRb*AGtlByttH`P@ST#VZDziEPM)I?|K@x*+w_55mI;)v27_648Emk0r z)mqRgXZ3JhWEELOR<+7%P<><-S=9xrOCeR2S-k)w`B{A@iNVL}z(#adg|-Y<{XS!` z8V;RuR;xH6tH>&{s#R8xe4&cfe_vc|UDbPzJ2spHbLBu5q^dHj^%{vu&ChCgxRd`7 zc%KV{)s75SlOQB&VNRqK~OwC?pR(-j-efw^+vD@avk zRwu(qepWY2V({%&ZQSUr8rm^fEz?4*Kq9Mkp;ON4vDU~cvWl!~mDSM(Rjgjw|7F_m z4o$J)9GEQ!Rza#Nv-%5+ ztE`^rpo&#||EQ1mk00|oNo4g3bjn!` z^F&sWRb*AGtlE8ptRk7Z;P`7uRb^JAVI)7R+a)ph4uLE7q_b*l#bC99w^)HhRvSR4 zoYm7l$SSgmtZJ3jaXpY#WK|ceCP1nxvw9Oo^0QjJr&tdByVbz{bXMc*Ggut~A&IO` zgHAcC4t<$XLZ6rWEELOR<+8iqrWOvYpe)1POp0XFgBb6bLGG{kgCe8&VrHrtnQJ-;5!7a z8boI`swIQfDnrByB(nMibjn%15P+;AtH`QWS)CZDiq%SA9zU?=lXh;{a1P9s1M4AG zm08V%k^HP$1&QUrzgrCnrL!tHGFTl2A&IQUK&PD5dLhUvvWl!~mDNjQRI%!wRx0J> zw01^pI0xp+fqx-Ym04{TDke2QtApWAepZi1&{>UVv3d+b5?Q?iopM$uk4ILKRb*AG ztk#cE#VWpk)W`eBk9nQCL8>aVIu}Orvzjc4!FLG!$utJ5JsG>zniIteB(mBRI_0eX zG8tJ#R*_Y$vN~ldvWjHtg5#edRh3!22P64eEjLXp2mama*x7Ve?Yc8q4TF$GR=YC3MPJy}1}!MOKkjt+F~}nJQM7&);gSpE4L5 z&Vku-AQ4hknbkjGBtNT_mW$=Ue+V2APiHmWi^1vy2uWmh0d&e)ZS(`OimW25T4gmO zP8F*IPxLwD5w^pK4d=jIIZ!PA19|L2U^f`a&+14?48Gm!#SL^;4V@UQUVxB9R{wxb zIjggNL{^biWL2xIHr}9$)n*-@xIV8Q?}iQMz+5@dA5v9$x4H~Q^0RtW5`&M`Pq)!o zjc5He=Jhs;6-Z>&0G)DHGk-=_kyT_>tE|r1s)|*7|EQ1mk00|o?S@oUX7z6v$ zlAqNvk{Eou)vE{TtY&s*90LCWA&IPJL8qM6x%-h-WEEM}DyuFBkyT_>7px9~R8`)s z{s1HSSv@IbxV!Dzd5zR`)}y zDzo|wM)I?2e^e|7{zKsDr|GQP^=7ad4IzoFu7XZEtF2BTtH>&{s#R7WoKnSVPVZW7 z*$wAo!#OZp4wOCpfjsshum_CfXLYf#%!SpDMk!bAU_J#-Ko&VjjdAO%uYnblV?lAqN&H^p+` zKLnorE1gw4*1OeN5R%Ah0(8n*b-RPCBCE)%R$2Y)t}0gX!pq#3?XMrmV;=&0!$^Ks zBPB8TcB^;)ptG9!En~Nu2_cEBzJyLWtIO^qtH>&{s#R9o{(-FGrHd;FQdN1kx&cP= zvwB$)gOAnbPw1=)tiKqp*`Hzs5?TEQI_0eX{TNwAR*_Y$vbrK0S;b2i*AYlnWmez8 zNPbp7dm@$t{~_@AFX^mCeZ$zT&V`UfR@XzPoYnTvkyT_BS=B15PhKFac_g!0Fp{6usgf9cyVd*e>8u+1F<89^A&IR13!QRSe|U?mBCE)%R$1-%9$Cdp7uRS= zRps64W*EuO>UBvBK2}>7D=k2Ws1Z%gE0YQGD0l_2NhK(NU?`dekV6~M{TFCti zV~MPGgHAcC&n(58Vl4%sn1_FOw}2r3zyv|~?~^853c`2`$Mg{Ig+;2*d{WW7Pt)EG z8MAviT^|-(b!XW_tJ1CZ-FIIYQm&a}XywQ07w(qsd~AB-qy>(*wr6GDYL(`gu{|f< zB`GFj*Pik&mFhNX95S;*1M9Hi$+qK;PrdXya@&Krb7^PX7JuAg0 zrT0JLI4vilv)iRf7aZy>LspSh&9WL-RIJbWg#^LM!#})-UtpMj`@mqo&>^{1ntMeT zg8u_Ayv%r=fK*jx)v}nF)cmYE!=3zxz>BQuta`t!wjkC*5PVAIPM<|Cy8n6WllzYg zAtaI2pP^IEsz)hg6?dz+Th;1r^&cx_6)#;}cGhC5Dzn-fM)I>dQxb!3xB93eomJt> zhICf{gpfp53zZR{Sy#OimYmtRj-Q3Dqgy{#zCqov$`Ed^0Rtd5`&Lb_ZoCo z<5{e_*@_iNWVIJ`%2|C?1zAN_kyWj-`eSuu6)#;}XCYOUSuI{eOlp2so4}p?hrr8g z(^-x3VeD3yK}aI2iO?x$)!QCfMOKkjt+M*Y0a?XM7nfsgF;$gW9RMTwS&fy%;M=Wc ze@16j=)qw1ZwN_bwV0#$%yL#Y)I(O0Rb*AGtakkjS;b2i*F;EFWmfmVNPbp-lf>X- zwZoTmR^yv9SZ&`xtUw~G{h?FN>N_W76&{s#R8n7RV}Iy142?sw%TO7)J85I$sil zZ@2o~jlrrrW4HPYLK0am-BK)1Ijfu7AgjnKvZ_^9d%7X3cXE?HotRkygWz{bTS;b2i*BnSyWmb>E zNPbqIN@DP_+9Qn4s?oq;wfji10*R~!L8qKmtI^0RvWl!~mDQwBWEC%6T)#r9DzjQW zOiXHiRy)C+{D;6>Cem3obY!r)8A1|SJp!F_RtJY8tH>&{s#R9YOhi`k(#7QhsjAHC z7#PXVYP=){-)^;VG@aGVo(xtkBgG0NvRVx~<*X)0A*;wLvZ_^9hfG6O@zTXL4^mZ` z)srxipVb$V7<{bunL}sQt|^1n-q8$JM?BCE)%R#_df99hLn7uRA) zRb^Js!AO2q-%4WevFe*ZXVt)Bb-)S+tK*c#z zwN8SV)cmaaz@7YuzbsCtWEEM}Dyzr#Agg%k z;(7w9s?6$Vd&Q*YXZ2gSlb_WChZwB3V6d7DA&IPBf=)TBW0H|oWEEM}DyuaQA**=l z;_3*gs?6$C7|GA-Hc1S=L*Vl1bXI*EF<32^B32-g)%wsWXZ7S^WEELOR<+7%*imE^ zFI`-5kgCe8UWbwVtQJid%YlElI{XZsRpZwTRs$d;k<}^CDQDIGB(jREBCA?u_4H|E z6)#;}|3IoLv+8_COlp2s`@x<3tfpS3vubF}VATjAiL73OPC2XNFCeSPDzd6oRvj)Q zt9a?+@`6-VW_2cv->Xujz{JYiQ-{`Cw+A?;lBOxS_)fvz!XSGfyvWl!Ct6F9C z!mr3GUb?v6K&mRU+T=GesrgwQ2zT=!yD0sdtbT}U7Q*2U}NzIsBcD(_b3!$^Ks4@qM1 zv0AG*ozH?i|R<9QpZ;G`Pgkm24;oSm)`~!0fHn)~1TMEK>3&->j z?}bIG&wNtRyHC^J4jHq1Ib9zXTXkpIL#xuQ_T6`17*ej8V`$~a=@;&n?tE-|pOBdHxNL6K4AHqm} zRx1`4%Ypw8IJ^vJk{q&uW?^1|O?+YtmVb@55lVP9?DdiLADPPC2W$t0Jq&Dzd6oR%g{fR`JrswG&cR znbpTIlAqP8HN|q^KLnoSNM|*(FN4)c2uWmhF?7mVZBh$aMOKkjt+JX~8(GCm7gtHg z59F~Af!o1IepW*yG5B_?R~pb+6^b%gy$m6Vto{X^a#mwMMOKkjWL2xIHfw;a;-!nr z4^mZmx4IHW^0Rte5`&M`294>g#3ZR`Jrs zl?17(%<5AZ$J4`~t5MGwtX_wZ zL{^_br<~RKuE;8~imYmt)mHAvDqgy{hCr$+?^fesBtNTXBr*6{{o-pntG*8ytU9+9 zE0D-)N9dHZ`mjB+imW25T4i-%Cu9{bU0eqtRh3zN0VDZYt^KuF4*Z9}FOasaXLU(;WEELOR<+8i+qcLnUb?tOK&mS5R@cEuepW9^V(_ur)R)ex z@R)H3+@zOSfkallpi|E3K%jCSO`gE^+)KGv)XPjvWl!Ct6F9C?;*%4Ub?ud4E;bJ`w-X%M)I>7C5gee zTkSYZWYtL!gmVA;7sGW99_;Vw9e#BFe}BlPx*!Nc0s?~u29NI+KFYsSJISB8$sPIM zpSo!|%Adl+`s3~JvcZ}@*JHAUte;afhVCY!n`Fsi(sTZ!p?yF zUxcN@*^6NKJ`am9dpKngB8Q7lP!NmIbp*Q-&X49w+L6^NobW|T+FiwCuxsx5FQ~v|8@A9w+i-IVNFf*v&7NPG* zb|o05@+`tPBPoyIJ~IC+p-wP+5xfKQun1LxDNj&3xZoDyE<6dX60%LYse<`3?GcW_ zBjjf#{5*=i2+ou8un4P1Q5IqTsDfLBAtCHauo=r!3B5unkKh@S|CQi8n!N~yVR={t zhtZTLupM1+i|`1ZgjNa0kvxlVoAwA7;1Tk(5_XSaFM{37JS@V-F_cAEIi}ziVN@u) z60%KCqUv8qgF-2f&?7YeE1^Xgdl9@B=3x;UhEbltF09}d;W<1BtrC1Ac`D%{?GbLm zBjjf#q>N=Rg72t2EW(blltoxKw%`_F!Z>y%_%7vHgrIShNAMk&|CP{gJbMvr=H+1# znvJJCLH+Rsw+QdyNobWYZx+uYJf%ItJ$Quttb`Nc>_sp}6S%h&DD336FLjG4m=Lq&92$S=$2yPLSCukf|aEnl4B6|_+7V#{?TiPT14UdqY zm2e5ZI_&^&-o!jCLi$9?BJ7)3aEmZElD!Ct^LZ9wN+jhGLL>9P626_pu7u2Kc~}IG zNt7pOGpXPfq5Nd_BAhqXw5tC^EjpR<2(RD~^0N{$;H%RrA=^~MJV)8*X-|+gx!@LI zSrmH_d}s4i!kj3|B20?P|4JA*gpRi^cdlBNJcot#tG|D2xOw0d82#jV|g5aNr zMHmoGd4jId1y>1mr?VH~yy;0)nNW2)!+fv--hgn7YvScKncPjD5Updcz? z^9=SPBu4X8Lfj0>A}pAZ|BEnoCc6@xL-Mc)0W&F2(069RRl*lB>_vzl!m|jqVB`#Jf)2t{Jqi(nU&hedcvdxA&s1O-tEMtBn1 z0iMA1zqZ&JOId{VvH8CUv%h06LZ<1ZAkStk@;k~CjQXzND&ecS>`HJx%~J`@=TaWw zv$^@d2xY!!FT%XUJXAuV?hz3G>$SEW$C`BkW(0|BJACA$t*Qe#*ll%wI@Zgy@9@R|&lqu`A)cDVH}{{x5>VV)i2VZqLIa*e<3#L5al$w+Of4NobW|vzMn5F3=v~2s}c59%XM_!d?W! zo;)nV$|aOVn7gFl7Gcm*b|u&y=UIdvODT`gX=(mfLc?Y3MX)jbHwDjsqS`H^JVE(o z1-A$f;Ynzf;2qDi2sdeua26gRKPzF!a`qyO+L(t*Sht+A2+Nii+#&?6U{`|i1kWP) zuAn@E&x-u7gk~$*i;!vh4?CVpsK1i(1T|I`+#)=MC!tls`JFtAaF6x~*WeNIvl0%h zVlRRrEf1BjZ53q^)~qVHMHu%3yAr&Q@hrmdA1IH|?}z-a1h>`fMeyFAhec?-n(_p7 zR~OtOyoD#BRf1s?&m#OydxT%%5%RMV(&N~RkZJl4JDz_X?Te!`F*H z%CiWe@svjx8lV4_;E}*ygv8Z(sDw5NlqdKiq2Lyw=o z1TB9oxJ9s8$6f@x1fE5(Tt|6?f8Y`Fvl4E=SEp5i^Nu_$!Wr5V7}pitA}n6dUIc;b zKT%`WQx+j&eg0R%fDP(Md-SL@&sRPD7Zzax{6`L@5dwZ_wP&G7pRJoc06{;Ry<&5)Q(X&<^l~ z^*oD^xP!6?Yj@=TBFx;$UWD_eug>#dM-z5Zo*-yv!Bv9$E_NkE?c-U5Cc7w)P;XcM zFGA_v>_v#$oQFzyPkVx=@B{@>3CG|`XqDi-g=Z1=@1`ummfiWk2=n)_7r}TS4~r1J zhw=pD_7q$tcG@SH{6g%&ye1Et7|MUGz|M!a&KYW%?$^ZFi$uCiCC;rC7Y*)!|PLy52 z$>R6V#h3K`1tWZa8$l4dk-ql8WXjim1Yf(Z`1>C%|NGkC`VtT!K>yLwZ)zb3 z@ujT4OtDKApY?xk>P5Nf{rmSR4kLOQx|43|O~2{=%JQ!mb29A!drrHYYu{zrXWmqqZrMNswJV53y^1)M3@N|MeltlS+6z+MMiu^4HrzzgIT4Bi%&HlkF2XRo?dS>7j7a zO|&^_Q|RiAxof-_bK-NDUHkFRRo8y|!<5N!Ib3kHKQxWKriphXYf7yB-f5Jt{TqC3 zRkfd+X2v3y4^&PgBm!+sZ3Mx%*{Zg|i*yrhO>-j|;*TAaB)05|IHE8o7bSB-to@Nk zD0A|H^i64bE`F_S*9J#8=EQW9AL%C6oCwVSKK%YDdrl00O6G)E`%{ln=A_h7!sAir zBnYQGohChDC0cd^ceW}acs z$-Lhsb3&~B31=vCVtIz}c(gh3T)FJ_xkt4O%}F=W@?^YIRK$$P3a&w=qvTHxnlqbq(eJ##XCa2-qf~);L=h$mH>Xu|piM8MP9OY|Yg|Dru_V0Y> z`|D4~I;NC9M@R(Pnr6R$A2+v=gTak-6Kze)2!ii#d!I0BKlnU*PJ}a(IU&~m!1I(j zc|`iAv^+Oeq}_RrIWgVTopcjzPE0q6KS|fL3+y?GzbTm$V(pK;K$(;Gq;JZe6G3Qv zfqPB_A%Jufdrnwa+l%blKYs(}M7j2xUZhOUrxy#Z_IqApuW3}KWKD^+|Mexx*S-W_ zTUG5_2!dVo0&8ROOPp)kBDjj7HR&eWn&w72c&3(tzN#ZGv**P5zGO~_wcr0TWlkQD zz9~D;vt6rS=A4t<|9tO4x`{R?;#{!YpL~TqCsCIqb3&~B(N`#Q@`m(H*>fTY&R4kS zL=gN*H?il0b-DhcQ2VBRkaF!e`h_w%j=vOK?fYD1uW9xb$(j;tzx`Fp*FFbdTUG7n z&hg~6)`r4Y`PMYkGq{Sug>(~ZP0O8S)&9_H>^bqylFSLQ_IqEW%*k)0Z_3W|Y}d-y z_~zul+V>*e#F`WKem~+mdrq?dmdpvU_D5c)%*hMVH)YR>AT+qnJtu8Y1y}pu++?q*%}dFe5^LZ6Cgp3Ng0HQr_ALb=zU7~#4Z=;1 zHTC}My=%rdwGB;3H__HKvz1j;lc+4lK5o!0_MF6@mCOmT_Iuo-%*h?nH)ZE}wrho3 z9CIQjYqo1A(oM8EG2KMZ^l=&NIk8i${oxsuImsb?Q`(%2ZkA(P=eUKjUIxdU7-zNa z)uCgmYd_LWv^hE3|JU}bB0o3M=cL(fcI}Tk2YI4g`}J>ACa1>jf~$RxJM1+zWJvOy zSo>}6P`>st_}Z#!AF{92ThdLm{eCe)Fbrr_%kae=LL$)Cl)jdxYd|J@PK?=-IU&}5 z*G$Ts+$4QdTAst4xY}eA9*;IBrklPZ-Nc>~)_?PlxvMZIzewhU=>CwqlsWmE^i64V zGNoE-OY6IWq4r&#Icfjr$y4d)Q+knZqRq+w^>*&@GFI>Vf1J;3Ip@&OK}y-Ad?fZ0 zNg=jFm=VTdhiq)85NS%HgW9Q-N+ul~(=Iu5+@lByyA&y9oRdQ%$(iqKoBO`aT63+% zyk5Wkn?Jtw?eo6Yv(|O3duI0D&vUQ;YA$@N(1e>UKO5e%(_Z^Ye_VF$U$@g>PL-W` zSNpAY*)t7a@^k<8U506YL(@*6_B~&oKqAvVFX%YIJEz~_-n0vB1XHHb;<(H5H@@z> z?Vh+fG5Z|We!JZUPqv_$n)W%Damn3ac_vR-bSDzoJ+amP&^>lf!u|K40?=Rh~J@*?t*@tFo@?_M>XNNUQ`Z}fB{scT({(SfK&lRrac0eMN zC$rPPnSc7Nik9#EH~wX>{nQKCY9&J*#;6Ik1Z95&bdlEPm;|Z+& zyAK*X*@$Lp+UH!x1rLJdnLJ@pVl7hWEYyL$&=*n zk)d}zawGZ2CKltZm*Z!4<4d#?O zoOiX~>^%>#_PZQ0c(NVM)Z|I~N-vc?H0lPo{E-Aa`5^1)r_E3Oka8~)nLKGVc+0Ej zX5C=<+`sxCd+q!8Tz2hO{KsHUv48Te_8T3&M5dRl{Tq%NroEV^eR;LNqVv98O}C}| ziA1J-o;76Yv#*aVBl z_p$C*xGj;$v`>7^zL`1y`eaM(U-h58_LH|>cI{vBpTV3$|K(ln-*ViZsl)ds8K2?3 z?zmyvAJVihtM(U$zuEZAyn>JN-{d%V_k!kEchu`^Yoi~{l{1=H#p0KFSnM6Ff zWbJo7YxgAcT#P5M_FJDdc(Mu2)Z|I|e``-awxokw^ekAO$&*meK#z4js<};($h1$| zzw=4c<(oW~&;3g0?6sdds^ino<#U|N`1^kGa|UzH(v+zI%>UEg9XFo0XBzO){EeUc zHO?ERJ?9*V$CRn_@E5N&n71f<8xol^4cxZ>^Exy0yJgRVE15ENmd_dg)Ybu(+D~yx zJGq@kO#MtE^J6@LpZg7*($R8q9H(UJ@Sz!L!$%HG8__8Fb2L+doo z=zEv3_OC2pnD#sQK|H2RpJ|c<`lxepf{Z_6RR>Lh-09?tGsgruwq$wL# zSZcpXLAxhOTVgzcwSRL#gD1<-Oii9dYcP^>5Q$8lu&8FiL_E3hvVG@oU&!u>zi#`B z`vlg0^Fjts)}fi2Jo)kc>9v!dYU4VE!17F)?f zJ%5?P_S*NPk|&qGuP=XLgE_}&%6U=yR~NBo8tf92Dg4e~v4~;XvkHTFOqm8=pX#jW zJSY1nBr;_hxWCH(_CH(5Emj0v$&{(%y!zLbb!?yejf&bm@ehvi1lIlyMGc-TMl&^e z!WH=^5}7<Ia3y2yhwkps`QDC}&;46U z+C6cm$9Mv3|GJU}Pd-F5HF`o7xf_X0p0KD&$wWM%D@Ff_Uad;mJqaw0@dVcX?WGK! ze1m3c@}%wLeyeuAcDH*1iA5J&&fWK_XM8POByNe>5zgdlrd|weP$*W7Uj7me2hg%iBG1+sAkUYrjT$ zgC}#!CE^KH|JwZ|)tF8qFwa zsr}RBiLv%Sz3kdQY%*sDO*t=Wzf4tortXQDOkwTkuWHEj*(-t5rc5^+`E=f~R|>cx zBr;|C=j0YAe!8Nndkl$;`@CS)>cv{Ev+VP$tJytq@^`rS{T9}K#cBpmW>rnVlV}Y_ zQhq`rlP4@HRt;Rq=*fkb?Q_3Tb-O2_-7)(F*8UCE4W2AUGd1m#FXz5@W&J((xql*& z$&=9^|CUj^boo&A>IryqK66c{4_nr?)c$eu#8ms9X8WGM%)jsdWisb?nsQ#$eu=B> zndY>h`5XVncdmvZ)5$e})22+Fi9f9J&3`ZD3nVgS>e<<=_TCE^KHWDXLUJYi8G54e)qliZiB_HU_a_arqr#uHfk z*VQz5@*$e3X`kGZ{?YV_)jGMmk;vppqpo)zyQ_80P?eeqc=FN6=dapZpr)nvkCG>* z+V?+LV%lZa{$7(gTWQL9QTs)%wr85ulICx${Zq9JnNF+)oHk|Zq+k2bUkl$$S&l@e zOas-sq{*s|jkjRv&=ivFrHnzXU-H$}ZecrTGVBTZ4o?Vr$w|kOxcg#MA zwO{;tgC{T5PQa6B4MtMdAd$%v7M(>RqbC<$w$J?=>)1WXOpEaZ)_#pT22bW(pMWQ8 zLN&rGR^Y7VpY?Kwc6m}=iY;<9W150g1R z(3JC{_Rrs7&(z;GCR14Z|J-26bleTVX;bY-cVFc%vyjM?>ACagw}08Jmb(XuOqoWn zIwZpCPZ2kK7kte3w z5BIw4+W*yL&U%`1Uex~So9&r~`o&}lYya@ghD=A_44k&te&maVNMy>?aUB2iuiWA8 zKq6D7(c<`@rS{7t+dYY7#CQU0KYy~plV|HC?nz1ri7cL6_|g3s64^bm)&AA>?VbeN z$9Mv3zhZrZC$o|h@Z`roH|}_BZT^&>kjUi8Bi$C&f9tVD*~RLEE15iLSZsFBr*`JE z{9b4md19*ll?`+qesWICb&aN1t`MVrn=B2%V? z9mjq4p2qI)NMy>CKKCvC`bspkdlHWQ9SE%bbGH~gnS4vaoCcOgNada8Suwp+dKUE15jm zk}{%f`?o7ve%{|so)~NYzRRxtA5G@0qABM^?H|3(o@qEeCR14Zdv7yjI`lT+w5j$t zS1;me^=g68yGUfp)IYh3|KX&n?p7o+W$HM$Jzjc&?QeWV{%7|j&??3gSo^0M89bTT zC;?BnjF%&k$rBbGLL###xi4GoS8Z(f#2FCd39S9njSZf>`o9D`d7$$8k2gNt!u=kJ zOrBKz>+q}|gFSA(#^6dOPclc9`eV*b1uXaU{zjgdYCoytW!L@&lQ}DB%6U=yf8TD; z)bEYS6xROE+YOlxx*a%es(t5&e%1RPotqs*B2%Wx2Ri$o{3*ZtGZL9H&E4fWGix=A z772P4xWn#A>OC=@z}o+>iNTY{nk3@Mg;yly6C^Tu!lM01Wb?#c`<0s7J#p`f@dVa> z@umh(Ub-UzPbQ|^f9ZjC?zDU2c8Ku=)_&nT4W7KnRm6nuem+btidsv!rK3}xgpcO%@fFU`^c#J2o_Vc$ic=GIB33xJl$L|kMXxqXKA(6?G zVUeZ-=d~>qI)+3hPnHGm8vWA1B9@=`HPOaO>cF?ph==WtzLqgI%gvKKGBevU`&8 zP>d(A_Wx>S@MJ`*L_DF2oQp&zPgwLj64^Ylf9Ef8uicZJOa8on?jD0DlkZ8ule+8o zz1HonRQC%cGI^5m{)3;b?_SY8fd19*l2!Ch3^mBY)-D@!C zqkHqN_P4jTXPP=RW}m~_|FN}U+TB|xkf~Fm^7%QHva&Og$dsvDrLX^aUw(HL5}7i+ zQ2V#lw$%R7Hg-<}ont(KwZFHG!IPnF67hs;|6L?9dBUQtNM!TGUi(GvvwM`QqLiA-(~bTW9-zf&Tf zP({9pL?%yI^aB#vJh6Z7pYLqBqU$WRzpty^ zlPrIXC-8Is*RBRn`gTpg6E5S|kjUf-i`FBN#gj|a{^@RZPdu^rI>OpN+|A(0=xzyk zQmyDy`MvY+cNZd&$&&`tlj|KATGrixL?%y`H>)motItvi@XMN z-uC8Q?QitiGff^Dv(I7ef9*3&yNxe_OuMu_zkSPsf^GnbOqu3PIkWwz^3~iWNMy>? zDPPFBagyz9j$PgDo;aLo?z4@s_BVGoc+#tT0-kUgzl=mCPgt}TiHx3Hc-g-5AAi8^ zNw9g$K7qCW*8>JmMm&&!Cy)PLV`0-{l|plo$mGeu8e`kvJaj?!??`0wWMx+CNYdAp zET8+!df00}(EGA$e|`^xIWv3YUG1;yY0osZPfVt;_P^?Bn0Bk431sR_KXZQf&r?#y zBatc7K&L{^s22*mA0d$`(+k_&eamt`|Mp&XPdt5NJb|_UV=sdz-FqeC2~}h!5}7<< z(JCaedSb2pqkg+5kyuY)?eFy)JQ?awz?08fHD8hbPYL&3BrC$RQ+_A_`gs9yq}d|u+SmDB$^of1SMlP4Sd zE_IWMk13Zn?~=gTV+IX%jf=wY4+MroqpN1KReA}&MRqoSNq>QXwTI1ZcL`I z_Ln|rn0Cs831qrCoZnxlspF1BB2%V;J%`V4pL!}~9uk={b&5NI)YC^S@8?_k+dXlo z#drd1|GWMMPdfEaz!NUxDM)1UghgK>kfCN0L zbM)SI$JRA;-$WvlC-=_%^-OZXnxP+%$mB_dcYEDf`uv@i+FvlxUi-m^FT3{N8fY-* z#esQO``HiKGfjFbCR14ZA3tQ6c9Vw^$kh3vfzzkR`jiYLGG%(|&qBf6Gq~SFB2%Up zw)wW7Ezj|78gvOyUW)Mq*8aDH44$+fl!zx(kxwF#$rBcRibPgVthK){-R_AyCdLz3 z`@g0eJn5UBfG6&A>E&l!Rmpt~iA_e|^%T7lkQ>F#y zoJlD+vXJ{W5}7i+P#o8h$|}DQl6)m#+Qk!wlv;JuL5Pf7x(*rlI#@GKIB2f4E`Vw+v4p(;ijs z-tpwH8twojGG*$?U!+!rHB~}0k;s(k=9_nYc}v-omV0~Fjj(&-T=M7ruSOU=X*D7N zPrkqKo0Le(cqB4;;#~MOV!bj&`1wg2NtgD2fbCg4fO zAMR*={N_(mGLgvS$-7hgell+A;_OvOWb)+Yo8BEfYV?Dazwyl)Wv~6z@t0lu(?%K0 znKUZzYJc&=_Dpjw`MbXNA2v+8-opuG>Nw$B|LXI@SN)L4l(*{gV6ZO*w1%e)#I6_S%nJ{@?hXdDLLeqmSlY?Jt;M&opUl zOs25*-EK4?3Os<*Nsf$du`xz0D7Nc10ccMINx(?+i%$T724s^ zSN3CePeRYecmiwxb7dRyzMpalSpLp{PhNW5 zUiV`z7 zOmik}>g``sB{UU@Oqm|~c31VqrEEX%e?HOfN#=|gPhjmYnrQH((ZmEi*+@U{rz4Tc zlRX!1wTh&?jYK9-4qWo*{f$rBJ;{1G#uHfkUq5N^q|K8Fc+%(1bFZB5`B_Q;iA+jAXCRlENuVk?%ub-@|}O# zWVQi_|_D4u$@}y9$x{U^m*9m;C_}nLJtl!b9P`*PpX^GI^@K_Wgm&uKh=*8q66yHScQwjpyx|CdJ;X32XoP z=MB@Y^n3!DI!@-orD;EX)fS0NnZCMkYT?|U_a8?hQ>Km+>@jrRD$D2ohcDPYaVN#> zb6EScUod!b;|mFSlKYCJ_>suuNwjbyDX$=r*^}s%qGI&=Ce!Xo*4r_jz}jD$Y49W^ zGXYPYKHR%g&o!>z!hd%1|Oq1X{U(eICnaZlP|SXA;)oA3{4+8yi-yBw~nov$NcBq zdC@Kkr^t4qe{r1CFGkb4H9A~n$8kCi9eH8pclPZ&YVfG^3;%xK(0*y13ObIHHe}S` z3u9jRKlkQ~TXyX039=yf53A)`3{6i@>ziw7%Q1b^M~xWxa9Uf>nC&lKu(hV+IK77q z9DMtTL22n}BZm&@m7eRnlkcv9BQnx^kBxdg&f5W#m7UXfbrikm!|1 zY@iwCes#;&qEmjyaoV?Un^B`(kKAdrWz8{+(I#l?Jh$q?w5z=ojaVIx!xgLr#8Ssb z2a&z?5X3x>XxNJo%bc!Z%OU2zpkdn~mNQ(#3crk2n*5rE-2}1FD;m}rV!^2zHV$I$ z6B;%fVyWpGwiaR$-QEbqk|$`RReA*(lJu~KHG`NtK*Q1?78;^q&q2&HS;H1XETUt- zLM-(qZM1yT(MtV~YS{G{%h0g)7<*O29)?&_riRUgSmx6jwi05YaT<02V!;s_cEzj6 z5a%%sYYZ{Z%Npi~Smt;Qn+&n67d31V#KIFb>}QDO=u0>Qv53Bet6xKg_@B`(+8ScX z&uZ8(hy|u;*lQ3=8mM8}5DNx0Y%j!|Gz}{?1FbYi#~MN`bEr02cZg*@sbNn*EP0rQ z&4XC*K@H1+SXlS%IK;9Z(nhQCIx-|MNyA!VY>YWA z49U?i>O#!_kv3X?h$Su4u;(G>F4eFl5c90jux$`a(!(k+6Rk8gsEu|5#4_e;SO*l$4Dr9KVQnE6_*TP4K+N;DhP@84IYzV|W`e?5}EHqmi?F)z{XKUClhy~|pSn=6trJ3JpSbc~&?`v2$h~?LtUmEr-#4`TVu#X|;9@ns~5DOgAFz0==Qs-X{s|~TF0~*#2 zVp#_@Y!t+je$cQtA(pvY!@hx7SRd^#h-GZkMk_l98nRx){s*z(ZyMGMVmZHR*i#S- zgf;8~h$ZjUu%93n*rZ{nA(o>@Uu!NhB=WO1+Px4p}y#IjCm*ryN+>njaIEcGXCv?2@8N>g`e*v$~j+@fLk zLo9Gg!^T6*|BHsb1F_(r8ulH;oP8R01Y(|@8diBBG9*WT8%%+ie~&iWgAmKn=Qb5$ zsi(EkK7pA39}W8rV#!-IEdK{+rH=j};1XCaofMZ>Q75EAX*kFjc?KSLWh=uxS*yj+-nx}_Zl3Hrm?-0xEreOs?K`V9IY1oYr3l7w<);zgEXu!#KLr3h-CT<#6tbF(LRD$gc`HUXum)#*j^j$ zJj9awYuI&5ks%Q}?MN4?wj2quP*?4uZ$K>hJ`MXCVqrSXMCP_1Vu4oLXi3Y^ zO8H!S8Lbh-_^5ZmdP0m(R2OU##Q2bL!4^V{&)pVm6U6u^YQauHj8A+PtmblL2p@th z*gX*AbAbgL3Nbz^SFq_2;}dBG`x0YxNULDGA;#yH3RdD%v{F9GQ?LdQ;}bIl^FoXd zkrXTdF+NvOusIOpqXq@r05Lw%Pq1SU<3sKQtM(Z(gwK5wtOdmQC^W$yf*7ATCfJJ* z<3qRvTMjWkmrAhh5aXko1S|YGS}C81B-l+5<3oZ3>kKhIH%G8>5aXj{1e*;pKCwlx zwGiV&OazNSjL-EDtkM_A5I*Wcux1eB6D0&ogBTyOAlP#d<8ucDTMRL7#V^>e5aW*b zg5~=Xt(2R<3wAxkxG%b3?IFgk!UcO6V%(8iu$d6!Ce?zigc$d27VH4TxRtSBS9}Ex zq0WbbHHH{B(G|=OG43lX*kp)tt5v}kL5w?^3idO`sL7{bXCTIXF9o|g8yUi_AO&j; zG48l1*f5B36GFjWgBbVa6D%8I+^SBny%6J$aDtTzp_OuzG{G7|jQfTO)*WKpN=vXO zAjTc51e*sjZsH_Z4#c>xkzmIm#;tw?tFZzZ!X0%4YY8!KG9y?z#JKN@U@t+8TagI% z8N|5bhhRG(#!WB;EBZBBDffjCtRBR;Rf1q$AjTaD1bY->{E)t2??Q~9TNi8{#Q0He z!Ty05KQS#>m2Z$C{1CBVF2wk`TEY55j2|@>?0Jas6PZAo4KmAlluhDO)-zIq+YyLgD=`C_raI8 zebYUihxZ;bBKq{s&m_G;k;;7;BF%liCRfT&0G0eUddWJ9PHy`UT?x{4>f1Yg;E?{! zNp`&=lY37@R@`x%E(1pl>@zTZ;K;G#NOhy4lBZ-uRmyRk2M4AP?lW{u=dl@S_uln6 z2^%Ovd2U98xsPt85A8eX-XRaBk4hWTH?3>h!2Sb9j@bDvN;7-|h0d`STaB>HWZFWE z-L)FUBzLVahGH5|QZ**IMMb1~Op8gU#w2&Zh)#=XKgraXwHtK*HliaN% zQavUg>C~9yW+2gNF=diWjY;lE5}6v)T2iSo$#Y$zii@e(chS|UG0Br&A~eO6{2hwP zUx#AiAi6><*qCBsYy!kQPiWYC5OY306n&@V(ZaMgHFUW%iZK*=<#i}@xeZFBdg$#* zr-m+fS&2>yeGAg=9K=zGMINM>7`t)<8ZE22hTXpbr75@7 z@n|T`sU%g?lzZqzs;9Y`bOk`@J1>+&g*Boj9N`{>mXyu|57>8rK$eQeS#v@{lANJs{e8uqUbdL zA0e6QzuXHcGS&aZq*DEtCvim;=l@X>s{YHfxgs?Af8`IzfByjTp9|ssAJG1n+ano6 z{!b;T>c89zDN^14m84Vsms>4Gr}=-1WSakczo*Dl|8Myb?SFZ8SyXZUk07DyzdX$> zLX-cm|A_qebSD4#OTr3>h1$^D6k}&-Hfov3ouZ7Pm>OZSRNq2pNT+Tgxn*2*+7@cCH9Avu3(0-!B2%}}AX2GYNP1U@ zDsBrcAfdX2q??5ZO#plicyn7>X&Kq-soZd%H;W znBF0s8k5{TFFGxztt3-pl3Vyirp9!|Z>Z9xDTt`zV(LgjH702jB0^J4V}FA&`6(t2 zA_%d_T&gC0ED2TrrDKf0;v_R>j5S2}g}lW4hQ1h=rz@T7^+e!QK=T2QdUGA3DuaS$C3z5F&*B4VhRtXm^g?!J5ia)qdklv|9g{E^PivN5vlI~Yot^Cm&b%e zr}@8uWUBx2tdhu7|BLL3u21z}dQgcf&i_^`(glbIE?n{KGm@4c+F$FUyCJy2bhy?~xOpJ}*gQ`g$_+kvj^dU*rnB?g$ zk?Jw+C7l|RJUk{kEv9OFqcc@wk|)?irp9zXsnnRHYnrIyVtR#yYE05cO@yYHzSxUm z^6*bO9K>cund-khr6)4g|DQ>v z`Y(OvL>1?Mg+HUKQ~j6Db0RePf5)H5|6o5V6aLLWUxjYJeJ(JS!+VEv6PEQ)7|`7DcAUG@evyOwzzlRBc|+1=~0rZG0Ag{BGqI1gmh|5^4O&4 zw3z-PnHCd2yD2g?rmGJ`*QdrLoe@P97gJvnsxe8gL=l=|dgcJ~KRk|N;viPhWmNy= zaZbjN|7S_6`Y+FJid6T%;Xza;@@S~&H2)tWnd-khpDHrd|942G`Y*jCMHT1&E)uH# zOLs{Tn*1+*2>BlzOaAjOFzZ7sJd4VNvGhZzOytQ{#!yV}l2naJ9%B`$9@B56Q_Do2 zk`!|ZxoX}sEsIQz=?JORn56ru zsN!O(ABh^H#w7hvMQDntTLi@vPN$eSh?nRx>bsdd$jlh>e;r9x|K+J=k?Q{EKN4M; z>c2b`EjrEr|B+1fU!Kesnd<*AQmOt+zgSVl`Tr3KRsW@ftO!m1|8fNR@8M4qzIX0C z#Qc9!nJ{+yKd?;rnQq2VOv6d4#v~7Li&T$k9_iGWr-QrM!cemi>Vt4)tIC;uLw;sJ$4ku6zooA!a=+bv5X@W6JtAQHflA=|3anh+VUF;gbIxVJ~ z{)^63jp<_R0+y*UJxD4wri-nkSrr%4`y^Cjy4Xybg{GL+|A%4cbG|&C~;0DFo9AZgrHEbZna%yW>CdAzJ8n*5@+CtKhf#-&{P=OPu(xv-?NcAmr zJL%LdB+VT}r){AOlBrurI!uU6-9qz7rEVeV7cQ!}EwrD6>K2j?;vzI{p`?>2bpHdi zg?N)Rf>>q&iixq|Cs9n&n}RVE(|nSul`f4aM5@QMgLG<4(&s{ST1=Hrp-Pu#8zNI< zN+p#VlQd!%Ra{J&BvfOP*6boQ#kA}ciYeTKV&WkFz*sWH#8{QnC?;vs!5E6E14-4G zq$h_+^_ZrRPK`-geuz$s=_`_{)g*mKM5e}coK$K|(&1iIaWOSI6E#MSNqXLk&=gb8 zGbkp1ABu^Cm_e6Ozqd#$62_4KKaf=OzXP>(5vlHf(X-K&ss2k_6VYk@HzS$qzw}lS znd<*&QmOvSnE;}S^M4r$RsZFb01=w}|Klw5e;E1CpJj#4AuQ6E%7iiZ94Zs(%EB0m zX$(o#n4|@ZNcEULB%KjY*DQ z5TPliN#~LO!JZTo2eA-iB`GGx_R(zAYLW&ujG>sWa>`tI2vvnHtk7QmHY?DHfuNi>Xk)=<3v%+`4)moQFSj zIEemq8P$Jj!owKye-=qq|E1%ONOk`=lTP(t8v2M%^S@;Ns3EHV(p5-gs{buXrTQ=D zeuyg0|4AfN{g;zKL}>DVVSea8-^0vbxi>*9s{)k?W2Fm37q7-7{fHPtG2Km4H7033 zBvL)5M@gr~B)yG9r^U3GWNJ*(U`b?ZOb1D&#v})-h$=3ox&=|0$Pp_dG{w}ZAdHEB z^~XUx0ifLx+R7wJ<6ZX+Omn@_#T%RsW^e zlt^{|-zA;uzqGOvo#y|qBvbvDep(_^{V!J}x<1u^Ion56asGEAq3XY!_9H@*|Bn=b z{`V*U`8NY^L(FMGWy07tnvGf}(us>P6jS-4Q3uqRr0teS^_bd_PK`;rdWlYp>2Z>& zF-dDNk*P6#Mk+NXIW$RBaWS1Dp&FAMqa;F8Of`$amM{L8IyEL~a3(q}rt6DGXR5{|UDiaV#?+fsYD{t(m8jxkdYgn= zOng3-2u(4qDGp=0pR0+2C{P0VFOAn2L;g1*sp`LUSre)5|8UZ&{!0@#(P{qAC7J5K zbdnR9>i-T>ss79PU80Kfzh=p(F{=M^qL&Cw{@+s)`S0&S{_`&|he9lMGnENr^JzBf zyP5Q$V+_T#lcZ`)(r`|sdQ4SHMGa76l74og(_(5*GBqY?swXlvrYWRSW0Hf>L=_j) z8WO58$x&${G{y9HDHM~3e?!heR4k3KfS+PwtV3y3P125!F%;9&BvoUQ-g_d|V+xT@ zjY(SjiB5~@Ka#02Nq<3+sWH_n6J4Jglbkpws<@bjl2DCF&Y%;aDW>UVkpKQ6R81Vj z4|Ex|Or+%?W61wvNztXL{!4#Bk?Q`tq*MKu_JyL;{C}8as{hhMQDmzBACgM-U(VB}onOu@$} zCJtgZ#InXwOpIMs4#gymC>cXBbtS19lXRUFsUFkwq*G&(rk0}9Vp>TuH74n-DKa&t zv!qgEl2au`6&F*}@=;^dnB<&E5t?G^S02UW;ipbGh-V=dnME-%_ASjuebbYkoQ$EE z&XH7&Ng8m9RFCP_3Q+^pn54g_=(LyykxY$Anv9A}jp=wB zQ)7~|WJPF-sX-MKQ*Z>82?ybYSjL|e6JsyaY}A;f8!clfrte9r#w4w0MXJYC;L4~0 zYE07ER&-iSjY+1)B<*!Yrp7d!RBB9eB(JFAV)~ebYD{uSuLw;sZM_o3aS%>b zgoU1@m>6qPHR_of)5XTT6f25p1WDDHE_UH%sUFjO(y1|BZ1T%GEv7KZ)R-=I8fKXq zQ*u+kw(U%)BN|7O!Z&7DT_??e+H>k|K)UOQN{Vcm4vGQa$d9uP5xJ{5nW|N zwYzSc+S4v{lHoSHohmwx({DWLuiFET5bj1Ja0gh+2(#b_PFEU%o0D2b*a1ffw5Jic z)1_sEtFJ;nxIJiu)b!{fiIx%4@Cdi_DkfZVggJ18)Du;sS#aw*%N+K@5u96YqBJL8 zat=3okPkr~f%}44<}etJ5a>j6;FeXE5k7~@@gJpy!wU7^i6q*CK9$ZwnMUA;=Pe^-!x6&w(Fpupw`GKUSEE&gJJJaJ$gyRF7I1`+%RUUdWMxf)Be?g_ z2>d*!We%(12;r_Y0zYbK8KKxU$Oq4DGy*>?XBnXl93j+%SMl&AeV7VI2sfq?_z@$^ z95%ucTpocRlCg|X_FCkFzY)!WpWm>I&Ay<0}uf=9TW zM&O&CEhAL94*Jl5M&SE#EhBV?BZOMh2z;xkWrUe<1h*lLz&ATuM%WHV2=fShAD(4| znzfM+ZVQ?N-y&uip)VZ4e>bmU*(K}ZJvf5XmPX+FZ!B}z2S*6CrxEzp5X%U4u17wE zdeR7dbAx4sL2!gX4;q30?rs_312}?*=fHmwwv6yM9>Gg<;6G|wMyOv0`4H?*Bkr><8Xu^kHEiYx2&S^4akSk-n!B6ll&`S%LwD( z2!VfT1pe)$WrQ!`2>yLE0{?!^GQxQ{LZ~2TvG9^k-gzVPAy9xu;NMDE<}eYC;2fe= z@DI$E5mvzw0_SK1{*liz!oeHS&)R%|N?XsE=;`y&pl`G2p&1#QiIJKX73Ye8>$? zrp!&zHLG*?gfQ-H2JxI*{}(+WNE_WZ7~)9{2X89pE;F5U*DQ!R2!wa$#{_N(#s#&}VTdov;K6v4PJ8{(cqg!7>~?C4>L zhYMibTfH9I4Z)Ha_uWspS}-A=44>r^=jfC0GXBDJ89q9O7qJ-Q`7rL?32{$xjQh$a z!!>gNeEtnj#)WvGAdRl!-k}ipI2iZMAzXDd`MoADMEBZ%wAXTfXBYbxv>9F|^Ig*M zxh%YhLiN#_vu0!5+YsWBxfu8Lg?Mt1a6VjyCo>J=NpmpnT>qd7bo zKGP)5(d!!^i*n}EtoR5OUPM=jXS|Pb?^6)ZT!eAo5{L)R-y3}k;&WhlGP@z3^F58O z;ofq$prvN5#kj8x;i{t<>j~#`MdBQN1YRa{1?l)06JEqTh^Kysaqlk>Pg;p_Uy+7r z%}KmwK8uAXa~s5ySJUVk?oESugy*i|zL|upj%M-P`J|9IN56-c$=X1(;)6+e5vL)Z z!;8>x?+v#ii;};_qx-xVfB7h#3b;xAn4ALf$TW<5mq9$~4UGH#CR}rraX$Ma&e0mT z!8OmI%kWVn?C5z)T|dV?z@w4 z)zOUC3Fl)v;vCI@mq`tA^QV7ws4y`IKs%}!yA``SZ1 zT$1t4YP=I5?kR?G?*|YM6veo258{E<-;%H94&u4T65;KKG99bXKk>fEg+u! z62`s5A)fRK#(i%?JS&rMJ}`tQlLPULw=nKK5AoDDFz##AB-gviUc@U9kI1b4PY_Ijb=4eFx%6n=$VDjd0b`jBg3&6BgneE#3^RIq7TC@qrG!h{h04-imSW0ElPt zBDB$cuVVZ+8l6w2;K_Uo@znJg_a1|I@lK|JRVjQjROJehGmXM!hF*+sh{Cq$!bxVII=Q`cbJ_ZZ>o9?g7}a6aB3 z&e28iGMQ^h$EPXqB7TQ>gtvu;drRJl)*K3*kACiHxUUJsgUbo$BO!P)4?*1jEylew zARhV-Jkh;!6wj@IlfX5Crkqo!LuhzCByxVI<7o$oR3n+oyp8p8SX z26prdhzEIe4fh^^xbrn0-FI~hRQ2I+2 zPaWVzY{K|@jC=F9L~Hi2McU}T`WWXo2|hZ3C*y~B&UgIAShxMtxxdOJ-1`E?`Mb1+ z`&JXKI_mkPAl>JcN~7!Fp8kWE39*h32;fCrdpEMkpG}w1aBpXbJ0D@(Hxc6gEW-Je z1D?#s5DzTIxOWG{-DMc}RcVE)-oKLYaKPZ`J)~2sKFpWlmjAqn(Gd51N|(`a@B0vU zS76-tGsK;xg!8!tJeh*`z<4)c+LrxRE|DqH1fj=0Fy`k7~HLHN-t@@aVp=5Dyn96n*RB(*Srfb0O|OPNQqM zcMHUW`SIw!GHp=Rdx{gzz3Sr}ZALn^>I27UR@@q&7cm&(q5m-MeG}sTGZ^=+gLt4c zErR>|^JGpz+~oi?+*_wD+6`_|Ji4zp;p!gs|3h=(}djQgtJht?b{LX+WE{5+Yq5ce0xxOW`HowGC)(pD(Sd|JTIaz!~?Hm+&c~8!PhYETLJO#JA`u| ze4b1M;_h6Gd#_4`yWtIt`??aY?a}FkbNlr;N1wu%36hSxz4IcLK-^u1aqn)3`=?>t zSFQtEvwsQU+_Ii0(;VWVPcZHs25}Etq>b*IN4V-}nDgRJ>2Z$!0x#pwqFHfcc3wo0 zj%dx{w=nL#4dS8s826 zL5q0PaSwG~gcst$g>)GW_fCPh=RJ)3mO(tQh;VKM&y(2;ac2(3y%jp6rMe$r+;<=0 zs-xiXb?%%wKvk(t|i*aw=F36(5ml*eThq!+& z;oQQUC-V%(H(=cRDa3=HW88OyaMjV!8p64AcATT0u5iuENym-4c@ga)9_E}i+&cl{ z4sU4<_k93y|4Nz+cN^!)Y{Pgq#=RxFp{05p`fjF;?rTA~>Zr?`hkIeiIXWC(CTC>% z=(jFzz0Hew8{(0^829EtJZC7zedi&b%sBTC=gHjcMHc0Bq0u$m+XLds-7)Tag>co; ztcMBbw$*Wtu7sD#>Ong0lFf@a3h|5#jC*VO(3&$wVcgdN;;Ex~5yPV$*?BSni05>` zxc5VdXQgA@w~uhu(VT|}=MK|xj#lgr*W8tK+|ZgA(GucW-7xMQ3Gs{vFz$N?;#vI( z=dRp5nI9pZ#JfSmz4;zMOO0?|8t!XMxaw#smm~L#j&pPXyi8^c*OgQ)1=E+>s16h=uhH-Bvi02q^-?N0PjwbVa3b%KTbM!NKnaBW| z6?c>7MeK)o5?79fdn@-uYt9^kNB6aYcXcoLokbl_auFJfL?GSh6 z7oK-2pT^$OebAc2FViCqF?2>bu>>V9pV{fFz$T=;+dr|?%PDT>S$_7 z!ntE{oTK^sqBSR1CmlCP=0((pcur}Id;JhkDuHp|3lPt|f^hEg%#-;F;*qi#_a1_H zPBD!8uI-1aKBqFz{TbRk`d^njlTNMr2q(cUk9iRjA)d^a(Qxm_5YMVWv(j+i4v6QJ zBb@s-^JJ3J&~AuS#ke;G;}tRP8%?;nM{{_ual7C+N8g8+NiIm2;qJt|h@T;zvx6JR zOjE1A;Dcz*S$|^OcMHT*j}p!;mU%LLFuot--WMUBbq3?UwS=pVX6z)KJNw2tdIDZ1 z=@99-kuWc!c7J41gcqUV-YyVNJ&Q;8O@eslzl3u)WS-0?5RdTa8t&Z%@vOqUdB!Na z!B=$vs`{jSgmbUnI7eHPPOJJNq~q4Wyoj+7&)P+6)^P7!h(~r~+_wednR^K5{>D6+ z!UIvfS-cxG+ropr4fmBz zM^ztcKsYz6jdRo`om%y7P1131TwcUbh9!-mm)>meSfMWb_rU!Kevh`ZNe z+P0DR2$vbmvD8DhEr&CZa*96=rnj4e;v|sw_9Gs3Wz(+Fz$^&+~rwmqx-HJ zg4P`5(Ya+WPo^EjLmaP$dmn{(pf+3dsQSsYgmBeS|NjW*PO)*0?uM6flS#*oX?YRl zhN3n5n`7MD9O7Z__ot2S8wPQw1&z+#b$K#DjNgNC??#BbcVXODBm-4_;5Nd!scW30 zw~Kk0Dey8u?tRJaUU?DAAnv)JW~JfYy%6`e#kjA+aI|KB7s9z`El=hy zhzIY(xOW7^-Fq?aTR^zxC>IQORE=}=S9qBqR}MFD&@F0?$E=@9pKz_@o6#NAF9_c^hzWh2YT|68bY??GuJ3XLq|(m$XOK)DWt>4Gvjy_&FQgehZd$OATU;h8SPWYaC=#OJtCmh^ga@VLA>Xi6D Damj0M literal 0 HcmV?d00001 diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6f16e6e1bf..89f61b78a3 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -103,6 +103,13 @@ const QString HEAD_BLENDING_NAME = "lookAroundAlpha"; const QString HEAD_ALPHA_NAME = "additiveBlendAlpha"; const float HEAD_ALPHA_BLENDING = 1.0f; +const QString SEATED_POINT_BLENDING_NAME = "seatedPointAroundAlpha"; +const QString SEATED_POINT_ALPHA_NAME = "seatedPointBlendAlpha"; +const QString IDLE_POINT_BLENDING_NAME = "idlePointAroundAlpha"; +const QString IDLE_POINT_ALPHA_NAME = "idlePointBlendAlpha"; +const QString POINT_REF_JOINT_NAME = "RightShoulder"; +const float POINT_ALPHA_BLENDING = 1.0f; + MyAvatar::SitStandModelType stringToUserRecenterModel(const QString& str) { if (str == USER_RECENTER_MODEL_FORCE_SIT) { return MyAvatar::ForceSit; @@ -6108,6 +6115,9 @@ bool MyAvatar::beginReaction(QString reactionName) { } bool MyAvatar::endReaction(QString reactionName) { + if (reactionName == "point") { + resetPointAt(); + } int reactionIndex = beginEndReactionNameToIndex(reactionName); if (reactionIndex >= 0 && reactionIndex < (int)NUM_AVATAR_BEGIN_END_REACTIONS) { std::lock_guard guard(_reactionLock); @@ -6657,6 +6667,39 @@ void MyAvatar::updateLookAtPosition(FaceTracker* faceTracker, Camera& myCamera) getHead()->setLookAtPosition(lookAtSpot); } +glm::vec3 MyAvatar::aimToBlendValues(const glm::vec3& aimVector, const glm::quat& frameOrientation) { + // This method computes the values for the directional blending animation node + + glm::vec3 uVector = glm::normalize(frameOrientation * Vectors::UNIT_X); + glm::vec3 vVector = glm::normalize(frameOrientation * Vectors::UNIT_Y); + + glm::vec3 aimDirection; + if (glm::length(aimVector) > EPSILON) { + aimDirection = glm::normalize(aimVector); + } + else { + // aim vector is zero + return glm::vec3(); + } + + float xDot = glm::dot(uVector, aimDirection); + float yDot = glm::dot(vVector, aimDirection); + + // Make sure dot products are in range to avoid acosf returning NaN + xDot = glm::min(glm::max(xDot, -1.0f), 1.0f); + yDot = glm::min(glm::max(yDot, -1.0f), 1.0f); + + float xAngle = acosf(xDot); + float yAngle = acosf(yDot); + + // xBlend and yBlend are the values from -1.0 to 1.0 that set the directional blending. + // We compute them using the angles (0 to PI/2) => (1.0 to 0.0) and (PI/2 to PI) => (0.0 to -1.0) + float xBlend = -(xAngle - 0.5f * PI) / (0.5f * PI); + float yBlend = -(yAngle - 0.5f * PI) / (0.5f * PI); + glm::vec3 blendValues = glm::vec3(xBlend, yBlend, 0.0f); + return blendValues; +} + void MyAvatar::resetHeadLookAt() { if (_skeletonModelLoaded) { _skeletonModel->getRig().setDirectionalBlending(HEAD_BLENDING_NAME, glm::vec3(), @@ -6676,39 +6719,10 @@ void MyAvatar::resetLookAtRotation(const glm::vec3& avatarPosition, const glm::q void MyAvatar::updateHeadLookAt(float deltaTime) { if (_skeletonModelLoaded) { glm::vec3 lookAtTarget = _scriptControlsHeadLookAt ? _lookAtScriptTarget : _lookAtCameraTarget; - glm::vec3 avatarXVector = glm::normalize(getWorldOrientation() * Vectors::UNIT_X); - glm::vec3 avatarYVector = glm::normalize(getWorldOrientation() * Vectors::UNIT_Y); - glm::vec3 avatarZVector = glm::normalize(getWorldOrientation() * Vectors::UNIT_Z); - glm::vec3 headToTargetVector = lookAtTarget - getDefaultEyePosition(); - if (glm::length(headToTargetVector) > EPSILON) { - headToTargetVector = glm::normalize(headToTargetVector); - } else { - // The target point is the avatar head - return; - } - - float xDot = glm::dot(avatarXVector, headToTargetVector); - float yDot = glm::dot(avatarYVector, headToTargetVector); - float zDot = glm::dot(avatarZVector, headToTargetVector); - // Force the head to look at one of the sides when the look at point is behind the avatar - if (zDot > 0.0f && xDot != 0.0f) { - //xDot /= fabsf(xDot); - } - - // Make sure dot products are in range to avoid acosf returning NaN - xDot = glm::min(glm::max(xDot, -1.0f), 1.0f); - yDot = glm::min(glm::max(yDot, -1.0f), 1.0f); - - float xAngle = acosf(xDot); - float yAngle = acosf(yDot); - - // xBlend and yBlend are the values from -1.0 to 1.0 that set the directional blending. - // We compute them using the angles (0 to PI/2) => (1.0 to 0.0) and (PI/2 to PI) => (0.0 to -1.0) - float xBlend = -(xAngle - 0.5f * PI) / (0.5f * PI); - float yBlend = -(yAngle - 0.5f * PI) / (0.5f * PI); - glm::vec3 lookAtBlend = glm::vec3(xBlend, yBlend, 0.0f); + glm::vec3 aimVector = lookAtTarget - getDefaultEyePosition(); + glm::vec3 lookAtBlend = aimToBlendValues(aimVector, getWorldOrientation()); _skeletonModel->getRig().setDirectionalBlending(HEAD_BLENDING_NAME, lookAtBlend, - HEAD_ALPHA_NAME, HEAD_ALPHA_BLENDING); + HEAD_ALPHA_NAME, HEAD_ALPHA_BLENDING); if (_scriptControlsHeadLookAt) { _scriptHeadControlTimer += deltaTime; @@ -6732,3 +6746,28 @@ void MyAvatar::setHeadLookAt(const glm::vec3& lookAtTarget) { _scriptHeadControlTimer = 0.0f; _lookAtScriptTarget = lookAtTarget; } + +void MyAvatar::setPointAt(const glm::vec3& pointAtTarget) { + if (QThread::currentThread() != thread()) { + BLOCKING_INVOKE_METHOD(this, "setPointAt", + Q_ARG(const glm::vec3&, pointAtTarget)); + return; + } + if (_skeletonModelLoaded) { + glm::vec3 aimVector = pointAtTarget - getJointPosition(POINT_REF_JOINT_NAME); + glm::vec3 pointAtBlend = aimToBlendValues(aimVector, getWorldOrientation()); + _skeletonModel->getRig().setDirectionalBlending(IDLE_POINT_BLENDING_NAME, pointAtBlend, + IDLE_POINT_ALPHA_NAME, POINT_ALPHA_BLENDING); + _skeletonModel->getRig().setDirectionalBlending(SEATED_POINT_BLENDING_NAME, pointAtBlend, + SEATED_POINT_ALPHA_NAME, POINT_ALPHA_BLENDING); + } +} + +void MyAvatar::resetPointAt() { + if (_skeletonModelLoaded) { + _skeletonModel->getRig().setDirectionalBlending(IDLE_POINT_BLENDING_NAME, glm::vec3(), + IDLE_POINT_ALPHA_NAME, POINT_ALPHA_BLENDING); + _skeletonModel->getRig().setDirectionalBlending(SEATED_POINT_BLENDING_NAME, glm::vec3(), + SEATED_POINT_ALPHA_NAME, POINT_ALPHA_BLENDING); + } +} diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 7b63e8e86b..fefac6b945 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1765,6 +1765,15 @@ public: */ Q_INVOKABLE glm::vec3 getHeadLookAt() { return _lookAtCameraTarget; } + /**jsdoc + * Aims the pointing directional blending towards the provided target point. + * The "point" reaction should be triggered before using this method. + * MyAvatar.beginReaction("point") + * @function MyAvatar.startPointingAt + * @param {Vec3} pointAtTarget - The target point in world coordinates. + */ + Q_INVOKABLE void setPointAt(const glm::vec3& pointAtTarget); + glm::quat getLookAtRotation() { return _lookAtYaw * _lookAtPitch; } /**jsdoc @@ -2681,6 +2690,8 @@ private: void updateHeadLookAt(float deltaTime); void resetHeadLookAt(); void resetLookAtRotation(const glm::vec3& avatarPosition, const glm::quat& avatarOrientation); + void resetPointAt(); + glm::vec3 aimToBlendValues(const glm::vec3& aimVector, const glm::quat& frameOrientation); // Avatar Preferences QUrl _fullAvatarURLFromPreferences; diff --git a/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js b/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js index 189608fafd..5f271ced52 100644 --- a/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js +++ b/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js @@ -203,10 +203,19 @@ function maybeDeleteRemoteIndicatorTimeout() { } } - var reactionsBegun = []; var pointReticle = null; var mouseMoveEventsConnected = false; +var targetPointInterpolateConnected = false; +var pointAtTarget = Vec3.ZERO; + +function targetPointInterpolate() { + if (reticlePosition) { + pointAtTarget = Vec3.mix(pointAtTarget, reticlePosition, POINT_AT_MIX_ALPHA); + MyAvatar.setPointAt(pointAtTarget); + } +} + function beginReactionWrapper(reaction) { maybeDeleteRemoteIndicatorTimeout(); @@ -231,10 +240,13 @@ function beginReactionWrapper(reaction) { Controller.mouseMoveEvent.connect(mouseMoveEvent); mouseMoveEventsConnected = true; } + if (!targetPointInterpolateConnected) { + Script.update.connect(targetPointInterpolate); + targetPointInterpolateConnected = true; + } } } - // Checks to see if there are any reticle entities already to delete function deleteOldReticles() { MyAvatar.getAvatarEntitiesVariant() @@ -250,6 +262,8 @@ function deleteOldReticles() { var MAX_INTERSECTION_DISTANCE_M = 50; var reticleUpdateRateLimiterTimer = false; var RETICLE_UPDATE_RATE_LIMITER_TIMER_MS = 75; +var POINT_AT_MIX_ALPHA = 0.15; +var reticlePosition = Vec3.ZERO; function mouseMoveEvent(event) { if (!reticleUpdateRateLimiterTimer) { reticleUpdateRateLimiterTimer = Script.setTimeout(function() { @@ -261,11 +275,10 @@ function mouseMoveEvent(event) { var pickRay = Camera.computePickRay(event.x, event.y); - var avatarIntersectionData = AvatarManager.findRayIntersection(pickRay); + var avatarIntersectionData = AvatarManager.findRayIntersection(pickRay, [], [MyAvatar.sessionUUID], false); var entityIntersectionData = Entities.findRayIntersection(pickRay, true); var avatarIntersectionDistanceM = avatarIntersectionData.intersects && avatarIntersectionData.distance < MAX_INTERSECTION_DISTANCE_M ? avatarIntersectionData.distance : null; var entityIntersectionDistanceM = entityIntersectionData.intersects && entityIntersectionData.distance < MAX_INTERSECTION_DISTANCE_M ? entityIntersectionData.distance : null; - var reticlePosition; if (avatarIntersectionDistanceM && entityIntersectionDistanceM) { if (avatarIntersectionDistanceM < entityIntersectionDistanceM) { @@ -349,6 +362,10 @@ function endReactionWrapper(reaction) { Controller.mouseMoveEvent.disconnect(mouseMoveEvent); mouseMoveEventsConnected = false; } + if (targetPointInterpolateConnected) { + Script.update.disconnect(targetPointInterpolate); + targetPointInterpolateConnected = false; + } maybeClearReticleUpdateLimiterTimeout(); deleteOldReticles(); break; @@ -757,7 +774,6 @@ function toggleEmojiApp() { emojiAPI.registerAvimojiQMLWindow(emojiAppWindow); } - // #endregion // ************************************* // END EMOJI_MAIN From 7c4fe399187558112ab238ced4f680b4570ea591 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 24 Sep 2019 18:24:27 -0700 Subject: [PATCH 02/15] Add point directional blending node to animation json --- .../resources/avatar/avatar-animation.json | 685 ++++++++++++++---- 1 file changed, 526 insertions(+), 159 deletions(-) diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index 436f8b5949..51a26386aa 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -1544,103 +1544,292 @@ "type": "randomSwitchStateMachine" }, { - "children": [ + "children": [ { - "children": [ + "children": [ + { + "children": [ + { + "children": [ + ], + "data": { + "endFrame": 21, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_all.fbx" + }, + "id": "seatedReactionPointIntro", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 100, + "loopFlag": true, + "startFrame": 21, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_all.fbx" + }, + "id": "seatedReactionPointLoop", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 134, + "loopFlag": false, + "mirrorFlag": false, + "startFrame": 100, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_all.fbx" + }, + "id": "seatedReactionPointOutro", + "type": "clip" + } + ], + "data": { + "currentState": "seatedReactionPointIntro", + "randomSwitchTimeMax": 10, + "randomSwitchTimeMin": 1, + "states": [ + { + "easingType": "easeInOutQuad", + "id": "seatedReactionPointIntro", + "interpDuration": 18, + "interpTarget": 18, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + { + "randomSwitchState": "seatedReactionPointLoop", + "var": "seatedReactionPointIntroOnDone" + } + ] + }, + { + "easingType": "easeInOutQuad", + "id": "seatedReactionPointLoop", + "interpDuration": 18, + "interpTarget": 18, + "interpType": "evaluateBoth", + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "seatedReactionPointOutro", + "var": "reactionPointDisabled" + } + ] + }, + { + "easingType": "easeInOutQuad", + "id": "seatedReactionPointOutro", + "interpDuration": 18, + "interpTarget": 18, + "interpType": "evaluateBoth", + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "seatedReactionPointLoop", + "var": "reactionPointEnabled" + } + ] + } + ], + "triggerRandomSwitch": "" + }, + "id": "seatedReactionPoint", + "type": "randomSwitchStateMachine" + } ], "data": { - "endFrame": 21, - "loopFlag": false, - "startFrame": 1, - "timeScale": 1, - "url": "qrc:///avatar/animations/sitting_emote_point_all.fbx" + "alpha": 0, + "alphaVar": "seatedPointBlendAlpha", + "blendType": "addAbsolute" }, - "id": "seatedReactionPointIntro", - "type": "clip" + "id": "seatedReactionPoint", + "type": "blendLinear" }, { "children": [ + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 11, + "loopFlag": true, + "startFrame": 11, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx" + }, + "id": "seatedPointLeft", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 30, + "loopFlag": true, + "startFrame": 30, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx" + }, + "id": "seatedPointRight", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 50, + "loopFlag": true, + "startFrame": 50, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx" + }, + "id": "seatedPointUp", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 70, + "loopFlag": true, + "startFrame": 70, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx" + }, + "id": "seatedPointDown", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 90, + "loopFlag": true, + "startFrame": 90, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx" + }, + "id": "seatedPointUpLeft", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 110, + "loopFlag": true, + "startFrame": 110, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx" + }, + "id": "seatedPointUpRight", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 130, + "loopFlag": true, + "startFrame": 130, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx" + }, + "id": "seatedPointDownLeft", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 150, + "loopFlag": true, + "startFrame": 150, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx" + }, + "id": "seatedPointDownRight", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 3, + "loopFlag": true, + "startFrame": 3, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_aimoffsets.fbx" + }, + "id": "seatedPointCenter", + "type": "clip" + } ], "data": { - "endFrame": 100, - "loopFlag": true, - "startFrame": 21, - "timeScale": 1, - "url": "qrc:///avatar/animations/sitting_emote_point_all.fbx" + "alpha": [ + 0, + 0, + 0 + ], + "alphaVar": "seatedPointAroundAlpha", + "centerId": "seatedPointCenter", + "downId": "seatedPointDown", + "downLeftId": "seatedPointDownLeft", + "downRightId": "seatedPointDownRight", + "leftId": "seatedPointLeft", + "rightId": "seatedPointRight", + "upId": "seatedPointUp", + "upLeftId": "seatedPointUpLeft", + "upRightId": "seatedPointUpRight" }, - "id": "seatedReactionPointLoop", - "type": "clip" - }, - { - "children": [ - ], - "data": { - "endFrame": 134, - "loopFlag": false, - "mirrorFlag": false, - "startFrame": 100, - "timeScale": 1, - "url": "qrc:///avatar/animations/sitting_emote_point_all.fbx" - }, - "id": "seatedReactionPointOutro", - "type": "clip" + "id": "seatedPointAround", + "type": "blendDirectional" } ], "data": { - "currentState": "seatedReactionPointIntro", - "randomSwitchTimeMax": 10, - "randomSwitchTimeMin": 1, - "states": [ - { - "easingType": "easeInOutQuad", - "id": "seatedReactionPointIntro", - "interpDuration": 18, - "interpTarget": 18, - "interpType": "evaluateBoth", - "priority": 1, - "resume": false, - "transitions": [ - { - "randomSwitchState": "seatedReactionPointLoop", - "var": "seatedReactionPointIntroOnDone" - } - ] - }, - { - "easingType": "easeInOutQuad", - "id": "seatedReactionPointLoop", - "interpDuration": 18, - "interpTarget": 18, - "interpType": "evaluateBoth", - "priority": 0, - "resume": false, - "transitions": [ - { - "randomSwitchState": "seatedReactionPointOutro", - "var": "reactionPointDisabled" - } - ] - }, - { - "easingType": "easeInOutQuad", - "id": "seatedReactionPointOutro", - "interpDuration": 18, - "interpTarget": 18, - "interpType": "evaluateBoth", - "priority": 0, - "resume": false, - "transitions": [ - { - "randomSwitchState": "seatedReactionPointLoop", - "var": "reactionPointEnabled" - } - ] - } - ], - "triggerRandomSwitch": "" + "alpha": 0, + "alphaVar": "seatedPointBlendAlpha", + "blendType": "addAbsolute" }, "id": "seatedReactionPoint", - "type": "randomSwitchStateMachine" + "type": "blendLinear" } ], "data": { @@ -3531,97 +3720,275 @@ "children": [ { "children": [ + { + "children": [ + ], + "data": { + "endFrame": 21, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_all.fbx" + }, + "id": "reactionPointIntro", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 100, + "loopFlag": true, + "startFrame": 21, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_all.fbx" + }, + "id": "reactionPointLoop", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 134, + "loopFlag": false, + "startFrame": 100, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_all.fbx" + }, + "id": "reactionPointOutro", + "type": "clip" + } ], "data": { - "endFrame": 21, - "loopFlag": false, - "startFrame": 1, - "timeScale": 1, - "url": "qrc:///avatar/animations/emote_point01_all.fbx" + "currentState": "reactionPointIntro", + "randomSwitchTimeMax": 10, + "randomSwitchTimeMin": 1, + "states": [ + { + "easingType": "easeInOutQuad", + "id": "reactionPointIntro", + "interpDuration": 1, + "interpTarget": 1, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + { + "randomSwitchState": "reactionPointLoop", + "var": "reactionPointIntroOnDone" + } + ] + }, + { + "id": "reactionPointLoop", + "interpDuration": 1, + "interpTarget": 1, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "reactionPointOutro", + "var": "reactionPointDisabled" + } + ] + }, + { + "easingType": "easeInOutQuad", + "id": "reactionPointOutro", + "interpDuration": 6, + "interpTarget": 6, + "interpType": "evaluateBoth", + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "reactionPointLoop", + "var": "reactionPointEnabled" + } + ] + } + ], + "triggerRandomSwitch": "" }, - "id": "reactionPointIntro", - "type": "clip" + "id": "reactionPoint", + "type": "randomSwitchStateMachine" }, { "children": [ + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 11, + "loopFlag": true, + "startFrame": 11, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx" + }, + "id": "idlePointLeft", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 30, + "loopFlag": true, + "startFrame": 30, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx" + }, + "id": "idlePointRight", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 50, + "loopFlag": true, + "startFrame": 50, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx" + }, + "id": "idlePointUp", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 70, + "loopFlag": true, + "startFrame": 70, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx" + }, + "id": "idlePointDown", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 90, + "loopFlag": true, + "startFrame": 90, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx" + }, + "id": "idlePointUpLeft", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 110, + "loopFlag": true, + "startFrame": 110, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx" + }, + "id": "idlePointUpRight", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 130, + "loopFlag": true, + "startFrame": 130, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx" + }, + "id": "idlePointDownLeft", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 150, + "loopFlag": true, + "startFrame": 150, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx" + }, + "id": "idlePointDownRight", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "baseFrame": 1, + "baseURL": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx", + "blendType": "addAbsolute", + "endFrame": 3, + "loopFlag": true, + "startFrame": 3, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_aimoffsets.fbx" + }, + "id": "idlePointCenter", + "type": "clip" + } ], "data": { - "endFrame": 100, - "loopFlag": true, - "startFrame": 21, - "timeScale": 1, - "url": "qrc:///avatar/animations/emote_point01_all.fbx" + "alpha": [ + 0, + 0, + 0 + ], + "alphaVar": "idlePointAroundAlpha", + "centerId": "idlePointCenter", + "downId": "idlePointDown", + "downLeftId": "idlePointDownLeft", + "downRightId": "idlePointDownRight", + "leftId": "idlePointLeft", + "rightId": "idlePointRight", + "upId": "idlePointUp", + "upLeftId": "idlePointUpLeft", + "upRightId": "idlePointUpRight" }, - "id": "reactionPointLoop", - "type": "clip" - }, - { - "children": [ - ], - "data": { - "endFrame": 134, - "loopFlag": false, - "startFrame": 100, - "timeScale": 1, - "url": "qrc:///avatar/animations/emote_point01_all.fbx" - }, - "id": "reactionPointOutro", - "type": "clip" + "id": "idlePointAround", + "type": "blendDirectional" } ], "data": { - "currentState": "reactionPointIntro", - "randomSwitchTimeMax": 10, - "randomSwitchTimeMin": 1, - "states": [ - { - "easingType": "easeInOutQuad", - "id": "reactionPointIntro", - "interpDuration": 1, - "interpTarget": 1, - "interpType": "evaluateBoth", - "priority": 1, - "resume": false, - "transitions": [ - { - "randomSwitchState": "reactionPointLoop", - "var": "reactionPointIntroOnDone" - } - ] - }, - { - "id": "reactionPointLoop", - "interpDuration": 1, - "interpTarget": 1, - "priority": 0, - "resume": false, - "transitions": [ - { - "randomSwitchState": "reactionPointOutro", - "var": "reactionPointDisabled" - } - ] - }, - { - "easingType": "easeInOutQuad", - "id": "reactionPointOutro", - "interpDuration": 6, - "interpTarget": 6, - "interpType": "evaluateBoth", - "priority": 0, - "resume": false, - "transitions": [ - { - "randomSwitchState": "reactionPointLoop", - "var": "reactionPointEnabled" - } - ] - } - ], - "triggerRandomSwitch": "" + "alpha": 0, + "alphaVar": "idlePointBlendAlpha", + "blendType": "addAbsolute" }, "id": "reactionPoint", - "type": "randomSwitchStateMachine" + "type": "blendLinear" } ], "data": { From 0aab2ed07f49b25aa2fbe1324334b29f301e7c61 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 25 Sep 2019 12:37:24 -0700 Subject: [PATCH 03/15] Disable head look at when pointing --- .../resources/avatar/avatar-animation.json | 16 +++--- interface/src/avatar/MyAvatar.cpp | 56 ++++++++++--------- interface/src/avatar/MyAvatar.h | 3 +- .../simplifiedEmote/simplifiedEmote.js | 1 + 4 files changed, 40 insertions(+), 36 deletions(-) diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index 51a26386aa..df130cffa4 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -1652,7 +1652,7 @@ "alphaVar": "seatedPointBlendAlpha", "blendType": "addAbsolute" }, - "id": "seatedReactionPoint", + "id": "seatedReactionPointBase", "type": "blendLinear" }, { @@ -1808,7 +1808,7 @@ 0, 0 ], - "alphaVar": "seatedPointAroundAlpha", + "alphaVar": "pointAroundAlpha", "centerId": "seatedPointCenter", "downId": "seatedPointDown", "downLeftId": "seatedPointDownLeft", @@ -1825,7 +1825,7 @@ ], "data": { "alpha": 0, - "alphaVar": "seatedPointBlendAlpha", + "alphaVar": "pointBlendAlpha", "blendType": "addAbsolute" }, "id": "seatedReactionPoint", @@ -3967,7 +3967,7 @@ 0, 0 ], - "alphaVar": "idlePointAroundAlpha", + "alphaVar": "pointAroundAlpha", "centerId": "idlePointCenter", "downId": "idlePointDown", "downLeftId": "idlePointDownLeft", @@ -3984,7 +3984,7 @@ ], "data": { "alpha": 0, - "alphaVar": "idlePointBlendAlpha", + "alphaVar": "pointBlendAlpha", "blendType": "addAbsolute" }, "id": "reactionPoint", @@ -6050,16 +6050,16 @@ "upLeftId": "lookUpLeft", "upRightId": "lookUpRight" }, - "id": "lookAround", + "id": "lookAroundBlend", "type": "blendDirectional" } ], "data": { "alpha": 0, - "alphaVar": "additiveBlendAlpha", + "alphaVar": "lookBlendAlpha", "blendType": "addAbsolute" }, - "id": "additiveBlend", + "id": "lookAround", "type": "blendLinear" } ], diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 89f61b78a3..88f5ed01a8 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -99,14 +99,13 @@ static const QString USER_RECENTER_MODEL_FORCE_STAND = QStringLiteral("ForceStan static const QString USER_RECENTER_MODEL_AUTO = QStringLiteral("Auto"); static const QString USER_RECENTER_MODEL_DISABLE_HMD_LEAN = QStringLiteral("DisableHMDLean"); -const QString HEAD_BLENDING_NAME = "lookAroundAlpha"; -const QString HEAD_ALPHA_NAME = "additiveBlendAlpha"; +const QString HEAD_BLEND_DIRECTIONAL_ALPHA_NAME = "lookAroundAlpha"; +const QString HEAD_BLEND_LINEAR_ALPHA_NAME = "lookBlendAlpha"; const float HEAD_ALPHA_BLENDING = 1.0f; -const QString SEATED_POINT_BLENDING_NAME = "seatedPointAroundAlpha"; -const QString SEATED_POINT_ALPHA_NAME = "seatedPointBlendAlpha"; -const QString IDLE_POINT_BLENDING_NAME = "idlePointAroundAlpha"; -const QString IDLE_POINT_ALPHA_NAME = "idlePointBlendAlpha"; +const QString POINT_REACTION_NAME = "point"; +const QString POINT_BLEND_DIRECTIONAL_ALPHA_NAME = "pointAroundAlpha"; +const QString POINT_BLEND_LINEAR_ALPHA_NAME = "pointBlendAlpha"; const QString POINT_REF_JOINT_NAME = "RightShoulder"; const float POINT_ALPHA_BLENDING = 1.0f; @@ -955,13 +954,16 @@ void MyAvatar::simulate(float deltaTime, bool inView) { qCDebug(interfaceapp) << "MyAvatar::simulate headPosition is NaN"; headPosition = glm::vec3(0.0f); } - head->setPosition(headPosition); head->setScale(getModelScale()); head->simulate(deltaTime); CameraMode mode = qApp->getCamera().getMode(); if (_scriptControlsHeadLookAt || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) { - updateHeadLookAt(deltaTime); + if (!_pointAtActive) { + updateHeadLookAt(deltaTime); + } else { + resetHeadLookAt(); + } } else if (_headLookAtActive){ resetHeadLookAt(); _headLookAtActive = false; @@ -6109,25 +6111,30 @@ bool MyAvatar::beginReaction(QString reactionName) { if (reactionIndex >= 0 && reactionIndex < (int)NUM_AVATAR_BEGIN_END_REACTIONS) { std::lock_guard guard(_reactionLock); _reactionEnabledRefCounts[reactionIndex]++; + if (reactionName == POINT_REACTION_NAME) { + _pointAtActive = true; + } return true; } return false; } bool MyAvatar::endReaction(QString reactionName) { - if (reactionName == "point") { - resetPointAt(); - } int reactionIndex = beginEndReactionNameToIndex(reactionName); if (reactionIndex >= 0 && reactionIndex < (int)NUM_AVATAR_BEGIN_END_REACTIONS) { std::lock_guard guard(_reactionLock); + bool wasReactionActive = true; if (_reactionEnabledRefCounts[reactionIndex] > 0) { _reactionEnabledRefCounts[reactionIndex]--; - return true; + wasReactionActive = true; } else { _reactionEnabledRefCounts[reactionIndex] = 0; - return false; + wasReactionActive = false; } + if (reactionName == POINT_REACTION_NAME) { + _pointAtActive = _reactionEnabledRefCounts[reactionIndex] > 0; + } + return wasReactionActive; } return false; } @@ -6676,8 +6683,7 @@ glm::vec3 MyAvatar::aimToBlendValues(const glm::vec3& aimVector, const glm::quat glm::vec3 aimDirection; if (glm::length(aimVector) > EPSILON) { aimDirection = glm::normalize(aimVector); - } - else { + } else { // aim vector is zero return glm::vec3(); } @@ -6702,8 +6708,8 @@ glm::vec3 MyAvatar::aimToBlendValues(const glm::vec3& aimVector, const glm::quat void MyAvatar::resetHeadLookAt() { if (_skeletonModelLoaded) { - _skeletonModel->getRig().setDirectionalBlending(HEAD_BLENDING_NAME, glm::vec3(), - HEAD_ALPHA_NAME, HEAD_ALPHA_BLENDING); + _skeletonModel->getRig().setDirectionalBlending(HEAD_BLEND_DIRECTIONAL_ALPHA_NAME, glm::vec3(), + HEAD_BLEND_LINEAR_ALPHA_NAME, HEAD_ALPHA_BLENDING); } } @@ -6721,8 +6727,8 @@ void MyAvatar::updateHeadLookAt(float deltaTime) { glm::vec3 lookAtTarget = _scriptControlsHeadLookAt ? _lookAtScriptTarget : _lookAtCameraTarget; glm::vec3 aimVector = lookAtTarget - getDefaultEyePosition(); glm::vec3 lookAtBlend = aimToBlendValues(aimVector, getWorldOrientation()); - _skeletonModel->getRig().setDirectionalBlending(HEAD_BLENDING_NAME, lookAtBlend, - HEAD_ALPHA_NAME, HEAD_ALPHA_BLENDING); + _skeletonModel->getRig().setDirectionalBlending(HEAD_BLEND_DIRECTIONAL_ALPHA_NAME, lookAtBlend, + HEAD_BLEND_LINEAR_ALPHA_NAME, HEAD_ALPHA_BLENDING); if (_scriptControlsHeadLookAt) { _scriptHeadControlTimer += deltaTime; @@ -6756,18 +6762,14 @@ void MyAvatar::setPointAt(const glm::vec3& pointAtTarget) { if (_skeletonModelLoaded) { glm::vec3 aimVector = pointAtTarget - getJointPosition(POINT_REF_JOINT_NAME); glm::vec3 pointAtBlend = aimToBlendValues(aimVector, getWorldOrientation()); - _skeletonModel->getRig().setDirectionalBlending(IDLE_POINT_BLENDING_NAME, pointAtBlend, - IDLE_POINT_ALPHA_NAME, POINT_ALPHA_BLENDING); - _skeletonModel->getRig().setDirectionalBlending(SEATED_POINT_BLENDING_NAME, pointAtBlend, - SEATED_POINT_ALPHA_NAME, POINT_ALPHA_BLENDING); + _skeletonModel->getRig().setDirectionalBlending(POINT_BLEND_DIRECTIONAL_ALPHA_NAME, pointAtBlend, + POINT_BLEND_LINEAR_ALPHA_NAME, POINT_ALPHA_BLENDING); } } void MyAvatar::resetPointAt() { if (_skeletonModelLoaded) { - _skeletonModel->getRig().setDirectionalBlending(IDLE_POINT_BLENDING_NAME, glm::vec3(), - IDLE_POINT_ALPHA_NAME, POINT_ALPHA_BLENDING); - _skeletonModel->getRig().setDirectionalBlending(SEATED_POINT_BLENDING_NAME, glm::vec3(), - SEATED_POINT_ALPHA_NAME, POINT_ALPHA_BLENDING); + _skeletonModel->getRig().setDirectionalBlending(POINT_BLEND_DIRECTIONAL_ALPHA_NAME, glm::vec3(), + POINT_BLEND_LINEAR_ALPHA_NAME, POINT_ALPHA_BLENDING); } } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index fefac6b945..ef1a30f4a5 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1769,7 +1769,7 @@ public: * Aims the pointing directional blending towards the provided target point. * The "point" reaction should be triggered before using this method. * MyAvatar.beginReaction("point") - * @function MyAvatar.startPointingAt + * @function MyAvatar.setPointingAt * @param {Vec3} pointAtTarget - The target point in world coordinates. */ Q_INVOKABLE void setPointAt(const glm::vec3& pointAtTarget); @@ -2662,6 +2662,7 @@ private: bool _shouldTurnToFaceCamera { false }; bool _scriptControlsHeadLookAt { false }; float _scriptHeadControlTimer { 0.0f }; + bool _pointAtActive{ false }; Setting::Handle _realWorldFieldOfView; Setting::Handle _useAdvancedMovementControls; diff --git a/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js b/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js index 5f271ced52..b30ed989e8 100644 --- a/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js +++ b/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js @@ -236,6 +236,7 @@ function beginReactionWrapper(reaction) { break; case ("point"): deleteOldReticles(); + pointAtTarget = MyAvatar.getHeadLookAt(); if (!mouseMoveEventsConnected) { Controller.mouseMoveEvent.connect(mouseMoveEvent); mouseMoveEventsConnected = true; From d7fc4e905cc46e323a05ce7630175d19b2667b42 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 25 Sep 2019 14:02:43 -0700 Subject: [PATCH 04/15] fix function on jsdoc --- interface/src/avatar/MyAvatar.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index ef1a30f4a5..20ce6fa147 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1769,7 +1769,7 @@ public: * Aims the pointing directional blending towards the provided target point. * The "point" reaction should be triggered before using this method. * MyAvatar.beginReaction("point") - * @function MyAvatar.setPointingAt + * @function MyAvatar.setPointAt * @param {Vec3} pointAtTarget - The target point in world coordinates. */ Q_INVOKABLE void setPointAt(const glm::vec3& pointAtTarget); From 2077da6f371bdba5cdb7fb13c8f89dc67085dde4 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Thu, 26 Sep 2019 17:02:42 -0700 Subject: [PATCH 05/15] Create ReweightDeformersTask --- .../model-baker/src/model-baker/Baker.cpp | 8 +- .../model-baker/src/model-baker/BakerTypes.h | 8 ++ .../src/model-baker/BuildGraphicsMeshTask.cpp | 110 +++------------- .../src/model-baker/BuildGraphicsMeshTask.h | 6 +- .../src/model-baker/ReweightDeformersTask.cpp | 119 ++++++++++++++++++ .../src/model-baker/ReweightDeformersTask.h | 29 +++++ 6 files changed, 180 insertions(+), 100 deletions(-) create mode 100644 libraries/model-baker/src/model-baker/ReweightDeformersTask.cpp create mode 100644 libraries/model-baker/src/model-baker/ReweightDeformersTask.h diff --git a/libraries/model-baker/src/model-baker/Baker.cpp b/libraries/model-baker/src/model-baker/Baker.cpp index 1a68d3508d..a567537105 100644 --- a/libraries/model-baker/src/model-baker/Baker.cpp +++ b/libraries/model-baker/src/model-baker/Baker.cpp @@ -13,6 +13,7 @@ #include "BakerTypes.h" #include "ModelMath.h" +#include "ReweightDeformersTask.h" #include "BuildGraphicsMeshTask.h" #include "CalculateMeshNormalsTask.h" #include "CalculateMeshTangentsTask.h" @@ -151,8 +152,13 @@ namespace baker { const auto calculateBlendshapeTangentsInputs = CalculateBlendshapeTangentsTask::Input(normalsPerBlendshapePerMesh, blendshapesPerMeshIn, meshesIn).asVarying(); const auto tangentsPerBlendshapePerMesh = model.addJob("CalculateBlendshapeTangents", calculateBlendshapeTangentsInputs); + // Skinning weight calculations + // NOTE: Due to limitations in the current graphics::MeshPointer representation, the output list of ReweightedDeformers is per-mesh. An element is empty if there are no deformers for the mesh of the same index. + const auto reweightDeformersInputs = ReweightDeformersTask::Input(meshesIn, shapesIn, dynamicTransformsIn, deformersIn).asVarying(); + const auto reweightedDeformers = model.addJob("ReweightDeformers", reweightDeformersInputs); + // Build the graphics::MeshPointer for each hfm::Mesh - const auto buildGraphicsMeshInputs = BuildGraphicsMeshTask::Input(meshesIn, url, meshIndicesToModelNames, normalsPerMesh, tangentsPerMesh, shapesIn, dynamicTransformsIn, deformersIn).asVarying(); + const auto buildGraphicsMeshInputs = BuildGraphicsMeshTask::Input(meshesIn, url, meshIndicesToModelNames, normalsPerMesh, tangentsPerMesh, shapesIn, dynamicTransformsIn, reweightedDeformers).asVarying(); const auto graphicsMeshes = model.addJob("BuildGraphicsMesh", buildGraphicsMeshInputs); // Prepare joint information diff --git a/libraries/model-baker/src/model-baker/BakerTypes.h b/libraries/model-baker/src/model-baker/BakerTypes.h index 3d16afab2e..8760fa6db4 100644 --- a/libraries/model-baker/src/model-baker/BakerTypes.h +++ b/libraries/model-baker/src/model-baker/BakerTypes.h @@ -36,6 +36,14 @@ namespace baker { using TangentsPerBlendshape = std::vector>; using MeshIndicesToModelNames = QHash; + + class ReweightedDeformers { + public: + std::vector indices; + std::vector weights; + uint16_t weightsPerVertex { 0 }; + bool trimmedToMatch { false }; + }; }; #endif // hifi_BakerTypes_h diff --git a/libraries/model-baker/src/model-baker/BuildGraphicsMeshTask.cpp b/libraries/model-baker/src/model-baker/BuildGraphicsMeshTask.cpp index ea05b81d1f..deacd6a977 100644 --- a/libraries/model-baker/src/model-baker/BuildGraphicsMeshTask.cpp +++ b/libraries/model-baker/src/model-baker/BuildGraphicsMeshTask.cpp @@ -2,8 +2,8 @@ // BuildGraphicsMeshTask.h // model-baker/src/model-baker // -// Created by Sabrina Shanman on 2018/12/06. -// Copyright 2018 High Fidelity, Inc. +// Created by Sabrina Shanman on 2019/09/16. +// Copyright 2019 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -27,83 +27,7 @@ glm::vec3 normalizeDirForPacking(const glm::vec3& dir) { return dir; } -class ReweightedDeformers { -public: - std::vector indices; - std::vector weights; - bool trimmedToMatch { false }; -}; - -ReweightedDeformers getReweightedDeformers(size_t numMeshVertices, const hfm::DynamicTransform* dynamicTransform, const std::vector deformers, const uint16_t weightsPerVertex) { - size_t numClusterIndices = numMeshVertices * weightsPerVertex; - ReweightedDeformers reweightedDeformers; - // TODO: Consider having a rootCluster property in the DynamicTransform rather than appending the root to the end of the cluster list. - reweightedDeformers.indices.resize(numClusterIndices, (uint16_t)(deformers.size() - 1)); - reweightedDeformers.weights.resize(numClusterIndices, 0); - - std::vector weightAccumulators; - weightAccumulators.resize(numClusterIndices, 0.0f); - for (uint16_t i = 0; i < (uint16_t)deformers.size(); ++i) { - const hfm::Deformer& deformer = *deformers[i]; - - if (deformer.indices.size() != deformer.weights.size()) { - reweightedDeformers.trimmedToMatch = true; - } - size_t numIndicesOrWeights = std::min(deformer.indices.size(), deformer.weights.size()); - for (size_t j = 0; j < numIndicesOrWeights; ++j) { - uint32_t index = deformer.indices[j]; - float weight = deformer.weights[j]; - - // look for an unused slot in the weights vector - uint32_t weightIndex = index * weightsPerVertex; - uint32_t lowestIndex = -1; - float lowestWeight = FLT_MAX; - uint16_t k = 0; - for (; k < weightsPerVertex; k++) { - if (weightAccumulators[weightIndex + k] == 0.0f) { - reweightedDeformers.indices[weightIndex + k] = i; - weightAccumulators[weightIndex + k] = weight; - break; - } - if (weightAccumulators[weightIndex + k] < lowestWeight) { - lowestIndex = k; - lowestWeight = weightAccumulators[weightIndex + k]; - } - } - if (k == weightsPerVertex && weight > lowestWeight) { - // no space for an additional weight; we must replace the lowest - weightAccumulators[weightIndex + lowestIndex] = weight; - reweightedDeformers.indices[weightIndex + lowestIndex] = i; - } - } - } - - // now that we've accumulated the most relevant weights for each vertex - // normalize and compress to 16-bits - for (size_t i = 0; i < numMeshVertices; ++i) { - size_t j = i * weightsPerVertex; - - // normalize weights into uint16_t - float totalWeight = 0.0f; - for (size_t k = j; k < j + weightsPerVertex; ++k) { - totalWeight += weightAccumulators[k]; - } - - const float ALMOST_HALF = 0.499f; - if (totalWeight > 0.0f) { - float weightScalingFactor = (float)(UINT16_MAX) / totalWeight; - for (size_t k = j; k < j + weightsPerVertex; ++k) { - reweightedDeformers.weights[k] = (uint16_t)(weightScalingFactor * weightAccumulators[k] + ALMOST_HALF); - } - } else { - reweightedDeformers.weights[j] = (uint16_t)((float)(UINT16_MAX) + ALMOST_HALF); - } - } - - return reweightedDeformers; -} - -void buildGraphicsMesh(const hfm::Mesh& hfmMesh, graphics::MeshPointer& graphicsMeshPointer, const baker::MeshNormals& meshNormals, const baker::MeshTangents& meshTangentsIn, const hfm::DynamicTransform* dynamicTransform, const std::vector meshDeformers) { +void buildGraphicsMesh(const hfm::Mesh& hfmMesh, graphics::MeshPointer& graphicsMeshPointer, const baker::MeshNormals& meshNormals, const baker::MeshTangents& meshTangentsIn, uint16_t numDeformerControllers, const baker::ReweightedDeformers reweightedDeformers) { auto graphicsMesh = std::make_shared(); // Fill tangents with a dummy value to force tangents to be present if there are normals @@ -162,19 +86,16 @@ void buildGraphicsMesh(const hfm::Mesh& hfmMesh, graphics::MeshPointer& graphics // Support for 4 skinning clusters: // 4 Indices are uint8 ideally, uint16 if more than 256. - const auto clusterIndiceElement = ((meshDeformers.size() < (size_t)UINT8_MAX) ? gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW) : gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW)); + const auto clusterIndiceElement = ((numDeformerControllers < (uint16_t)UINT8_MAX) ? gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW) : gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW)); // 4 Weights are normalized 16bits const auto clusterWeightElement = gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW); - // Calculate a more condensed view of all the deformer weights - const uint16_t NUM_CLUSTERS_PER_VERT = 4; - ReweightedDeformers reweightedDeformers = getReweightedDeformers(hfmMesh.vertices.size(), dynamicTransform, meshDeformers, NUM_CLUSTERS_PER_VERT); // Cluster indices and weights must be the same sizes if (reweightedDeformers.trimmedToMatch) { HIFI_FCDEBUG_ID(model_baker(), repeatMessageID, "BuildGraphicsMeshTask -- The number of indices and weights for a deformer had different sizes and have been trimmed to match"); } // Record cluster sizes - const size_t numVertClusters = reweightedDeformers.indices.size() / NUM_CLUSTERS_PER_VERT; + const size_t numVertClusters = reweightedDeformers.indices.size() / reweightedDeformers.weightsPerVertex; const size_t clusterIndicesSize = numVertClusters * clusterIndiceElement.getSize(); const size_t clusterWeightsSize = numVertClusters * clusterWeightElement.getSize(); @@ -263,7 +184,7 @@ void buildGraphicsMesh(const hfm::Mesh& hfmMesh, graphics::MeshPointer& graphics // Clusters data if (clusterIndicesSize > 0) { - if (meshDeformers.size() < UINT8_MAX) { + if (numDeformerControllers < (uint16_t)UINT8_MAX) { // yay! we can fit the clusterIndices within 8-bits int32_t numIndices = (int32_t)reweightedDeformers.indices.size(); std::vector packedDeformerIndices; @@ -461,7 +382,7 @@ void BuildGraphicsMeshTask::run(const baker::BakeContextPointer& context, const const auto& tangentsPerMesh = input.get4(); const auto& shapes = input.get5(); const auto& dynamicTransforms = input.get6(); - const auto& deformers = input.get7(); + const auto& reweightedDeformersPerMesh = input.get7(); // Currently, there is only (at most) one dynamicTransform per mesh // An undefined shape.dynamicTransform has the value hfm::UNDEFINED_KEY @@ -478,20 +399,17 @@ void BuildGraphicsMeshTask::run(const baker::BakeContextPointer& context, const for (int i = 0; i < n; i++) { graphicsMeshes.emplace_back(); auto& graphicsMesh = graphicsMeshes[i]; + const auto& reweightedDeformers = reweightedDeformersPerMesh[i]; - auto dynamicTransformIndex = dynamicTransformPerMesh[i]; - const hfm::DynamicTransform* dynamicTransform = nullptr; - std::vector meshDeformers; - if (dynamicTransformIndex != hfm::UNDEFINED_KEY) { - dynamicTransform = &dynamicTransforms[dynamicTransformIndex]; - for (const auto& deformerIndex : dynamicTransform->deformers) { - const auto& deformer = deformers[deformerIndex]; - meshDeformers.push_back(&deformer); - } + uint16_t numDeformerControllers = 0; + if (reweightedDeformers.weightsPerVertex != 0) { + uint32_t dynamicTransformIndex = dynamicTransformPerMesh[i]; + const hfm::DynamicTransform& dynamicTransform = dynamicTransforms[dynamicTransformIndex]; + numDeformerControllers = (uint16_t)dynamicTransform.deformers.size(); } // Try to create the graphics::Mesh - buildGraphicsMesh(meshes[i], graphicsMesh, baker::safeGet(normalsPerMesh, i), baker::safeGet(tangentsPerMesh, i), dynamicTransform, meshDeformers); + buildGraphicsMesh(meshes[i], graphicsMesh, baker::safeGet(normalsPerMesh, i), baker::safeGet(tangentsPerMesh, i), numDeformerControllers, reweightedDeformers); // Choose a name for the mesh if (graphicsMesh) { diff --git a/libraries/model-baker/src/model-baker/BuildGraphicsMeshTask.h b/libraries/model-baker/src/model-baker/BuildGraphicsMeshTask.h index be1e4350be..1bb9b9be0c 100644 --- a/libraries/model-baker/src/model-baker/BuildGraphicsMeshTask.h +++ b/libraries/model-baker/src/model-baker/BuildGraphicsMeshTask.h @@ -2,8 +2,8 @@ // BuildGraphicsMeshTask.h // model-baker/src/model-baker // -// Created by Sabrina Shanman on 2018/12/06. -// Copyright 2018 High Fidelity, Inc. +// Created by Sabrina Shanman on 2019/09/16. +// Copyright 2019 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -20,7 +20,7 @@ class BuildGraphicsMeshTask { public: - using Input = baker::VaryingSet8, hifi::URL, baker::MeshIndicesToModelNames, baker::NormalsPerMesh, baker::TangentsPerMesh, std::vector, std::vector, std::vector>; + using Input = baker::VaryingSet8, hifi::URL, baker::MeshIndicesToModelNames, baker::NormalsPerMesh, baker::TangentsPerMesh, std::vector, std::vector, std::vector>; using Output = std::vector; using JobModel = baker::Job::ModelIO; diff --git a/libraries/model-baker/src/model-baker/ReweightDeformersTask.cpp b/libraries/model-baker/src/model-baker/ReweightDeformersTask.cpp new file mode 100644 index 0000000000..2dd5030c78 --- /dev/null +++ b/libraries/model-baker/src/model-baker/ReweightDeformersTask.cpp @@ -0,0 +1,119 @@ +// +// ReweightDeformersTask.h +// model-baker/src/model-baker +// +// Created by Sabrina Shanman on 2019/09/26. +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ReweightDeformersTask.h" + +baker::ReweightedDeformers getReweightedDeformers(size_t numMeshVertices, const hfm::DynamicTransform* dynamicTransform, const std::vector deformers, const uint16_t weightsPerVertex) { + size_t numClusterIndices = numMeshVertices * weightsPerVertex; + baker::ReweightedDeformers reweightedDeformers; + reweightedDeformers.weightsPerVertex = weightsPerVertex; + // TODO: Consider having a rootCluster property in the DynamicTransform rather than appending the root to the end of the cluster list. + reweightedDeformers.indices.resize(numClusterIndices, (uint16_t)(deformers.size() - 1)); + reweightedDeformers.weights.resize(numClusterIndices, 0); + + std::vector weightAccumulators; + weightAccumulators.resize(numClusterIndices, 0.0f); + for (uint16_t i = 0; i < (uint16_t)deformers.size(); ++i) { + const hfm::Deformer& deformer = *deformers[i]; + + if (deformer.indices.size() != deformer.weights.size()) { + reweightedDeformers.trimmedToMatch = true; + } + size_t numIndicesOrWeights = std::min(deformer.indices.size(), deformer.weights.size()); + for (size_t j = 0; j < numIndicesOrWeights; ++j) { + uint32_t index = deformer.indices[j]; + float weight = deformer.weights[j]; + + // look for an unused slot in the weights vector + uint32_t weightIndex = index * weightsPerVertex; + uint32_t lowestIndex = -1; + float lowestWeight = FLT_MAX; + uint16_t k = 0; + for (; k < weightsPerVertex; k++) { + if (weightAccumulators[weightIndex + k] == 0.0f) { + reweightedDeformers.indices[weightIndex + k] = i; + weightAccumulators[weightIndex + k] = weight; + break; + } + if (weightAccumulators[weightIndex + k] < lowestWeight) { + lowestIndex = k; + lowestWeight = weightAccumulators[weightIndex + k]; + } + } + if (k == weightsPerVertex && weight > lowestWeight) { + // no space for an additional weight; we must replace the lowest + weightAccumulators[weightIndex + lowestIndex] = weight; + reweightedDeformers.indices[weightIndex + lowestIndex] = i; + } + } + } + + // now that we've accumulated the most relevant weights for each vertex + // normalize and compress to 16-bits + for (size_t i = 0; i < numMeshVertices; ++i) { + size_t j = i * weightsPerVertex; + + // normalize weights into uint16_t + float totalWeight = 0.0f; + for (size_t k = j; k < j + weightsPerVertex; ++k) { + totalWeight += weightAccumulators[k]; + } + + const float ALMOST_HALF = 0.499f; + if (totalWeight > 0.0f) { + float weightScalingFactor = (float)(UINT16_MAX) / totalWeight; + for (size_t k = j; k < j + weightsPerVertex; ++k) { + reweightedDeformers.weights[k] = (uint16_t)(weightScalingFactor * weightAccumulators[k] + ALMOST_HALF); + } + } else { + reweightedDeformers.weights[j] = (uint16_t)((float)(UINT16_MAX) + ALMOST_HALF); + } + } + + return reweightedDeformers; +} + +void ReweightDeformersTask::run(const baker::BakeContextPointer& context, const Input& input, Output& output) { + const uint16_t NUM_WEIGHTS_PER_VERTEX { 4 }; + + const auto& meshes = input.get0(); + const auto& shapes = input.get1(); + const auto& dynamicTransforms = input.get2(); + const auto& deformers = input.get3(); + auto& reweightedDeformers = output; + + // Currently, there is only (at most) one dynamicTransform per mesh + // An undefined shape.dynamicTransform has the value hfm::UNDEFINED_KEY + std::vector dynamicTransformPerMesh; + dynamicTransformPerMesh.resize(meshes.size(), hfm::UNDEFINED_KEY); + for (const auto& shape : shapes) { + uint32_t dynamicTransformIndex = shape.dynamicTransform; + dynamicTransformPerMesh[shape.mesh] = dynamicTransformIndex; + } + + reweightedDeformers.reserve(meshes.size()); + for (size_t i = 0; i < meshes.size(); ++i) { + const auto& mesh = meshes[i]; + uint32_t dynamicTransformIndex = dynamicTransformPerMesh[i]; + + const hfm::DynamicTransform* dynamicTransform = nullptr; + std::vector meshDeformers; + if (dynamicTransformIndex != hfm::UNDEFINED_KEY) { + dynamicTransform = &dynamicTransforms[dynamicTransformIndex]; + for (const auto& deformerIndex : dynamicTransform->deformers) { + const auto& deformer = deformers[deformerIndex]; + meshDeformers.push_back(&deformer); + } + } + + reweightedDeformers.push_back(getReweightedDeformers((size_t)mesh.vertices.size(), dynamicTransform, meshDeformers, NUM_WEIGHTS_PER_VERTEX)); + } +} diff --git a/libraries/model-baker/src/model-baker/ReweightDeformersTask.h b/libraries/model-baker/src/model-baker/ReweightDeformersTask.h new file mode 100644 index 0000000000..98befa8000 --- /dev/null +++ b/libraries/model-baker/src/model-baker/ReweightDeformersTask.h @@ -0,0 +1,29 @@ +// +// ReweightDeformersTask.h +// model-baker/src/model-baker +// +// Created by Sabrina Shanman on 2019/09/26. +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ReweightDeformersTask_h +#define hifi_ReweightDeformersTask_h + +#include + +#include "Engine.h" +#include "BakerTypes.h" + +class ReweightDeformersTask { +public: + using Input = baker::VaryingSet4, std::vector, std::vector, std::vector>; + using Output = std::vector; + using JobModel = baker::Job::ModelIO; + + void run(const baker::BakeContextPointer& context, const Input& input, Output& output); +}; + +#endif // hifi_ReweightDeformersTask_h From cd94dc15f9fd4d05368704246c70b118f7f623aa Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 27 Sep 2019 16:13:55 -0700 Subject: [PATCH 06/15] Add CollectShapeVerticesTask --- .../model-baker/src/model-baker/Baker.cpp | 11 ++- .../model-baker/CollectShapeVerticesTask.cpp | 92 +++++++++++++++++++ .../model-baker/CollectShapeVerticesTask.h | 30 ++++++ 3 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 libraries/model-baker/src/model-baker/CollectShapeVerticesTask.cpp create mode 100644 libraries/model-baker/src/model-baker/CollectShapeVerticesTask.h diff --git a/libraries/model-baker/src/model-baker/Baker.cpp b/libraries/model-baker/src/model-baker/Baker.cpp index a567537105..ccb5e1816f 100644 --- a/libraries/model-baker/src/model-baker/Baker.cpp +++ b/libraries/model-baker/src/model-baker/Baker.cpp @@ -14,6 +14,7 @@ #include "BakerTypes.h" #include "ModelMath.h" #include "ReweightDeformersTask.h" +#include "CollectShapeVerticesTask.h" #include "BuildGraphicsMeshTask.h" #include "CalculateMeshNormalsTask.h" #include "CalculateMeshTangentsTask.h" @@ -105,7 +106,7 @@ namespace baker { class BuildModelTask { public: - using Input = VaryingSet6, std::vector, QMap, QHash, FlowData>; + using Input = VaryingSet7, std::vector, QMap, QHash, FlowData, std::vector>; using Output = hfm::Model::Pointer; using JobModel = Job::ModelIO; @@ -116,6 +117,9 @@ namespace baker { hfmModelOut->jointRotationOffsets = input.get3(); hfmModelOut->jointIndices = input.get4(); hfmModelOut->flowData = input.get5(); + hfmModelOut->shapeVertices = input.get6(); + // These depend on the ShapeVertices + // TODO: Create a task for this rather than calculating it here hfmModelOut->computeKdops(); output = hfmModelOut; } @@ -156,6 +160,9 @@ namespace baker { // NOTE: Due to limitations in the current graphics::MeshPointer representation, the output list of ReweightedDeformers is per-mesh. An element is empty if there are no deformers for the mesh of the same index. const auto reweightDeformersInputs = ReweightDeformersTask::Input(meshesIn, shapesIn, dynamicTransformsIn, deformersIn).asVarying(); const auto reweightedDeformers = model.addJob("ReweightDeformers", reweightDeformersInputs); + // Shape vertices are included/rejected based on skinning weight, and thus must use the reweighted deformers. + const auto collectShapeVerticesInputs = CollectShapeVerticesTask::Input(meshesIn, shapesIn, jointsIn, dynamicTransformsIn, reweightedDeformers).asVarying(); + const auto shapeVerticesPerJoint = model.addJob("CollectShapeVertices", collectShapeVerticesInputs); // Build the graphics::MeshPointer for each hfm::Mesh const auto buildGraphicsMeshInputs = BuildGraphicsMeshTask::Input(meshesIn, url, meshIndicesToModelNames, normalsPerMesh, tangentsPerMesh, shapesIn, dynamicTransformsIn, reweightedDeformers).asVarying(); @@ -191,7 +198,7 @@ namespace baker { const auto blendshapesPerMeshOut = model.addJob("BuildBlendshapes", buildBlendshapesInputs); const auto buildMeshesInputs = BuildMeshesTask::Input(meshesIn, graphicsMeshes, normalsPerMesh, tangentsPerMesh, blendshapesPerMeshOut).asVarying(); const auto meshesOut = model.addJob("BuildMeshes", buildMeshesInputs); - const auto buildModelInputs = BuildModelTask::Input(hfmModelIn, meshesOut, jointsOut, jointRotationOffsets, jointIndices, flowData).asVarying(); + const auto buildModelInputs = BuildModelTask::Input(hfmModelIn, meshesOut, jointsOut, jointRotationOffsets, jointIndices, flowData, shapeVerticesPerJoint).asVarying(); const auto hfmModelOut = model.addJob("BuildModel", buildModelInputs); output = Output(hfmModelOut, materialMapping, dracoMeshes, dracoErrors, materialList); diff --git a/libraries/model-baker/src/model-baker/CollectShapeVerticesTask.cpp b/libraries/model-baker/src/model-baker/CollectShapeVerticesTask.cpp new file mode 100644 index 0000000000..755b61b7df --- /dev/null +++ b/libraries/model-baker/src/model-baker/CollectShapeVerticesTask.cpp @@ -0,0 +1,92 @@ +// +// CollectShapeVerticesTask.h +// model-baker/src/model-baker +// +// Created by Sabrina Shanman on 2019/09/27. +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "CollectShapeVerticesTask.h" + +#include + +// Used to track and avoid duplicate shape vertices, as multiple shapes can have the same mesh and dynamicTransform +class VertexSource { +public: + uint32_t mesh; + uint32_t dynamicTransform; + + bool operator==(const VertexSource& other) const { + return mesh == other.mesh && + dynamicTransform == other.dynamicTransform; + } +}; + +void CollectShapeVerticesTask::run(const baker::BakeContextPointer& context, const Input& input, Output& output) { + const auto& meshes = input.get0(); + const auto& shapes = input.get1(); + const auto& joints = input.get2(); + const auto& dynamicTransforms = input.get3(); + const auto& reweightedDeformers = input.get4(); + auto& shapeVerticesPerJoint = output; + + shapeVerticesPerJoint.reserve(joints.size()); + std::vector> vertexSourcesPerJoint; + vertexSourcesPerJoint.resize(joints.size()); + for (size_t i = 0; i < shapes.size(); ++i) { + const auto& shape = shapes[i]; + const uint32_t dynamicTransformKey = shape.dynamicTransform; + if (dynamicTransformKey == hfm::UNDEFINED_KEY) { + continue; + } + + VertexSource vertexSource; + vertexSource.mesh = shape.mesh; + vertexSource.dynamicTransform = dynamicTransformKey; + + const auto& dynamicTransform = dynamicTransforms[dynamicTransformKey]; + for (size_t j = 0; j < dynamicTransform.clusters.size(); ++j) { + const auto& cluster = dynamicTransform.clusters[j]; + const uint32_t jointIndex = cluster.jointIndex; + + auto& vertexSources = vertexSourcesPerJoint[jointIndex]; + if (std::find(vertexSources.cbegin(), vertexSources.cend(), vertexSource) == vertexSources.cend()) { + vertexSources.push_back(vertexSource); + auto& shapeVertices = shapeVerticesPerJoint[jointIndex]; + + const uint16_t deformerIndex = dynamicTransform.deformers[j]; + const auto& mesh = meshes[shape.mesh]; + const auto& vertices = mesh.vertices; + const auto& reweightedDeformer = reweightedDeformers[shape.mesh]; + const glm::mat4 meshToJoint = cluster.inverseBindMatrix; + + const uint16_t weightsPerVertex = reweightedDeformer.weightsPerVertex; + if (weightsPerVertex == 0) { + for (int vertexIndex = 0; vertexIndex < (int)vertices.size(); ++vertexIndex) { + const glm::mat4 vertexTransform = meshToJoint * glm::translate(vertices[vertexIndex]); + shapeVertices.push_back(extractTranslation(vertexTransform)); + } + } else { + for (int vertexIndex = 0; vertexIndex < (int)vertices.size(); ++vertexIndex) { + for (uint16_t weightIndex = 0; weightIndex < weightsPerVertex; ++weightIndex) { + const size_t index = vertexIndex*4 + weightIndex; + const uint16_t clusterIndex = reweightedDeformer.indices[index]; + const uint16_t clusterWeight = reweightedDeformer.weights[index]; + // Remember vertices associated with this joint with at least 1/4 weight + const uint16_t EXPANSION_WEIGHT_THRESHOLD = std::numeric_limits::max() / 4; + if (clusterIndex != j || clusterWeight < EXPANSION_WEIGHT_THRESHOLD) { + continue; + } + + const glm::mat4 vertexTransform = meshToJoint * glm::translate(vertices[vertexIndex]); + shapeVertices.push_back(extractTranslation(vertexTransform)); + } + } + } + } + } + } +} diff --git a/libraries/model-baker/src/model-baker/CollectShapeVerticesTask.h b/libraries/model-baker/src/model-baker/CollectShapeVerticesTask.h new file mode 100644 index 0000000000..3111dcadc1 --- /dev/null +++ b/libraries/model-baker/src/model-baker/CollectShapeVerticesTask.h @@ -0,0 +1,30 @@ +// +// CollectShapeVerticesTask.h +// model-baker/src/model-baker +// +// Created by Sabrina Shanman on 2019/09/27. +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_CollectShapeVerticesTask_h +#define hifi_CollectShapeVerticesTask_h + +#include + +#include "Engine.h" +#include "BakerTypes.h" + +class CollectShapeVerticesTask { +public: + using Input = baker::VaryingSet5, std::vector, std::vector, std::vector, std::vector>; + using Output = std::vector; + using JobModel = baker::Job::ModelIO; + + void run(const baker::BakeContextPointer& context, const Input& input, Output& output); +}; + +#endif // hifi_CollectShapeVerticesTask_h + From b4c50b3f48fde359affe672ae9890ae86a8d21c1 Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Fri, 27 Sep 2019 17:46:12 -0700 Subject: [PATCH 07/15] Remove unused parameter from getReweightedDeformers --- .../model-baker/src/model-baker/ReweightDeformersTask.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/model-baker/src/model-baker/ReweightDeformersTask.cpp b/libraries/model-baker/src/model-baker/ReweightDeformersTask.cpp index 2dd5030c78..98f9d419ba 100644 --- a/libraries/model-baker/src/model-baker/ReweightDeformersTask.cpp +++ b/libraries/model-baker/src/model-baker/ReweightDeformersTask.cpp @@ -11,7 +11,7 @@ #include "ReweightDeformersTask.h" -baker::ReweightedDeformers getReweightedDeformers(size_t numMeshVertices, const hfm::DynamicTransform* dynamicTransform, const std::vector deformers, const uint16_t weightsPerVertex) { +baker::ReweightedDeformers getReweightedDeformers(size_t numMeshVertices, const std::vector deformers, const uint16_t weightsPerVertex) { size_t numClusterIndices = numMeshVertices * weightsPerVertex; baker::ReweightedDeformers reweightedDeformers; reweightedDeformers.weightsPerVertex = weightsPerVertex; @@ -114,6 +114,6 @@ void ReweightDeformersTask::run(const baker::BakeContextPointer& context, const } } - reweightedDeformers.push_back(getReweightedDeformers((size_t)mesh.vertices.size(), dynamicTransform, meshDeformers, NUM_WEIGHTS_PER_VERTEX)); + reweightedDeformers.push_back(getReweightedDeformers((size_t)mesh.vertices.size(), meshDeformers, NUM_WEIGHTS_PER_VERTEX)); } } From f773bdeca264d629cbacb3fd83d085f11c55b8cb Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Mon, 30 Sep 2019 09:07:42 -0700 Subject: [PATCH 08/15] Remove unused variable --- .../model-baker/src/model-baker/CollectShapeVerticesTask.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/model-baker/src/model-baker/CollectShapeVerticesTask.cpp b/libraries/model-baker/src/model-baker/CollectShapeVerticesTask.cpp index 755b61b7df..8aeb0145d5 100644 --- a/libraries/model-baker/src/model-baker/CollectShapeVerticesTask.cpp +++ b/libraries/model-baker/src/model-baker/CollectShapeVerticesTask.cpp @@ -57,7 +57,6 @@ void CollectShapeVerticesTask::run(const baker::BakeContextPointer& context, con vertexSources.push_back(vertexSource); auto& shapeVertices = shapeVerticesPerJoint[jointIndex]; - const uint16_t deformerIndex = dynamicTransform.deformers[j]; const auto& mesh = meshes[shape.mesh]; const auto& vertices = mesh.vertices; const auto& reweightedDeformer = reweightedDeformers[shape.mesh]; From 02d889ba6e5525006f5b70bbb7f964599eb27513 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 30 Sep 2019 11:35:00 -0700 Subject: [PATCH 09/15] account for point target validity --- interface/src/avatar/MyAvatar.cpp | 28 +++++++++++++------ interface/src/avatar/MyAvatar.h | 6 ++-- .../simplifiedEmote/simplifiedEmote.js | 5 ++-- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 88f5ed01a8..30881aa01c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -959,7 +959,7 @@ void MyAvatar::simulate(float deltaTime, bool inView) { head->simulate(deltaTime); CameraMode mode = qApp->getCamera().getMode(); if (_scriptControlsHeadLookAt || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) { - if (!_pointAtActive) { + if (!_pointAtActive || !_isPointTargetValid) { updateHeadLookAt(deltaTime); } else { resetHeadLookAt(); @@ -6113,6 +6113,7 @@ bool MyAvatar::beginReaction(QString reactionName) { _reactionEnabledRefCounts[reactionIndex]++; if (reactionName == POINT_REACTION_NAME) { _pointAtActive = true; + _isPointTargetValid = true; } return true; } @@ -6145,10 +6146,13 @@ void MyAvatar::updateRigControllerParameters(Rig::ControllerParameters& params) for (int i = 0; i < TRIGGER_REACTION_NAMES.size(); i++) { params.reactionTriggers[i] = _reactionTriggers[i]; } - + int pointReactionIndex = beginEndReactionNameToIndex("point"); for (int i = 0; i < BEGIN_END_REACTION_NAMES.size(); i++) { // copy current state into params. params.reactionEnabledFlags[i] = _reactionEnabledRefCounts[i] > 0; + if (params.reactionEnabledFlags[i] && i == pointReactionIndex) { + params.reactionEnabledFlags[i] = _isPointTargetValid; + } } for (int i = 0; i < TRIGGER_REACTION_NAMES.size(); i++) { @@ -6753,18 +6757,24 @@ void MyAvatar::setHeadLookAt(const glm::vec3& lookAtTarget) { _lookAtScriptTarget = lookAtTarget; } -void MyAvatar::setPointAt(const glm::vec3& pointAtTarget) { +bool MyAvatar::setPointAt(const glm::vec3& pointAtTarget) { if (QThread::currentThread() != thread()) { - BLOCKING_INVOKE_METHOD(this, "setPointAt", + bool result = false; + BLOCKING_INVOKE_METHOD(this, "setPointAt", Q_RETURN_ARG(bool, result), Q_ARG(const glm::vec3&, pointAtTarget)); - return; + return result; } - if (_skeletonModelLoaded) { + if (_skeletonModelLoaded && _pointAtActive) { glm::vec3 aimVector = pointAtTarget - getJointPosition(POINT_REF_JOINT_NAME); - glm::vec3 pointAtBlend = aimToBlendValues(aimVector, getWorldOrientation()); - _skeletonModel->getRig().setDirectionalBlending(POINT_BLEND_DIRECTIONAL_ALPHA_NAME, pointAtBlend, - POINT_BLEND_LINEAR_ALPHA_NAME, POINT_ALPHA_BLENDING); + _isPointTargetValid = glm::dot(aimVector, getWorldOrientation() * Vectors::FRONT) > 0.0f; + if (_isPointTargetValid) { + glm::vec3 pointAtBlend = aimToBlendValues(aimVector, getWorldOrientation()); + _skeletonModel->getRig().setDirectionalBlending(POINT_BLEND_DIRECTIONAL_ALPHA_NAME, pointAtBlend, + POINT_BLEND_LINEAR_ALPHA_NAME, POINT_ALPHA_BLENDING); + } + return _isPointTargetValid; } + return false; } void MyAvatar::resetPointAt() { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 20ce6fa147..7d1537e30a 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1769,10 +1769,11 @@ public: * Aims the pointing directional blending towards the provided target point. * The "point" reaction should be triggered before using this method. * MyAvatar.beginReaction("point") + * Returns true if the target point lays in front of the avatar. * @function MyAvatar.setPointAt * @param {Vec3} pointAtTarget - The target point in world coordinates. */ - Q_INVOKABLE void setPointAt(const glm::vec3& pointAtTarget); + Q_INVOKABLE bool setPointAt(const glm::vec3& pointAtTarget); glm::quat getLookAtRotation() { return _lookAtYaw * _lookAtPitch; } @@ -2662,7 +2663,8 @@ private: bool _shouldTurnToFaceCamera { false }; bool _scriptControlsHeadLookAt { false }; float _scriptHeadControlTimer { 0.0f }; - bool _pointAtActive{ false }; + bool _pointAtActive { false }; + bool _isPointTargetValid { true }; Setting::Handle _realWorldFieldOfView; Setting::Handle _useAdvancedMovementControls; diff --git a/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js b/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js index b30ed989e8..8633fe8870 100644 --- a/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js +++ b/scripts/simplifiedUI/simplifiedEmote/simplifiedEmote.js @@ -208,11 +208,12 @@ var pointReticle = null; var mouseMoveEventsConnected = false; var targetPointInterpolateConnected = false; var pointAtTarget = Vec3.ZERO; +var isReticleVisible = true; function targetPointInterpolate() { if (reticlePosition) { pointAtTarget = Vec3.mix(pointAtTarget, reticlePosition, POINT_AT_MIX_ALPHA); - MyAvatar.setPointAt(pointAtTarget); + isReticleVisible = MyAvatar.setPointAt(pointAtTarget); } } @@ -297,7 +298,7 @@ function mouseMoveEvent(event) { } if (pointReticle && reticlePosition) { - Entities.editEntity(pointReticle, { position: reticlePosition }); + Entities.editEntity(pointReticle, { position: reticlePosition, visible: isReticleVisible }); } else if (reticlePosition) { pointReticle = Entities.addEntity({ type: "Box", From d4a74f798c4496d5460bf48b256ca49e78fa4198 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 1 Oct 2019 10:15:16 -0700 Subject: [PATCH 10/15] aimToBlendValues to static function --- interface/src/avatar/MyAvatar.cpp | 4 ++-- interface/src/avatar/MyAvatar.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 30881aa01c..e6e03fec4b 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -6730,7 +6730,7 @@ void MyAvatar::updateHeadLookAt(float deltaTime) { if (_skeletonModelLoaded) { glm::vec3 lookAtTarget = _scriptControlsHeadLookAt ? _lookAtScriptTarget : _lookAtCameraTarget; glm::vec3 aimVector = lookAtTarget - getDefaultEyePosition(); - glm::vec3 lookAtBlend = aimToBlendValues(aimVector, getWorldOrientation()); + glm::vec3 lookAtBlend = MyAvatar::aimToBlendValues(aimVector, getWorldOrientation()); _skeletonModel->getRig().setDirectionalBlending(HEAD_BLEND_DIRECTIONAL_ALPHA_NAME, lookAtBlend, HEAD_BLEND_LINEAR_ALPHA_NAME, HEAD_ALPHA_BLENDING); @@ -6768,7 +6768,7 @@ bool MyAvatar::setPointAt(const glm::vec3& pointAtTarget) { glm::vec3 aimVector = pointAtTarget - getJointPosition(POINT_REF_JOINT_NAME); _isPointTargetValid = glm::dot(aimVector, getWorldOrientation() * Vectors::FRONT) > 0.0f; if (_isPointTargetValid) { - glm::vec3 pointAtBlend = aimToBlendValues(aimVector, getWorldOrientation()); + glm::vec3 pointAtBlend = MyAvatar::aimToBlendValues(aimVector, getWorldOrientation()); _skeletonModel->getRig().setDirectionalBlending(POINT_BLEND_DIRECTIONAL_ALPHA_NAME, pointAtBlend, POINT_BLEND_LINEAR_ALPHA_NAME, POINT_ALPHA_BLENDING); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 7d1537e30a..6b1344aad2 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -2694,7 +2694,7 @@ private: void resetHeadLookAt(); void resetLookAtRotation(const glm::vec3& avatarPosition, const glm::quat& avatarOrientation); void resetPointAt(); - glm::vec3 aimToBlendValues(const glm::vec3& aimVector, const glm::quat& frameOrientation); + static glm::vec3 aimToBlendValues(const glm::vec3& aimVector, const glm::quat& frameOrientation); // Avatar Preferences QUrl _fullAvatarURLFromPreferences; From 09f02222855a1c23c0fadb92ed6c551866676a3c Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 1 Oct 2019 14:18:46 -0700 Subject: [PATCH 11/15] Restore previous control keys for free camera --- .../resources/controllers/keyboardMouse.json | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/interface/resources/controllers/keyboardMouse.json b/interface/resources/controllers/keyboardMouse.json index 1f7ea097da..eb07c9a6dd 100644 --- a/interface/resources/controllers/keyboardMouse.json +++ b/interface/resources/controllers/keyboardMouse.json @@ -3,8 +3,10 @@ "channels": [ { "from": "Keyboard.A", "when": ["Keyboard.RightMouseButton", "!Keyboard.Control"], "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.D", "when": ["Keyboard.RightMouseButton", "!Keyboard.Control"], "to": "Actions.LATERAL_RIGHT" }, - { "from": "Keyboard.E", "when": ["!Application.CameraSelfie", "!Application.CameraLookAt", "!Keyboard.Control"], "to": "Actions.LATERAL_RIGHT" }, - { "from": "Keyboard.Q", "when": ["!Application.CameraSelfie", "!Application.CameraLookAt", "!Keyboard.Control"], "to": "Actions.LATERAL_LEFT" }, + { "from": "Keyboard.E", "when": ["!Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LATERAL_RIGHT" }, + { "from": "Keyboard.Q", "when": ["!Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LATERAL_LEFT" }, + { "from": "Keyboard.Q", "when": ["Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LATERAL_RIGHT" }, + { "from": "Keyboard.E", "when": ["Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.T", "when": "!Keyboard.Control", "to": "Actions.TogglePushToTalk" }, { "comment" : "Mouse turn need to be small continuous increments", @@ -122,18 +124,18 @@ }, { "from": { "makeAxis" : [ - ["Keyboard.Q"], - ["Keyboard.E"] - ] + ["Keyboard.A"], + ["Keyboard.D"] + ] }, "when": ["Application.CameraLookAt", "!Keyboard.Control"], "to": "Actions.Yaw" }, { "from": { "makeAxis" : [ - ["Keyboard.E"], - ["Keyboard.Q"] - ] + ["Keyboard.A"], + ["Keyboard.D"] + ] }, "when": ["Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.Yaw" @@ -215,10 +217,6 @@ { "from": "Keyboard.S", "when": ["!Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LONGITUDINAL_BACKWARD" }, { "from": "Keyboard.S", "when": ["Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LONGITUDINAL_FORWARD" }, { "from": "Keyboard.W", "when": ["Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LONGITUDINAL_BACKWARD" }, - { "from": "Keyboard.A", "when": "Application.CameraLookAt", "to": "Actions.LATERAL_LEFT" }, - { "from": "Keyboard.D", "when": "Application.CameraLookAt", "to": "Actions.LATERAL_RIGHT" }, - { "from": "Keyboard.A", "when": "Application.CameraSelfie", "to": "Actions.LATERAL_RIGHT" }, - { "from": "Keyboard.D", "when": "Application.CameraSelfie", "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.Shift", "when": ["!Keyboard.Left", "!Keyboard.Right"], "to": "Actions.SPRINT" }, { "from": "Keyboard.C", "when": "!Keyboard.Control", "to": "Actions.VERTICAL_DOWN" }, { "from": "Keyboard.Left", "when": "Keyboard.Shift", "to": "Actions.LATERAL_LEFT" }, From 1068637d3976dda81261add7f6c5aa7089bc4625 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 1 Oct 2019 14:28:10 -0700 Subject: [PATCH 12/15] Fix for avatars that are stuck in idle pose for observers The problem can occur because the default constructor for the NetworkAnimState does not initialize the blendTime member. This can cause the avatar to remain stuck in an idle pose for observers when blendTime happens to be randomly initialzied to a large negative floating point value. To fix this we explicitly initialize it to FLT_MAX. Additionally, a debug print has been added to help diagnose this issue if it occurs again. --- libraries/animation/src/Rig.h | 2 +- .../src/avatars-renderer/Avatar.cpp | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 51ff537d51..98431e1dca 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -359,7 +359,7 @@ protected: A, B }; - NetworkAnimState() : clipNodeEnum(NetworkAnimState::None) {} + NetworkAnimState() : clipNodeEnum(NetworkAnimState::None), fps(30.0f), loop(false), firstFrame(0.0f), lastFrame(0.0f), blendTime(FLT_MAX) {} NetworkAnimState(ClipNodeEnum clipNodeEnumIn, const QString& urlIn, float fpsIn, bool loopIn, float firstFrameIn, float lastFrameIn) : clipNodeEnum(clipNodeEnumIn), url(urlIn), fps(fpsIn), loop(loopIn), firstFrame(firstFrameIn), lastFrame(lastFrameIn) {} diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index b0f3934278..75a7693de8 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -133,7 +133,21 @@ void Avatar::setShowNamesAboveHeads(bool show) { showNamesAboveHeads = show; } +static const char* avatarTransitStatusToStringMap[] = { + "IDLE", + "STARTED", + "PRE_TRANSIT", + "START_TRANSIT", + "TRANSITING", + "END_TRANSIT", + "POST_TRANSIT", + "ENDED", + "ABORT_TRANSIT" +}; + AvatarTransit::Status AvatarTransit::update(float deltaTime, const glm::vec3& avatarPosition, const AvatarTransit::TransitConfig& config) { + AvatarTransit::Status previousStatus = _status; + float oneFrameDistance = _isActive ? glm::length(avatarPosition - _endPosition) : glm::length(avatarPosition - _lastPosition); if (oneFrameDistance > (config._minTriggerDistance * _scale)) { if (oneFrameDistance < (config._maxTriggerDistance * _scale)) { @@ -150,6 +164,10 @@ AvatarTransit::Status AvatarTransit::update(float deltaTime, const glm::vec3& av reset(); _status = Status::ENDED; } + + if (previousStatus != _status) { + qDebug(avatars_renderer) << "AvatarTransit " << avatarTransitStatusToStringMap[(int)previousStatus] << "->" << avatarTransitStatusToStringMap[_status]; + } return _status; } From c0a852d68cf1b0a2fdd7bc0106611288c831e85c Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Tue, 1 Oct 2019 16:55:37 -0700 Subject: [PATCH 13/15] updated audio wording and removed audio defaul spamming. --- interface/src/scripting/AudioDevices.cpp | 4 ++-- libraries/audio-client/src/AudioClient.cpp | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/interface/src/scripting/AudioDevices.cpp b/interface/src/scripting/AudioDevices.cpp index eae4a61552..8cc45a3bf5 100644 --- a/interface/src/scripting/AudioDevices.cpp +++ b/interface/src/scripting/AudioDevices.cpp @@ -282,9 +282,9 @@ void AudioDeviceList::onDevicesChanged(const QList& devices if (deviceInfo.isDefault()) { if (deviceInfo.getMode() == QAudio::AudioInput) { - device.display = "Default microphone (recommended)"; + device.display = "Computer's default microphone (recommended)"; } else { - device.display = "Default audio (recommended)"; + device.display = "Computer's default audio (recommended)"; } } else { device.display = device.info.deviceName() diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 8f71b1bd33..5e1f285a6c 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -494,7 +494,9 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { waveInGetDevCaps(WAVE_MAPPER, &wic, sizeof(wic)); //Use the received manufacturer id to get the device's real name waveInGetDevCaps(wic.wMid, &wic, sizeof(wic)); +#if !defined(NDEBUG) qCDebug(audioclient) << "input device:" << wic.szPname; +#endif deviceName = wic.szPname; } else { WAVEOUTCAPS woc; @@ -502,7 +504,9 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { waveOutGetDevCaps(WAVE_MAPPER, &woc, sizeof(woc)); //Use the received manufacturer id to get the device's real name waveOutGetDevCaps(woc.wMid, &woc, sizeof(woc)); +#if !defined(NDEBUG) qCDebug(audioclient) << "output device:" << woc.szPname; +#endif deviceName = woc.szPname; } } else { @@ -532,10 +536,10 @@ HifiAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { break; } } - +#if !defined(NDEBUG) qCDebug(audioclient) << "defaultAudioDeviceForMode mode: " << (mode == QAudio::AudioOutput ? "Output" : "Input") << " [" << deviceName << "] [" << foundDevice.deviceName() << "]"; - +#endif return foundDevice; #endif From 6eed3e43bcafc67484c7d0694d71f4c9199125ec Mon Sep 17 00:00:00 2001 From: sabrina-shanman Date: Wed, 2 Oct 2019 12:47:04 -0700 Subject: [PATCH 14/15] Fix skinning deformer data being added to graphics::Mesh even if the mesh has no skinning --- .../model-baker/src/model-baker/ReweightDeformersTask.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/model-baker/src/model-baker/ReweightDeformersTask.cpp b/libraries/model-baker/src/model-baker/ReweightDeformersTask.cpp index 98f9d419ba..097833e110 100644 --- a/libraries/model-baker/src/model-baker/ReweightDeformersTask.cpp +++ b/libraries/model-baker/src/model-baker/ReweightDeformersTask.cpp @@ -12,8 +12,12 @@ #include "ReweightDeformersTask.h" baker::ReweightedDeformers getReweightedDeformers(size_t numMeshVertices, const std::vector deformers, const uint16_t weightsPerVertex) { - size_t numClusterIndices = numMeshVertices * weightsPerVertex; baker::ReweightedDeformers reweightedDeformers; + if (deformers.size() == 0) { + return reweightedDeformers; + } + + size_t numClusterIndices = numMeshVertices * weightsPerVertex; reweightedDeformers.weightsPerVertex = weightsPerVertex; // TODO: Consider having a rootCluster property in the DynamicTransform rather than appending the root to the end of the cluster list. reweightedDeformers.indices.resize(numClusterIndices, (uint16_t)(deformers.size() - 1)); From 001718224eece68d2f95493c0b29c7b92c6d0324 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 2 Oct 2019 14:39:00 -0700 Subject: [PATCH 15/15] fine tune the recent changes to be able to return to rendering of the hfm::Mesh loaded, not the shapes yet --- .../model-baker/src/model-baker/BuildGraphicsMeshTask.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/model-baker/src/model-baker/BuildGraphicsMeshTask.cpp b/libraries/model-baker/src/model-baker/BuildGraphicsMeshTask.cpp index deacd6a977..8c27968de9 100644 --- a/libraries/model-baker/src/model-baker/BuildGraphicsMeshTask.cpp +++ b/libraries/model-baker/src/model-baker/BuildGraphicsMeshTask.cpp @@ -95,7 +95,7 @@ void buildGraphicsMesh(const hfm::Mesh& hfmMesh, graphics::MeshPointer& graphics HIFI_FCDEBUG_ID(model_baker(), repeatMessageID, "BuildGraphicsMeshTask -- The number of indices and weights for a deformer had different sizes and have been trimmed to match"); } // Record cluster sizes - const size_t numVertClusters = reweightedDeformers.indices.size() / reweightedDeformers.weightsPerVertex; + const size_t numVertClusters = (reweightedDeformers.weightsPerVertex ? hfmMesh.clusterIndices.size() / reweightedDeformers.weightsPerVertex : 0); const size_t clusterIndicesSize = numVertClusters * clusterIndiceElement.getSize(); const size_t clusterWeightsSize = numVertClusters * clusterWeightElement.getSize(); @@ -404,8 +404,10 @@ void BuildGraphicsMeshTask::run(const baker::BakeContextPointer& context, const uint16_t numDeformerControllers = 0; if (reweightedDeformers.weightsPerVertex != 0) { uint32_t dynamicTransformIndex = dynamicTransformPerMesh[i]; - const hfm::DynamicTransform& dynamicTransform = dynamicTransforms[dynamicTransformIndex]; - numDeformerControllers = (uint16_t)dynamicTransform.deformers.size(); + if (dynamicTransformIndex != hfm::UNDEFINED_KEY) { + const hfm::DynamicTransform& dynamicTransform = dynamicTransforms[dynamicTransformIndex]; + numDeformerControllers = (uint16_t)dynamicTransform.deformers.size(); + } } // Try to create the graphics::Mesh