From b8ae9808a8e50762f28aafb2cda27bacb55fd13d Mon Sep 17 00:00:00 2001 From: ternaryop8479 Date: Wed, 11 Feb 2026 00:27:37 +0800 Subject: [PATCH] =?UTF-8?q?Refractor&Add:=20=E4=BD=BF=E7=94=A8shared=5Fptr?= =?UTF-8?q?=E4=BC=98=E5=8C=96Shader=E7=AE=A1=E7=90=86=E3=80=81=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=9F=BA=E4=BA=8EG-Buffer=E7=9A=84=E5=85=89=E7=BA=BF?= =?UTF-8?q?=E8=BF=BD=E8=B8=AA=E3=80=81=E6=B7=BB=E5=8A=A0=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E9=87=8D=E5=BB=BAAPI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/cornell_box | Bin 410304 -> 409512 bytes examples/cornell_box.cpp | 2 +- include/core/raytracer.h | 5 +- include/core/renderer.h | 3 + include/core/shader_manager.h | 17 +- include/resource/shader.h | 6 + shaders/raytracing.comp | 112 +++++-- src/core/bvh.cpp | 6 + src/core/raytracer.cpp | 560 +++++++++++++++++----------------- src/core/renderer.cpp | 27 +- src/core/shader_manager.cpp | 64 ++-- src/resource/shader.cpp | 19 ++ 12 files changed, 457 insertions(+), 364 deletions(-) diff --git a/examples/cornell_box b/examples/cornell_box index befa73fdfd211459f8b36e00490711ae176dba60..5ccfb29f4515b93718c809d1c6b57db2e12d52dc 100644 GIT binary patch delta 124338 zcmagH30#%M_dkATSiCBDQQ6#4uL`0FE{O{Y33^f7H7zx9%`I1Ow@U)%?M9(bHC9%d z?VnOh6SY#zJ#)=ma=|s{iVEhM3-|v%^E@D+-~Z3o%V%cJHfPSvoH;YkJeS$V z@qgKFPX$e_`epI2tgOKnq7u?wS!3Px=wdl4~Tv~U{ zqqQ&34%He|jqped_gL4z>c{@};$|7_rWJ4Ma#k2}i{WV*I{fQ$@InK=wj6w_(GwfX z!TT8Ub9K08X8`>4H8#>YDB; z&tNEYs2seHQNf9F@N5Hqt{gnqfXfoNUcaf2p;2K8g6v{4oiiBjmxFJ#=z}xY7~REV zD5RebKU5B$X24IBgKtbW0J0n+*I+0t2j5d%HY`$Hv1x!_v0pj(9&KA#3${nQ8P+1I zn0H(`npng6O)UrCqt$O(kA-S+O@nHL7&!9GnfM<}*1^B~+O(!Ynr!OhyAY*f=tga2 z(;(D(7|(O`)D}1O(R{*vmWD^NWQ~OfX|uz9w2t9EzH9Sz#mU{*&^`uc5}>)Ipv|@Y zfG!XBsd1L;h(*3OO&@+b740A?GKuEfl( z477hjB>(-3$8CBP;E|0+D2?P2l&FDoK$LCEih1P=50iXUNCLL^%)FFR#pbw?ymfx>t#gzvC9IZe>9>0ipu1+u3i=w}c#1wmlY_eKN4iExoYSX4-=RP-fr^#X3dNeIqpxx@QyESzg)Nr0jddR#<>XK0W@S$9a03#$!t#HAM=f zU0X3AsMR1tTni;G-a7b+(FT#Mwj^sQ@g*C4ZHTX;ufca&%N-D8zfMN6Q59Y2(TV7( z8km`v@Zr!v!5~g>8GdpRImIBybK0X zR;Nc5dQ_x`Cmz(k`IMGS12qdmNvjM)@X)96YFv*d!CU)X$8$3tB&y}pq)JqKLsYe= z@k&%p5|v7lrsAP}@fmhTj|9Yg50+o6T!wWS zmYgReDS(>sJsI7xozzHoT{!2B|5Y~N-_rUx!1In1N`j; za*qL6@iYUhR3N_wUU~p2i^wGZ(c?BAPjy~a%(_qDIL&BCIb2ovUqQHQE->eigda(Q zW2c=|X=2o@dqg!9BB|yUx@I7go==k~pXo!&y+Q&`A*pe ziL$6YM1K1;qY_QsEPaa!ljTC9gSK;3S|C3=LvBCAx)?L)N$1z55i*N<3B8dldm2m$ zNb~o~Ey^~fc{&6K2nUfY$Ikppy4uT#1#QiKHtSs|O&zpE^-8JcsJ;t_g5NKP zQ2s0hQ)w`~P3VhP+-|#EO+(@v>L5oRS}g0LO4p}F&um%-)teR5m$<(K_fxG;rMg=Z z`i*CzsqX589tX5+<#OAx&gpg2C|gC@r@FL{kxl=j$8CBPP$Sjc9N3NG zgYwqESjv+Vhrzgo)+VNcnEs_sgUI7QacDmNmNPa+Hj;S*scvJ4lrmPounA`e}D zCS7NSy)CBXVj?_q5j0O+P+ddqz%u%lR8j1Lg49?kKk3K~v?8I4NoYxHi+51u2K)&< z-VVHM4eewLQc<6npCkMKa6!ifxSKswIMuz8(7w+^Q{5jB`o;y+YTrcWSx;tkijS0dM2`g0ZJl?$SAxB3!7 zg1|N#l;sQL+eBA3lvQEV`y}Zm8SWajP|f?1+REWURVNT;CxFH@YOmb{^m&4Q`~+H! zpnYo+G*v+{o0TNg75c>cskw4n^~x3b2h~&-uY!}Kz{?gu%BI?j$#uLhya&s+)#fMH z7`z?Xq^w`8X>dQ%?>tCO!Qw_t)5YjJ;~vg zf!g)tTI2grJztz7)?ci-sG+2$bEqUgm&ROKIX>w3n#45)T(UiNej7Yo1Kr4lQ?W4~ zdN(dNa(;5DHf==Bv4XnoUo@dycTgzs!@H2_O`7P@W)I?hMz8fJ8LP<*-;f|RTo_NWf^~#bpOSA2*HcIqNp;gCvYOCcbIm4WX0#yv~=uNwDKSXyY39*CYg#_u|uP# zUPU&4y&Q!k(b-knoB_G1TC-90eW*ul&IE!i)LtCbs7idQUil%63HgTh)~K5H`HH4= zt!P*3b1=)YrD*(hQi|qszHF)2DBpzAuA2yHucKv{@~ z(OF|Ozp;Up{-wc#c8@)$ScZ@Bs<4n)j-M(PQF|1XH=Y7_I*EAgiHKWgKvbvFZM2@O z{|6PT`yp6_z{3Xc8wJ!RkM*vx8X#E_?7D63O3*zyOQ%>d);nZAQ5+|2kI-X3J@(*1 z3?Z`98ESFWu0*sFP{SL-bBqo0sSBu1cKfvE_ex;ZN3e+;RKmRfw02``;PZb0s+0YX zP?*rAc1J2oSVw$SfRq*K;YnnUf-UEip?1p8wRc{r#TIM-d!=UOS78)e*1S;Z`JQ&@ zm72_^<-bxhs5wEM^UV4|RlNiHK~)8<_P7uhsKtz{&*HV=<7(T_WWla2Pm=AfCOL}8 zXroVnHGHBusomunt`r~?v~4sLuwNgT>c+pb%o;HQH86Yo2svz8VSW;e+$h&1}^_vsbr3k zRL&v3g|LZSfQRcr5z%Y)CU|+bCbWad?WyEW1E@TK$lDNkBt63M$j(mhU`q9fcXY79 zot->}b~}6G^l>1J)#gi>oCb)W{O~alD!1z>6jZrMB!dhc?46;*S$nl^kt6xxA{X+H? z>v!T&v3{N<`h82aq{5D4<1CYRxvD-}!!2Z(-l&yrskpJ(n55Cfays#r*Ej zkA8w>&A*`F1p9O(z!CxsRU#@; z02)ldSE+UVDB%2WF^av2rUu!}Uv(AQNXB@>D468}Bj+b)Am_>{(k&4xFR6xlHJ_{| zQH1vWt6`RF6Z9DqODkiGKS}wzHOY`xWn4q}Jv7ZV(TzG^{fkH{lX79C&1;G!s5{D) zs66~n5H$rkb;4)bh{=ru55EC;V}jo#)vw{<>QF>td@ChojmGiHOJup7)XciIY>va2 z7PZjuB*%lOT*&p=4gR)h3c{$HlWTPAMe)7t{qnQQZRswpcLZ19l>pP{UC5OaTQ%rgC&7-vP)n7`m>(Dn_&H@HLEMd=+Rk)5E zsr@h|$h$jG@+a-Ulp6MFi=fc1!>AGb<$t2QBQMEuOMZ)N{z}EC@hxjUKx)>6~^_EN$i5_yY1v2ciYmhGE2q| znh7r+($-81v`;$(>Oasfmunk&qEd~pWNsvnTY#F-&=nYQN$m92Cr6S!hbjF_%lDEe2@$UlTKsgs%AOe*2rojmv}(hrH;(u-U3H4;zWM~d1{0Q5 zvKa>WcOaAOpcXsbzx@)*{{yw;4`lA|=<(H4TwbyvRsFU?=mU#uY(`zSN(-40G`R=h z7`E}&;3wmj7PRo~5PpM%hY=^H#7ZThOjHs|7WjsG68P7j#;eVvg9g?mYEs@ot#68d z)I^B?Xd!LY=3A%A{Qb&+`q~{qG60U0Rwa$RZ_Pu*)wDjC3-FYL+NFRSU?cv?PqA&DRoDr zz-ZL%Ndzx;;gA(dM4_^cVk=0>`rNvL#(g7Iz9Q=wVr;Uyk&BcSja;yFt1(24x^qBV zk`hprURqPT?xM9++W{>tHK01iAl}FUBqP8;@Gl8oMMbawGf2|`su{SLs4h~I&eG!~ zJ&x|zUQhK8>RF;Tj$6`nON7c38k-%U6{dQ27!6ob)_2x(r2h~5ltElOXu_nBlqqS#^HVm_G^XJrq1;8r+G%KnI*`13K^=7Dbs+Jr~bg> z7(EW-LBxqA#GMtfMYTHK5LKICHT=~KnNMu947P$lsL?v{ZNqARD472+QuHtlTOiigkUu)HzSTWhgKBO!R9W1kroS$4othJQGagu$o z@mIs}Wl-dAmdAgm##67h*A|dyV^p5oqi9_ov?#3lU2i}wl3IF1=YLM^@}w$!)X=Ml zD&%M-vr&B_O~Vj@+QE=b^T{U18G^NkpbY;Vo2vkA@*IoLsrkhe;d|6BZTTGEz%?a6 z_invuW|=@d)uU3Chv-fn`30F_1s+D@FoU2lH4`&PseVr~Ra3=JNF8(?*Xqx$5nmVL zld{%Z3jviAQGtpUgILA#%}PQl?pI0}|>a^H5LRlgUJZ=Br~2 zYIpuB`3G7qck7KiG}kwL-aNgNRo9EqlxnUo*WKB^N8P-F}Hu2UFY*)Z| zVz;Vw>pZW}cjvpo$^Ca5qe~qD%WfF1vN)HR3Bi# zCgFXupL~e~Zjpb&5c(Fa1_6FjHIOnB2!Tzn8J_2fo@xemrdmH#_yxPKRaepT%P7zFJcU&9t`_rJP5VA&Y+XWTFscFDIYR%I!%RJKCB{rm z`3VJE`mZN|Fs1l_gmUsz9lECkN;&D!p%ho?v?{`yp~SgKoLi37Nf6E14H{(KvX2g? zDr3KnM5^`Z_WGEpU5xA}b|2magdkHG#uOQd?H*z*->7z?}L02FzU9>GsfGZp?!sDj7mY*cqpB)v1l-~&kb4dM zN>Zf^-jdmnrY2~<0F5*e0R+u{ijb}Y705J0(BLw7ZR5f!6NVChPOi@1q6}WWr&s)K z4Svg0cuVFfqe<0C&}3bZ9zma{g45`Wqq$mSdQJNYvKBO5t8iudUDdSFz-K>&w`6{0 z)buWBWWiQEuF~T&9wc(uQ!M&W8e@oz0p4ELjH#-l5=h<(67>;1-q+>nZK$Y(8f|z) zm@@sKuSA|CU^wxKu?R~&y7U0f^lNw-67vPHGFkOi%(j;x zJADVh0b^hG^heEY-T>P5@2_CY9*AO1?Q%u~d*)_RB~LE+Mo;fRFv`Gh$CY9^)as<_N;)$uvVow5p;&Mk19Hf8(Z%Tua95YF3ceA5gvT8nj79>PfV2vl0ZFK&pSL zfeSU#b7UC1Ws29v-|3)vYb@+K7S1Ka5{A<~dEpmQJq71{IK+UuBk__6N5_>%!pwAT z*ql)=GdHE7BA}h*!4pJ+C{0a&xt1h2V@^^h4FEUk{eU`8S-bsO=yb-uQMcoJM%oif z>G+F;-(rAg8fiocdj1TcKQ+LEjMP$sKC=esGy@!Mq=isOcK8S9Ta9%a*s|)h=}Ll1 z1Q?XNiSoyjlbe~n1Tf6YxB-T0UPqptmDM0(L6`PoSO z6Y1OFm+e50GkIl*N7F#M(ICk-(om46n7#$yMR{Q0icC|M@dXEs*;t&1&*N#;)129<7iT{X)5KOJ7rNZTTH{cI4uXaMIL=~5$IXQca#^xA)JyOQqt0NkN? zAP{!7ROwDvFC!gmq)UwS8>Fs3Rbjj94AN}fUj#gU5koesO~i0YVw!})unRXqW>&yO z9pgh7S1GL=&Q-`<$g- z8V0&)yOE-@Z}bX2(@r^RvoEy!j=D|%8Ui<%+G?OJJ*GQd=(jm8r}$#Rc!Sg(5DkzV z1xxSp`fgq9o0%TLBFF89_{s=nO{O7`9jm%#g?1(@B-;KH*(OgCQTly%Dj$LuOlKXt zhqxO3=yqG`#T!o3@t5+0m&?h0+sw{3#9>hPkAV=a?UY&4k|qk0|d{QsBAt89OlX#cxRk^(kp;`%uieJ!y7y|W}Wwso}5K$mDjJXw{of5y~&IrgYG$w7ZhQKF^v8!u&n8b*STJq z+KKh?Jojy_?oTz@=UTg;8nXrKl7Cvo*-XuI<5xag+F~yCC$Dk*O)Y0*ch+Ma-;~A} zTbI7Mp*Nek?yKA+hUE6PyNrFNsoHrY*<`Yj4H!yAh zVvFXok=AtI4=iro>3y$oe!juFgagYx*hKBZ;U4T&E#gQAbDvZ-@ZZ&@9jVR+ugg5r z+sAAkqZF`dr_WC02ghlNc^|Uw+NHcCRzZt8*MR>wN*j3YV8Ay+G3Gb;S51H5WqE@> zlCx#`wqDond@^IzwGS`M;vWsyKDtmtYj!b{KYUqRcQM9#^hIK6?H!kX-_w#20UqQy zUPNHpBgZV6yGCjLm-2!<;bPKp>WY^XyMUvthb6Pwx=NSV^GmRFd>64y1mIgPQc>puB+wI}PN^}IKl0TGXq;UT43G zl~q_%wo3d_g@v={#QiEPg7pziEbK6g75`b-Ox8q9^<(})-WSSPf>zZmuY2cnKJsH9 zFkWyb=ecUEGh?&G%1Lyo*TG{|z z+TffC!7Q>O|E*rm^7`y!55B#&=+KCb;J-BxpEP1qDzB;KVRCFkz5mq832w}S7~7Z= z*@V5x+4JJ(FgAqQL{L-qBWsoOdsDQ7dFK2V&diKCb9i%BpVcecfpDvqu^7iYyG15s z=2|kHx;s0$Bj@=D7RuPtoQW-1EpUl9BH8!+&^Ga06dMVPeGr8fHWMeKSY(Zdbv;bG z6a4EDuOq?7^(#gY9H`g-M1z)WY~+btH8?0>4y#6EVkcJY`G`4wSBL^xy#zWI?Qw{W zEm@C>MO*YC^@H$f#TxU6TSeszg>%`So?8lHde&!}uEmWs3$RC5p<)ezR z(?z0d>_upQzA6fnETJ&U<d2#F%FYJ3EmDYGi`n9;jQKB*nZ?HTY!KgX&Z*jg zz2Lzr=Zx#bMlp2FADvkQXRXA;IQE-IfxAfLKF?}0o^$GX){ya&Yc|9)4^K8rc-q(r ze(Bqsvo`h)i`;sz$elRqu?kmUa5KHy{hxvzErwx-ay*eP)A(Cuw)nU^#`VygJ>4;X z*h*2*gSBRra;!=0B4^8mxi?$Fg2jiu**P{+%l^UqP{ul}0XE3gk%0J4k!tD?8srXJ`Eq(*mN&^7<7^Mncr3l9FNQU)hEJgu^&LN}Rj9VbIeDC?>mE{+5sqt}}1%zs;M$T>cM zedo=-&B++T4wBgiyo_|)yE%=9v!5;IM>rOQUJZqu%!GNEUP=*fOktDEu0IvdEFMl_ z%_@%3OLy!daw@A|&52^E#n%z@e$J?=tR6xKkv@%$U|);N)0mUh7SpD)*0sCs2Q{YV z!O^q}I=eXya~5}@5UKAUEw)W(by$SRo6hF4hT^3eEF#GBP>~w>bXJg-#!dZc*B~Rr zr!!a$Hd<_&f&RXGS_G%C6+@36&}na3s(P)M>`@ZwQ~9k@WlQLuTNXdBlXJQ0mgVJb zgdVS>^@9upzo`^HLHMV#_PpqT=#$DaDw$DJRBrwuxkj8#Wdm6a(RwCJs~n2P0enCn z{6lPov*tH;2|1JHv-q5&v(P3sGpF|)=I_DgbHtfbeCvqZ zbmsqJ=vHppouN+YX+KeXF%>3`0HG!9E%kl~3;{Rbu8=nJ1_zOyBXXygMUgF6FQ^Et zZUZ^JOgYUn*q87MzlgswSv!88_a6Y9)b{QzoYqLq)+AseFcZH*}e>)mk!J;Qv-cu3ChSaz*9OftPF6M z4m?{1IP3=<`du05avk_b8Q>c_&{PIET?hJ>0S?oF|4bB%7h_r6A}%dv!`Qdtc?XN< zXSRsN4%U<3pCFDqV9eE`#hYwCOBCO|$y%Gg+o&d9Mpd2NsHpLKEROH|PK+Vq4`L{)YK_^S=|sxi#!7M0ktWvVI=?pLcUk zuVd{P-~F}-`ib@PYxp+#`T{u-DaPL9oH;+S>t0PJwB{z9+=WuZUP2yj2IoVr$rowy z-Yo~=tqG`w$oiQLYJL9=T}B~NK*zO1^MX%854r+)N(a`05SK?WaMv3m_!oAJwGjos zFe~%R@&A=AW^Aqacnf>K;s=q+qIEJw$F1ym#h+T}#V>Md=Q4)}^UwKmJ7SrNH(pcK zoea;pw}YB=V4-Na3x4a?0x@J4>r}nVf+F{5r)MKfHJoy!c5{056yNP)!_4XP6=QW# zbvOK2bJ1rvBG#&6{%*u-sbbk~*egcF?qMAoSDjbn&K}s`=C}n9{#G~~P5L#w!Wcj| z`;x4F@i38(Y$jIjVa=-bo(rkzJAlTW-0iSKw8-1TKEVilZ7-XMCE@B`wwm9bEk696 zy@$aYxsS!MA!7PI*0j=&AP*WtzPUl-%YCdp*0=NfpxXB$lf<+?*ch|-ETwi= zarO_^vihyiQr(`v&*^nMSTx+vKI8{eg?%rZz%MQo;Ro3FY`r*n03qu_@$di(=VQ%c z!ERQQ|Ngp&KghmAO*aoB#4l@U+^o{WiIU=qTBCs&gZdvob?bVFR<49)QdTmi!6+@ z0ixYy_72}MO#FTso1MPm(PfraDS4P$qL0W5V$nZrX|0r@dd%R6Ia0(;+s78a%y7hP z5v{JU^tR6pE^@2h(=Ux<6Jc`n2NzEVZ&B67;%kW) z^cbq%4O+HK$53^|R2QquUK8)Q*jzs2MKNRsYaTq{#V0Y;p^C*Z)N3z_6*E|H)%9o~ z9j_Kw@`;#pm91pcMXh}HB40L!VyiAMw4H_+tj^&b&p1>uhD{ zrGa`y{Vky`90Oj$RQJ1O8QR>Rll%GYvbQDlj%84rp5oATR?FIVNRj)N+%-Wyo zr%(@X#aRY#vkdauN9A}+)#2uNOX%r%aBNZ(Rl7wha4^7s6ZkVRuMj()H^lpetT#VZ zlyjw!J?7PIy-D6{xt77dspMs^=fu5RtW&cJy3m0w7iE6UW6EYkIm+f?ujG!*zi^l>9s-D)L>isZ=P}KxlCSF z0R1Mq&4Cv#-&yH`5zc$xvZf&;+lkTl+5T1!v3GsKxDAX107I7X-Iimyie$lF#G=QnE+6M9 z>T(_!5ke|Vw9!x)Kn?=$+^DaU$=|O}pfNtcI@MBD`Tz9^;wpsl=s4l)!GruQ31Gwh z7QAXuZ}$r1<9HEO#HxqOc-leUO{tO;b_-XBFyG~008wu&Munw%BT7suVr{Fn?g1ys_U2)2x zIfva?+}J_!8spD3UaaaIV2!2LIOC`_d8&1#Ta_;UX1o@k6{8weF(R(WjXkcbuL$D2 z0rL>;IjWDw?0S*|7n)p;L`x68u)~SYfH`)!cEHH4dR_HGEK*l@Jm}@sU;`L$q^}z3a#7&H z(-31#_2f0}mI$vkov?!nJu$apYK3^m3?IkD+K4#@SR>)(aLDSAC?#22<2l;e46q~$ z|Avmn>)TNHkr#L1|6%<9> z3)>(>B_798a!yv_6B*z0oapMqJHtmV^5GqQyFW*+aqwd_viS?*pbu}u%)-l;w+NW+ zM^g%i)rkmseBfvOyw0={iN1Uq`&azz%NOu#twsAPJc`AMNmaPOF{r17e}L1QPb_=@ zD-^dZyhYEsW=LtbYX&~-@%+Ko?za@rL`MRC%;>HqV_79cRIo)85)$ zTf4%P#>I>GlSNhx_v77~jBTmnia$5qTBIx9XDh0f1Bl~URG9ITJn@5cwS&7xsd zzS+K}mA=RxkD}oUkAr?7M}xpx&ESK8QyIgtOu0|Fa&o!y)N6WblymZTo%Y6(%#pUF3<*DV$ zY30hv49oj2-cP>=awrUDpx*NQWgjO`D&j{=a}jFU7jKM?74+-1n|)fC$>Qs zXJuHE(ZtOdS2&Yx^8%=h+Y!O?KvUrt$iJvMy*0cb?v|&4koIyxVpkxafK@drh*z&z zJCClP-NQj<&mjIH4&lEF;`I?=?hWE~a87>($7W(Z4623UOG%n0(Mw z$HtQUc5WTprx<(Mz^)(wJ}%L}MJ~o}X)2O~c~6|et`5fd49oGX!5ME6q$+$@U7)4z zd;_}~>?i2JrjS@2?^;bTkg?#*5v^uZslh} z#1Hj(5ZSsuuUnxOQLL>eZq(;<5ul83z~d@SZ>SIFzw3+j4R|vgG@ft31F_?{-+(vm z@X~P{h9!ic>rJi!*u^5ir?>7|v&>szB)rm}qX=khm|Tx>axa5JsI@y?i^Q;oJg(}E zquhiw*>mf8Um`z#Qmkpn8?;#WJ2!1MH8z>HuuzjpArVA}xC34)L70jW?tp~%t=vB_ zl29#P2am@SR4vie${VtJqL-B?Sn5-4Gt66Kv#7FK;xj8>&OQ;H8}XVfUA%;(_P9Uk zed1=Sl0O%szEV|{5Y9F2J+ zzsdDrS;R(WVvMTGh2MN0U=D)>OVwCE5faM%c}%dl*%;jyAk0m8k1BiXmSUMCMl``# z7%k>BfyIIpp=CVYzC_(M>U;E;_^k<#@(U}?_FZkgCjNPCQ8Sd+Y8ZqdV*_<{1bC^d zcVGxndfG^DHxz?I`S+EA>gYquT}xQPcnH57O_ZHh znX0A4-X%8m{x-X(^gM( zZ`9t+UjC5loEl;aN9ew-h`R&6+0RYXmUg09GoIMuD>Pn3x?3l|qA!6z1w#bf59(L$ zrx2;(e!dMBpEu*7teV*0j9Y7l2ZFa9LNrTeCm64!|JEH6m7DYNcy+iX96g;avYPYG zJo_E7H5^8d7MGi&Rqgd6zu+%AM(|Gj$G3I#n?j4=t@!&!v6ILn?5BE>U#TwIw%~Dm zeU?uBmRQmPvFe(2Vs#4$jS3WRN1|(A3=oG~@;Y8oN96Ih6eZ8ACOSv*09HW^jO1-e zsYo8g_xP6(KBp66zmOLRA3I2RMR6OeB6>yfXg>2Bv6#}1PQBiEys|_eG{K<&)i=C4 ziD_8mBvx5dJCZuH5vsNNCC1@P%(GKF>G(irnJ&7Q8+mQ(dvLEODqMT%`F; zaknKOV%b;C=ntA*2dawXRy?jjWxD+Li|P?9JJ{jS-V0j?>Ke5$y(G4`;t%bstI!PC z?m8W$rxk1+cYYNXSRG|Nc8HPWL-T41ErX%IQKH*iJj8CM@8 zooJ*^BaIis+wkuE$M41e+VD47WAWT`{3H7dI73Ol7F%kci;u9Qa?|Xy@rz}2ERAyo z`1(-86TY>LJYlHe31{xYaK+msXXS*by%S*b&HjrGS3b@gqko*a26m;+E}rgy9=MG6 z3~yh<9q{jlVoWJ-d1ixPR$kq{hmhqR{yG5Rog)pMYC|U!TN_1R6w~Hahx(Y;rd?fT zGh5bBt6$U+x?LEeZXc%5z7liC2ES`=04f&R zeA`zyuB{L72If21ojiSp7~Lei%VrYujq0s@^Ah$8LJ#JLG2? zOB17$95WD}U$r z#SJmqVfd0AI4{G3;VW*o=l;z?z2VIR$OHFMs_k^02p|==y9!mh)8z|iqc8g+q$3Zq z)8NPm#NfcCgHQ|*+&f6YZyc125-)VY?k-rNv0s`Oi8CD_OS&skAtM!XMr-WL30d5E z)fKWeA@N%lvGQm9ye=|><&TtsscgHuM8Bla*z4m*7z<>L&82MBtYVRSSC^?K>TPVJ zRF`82Kt{2JRG(La1Zl!GgH2;bQw1QUIsaN^(I|#D!nVbG)D~q-dR^6AV{fDb}au-Ozq4A z!pNjg)l!{m`4cuTnLA%r6l*)#?bmN&3mRK_=y_x9FlSL?Ku6|MaU!^ri<$WyUrdXr9&4q+4?>1iraCes!Xhy!tkFMHgP{Gu0kf$Zn0yEO# zJ=V_M-4sy?-sY@g+0eDJWy7HAHb-x>vzOVRaP;#2V_TJ@h){>sA`M!TM$N(w4gT_I?a zM*OOWZFC`K0uj><{_V1blHzZ*Ip^ZX5?(@2yDh07H1kLNZ>(D4xzK+oG(No?$QxCxW-iK7pLiv@hGJH4Cdr+hnd=o7$i+b1OW-GY zYhQ7sEAPRFyG6Zjd=?*DB$jpKjrjrGBI?E)R%&espR-9^@5X}ylX1x&wYJt@7wZ+r zZxS_ayk2PkqQ__|8E$r|U*mD*!tuB+)8i&R0)4~?8xN_limvM~x+oUgczA_rR2Xnk zY_{=;3LU9X@1iKM@fH=lso=UG8YS|`3J0--%O5X@p^3b;eIQ*@wq;F;#d}E_;plp% z#=p(c&FqXb+je(TUGC`SXQ|pPn5dCrI^b6YhLFpJPhW-%IcsB3DnCvAju)43tRK>{ zmySm^-PBq*yrkUV&yc-l>NExPT$keqHi|Tn%n!)V{)w_Gyo$+tmYA5 zPpOv{Gj2Jy2`Mi)yP324xE+JcIPp#ytj~?H_=SWDxRCn74G7xZ%}m43=IrBVYxjHV zKxFWbvq}-T8iR)hHT@23ZLrPhZF5dGBVem-ybKv?wNW29y3zCtv9)`g@*<7I zs%bF}T#>>WbPKwtCzu(vzP-&k%bb+eZKTW5}CeZFa`p3{U&9|ILkJ( z%Z6-rp=yiXo0d#ZfL!hHcw$GVB?iN&FaiT z^^hC|xa$VC5W3rOA9I~YA={=p=9tkj7JPkQleESdeSr0HY_`Zw^6emoLXxssyxMlt$W*S6zdRbEXbwUOZbTU9hi}idRvNlG_ z0HTbyj#ItibBENXH(%}Y@T2*ln5y7z%_yt#Lx5>$Ub!Y6`KN_ute=0M;n5;O`GtHI^sCH)dLN22VDM<{8(ye)DaNv z_O$9mn~7+z+C94iegnzimvoC|Ksysv-4%oRD)Nb03u18`fGQEvC(C+66=?7llCF#< zeFy}@ZdT)aW9snK8DoZzoCy_SKJh_sUMqR@v}d<@`Mt;JlYxl1)Sxct=}d*Wo;TaV zIfXzlzUmS`s%zVQuQ;58k5_|OUC4k5?vb_cJ`lcrc;lv>P)mLn8pcXj)!Edo5cMpr z>>o^hwpNGn1u!wkIR~cbt$-eoFn0QgSH}$B6>nVt`%|}VL~+!V)XAWVx2BS+<8a1h zk}LiX!LuRQmW3ffjVoxaTI<-A;9P(;y11*D@`Y|A}5bcvwWd}W0{Z!Epu-cTpRHy09oizTHaVf(S!|@ueRGYUw@Dx>& zc<=x@`u`Bv5du}PrCLdiOt5TNQ0++*1IR{!_>{U_>$cw)^OJbw3)H#=Y7g@CEcxkn zS>aZzZpC8rRVCTk7*^$E_q;D2CGk-E1$p!TklYTE>8J|RYO+RsaD(zo$FmWZR}G6UK~689!yR?kdE`J$XI*<^My4k8eG8$2k)`)lABo zYC+z#?S^O8Y|FL+?CU3gi_^9cG|(L|5nsb%mR7?g{Tx0ZE`}r z+opyE)mI4>`s)=63)}fk^FLCkGaNexS4c$f| zWTUGE;@#mmS3OZ6HVnt1#KtRP#7Hcw+4+y%Ta(dVITJaxAKEFyalIc=P-v24VkoUR z_%$^|;h8XtiozB7Adn|HCxWIxh9iQbedZ82QD-Y>f6uL8NT8orp)jAg<-Mz_0uZ5sKlDwm2OPJ}*~PpW`#IFK zHBEe*%p0?-;&3vr-h0_~tTtHgp>_z}1g}9i_iq7c{9OyToTgw-NTtacJWEa?oqs9F`;q_lXb#|i}F=1mS@${otU#9i>Oh&mVXE-eM@zM;a9wkx_ae{wWDz< z;lc%ws~@_!{|}jOyUU-vC(MkTnYEjMeLLr>6rG;;)TdY(v34iC3 zC>YB_nq4W?^qaE8=ZDbh6lt7T*1(|J6&o^HnIgK~Ib9H$!jkcjPIWNDbaVJZ8}(x= zvOnpCUg$=P3ew?sh4U3&-yUfxRzuC1Z5LG=mHLJi4!}F;R#1w5s#7TI85EEHDPyMv zied=tbSecO3g*f0@M{{hze8RbX^873kf_a}2p`9L_l!D1KW-VRLdjrQqj({t=@ud{ zss1v?Yt9wjCYw^mkC-%m?ik$a$Lm669gGfauTA3o82F0AXT_Ou2+}W5d&=&p=w1NS z=~Mhuz4Sx9x({*ONpu{g8=%fh(27fk!81@L4^SumkGZcD<7mE<_) z4mj{WPT5ib)n7*EV83hgrdJp}O=4wRUdNt*pvL(Yj?dULUQM?wL6kals{kt`mtbaK!s)49xnxJ zA|&}GVlo=cg(b|PIo!>cq=JYZmpRq_qSuq4@aRl%oKBnP-}7xZ7sl+Ze4Nt zTseGk>x%Kktt&1Ux30L1)(uk4F9sAhuefY9&#Smx+`8g&aqEi9#jUfP5iO?h1%B^f z>O|r8{FPmvq4?qNGvb#id_YJ`iY>7jjMeweS#7T1%W8GbN;7ft34E`{vn`J(Zh|Ku7D73d02)=ANK8V{_QdXnY^{u%?_<54SF zAB7)wQoIg4PdF()n1-OX;YsoHG`^lM_&WzxgmM1k39&qdcj2#|5a&~PMD04q;Oh^o zm}k2y0BgLf$SCZUB0QB(J?PYV_JE);NogdrMqT zMbJP0Em3JE(t906lbO&UAVwt4#NEi-9mRy1e0adTIVIN&f}NQ4@brZp#o3v>HUGA! z=o`ZWJN@`4BJW%rth)np-sYxw#|^{PFqEA0V%-5JvTzIFt~%$~jME_yzWke%C` zFw{5fxY#)xbD2tEK32=FT%=fo=n)GtUxi4*Y7IaicR=$uV4JKN@rHF@Mp3o=F>K}p zcxBo z4S7S@=kWTCF3r>#=Tq0f4&zGB6jQxnhp9uh%khWB&N=*L|4ry6vLb$032$J?#`pdb zZRhfa_P=PrFFpss#Rq5S0772Hsh9M8BymVRA4~abdcF_k3-x?5n9$a@_XhrnF7Rw-sn#w%E2 zsGIc45AGM11w5+7a{NZN(KD!pH2D39-Y)FJaO`6QgaHRtr&LjQo?6e@ivS`QXSMRv z{b0w*tjBphtz)E}jWozed!H9M3*bVcZSD4@VnPixCwA!Tm(n588HJ0o2;!W*q6K@6 z_u)VPF8aU5W2);fJh~xd>qdv+Fm(k{`*q%+dLI-_ySfd=AnAs9wOj1=Y_aTh9&LXY z@I+^)%@xL5b|*P*$ZLD3X{lx$f;bo8R5&-uanpA1uFQbq&{=)*w1*_)h(#5CM&Xua zN^Gd5+MYN|RZr_!o8`4Vw424@{`V6x6)YKac{e>4hx@Q(=|l8pJPML+SL%h3 zv2%Rck3!Ynw)CBT`9UQo=OTF_55mjLiK=I2n4vuW9E7y)eT;9{EE#nB&*t>7InF?Z z)IYLIx6QOitX{~Q4IuMxtO&jFFU{tGWy6+!zk+4aY=o7?_ecLlY(_u7`5f6}BN|Wt z>?*WNY9}oVk7400{xcL;q~9J9kre0O1b;UrDLb9X__m#P0&a@fFx} z6X_)o>Nin_{Im(?#2Q2`&TNIMh!lQNnHfV=!T%&O9N-SdTLE>VN#O)K5rMLLjik0k zfgqBO-}NQ%=6;MBI{UP3nm%UIm=QDdZII~K$)lRTqdUA9`8s&NP_-n!uwA`gY7l_| zQhsKHK`ELT`m7LB|K&~WqtNBX)aVaO^)TDi)g7`sF3?*tenKWKrf4i|mNE$^RrJ2F zKfN!sWZnZS8NV9dQ@O7G|H?_}n-;TK$%rm1qy0yQkOSxs*V`zR%*o;oV);vzf=|l3 zR9W=?%A=MSzP4~@t87>&WMxP65e-e#DLQe8HQ}^jV4~wO9XZHD__im}IjoN;xWj8V znXg8}qvbFd+sbXgzxRphw$^p5KeNA!tvFmlpTr0ornz`2616Z|Fjq%(jxW4 zVtc3o{0aSHgcZLPmjCWpxFU7(-e>~`~)wte7Wn=NR)%}$o zjVr}suEXlM|Df#Xiywb@(hCY?Cr6!KTp@F^#{UH%(kU0jI+A zR7fWorM*DhphU-U>Yum)a1=Na!gs!}Ut0!!=}Shn2Ogc|Y>k(_P3XPhdiBv#l5;v7 z>ubUOmPI>ZUYoN$KEY56jr=%QY=eukKS%Etja3DAeyC%xs=%#0218G0+n!E4MmnZ3 zIZ&JonbIzck4Sr*L$*=C$ll9z8{$m|JX_3Qt-m!}sn z%FA0a_IZ+(k_cc!K%9j4UrrldT*1HFiEMYQnJOU6xLvV+_-is-$XGy?Y(1u`r6Bw_ zsI6~FjF700f>#F|D{#UySKu}y)ugdQ34H}F{XrRC@Z(KsGX(gy*LP5FmS2a{0D~@* zX||*cPs*C?myeBp@m&Cf0Ev$4wA9CA9w)U+^-ImiM{JgiXc|ly$oOHBB*(vU)mD9N zuCKtwOsV@UcFg)xmj^&@#36U()GgSeP}CwDZ$q;&MzG~;LCzB{I03fZDM#DzJ2m*CeEL8N+YLfYSK2Hs^Sx^-BD4rf> zGlOgnPix62Q)5mBZKu(rmXlJ$BG9rZ;rRbY*_XiAbVUCr_vR5xydWD%2x8x2jV&Z3 zybz?e&{}KXx7dolkOZ$!2*uDUX(_6TDuUXVL{VE?)oN{3?z4s33Hg7|EH6v-_y7I! z`Q+XEojEgeX6DSynKR3USinY2Vo@z#h*~pbBft6pNqbOG$eXQZAA^sh&WEklzWJ|Kxd!lV1 z!aw7?C4|isk@+Gru{q=tZ4SZ6mom}a!i$FbZ75Ubq-#9&7!d$_elde~PidcH>)@XF z5_>~%4IWBon0rTTEpgViHGi)%87cp(x@(d6< z>V5)RA$+{Ht8p?P7uImUR?@neBBB*h$c?Lv=+*cCRn1GNEB!xIv+EwvzonLcgCOx* zw$g`g@>nXv3`Sf+g{gYvK#{iH+*zJU!$#>HVjN zv`HNkuc4^@LG4sXOAsjUB9zwY&Uhkh$Ll?fNWA*o_KeLeqx-hHvmWb+#aj-EvK4P) zNzByltg*L@ur=Wph&zkrcAB2<4yfp08|KU0AubtCEc~e!SmqHHRsY4IIq@$S7CuC; z8N3`yg_AKmzfr4TZpN}j)Aj0YnxP7vlsF2N1C^6+l=5*j;tZ7Ll7d~$nQeIQozn%9 z3&$%tU0`EHk@+&$fx0(KOVCTYju1*Yy<4ABA4vPQakEo}&BQKK6Bp8`X-7`HKK&$>JBTbvri2|pIZ0_XP;V4_Njw9i$2w;SqTG$ePB4>5pEk9PO48N*TbVz z$o}Z;B6zRxBMuTJggt#1Ez+D6j-e)k{j~rEaRRR~_K8i%P9IAeHmsJ^(+1Ii3l)hQ z?`T8~r;a_=7{SGo6lkKPIrl|rOMqU0jY61nXJQl4gaJb>c3OHse-96+@1$$f;1PmE za8C#JNzsaiRV2jg!P6Nv#s><6g8t3fXIgouITch1Veg0_KT!~S59&1|Y@I~6d5d!eQw@5M{26dHF70}q zgLM|FDylom39mrf!eHzt>7w}#)zknO!H916umOVxPpDI;j>Tq${-)}UNIHXrj9FMM z;=8{JRG?wqE(*9H6LDZd$a5IpusB3@9H}k>9|W_Vl1sswxqq6zSad8FcQM5_T;5m0U+F@RmR(N&hVc=`HV-a`)XX4)-k#X|dTn5Cb zD-usc;!*XU5;s%HBy8myXU)l2gCymA9vHwEG}XL~FO4R^4YrAVjAHc~2Zi!7`u+EB zXY@O`gGoN{JEcwvUDa=0++7@GSQ?VL>H{t#)FC;B zW0=Rx*2iLVBXv7Ev#lB<;RpvcM$Q)MKoaFc+~H1JksSxHkx6WAh82^%u<@!za1Qo0 zlX=WuI49PRTApJZ4d>-ua);&`6rb}$1%e?GY)4&;*{MjF7&7A5$x+u0 zdh!`9pX20nk$Bc|43`d@tS=&Jn-_uvkRC?;0wKi|x)Q>~|MqdD;{qXKSWqK#I&Q6bzc#`oV`DPRxd zZMJRR)V|uynlHyP72D1FEXVGz!Xn=KSH69n!*_R+$mcZ*`;f%L^kq9Pq}_R26FY$L zRTpm0la=$(HQtt$6T8?qSz6gzAATcRTabBYOt2aKr#Wc=q?(e%G!kvTHn`w^j%e0? zg;vEYn`(wiiW~B%OL>`&OSiPr+LLs)Vg)wa{jv#m{M}IFj8|K!_KrDDlIa%DzvWYd zJ&}+Yw@q|C3)oX4Q0tamv?&ySPTPmsJg12j znc71(RLoWq28wCVAmZjN)1DmAVuCB@cr7{ATkI*jDN1Qix%0k=vLuM#YEQ8y(VXD_ zG6VAcS_nZwdrH=3Dnlrk1tvhh!u>z(DKD(Ju?d>&L@@Dhg9?hpoE!|z_CM??s6=5) z8Om)bP>#r!m&XJ`%PRS7Dl@rF1)KD7bp^Pc3reFA|0h(N!O8wSc|F>cU#!*D$F=niMdoS&DOb-zT zl_`+Z|4Gcs7Z9^6TS#z%P;B^fidi}HoVi#f*n_R0BxUVk@kJvyG_Y^kWkr7JkFUiD zW6Eq=VR4Gt9~+6xNhM4v;UH0_lqLg2eBXiats<6$PjLLFgjwHaviofV6~@0!c8gF+ zZxgX;OgJb5n>fL62fXmeJ~@aysNA!Ew_zDIe^TmM^nl<6?tstzTzpQsxD zukzJlO^guSY}P#EwMU++ezJkp*^k|1Pbdm$K{?%5L~(q>f7R|H>P-I+7L?QL-d?%u zNYJSNC}=@hz&-L=P)o`F_4QSCt>1{`Hhj89qv$HQWQ^UC!1LYbd-@od3x}JwYJH!lg zS~^ML3*2xOA7Qb7h(Wi}x}C1XPTblc6&SKR4F*<*YsB$+_hVgOmTQcI%V)_HHXvtsUS;@PvCYi1e7gg!#6dt} zY}c^eA=-8knwru7S7Z)#(!gS;%?|N3E!M(md4+i+ zxpNRRE0}AbI2vo$QE_9v1ZR|~0pT55uLbEIj6Z3~#2J3d{SWaej;VMvyouZjLdv@v z&wG5Vu@#KnF`?k@)S%iJfbx_gmt{msrgH;KI%DLZEJ(NZG`>W4MhWNf-b&;AYc2*y z?krFZkk_TC)rw+2I)damT8ct^L^X=bIStn|c3>qo%>QhB{EMi(I_E0r3}RxZ9Fl_il{~dkh?JsMc}}fXvB09k)*`ACcbo^So7&&w@LA+ z|ILx+oi35{3Ozln#eZQt4;y);=bIsswn(2hcNUAWAjS@j@o#y zLe}RoDQ(@OVPKD`p5gjWboGA{uRll3=GpHeHN3<6ZhMHaqq9ArXlGl1d(#UO?mJq- zFVgOUbZmtp?UA0@lu))q-1u?J_zUx1s<7N|vd0%SR-wkJ`f=Ib6{8+1Hx=tz?g3;; zGmDO~HYm6tVmo&Ni9dVrxyJk|!&sEkCg*$FXonBvOet=oyP(Zm+3GK}nia~v2W^w) zVUe~Mn5$w>t9y>O30CBKPhn*De)TT9^M&SbF2qF)?U80`yVr{Y8sDzR9pSjN;+IeP z!4&PA)oj2TE!O-VRVX!HBEGzi6W6$a-2-H-A-CVfdjOY8q70#)P#mkNBO+_@bQPU7 zD@1#Z+F=|*vxDW5cK9VDKM|SG{n4${l7SJhnwN~@GFbvK^gP|ex~$bYR`&4 z>$GsK?^ zS{bbop`zakN`fy^HovpbZ~)@?yBJOJaO)_ky^rPlsg_+$^c^kkL4(W2VbZSM-GJ{BKibL4pYMr$s! zUe^O%JkGB-GJ#^&>kvS+>cRjq=Ew(pu?L1YIzbX{1TJCUexvnpJ;vNOYva4E0jri> z0n~uxWN;YvTa-1=xd3Ct9)CDOiz*gPrI%%7EGA+U9sTjS;4r=~?*~`t^I-lZL&=N7HMma&leZPm)* zYXqTNwLt%#AA^)8d6wolS0s$LdXU&D-GL$d}@w+jW9)YT%dU(x{ii$bo{`2ZPyyQ zhO!0QwXzk9BN3=9F-`xPbT`Ml9O{xP$_-BYXQR+@n-x2;UF%%71FDjWJ&2kq7CHt6 zd(xyg*7$@q*r7$bcWI4H_UDb3%(_F1F5~qP3JI)-I1kx}bJkC>YdbXGqT5q&gk>fo zZ^N{mT65R2=`D9^Wn4>ri5Ud(IfZ6Ecuw2MhNt6(xAyF(bghA}PaE($Be-~ucX7O# zcSZ&myEDtU$^v(3o$)P$(YtWAcO2%l_ChiCwm~r|ot#&5Sg;<2ZLXfS!m!A+t%ie= zICs+yByF2ma2W=!dV$HJogZD>5rYxAFX=8&gu`jEFEP{4^6VkD6+W=oTAa0HwuO;` zG_o^z^`t%Duiy%jW8+|!U; z6(BmL4_3D@8d7`igpd(Xz9X>JCA#TlbJ7hk4x1m&c-@N+rMAsN`ry3K7F(W9;0plw zPx=uWFBS#+V0ZDA_>$4~C{IgD!()_n!wM4Iu|5{P4ju3T6~0l0Et65zEKOgSlhSx9 z*jYpS-EggTN9fX6p^3Il!k&RBICRG`H0=MC_3+I46kFV&9J!sN{g=EJ_(n{s1A5_= z5Dlx6J0V^R^b!PbjHqtG^hBqDd&BVY%@~`(j|%Yn$|6b7M}*VB8%0zujtq1OT-hMr zP)EOkqe4v_ozY9Ml3!@0*^*s2_!{TI(syZ1%?+DTvmxc}K5pr`&vJHY&AY$<5ejG* zEt}zw8>Mio`Ez&koRiRi_t3s!bR${|(TyZ06LH>t$ST3H5@`rX)`<)PWZ;w_-s}RBhzsK`hUDok?t)}*KUG@Rt-gVhV zdfu(Wey8V*I;`kkt-f}(Hfy<8YfyZ8ZIlnzQQeJ24cN@R+NjEpW+7R7?LYAOhI&u= zJS4?*pbW0P#HK%dHW-rbaXf&P*r#-{1e%C`?QL_Rgp(aN>Z=|vtF8@pe=! zgUHZ}Z3;e%fH(^A1&?Qm8;2>T>Dc{5(bB!h7JTvPBB_u!je^~s6}{n;nIbQP=aE_&SZ5CX)#3(lTV82kq=8e zq%~T32%IYFUKfEte_#* zgR1ICqMu=;w8G_2u16nn%#wILe;#xAt``2a zBpr4i3&|J#%_w-o(+^UaLTiM|H;4!BJd<5HqBRP-h>LYF@3R~Ih#c9yitIX$;)lQw zpRtBVac$VXzuBy#=y5-q!PXwtnw5Bi>x+2Ucly%ws|2)QaDq&aziwW%Bwo7O+~Y%sxM+RViC}D#CEXknTkXPB)-zM9t%ZKT=Hlt~ z9Pz>q_Jm}O+rf-wQ`isH^;+z4CN9CXO=XRaYZ=<157_JDxCwQ~WETB{R%>MFB$&Of zPa~f4&A;P~nN!FB15>9kz|;Yu%vqLE5`OsuzyNcK=M2(>g&T{lO*P|tP&tEKp3JWP zp!t;ANok=Tr=TE7)mS%;xu4Kx)Z9=Ls$2tkT=3%%%_Z@5ar4~U$c>E}cNqw#z4&ar zb)LhvoX~0v?NH%A&ME&Bq&)JRQ~r}XV!!Twt(v^0HOKon9CI(z-s1}I9PjVoh!cw9 zi1f|6Ec~Q4FZwahFeHgYXDANf@I`-;;XLcy{oqa*w|$9ee_uG@U2GW1aKjetQ>^4E ztxWyJ@z6Qr7#FHp=pNGL^ezBORv~ z^0BdJ0t8%&^G0|MvBicfRtV!gi1^<;gL(d_m2JOmtPpiHM0xQQS}oSDKbZJBClZIy z9g%b~bdGTwomGTAR2Iom4BfnLFc}ba(>{^K|A?#p3YT-1943-MIo^|Nv#mdBiPde8 z9VgqhrWasaavThIe#1f8sbk*GSI7jm;Ivk;RPPC*RNkd|6G~^o$L#QFEi|HLE$W(0 zH=siB1MG>fO?>`6eHLWLYh&(J>p5pZw$DlSN|1G%#hRVLVb+~B*|;-Wwd%oC_$X}N zJ90Bl#ScX9h(Q%Pu4Fck<_A%$WR9a?&=H;1%t_9BQ(uuEI*c}png3a> zPPUT9xJ2H_5oSAlpImuj-;>Mh){!Dp!^Zx1rdE<4 zGF5yL`{0~bv#hl`4yTIdGbq?85joyNtFr^=v`$`I#tZ&(?K}6TaMMd=1IxVm8c--4 zz?45Rgsbz=fR>J6z0PX^UhT$UOlU`)aSGnZ&{H{;+0JWC0{wBEh)nRfUCn}RqX9H~ zMN;v>UPjO(cKN(^!kWZ$6CWIeIY@D85o<%^9(7tOOvffkDhFqV)i><=n>4jl4!4w{d6 z{c+l0FSh)Gwobc0l7;`O`9`k9w0#dv*^u1PK#^R@p>I#_9nc~YR$5>j{`-F0UKBOh0aC}A+G=Mogz9Wtp`5Z-_|9r$& zUBt0Utr9zR5d(DnitO=4tzIHcwQhcpAHFbac;Yokywdl=Dvx8)zeCM%DV;v#cYI<;OZH?d zEvXw8q*xPj>td z?Q`vj2OIgP7Nzwb$hQ5d#b|XrmtEHUw8!tWvX`O2oHDcbFKadYLOh`eKr0I#V!jX= z9L&GnR?GOv%+_AkDr;@tXD2U1-SaUszbl$WJ5_?ce?<%NsR2a{lUyFg!o$QGb4suc zS1<{6lwiMHK@F80z+PX0Icaz?w&SYS0@og#u7AYkx5mUZvZG1p?%n*2X=7C+i2}w zr(%tWE{T{bwUb5M6S^_XMr~$5b0Np{ z?QqI$H-n;pOECqksrYGienoc+EA@|FIM`t7E)?>4m!*2P*4d^Dq zo$to(-a)uVajeW;6!V>~tj%5RthER}acG|&pW|)NP58MbP>b>zulAWh1mYwRo(p1vkUCZ?@<@QoOuDVt&Z6~Q_@)Q0(4-s(Frf}MPbx!9@utlmGkTleCQr)@kraKwQa?WN7{64`Caz#Dg(cdwSL>=O(f zlRGfW6S()kL-Yao#_b+*zR;c-PjJP{?c1#MQ|*>kzXi*Fsx|iiAev_hx@tlk2EdfT z5Pg0MvCL)G@tM|Co8(~go@tZKb(+JzZyGHNVl?x3j^6LM!5Tf+7HCZjc8s1IZn5q! zv_%y!v{g%0FnjdsK|@u(?Id%$GxwJmHvKHLog_pX(w6mnsrAz$Z&G2DW~W|i?pn_# z?7~ZQ&xfMe>zCR(Ht>!1cM<1i30CiwHlgBIZG^G6u*G%=cQ~}h9S-&K-r;cZFLvw| zuBoZjhSks3VoD#y+|}q6k$2aHh$y=C{~XcO>ms645j>*8gB~NI7p+)SjEfn^Sj;9a_EckA0eWyxHyNlDJQgE`bG~7 z=tpq}fFW+bwp2H;`0r|I>M+l)HkgIF>PaGZ?=|F$7DxzIwx2QNlg$eju%zH7 z5XO23hv1D{?ChpUy4s|AQZOc+{E3M#`jx2$w^*R&Yr&t4bDq?|@n>dvYxu$vG-ic%`V(oM}OR8UJWL55A&QS2)75T6r>)Wct|N{85@b?eA+11 zZg5C)BWSsG7WW@#8A&`}S(u8uy6L{d*NSSYOyvywkvlA$rfL_cRfyW6MnY9+F^@Su z#60Q{%?HAb(@l{S$UTiDQ4@XWo|Y7`+(&h1F)kr1sKCACVfWZ~p3OpX=I!Tlqc)y3 zW$WGaaP7;M%;Bat)XXhec@vHZm3$wWgPDRdH=zy%fHj{|ESNdm7vct5eqRW`D7QFK zfjT}E{Un{XH$FlQI|>iLPc!_Gb{i_6P35yAd0O#9+uCe+7IR$eFVKtu?4U_+TxQOn z_;A{_3Sfw~Csd#$?ft76)=*|HqzBY^h^)pm9~A6vPAUyQd$Gh970pR^5f#peqS{;! zTMpe0GAI8&fORjV*VE=SWAh5>A!UyKfoRMBE82aH*||cxuisRJ?OBw;WPFiVXUy; zO#Av0`>C*A+3jc$T(S%60a~|atgO4yyvG;lI$2Vu-bWhb0rH;d?vw1_h-u&7?9NJc0RJmp8$s;FLd z@Z`o+W%TuK!%jZnjjvTu^ZmUMIV|B{RkY~uq93@z%X~4GsBrzrohB4hQt&QUBqVI^ zO^nG6cq48{jre>q;-L1Ci|k}ky}ov!5z8s6`!)O$(eh0*)M}Sg8d#|N4tDl#7a?BI z^}P5kCpfed)(kF4sdPiup_pDvD|3-eE2h^7`1@BRi9ZWkFLhFM3a&q5F((b{&khvR zYin0S+5KYr7h0``Y;kctT07T}{aIWe?DYZIBTZvibYiA!Ow*U<*^m0N9v*sU&9?zt z@1gh5>ViuTy;F~4|yMqIqtx`m);~DQjmyBy#-z}k6FJ4>u z8d-JO!V>y#TDN*^gjo*=YFv*ZC;c%c?DkI(ykli3H+;o2)7Vg#tuyPv+CL%e6g^Lc zuz$>YRj=ZRkGdyw@^0EyhNk6OkJa|nZ)&s7Gw+i6M(b$AOX}0oy429c$FitLkA*Cd zdkWkM_b-6Q6~GAvaB2aZRshqY7~=2hOyFPvg0lti)dKiI0qlZdPcY0DmD2yV?yO4{ z;K^&9`rf4A4OIV$&r6u+4DKmvDrgV&&FH4OUPmSTTq9qV)s!LVTBBE7#pi1(^Z`}l zD^3ay=r3>NuI4#gIc+Hr?}4CE?B}l{_9-=3VK04)?|9N&(FP8ZpJ)S~#<$hkk6!xl zN(V{lgeMtE)RO96gqDPUM&;_Pm$%+W_o?c_I-1de7&W+jSWgf~s6QSptz28|;^Ibb z6Wt_z(s`R%Ae;Vhw|0wC7ApK*7f2#723FHKPr$3hGetSQM9$T7^mgEAmF$TAZpp=65ux&4VwE zhn(sY&Zub(g#>X3`n%PKTtD72+PfSg9>tHMCh_mulHOuLQ2I00RAH}t^%h$9nyjgx z{zhBMD=d)pD5FCOtdicftp3VP+h2jjme<=@FL2fOh~qV$j+plN`Hp^e(ob{;%F_`? zC;99rp9ADGSw0_A*i90=!P8MF20s%J2L;~)K+jBaTt+`T@I!kWx?23P?-Lt+Qo`Op zf{r4r2xb5BdypYVh4QR+kbctIu%c-7yLlp}A=G@{g-eDjY>6+psz6S0a3a8$ z*vOwifAZ-g0k<&r=OEX@s4xi$5i6YL;?gdk!`1=>2Mge{1@KiTX8SAX$=*%56kvld z?+&@uuux&vv!Xs!dmYFQRn(7Y8v@vzN_xkRy~?B1NPQMrl-K)YigRlLfmEc&9KTyc zK|+W2D1IId5oe8Ik-|^cN9K1AVh@1@OQ;uiv7lhRQqiU)W$5rrnpnqReV|r6fNcxb z`)U6EtaN3)rS*G%5$oseVD!SkjvWZ$NzkULe#{WJNwp0F9ZAG46B0m*oseCO(Dqo2 z{j@#Z-O&_$!7w6}eB*mgOgcV@2mgz>I1xLiGWfvB*~)sDwxui|NX<*j<{3!mm1T{q z=#{jAWz*lQqBnKbss*rRRrLy`C;3q+rTEbrm%aI&L?f~cJ5d$U{O!$(RMTf@Lw#tK zuWBi8(1AnRbH}f##Ie{o%mmxu6Pt0E;4Lr9hQw(t*x_n=d2OVZSP9(x%d+aE0QsPY;DH>`VgC{@dR*}Up{ZLc_=f(wC9yl5eCq-J=t#x->84D(`+8hU`WaA~gP-O=vU zrM?F195bu&g}c*Wi?ovrV$YT(uF-aQk>f4noG&?M8je!Vl7KP|PlF+4v?!w=r?_IQ z$5SqHCxm^Kj{2We0$+x6cbVjwVOo)Hb#-y&LV@kOE?xJ~2_E{CPvYGmi#-%|`#C}w zUWgcKN($alTMOu6?}7!v86}_7Rv>(X%BVoerG))X zpOhI|s?6R#RNS2dd5(zM!f@I&vNoot2h-Vywe<##i)}(T?#5OYx-T%1ttYsbD zuhNI`igCrqqoS6hh)}PeQJge$y^E3o;iL_0S{=Q8ksqi`vBhO0J5@&yE!hjcw8b)I zALivb#t2X5Rab9VVl5?@64qxMilB*^^{A@{mFNr#i+x`Z(bXu$lIo%j{C$k2*VO~H zT_xFty80JIw(~rgqSmolA$qL=V>#dZD6>d&0Cp)`Y{@+-vwy=4A7OyHEf}>2zQUGm zMDI?twv{H%eu`<|S{{bqw(07DscYgJH}hO~cak0NtL0gVdU{#y=VGizJ^lCE^C;3h z8f@}&L}pI%z-&qBu9J^Y;aoAkDaPv6*8{vd!Ovn}N*s!t7L1w2*ns+a8J|KFiu5JO zs<#Z)sTfPGuTS*r+ybFel0A75V4B}7ijkuTS_%BU>qpI$~Q#6vA7tU-w^qlT#RjKsF!QqqZl!{?*TE1 z{U4ZSCFAQKNCT=$Gw!$aBK$1&9cS@C5ozWHU7*RK2ET{68HnfIP(7gO!G9))_l_6_UP2#T9qG4??tJ;3q+)2W21 zP|=gHqU&PbKaNKdA|n|_k=Xa~4D}Z8#1$=h6XRFuoftOsKxxRf{sE4{xgPan;V(XO)}ll{_O&#A7mvGRQ7CSkLCrlzJ9s%bM#= zI}zp3mrQ;3o+L)J*db?4gJS*BT{EI!u0XhS%8=sZd?!H$0pQ9Mo0iv zZ`cZQ$TTg$gST?{$xj6ID@O$A;rN*yBV0r}*$5>=Uygf*@0A)gbF!INEB&mtL1Q;t>9u@QcaXf2dJAI?Kd6Dd%qERh z57)a_SR8_=u!AX9wWsyp$@WAeNBHY(wmMv2Ua|*Gpb*D6ei+zTmdz{?dV;mvn`~Y- z3n)fDA* z9#2PDEdiF*WHqAnkizeyhcUulu>nzfQ_tBvoo>NBsrb8_T-l*G-QPVlo7Q>oo!tj< zdRcZWN-x*L_hoj@ep0*+;NAuoW8Mou>e3GA1g8;n4boi>xDy<~A^8>}_#PluJarem zcNXs+Fp3&&UM!2#eZBcdZNJQ>3`<7lxp79k*r#pvNGa_j4V1@U=KL3~)9_OOkuc*4U4O?yH-lfsDj zF=v4#7xzq+2G?Z4n*N9#X|K2Sezfslv3Widu{G>~*gk$NxS05uecb`vO#FwP?4Y;z ze*V?J!nr*a;lg7OZtf!Cf)7 zh|VxUybPw6EvyWD9L0uqrs&aQOTgP7hG$-TPEDs|PvitOdg zVP7rF>86))7w1IX?y`@%>eb96xTkDlGas-+T_Hf_c{D4v&+oID-4N~l+bpdcM(6?e z**?OXZ?mg}E8J(VyXlp@M`1^q;|#87m9qm3>eJI$qwZ*@jndfk?s_Zj@oKiWJ7zgY zSF^j_^(rNb-pj-OYj&_Jw7jgxtW^)arMB8Z4X-p!AdFde^Uy6JIv;kR2O=y-L;)pS z^7>ce@pyS-<$`u(Q1?|vya&nF9*1(V85F%2t;QN7@8pSo|0ACL5?deThTr~(-HroK zk8klnXsa&91!UJ*^u0tN_YNYEStRsvPraPa$XlQz38q0K7R%g5FGqIHvUhZUcD<+0 zw9*bXy_bGjYhbYV-qp`*{cf?k@97PS5C23-z`>hr%zOIa;6|9Gl6)p0c_qVPpOW13 zZQ2&YxR%Y%j>DHLyn5@lQqM76jY(M>oCb1I!0KKT?cr2!w1=%U87$BqvT>x3+QX)+ z)E>&Q*gpCq-*m3Z7ibhWuLzke(HD(k_cbbr|7sMUO5dx*#lITG%xmoPzL2$k*Vuu+ zsFhaN*pq+Zop;R6gtULeC@lstpxHg@mV z)6l!x8@<7!-VdbNg&VUU;!}NQPudu654#5sY{Tgm9ANxTaZUO;J15aC*fkO-BaB_= zvUC2Si_ty*G53Z#HN;%kH2*ppP2vT_Za3{hU@W8BOk40WoNXJa*Jw2rdy_0Fd-Hhx9;1jW{I0T9o zZD_M>ibpY=L^J;Ug}pOMA5*Cwl@J;VDNuWa{ixAGBqbY4h>?AkT_2_I@ZCt255lb= zbhe_9vuyKdeR$v_c*dk`52hYm#S%7;n#eQbD>i<-?#nui(c@e{U{}YZ-|Bsi?Vk!! zZh4Mf9RpD=cW&8O^pda6vPxt1VDDdWM|liNI0$)i#im2>>@$b;9;=u2?}1CSbMpg_ zTXQIt9OJX|Y|&VKfX^xjjG86Rk*3_L{CgMe-STalEU` zeyCn9#=0LMN_08RXSgX0KKscB9xg_$A35naa4^!&u+0eo^c3BWp5Azom^n#VSnJ!@SQ}sY;WA$x8H%Udy~9FAA*XFlu$t5KGTOxq)^?iyjM_RLP}1B0ekAZc{T!4oE#>o- zdH*T79G@_qX(q$X~#qpJVGV(ki!C?8kPL5vCZE+jR5yvg*S|1LMmyelkw%)pR z#J+6INRPpg)$Sy8*p$(9#t$|~lV2CeqAd%^#h8IR46spba3&RNO{^v-95@h!8HBl7 zqY6JTk3_v%Ghg_bOU4IJHCGGshY`=|2gH!oSHIL}yEGkL= zsag_GaBc7?vNn`l8@!yJ)hefub9Jo$aTqoxlZ7Yi-rAH*7MHBo)pj0b^OE(o6%J+) z8OB;ne85}fG{T5wFEC;maD;W7gL!DyE>?c7KDg|>T`298RO+8B{9Cxuwwrt{;22vq zSNF5_I7S|M&Kz`y1C*H{BI+gHL+HJacn_!d0pguEk-_4K*EMA z?zW@jU+9sV)3;m(yiX0WInD@#80!X#nR^gf2Jqd`cubkAzcJ3FgKzA@cDj0!>+WT=nkeRZF5W-GJ(?-IGTZnE&m=S^Ry3;r`4E{BavOzXXm}VbjD{ZiS ztU1D7+4S~W<_^~GBYl6-!aK6LJt6B5Gu!ph&KLS185BYY?Nme|H0H@Rw{I8AVpIBy za^TnN@Nx*J9H(uka-ef~s(6CP*|wc6wd*y@Z-TdD_I*(bJLU5ze;#ohzt67N^(NLQ z-;qCd)?^yZMo=n&{=F#sVP1I9<*D9eLM)F@3hgKB34!wna)6ssc2VFI3oc>q59@Ps z8n+RqRHKL8<7+A-Dn@)aAjM+`7V9iFcjHNS@-(f2rzNFNDqA*RFBR$5BM0+u(hfJ` z&0^;rFr@=NTn((8{8>crRwFSjM1Wm^~M70m5$ z&u~JRg#wzBKJaB%7wBFrBt)e>@cv zh9pysitrTd9p_}p%aKETa0GpcVvofs_L9MYVy`JmRIt|{A?V8KaJFlKUWR3*=!J?5 zq44IU5W!{f8d!7{#roh|R&Igr-}A2nd0D;JRih;#*0d*6S_xqn zVslyjuDdGL@m{&5+MR7!2*zi}vP%o~${xkH3L%6>Q*uA^NW~r}&nV&()8IW+ix-U%ANKx&qeyahMjTA z4LZlfHc|-QNPFz?fU`vF!*BH`2dN6ZctXI?OcVaac>p}h{F^0w1 z!%9(oU?EekkHpw(yYFQ~7VAr!Rp^yBiR29;r3R2gN{QCI@cFCe9eGL~*Z}90<3TKL ziC)pYvM05!H!-Z=$NK)JIdLMka2}1~yCg&{Pi$pkcx*bfJr$cT>#;Ms+DM2kc2nk@-XgPHD{ySNf<*-jQ*~xk=*FzdCLj%bZ?G_Yio@mq2g(2Er znC&?8wVf?mp;uv7mLt~5?bt1fb>R+Hcm>vUC+uLgR_OH`?uRT>tXD<3|B6vh#CnfP z>k67WVjW+YVvQ1|^+zAhtotu;ObA=mmK|83SMaE{&e{IzZD;pZ=)NTnHk18?Xn(z0 zvAUn=-lo)WBa6TK6?xK%H_10!SnMadSFh)QDEGioU3mF>_s0`m1DrheeJiS@JDiLV z9*nb`5Ox@?98`RGSPd~jrC@l7Lh&j|TNKCkeWKUU;-i@36ZCO!){>793olD+;EpMkqX#c%JPimEjALs@~DG>p;~TlcN<5Mi%x+2ECW?W!NG0VQ7) zM=IEAOQ#R%6I`L>u;KB@Ac5ZCKOK^tRd`t=X*4uvchd zYj&ERty?qyRq)S_U;|dce|rS`Y8BjvMzE*!EE~bvtkzp=7sA+b(let~I!n_}yIXB*IL|GPr5JYz z_snwQON58scjA+T1Mo$6K~J@?i=6(vBjWpd-WzL|8_FmlkoR9oY+G62bIAbqY2>(kGVe<5(jQTTQq{naXoiT;NoT9 zcaYqRll%5ZM6BFtbT=N)g?s9gyzZo+7=Mua-duMYYmd)m85{M6R(PR|ktDT#BZ(;8 zcscW!DXZhit)3`*&|M_D-sCnSmk#bUS{ae#{y{#@63D$4xrgV=3G$F*cv1R}QTaTM zlSlR(xX0y7U@E!aAa}~Tv1bW{7}GvKnu_CDRX(T4XAAi(2SW$>zbl`^<+C^Uw;pi> zNy3uSV~Bi`<$?lElh1L|{X_YjFQ1>v=TJ#EN&&%9r1X3hAR?fga$d8e^6F~LlgT+EsAabkM5J(~2;W zV$+kK>K;?!-55q*u7|TE8e;^aG0o={E=RkA)ABeFrb(Jkpe~=22K^`U$%o!ti3TnO0*I=eViBV=)eK93uT&N?c3e zU&AD>25dzHp)I6C6+uv5;UIz2n@WF)S2vNkg7BYP0FPC;qVSJXxV*qj;eaUm7Maat zRSsnYL8i(62;Ahre9TpFG+-L zCZ_Nsfe+xeG|s?Xfrl!5L*UK|UzJ!f@Vmfqszfge?5i^TvsF0U3Y7_*l@TZgP79m~ zb&4}^O5iOD{~+)}6=8q1rC+0fl9J>lKy^D1U3%37LQ*kU3c0TrzM(CdiBUJycHj5Lddz7&jQozSM4N ziSnja@;lm)Y$XiAc!_-~!m|h&-zNgc32aRXlMYptl*<5Fs!msm0KY1nCa_Z`)(X5{ z`AZzyNG2$8d4<0a^b4V?=KN$uJ6m!btL13gWw2wl)%n9A1?is6ia`m@HpW=Md8r`m*+V|d=g(# zGB!f^XF`Uooa4d5!P(KgFYpyrq!K%eT+%y*YJi~6Qc~Yf;JA9S3Wf+gm&+KH=p?-H z61C z1kY3g691}-Ok%Ub0|ouBiUEnoDlAJZRAE^{XH>IQRcuubBt0mYGpZR*6*yDX>2!ge zb)Fz_Kjoh!a65$)1$K5+a|O;)9aplz)@Q2O%@Yne3V$T<6@?ed2vi*}5I9re6oI!W zyhz|Ug_jE4O5qh8TTNA!!x}+QSK-wH7gk-f>?h7NmQ}V~_%BqLdK{EszxvXDiNKjS zBFJSZRp2;uUmVXTY_*vRD+gHu={Sxe70v`5A@B zAUuu#R^>2KL|9khVFF)KIgriHNiT)WNiU_^N#9$9U#P;XW~ng3^YPzTImiTltu0Gn zsEA;S!jd6hg=I&QQ%lmz4BS#!c06YkrW_-~=?agF6yyJDYpg_jAORYP(tTfwgi%hBRc%i~+0#A|H8uo>7 z=%)zQ3fxZNF9oiv@OpuL72YUtPIbxPHv->MSSl!IIHtaTFgD#eM^n^4?Q!@A-5&M* z?Q{En>Th^6{8&V2RSJp3{Zzjo@oLo%$d1UV70W7Ur8+WMMVY*xpz&W;fmwCEvZr!( zOtND+qqUEtLU|1EHw z!iK<^3f~c!DSThxp$b0~xNcQftKj&FaG0V9UI^Sy;nxEDD(osI5@)K&9LtGCmcoUF zf2P941m2>sS>U-<)c7wQo+*vRM@FEAOH7rh=NhXN2su-FrlefbuUELVppR47Q{ci1 z%bC;`t8yqV2>K~3r&4BxN}!4G z_f-kV>3Ct4Kr7*&rCNza;KC{coe5+7cec|Wg5Z`4&`01i3a^{MW#Ed!al$`NDI7fo zZl(NJ3Hk%7S+|$;s^{zmOymDh6`;EyNLRyaUxDW;|Na6y`-#By4t0P z$=TJ4o^}qhPd)8MVbHL?LjMzvaJ=J?3^)^zIhw1gK$ehIGzDlUymGl1`CDk&=&So-DM3ANYhYS2n;c)_AQFyAraY{yJ3EWR%?1-Rd+)Ck( zt->KxIV=|VmWq%G?3C)y1a_)iYXr`!C_AEc0-vcM@kW8u75+xx)e2j`6%KQi!*+qk zD!fbJIEB9#xRt^O1g@&^UV(FhBm;W{zNK)wz-J`3hV2jz>55>Rz^fJBD)3x|w@7-` zl}fx?;mwl103NHbEP*(IG5?nitrWo~5kb`g*sQQ*$f=OX3^)~%-6FhGA=xjmQz1Dl zuuw>7{Ld5)=}Ib33cOn3vjWdm_(y@AU9+Tj3Z;ziSJg_63i<;I9~5{!;dV6s?-LFS z6@lb1voh5owc{Ol%h!&vh*t*o3|jDRh_zi)BldZQUbe(T^aNPD!*-bW9NyE|4;gx> zPq+FI`ApL+c+nr)xy^L8CiBVE%NOZa0`w`SDp9OuCYGV+)MWiLu?O-*B>ON^_b zGGA@v2j+2k;4|a!WVQ(&)^!+;jac~75}ZAfu8ACT82@K&-uuy64KcqDbiuR=@AzPr zIjLg+Y{&~b2jWUO(@Z!LE19OT&bI;1x312&DCZmLJrp7l*7l?kI6-2~GzB?*OF4aY zb5eJn#48k}NaCLJ?TYj5oP0}s>1Ix@1DoJO?+cczWZUWMH8Kck1PIa>Lp`cWUi)GMST}Al*z;P3e?rO2(TTVx{d#FR(mE z&ysX$v#A4oP|e|xlh8JzpSFgz#vAI=5 zCyQ9(zG@;P+rdsHwo;7SDt}oe846D!hM=@=Rtkz$a9Br)(p-T{C@iZaLsW^)6j)w} zQb#PSN7}tlqX&sfK5tH2#wN(UDMTGYio+R)pg=JB8Qdm~qo3b(i z>AzWF8GekyGX6Sc)udIGfFhVJ66~a~%uzXo=L`QgWn_Yj1U{|sGJ!WM>@kE3?`2g5 z$-;kGB{gZ41Phcf28sapl`zTne^X&uhnE$W?YWLhaE?e|vPw|O&P^4+%s^W!WQYsN zLJ^>)!c20gTEiCtFHq9EQDViwR)Kq{=C)hl%Sw2U2>hXviIW0bJE;!lH{no6;Xeg- zHpeRhpB4$)O!ttrNV~`HU@$8A2MjYNF7>BC#xrzD&{t6j{x0wwB{P3>Y&Er2Mf8^- zn5-DMCh$5X)i(rws^}$Nrg}U>_-^F@QoFN?!y1RDuH4G?^M_fOq14C%Au4XSf{X$zzY;EBk(eX z0|j>0X$67XD*q}1*HO5-z)w{b)Rso;%gP}{5I8%Eh60~f{-FY2P`J6k`xR~_u(OUM z1suQ;SSPhT~0Z45(HHgmWx#-6z(qkeH88`u(RXoBXEZ5C*Bv>*%1vEc(U>z zZWRuFm4jSN8lvzx;qUB-CJNj``AaK#ONHgyQXz$t7vxfqv!k-grIiJWV3kZz z;SB<>Q&?I=hbX*P_*YT*xWIiC{#oF13SSjibyU`{yTakL8djeRd|6>>4_u|Nrc2>l%45B)brIJ8v(q-A7(Y1wYy7ykEEPc}&4F(sw{ z5P>@>JWSv^3Xc%DgucZa&LGUkf9bHwM+U&Xq`Zg}P7!#F!l?oeQHF{o0(VkaT3(ik60@1U#7m^z z)EHfN6d9}z3T1apKlDGmuTH@m>SVJTJiZioh{DqN)K=jg!vBKmYTF40oK@6b;5w?O zl=wp>Gtt6-ftMQpr9pABmn?yqB7q(XFBN#5=xS}I6uj8O1|ojC6zQN)xJn^bo*jP? z{VvrJ2ML^}a7BR)L?ZGpw-cRJJ$YS05UUC_RNxIt1ltJgsq)`J;IpcumBzbpm0xN6 zYof3e>DV$V|I!#|Q3T^fgw+(DA+U?WQlvapn~^nsRgHC@2>RoypIj?&n!?ghG}YfK z3tZaD`YVFYeYr#oQ&`&8VilHlmR+imO3P4xg^$YwOUd}p3!I>^Gz1;Dsz&#dAlRUa z{Gz~?5;B6z0;hUNd_&+6g>MU7P0>FTcvo>r|4iV6stU6OwmR!nZ_9J+#O?x5RXHvq zaH`6o#7(?q0)>Ttn!+;tI5iST`l-s_gVS407D0f$Yk09YT7&|~V^(+yHn~i{7W|e~ zO;F-@mB_k?_FwIaB>?22~;ovkhLDKdT601>UQ0SAiQUfgB)klB)mF z0xwZbb~?va(|qNSBnU<+JYV2$3Kx5i7vU(?$;^`UN+1^$z^~rr^pVPcp75`w@KVCi ze`A!x8bQ!d;Y%U{FNGfoyhP{t13gF$qr2igO1P28{jH;5a zB?Af{5xAj}fz5)xmcrX5R!vsXt4>E|C_v%WZN;XIKh(gQCL%bc>P+HIs!nB&mMFYI zGOX~|0y||uGU%oJ_X_{w3ZH0e<#lvd^-`w=!Osex7kID27X)6b@C`|?82(4nD~$U) zX<%Qgu)Dx93VT|GLqp}@Cvbqm0Rqog304p|Ug63D_g1*3z@rqdFK{=7Lj?|2*xE`s zoKjT~A+f5%HUb}2LfBd0Y}JkS7I>xdA1-i`!s7+*t?&o=u{A77I5?Zhe1U^ifJFjt zQq6Fsz&|UYTPJX~%D}e*-*A`x==TDjQaD54?E*vpJtrLgPz09*KC19dfj24qP~asB zzZQ6g!YCRHW91m3F@@SXz46u=D&;D7?y4Or-Z zGQzuRFp3iqE-5DKu&cn%2s;bxjIe{i6d@lwV+6jT;_D>vDTQT*wwsmy*If{-R0KT= zM9^2@qso7fz=H~4XZQiaf0XdInO;FS?A~EeA8`eHIO_Zz5D=?oP4@9Mz7tY5_;(%Trae3R2d0YrzA0G7a=9YF--7;+Kb=|*u z{l3{bO#_R=!-^}pvy6(sSVqf2i=scf=^EaOnXdS;@2=~0YwVQnIAgp8uLlBWQ}o>+ z9F~Em&)|}L&{_d0edNcA|D{(h@~RIVOfdEKW6l23%UcqWXMTwNsB!UK_@oTOQMoK* zFQ+=h&$Z&lBYx>+rctOjg*}AW+z>I2?*EAsBS&0ukFPKL{4c$Xbu)yX*fb~I#BZkQ z6NxiT^YKQ1nWhh&Z{y@!z4JEjL3qzJ^>F%GoNvvXZ!~g=ILbNSJe_ZvFT{iX9Dm%P z(=?cv)B0LC!epB2fJ`v4}V{}XPT}$ z-_9%ApK#I)C64l^A}5?Zyudwa$jS?ePC&?fc`RD!Tt? zmwN$4VO3Q8y(lLBUKI_?3Jn!Y6P1d}6bp;;*J@~J)^2GhoO9grWcj@>);`>@N*7wg07E)0yI`Fll^)p%Kx6^Ls4x0SIVW^?z2ZR?2l z&#RlPTe20Nj^v}aUopSQYQf+BtD3B$q9)6Szs7A%)(dFMe{%i=!|eDFgL(HiStsT4 z2}YNWcR$!?zzhMV`uek<{%)hrT%_wup`pJe@dZ!pe_da-m@oKos zkeAIeKEt&i`P*!xI(&{TTxM-E2g;8!j81q<0R84!C%lI1;{vGJO{UB?{w2RL!u!c( zXNC`rqiGcSw#5qKPkh&672x}?DLA%G3TD8B^gZSfTh~g`1@iGKglf!&!XHjq z`*585>nZCfXgN`j5Wj)ebP}TTZ>Ov#(9xit&O*!vE$S*n0jSYUhz`G>vJQiG0`)?b zZlH_titt{bbNdRB2bzS1^+nKKpr3&D?vL}81{_ol6e70alod=A!u!W5YyDs$Qa~F) zU;guyRWL+|uR(K$qT~OZvZ_JXfEEoC;?uvNz;GchIC;v-09^rE0eZE*jGr^f%CY(1e&KYx^Wv4w{HeRtTC8 zx(~Dt^eE^sB-9Qb@PV%F1o@yPp#EtvxHD2m;e|pR!9m6hA+~mb#h|-EcU=U9x0?AsCSMKC;K#6;$n<_U&sMn2s#1Vu=Dyg zS>>QT63`BNW)PuK(l!GRK8snO*WYApD>7bRMS)fU0qCdiu14w5$C`rbc zfYyLkgEoL315G^}0x=6>CqQG+2GDfSr1LNopfxiw_MOn-ETlouqjQke=`%9>T>3m0 zF#%eFY+nT00J@9nk+nmh83Cl}W5fWO&>0a-{wJpvE-_ zo-Xi64mt#_xxUFN1T9&LA*9bM5fgZ?Oy!M`1DdcJ27<0%gP{a12WcFX-xDr72F;1$g`=sU4JY9;(3(@w z7_`s=j_0k8;uk75c%440m)n6ar1c%GJS(cA&|iskx{J%~;uN6$Nl`^u}iEDCqjUW=q6Fz-s)A zIB5BrW-AZWSlet>f@a^`Y)$A79Bb`b(1bvmXFxOVZ?+E8=LegudeBNx;|$0FjRVct-W;%o;h<(aTuc?9 z8KBt@VQdKpT?-ofFkB9r3R(i13t9nM4!R$-2DA<|;SqRn5EKIK4O&?YmxE?w;a?A0 z2s#XFOgY{RfQCS0-$Okb82b@Spp~GhSd1D#GeMI+ zY_`fkQ$hFB=Z|0+7N?|x_+>HBT+m|Bj2gHcG#fM(i&knK6a;@p00%xCWP=J+G=L_6 zmVDK0?E{THiqBZha=&f1{Gc_*;8LQ;n=KDkwWFX3pd~-RLeQFDFq9)92V3-9(ClAf z2x#taaJ>(THDIVf8%{M_>7apJSBrH52PL3l6kHS0V&#Dv?OUu``V1O58X8BpSR0AP zfo}{t2JH=+)T6~p2F(D?09_C22Q2|z51QSp#cBkt1WianyWTCBI;OG`BF&PcdYO#tzbI)n9jPdw9xy7m^!JxIE z4WK7LjVVwJaD+743MJfc|4n|OVMM~UcCGEdip&BlSkV2T37~bL>p>eq3qg-UUT!IZ@j}f1 znw`)L0+OD_v;$qg3yh!{c)5vh1_bSfV9-j?%!|;$^H6XmK7(!q%`JyT>F^wA7HG+f zuoyJ;gBB}i78C?s51MoUu?1TAF@|I|-Ys|GXy^cZNvaRlWY2>tI!}Wg4N(Rl&wX96ga?m``^@V77x!irV(chIP4_s|@cUONQf4JH>!<8>PWgFcG z`_5>x77A57Ao=*)2+U}OZ6{pL$~L;3Q;DkVR#lZa_6};Yki_glB5LtB7uZq-i8#;` z_^XhQW*fcShZE&%*+yUYi9~sXXj7tW$;Q<=Lv~$g3~~*V=PU$Q-B5Y?LTJ5R-n`J5 z8eWJKnMXV_`Z{BP{Ar;vAik>Zl!Xk5vqS&7h&#eJnwyM!@J?Mp3aoVtQ6)!RV{~y9 z%E{LlBfAz(YO>ypAaGG~?jDD^xx$_#M*Ez=YCJTAUE+iu%4Ci;iUTuXX z13Lk1Yb$Izux`?IEqs$bqsc<g<2+ZDJb+HR88}h;+OEfmGiWLXs&1A%d987lyJ5B*mt&mk zN|h^fj0;`K@{Js0sw*VhU58I4^5W}^vt5~TGksbtzl1AYrP6ghd{80duQvv`8?KR4 zt~dI2HLh*4uH`wa7T%l_=XSHhM*@zrD%&q`i>yZ#VkO8H+LEv2x{NXSuflG}W+>d=OA6SaY6#3Fp zV+^9_r=>8@BgZc@di5#)5ZCeGLTtWL+*8^|M^1?n6utYRgea2Bml@Zh-RH}UsS&kx zP4qr-8F&(xl&1QP!LBs9+;0pB&&3ZRc)C&G#miTKpOb{sr}pd|8qw5_Lim80t*}gB z!+>$b*+ID&SfY$y4)-Lx#0%5&?k4^VC;2GkPC7#l*#heT;o!gTYgTTJo2wx1ff@sUug{On?0x5+DsCs zMhD&Q^>FOOD3ZOu6D|kOkt0?aXUTmljYwCyd~2m~VV}lJ{+U0oGbXDXz6!d)-K&f- z;YpX_=kZ*4t+>%!zP-vA0yTbJWnAjsb3k5jBXso2>u!V|Q1wRWkvsRF@dliVkk%H6AtA#UF?xqG=W!p!W3YfG}@8YtqE z%q5)OcwW?}BRXWbO z$G5^F5t3_x;T+8_B%(L4B6$EJhLocUTlUjcsi>+0M#-28(M(_`Zj{k$G0wf^@U`$q zNKONZSdSC>M@%(4!>2_TyWKy?&1>P3TDfPf(PeOMakGWh&Mwq(LJwTX1-6zkN@B^t zkR8?-+#&)1Wu#xC|HoS&bT9NBSjCK zElP2)_VH#5*+LlMs85adOpA`BeX>Z!koe_a0pr4`*pg=JB+{tym`~0O8k3_|K*?p) z=0=}TmbNwnefH8Fc8^-J zv-@BKN}Eq-RxcXm0h=p_-->itC1>3Vr^SJTerMcxX(Wx&0QvB(#u0C!XI%;wNjOJ@>dLM#tR|HZj_}&Pa{Ux+OYiYP5e=bl&9X zpzF%$tgz0m_R-!c(Q#O|Cq+k2j-vQ%f}Ho@&0HKCA3=`t=G8C(p@qNRSObn>Xf7xJ z?*#)|-$5O%3qv1asgOwmCsMj3_fH4^&(82{Qv&fj6@rw`L0!|{X6s7w`)zW{I>YN; z>5?wL5!=~|`ZCl%hqm9~*a*mb)*0O{r;BFwFJr8LiOguvI`@Uq-qq2GQ=@&eqLU{_ zr(7BBb*I}3OnVb76i)eQv+osT6l#N#g1_E~tqNfKaBTF3URTK$$e%hXYL(-Wsc(Lm z7VTR{!>2+i3vIrGK9moQ??=Ensx}9o*Pgv zL0OyGH5d3sFBA#Muh$!w1jxaQk(Kk_Xtownn|QRb9XyR33>)1SwDPYV-`l}I4t?Ns zNf^z;l~QnU3O-k$ZaZYTXt0i>4zkv{r@}+I?QIvGA9aH|m>!kUJ~}|dc41Vif-Xc5 zl0r=olJhUz7$YIOm5|dT?hoto_lQrnM|>FET<=VQO{9>29gR4RL{&T#dLI`6;Uy|r z_?rvD*?M#ni_tNH z)J=UG-%@wk{c$Iyy4f0tV=C$RYec*4z#=g=#w^+QPMjzFBsXtB61(C~quuD~*o$=d z;FMKM=H5Ge7bU<7Xabn>jC|uvS64YN-{?6e3spTGag`82;==DRH>y(r zI=dF@!Bh4{v(*gIM(HrMv3oz?h`*`^HT5u}oI0bhimnT5oib=<<|SbNjVp%5IJP&B zYp}(8yIBHjhx`uD%MRyt9&YO-HX#^h`XvE=v&W+^!W8mxX z-QT+ha{gNI#{qkRoZB!|-n$5Hf9Wn`!efHDA;9-P+`%k|OT zYEYoMr_KSVye#OM{38lAi@A~m|e<$hEi zSY>n_KPAcw-Vk_$nDwvY*cdnj#uc=Q(iGrF!6R^~w>P<_+YsB?7o{SO!s;+*6R|EJ zZDXB4@=t^J?fpq2mdRSkwTI!W!I0}j@g{c$c+yb650{I(kdE&TmNzXndS{-^;wDAM zO|iwzjB;;QJpfWYOr#zte7qRV%9s}GV;qYaNJR^yBQJ^e+8&^L%lYtNC56Yl!SddX z#>D6jF&LxHxPU}pKY3)M(KnFgUf4d`H_j?DNSC@E3Gxv41zxu+SS6*yO$- zI&LE^g?B(=;yN=mI^CVEIUzO59gx<6M|i=Sj&q^e5M|r?6p3oPdxRv> zfZ$BWa9}@e7s4Vj8|MOpWp<%%w?kGYup~0&amd23-RqttAK78V$*T*Dfn(~y5nat0 zb}9ANc0wmZN-WN{ycoPaU{wzPPnZhCk6i%qSE4SZJM(`&NG{rJ3?C=DAR##op8mT5*}5HBu@MdWMz`?&I8KX`KWsMoM*AU$?wLFf9^-u3?LMP_pct4JvM(TPFv(6oy_`pD?54`0j~nsv z)SwcTb*QwjNZ~Uzs0G%cXN$E&#&0rWWydW>ul{t$DHRw-%Py4KN{}DZfzf8g7%5k6 zF(!?sJImb=JO+8bBl2N%S$OL;Di!VMrt@0d^NFGq=8`{bG0qy21#CCkQUAt4ECta8 zX6u#FNBBrMEkRyXXp9(=jN|RNU*rd_*0O2XN6lB89Hb@0gP04RoFv(IlhOY?vNa!{ z_o2;m)CL8ritWTRutl8_B5}<_dQSnKgfpB1;LFL5h=F!WOdL+rFE!eGIyvF0jGf~0 zz&$;w#X5qP#ybh}*+OGtOclVx05_1CHzi1mz&Om9VP~{hQ)xn6ksxPoHO3Fg0{FF) z_lIMJrM%y2TL45DqcFmW^0}=>|L|crj!Tq>=$M{g@!H3IrFWZQgs%mVm?(#AGkS(^ z$8mC^ynv4P;W&+t592s9QEni-3CB5!@~LeQmM|I%R-*iPn=vG&1~FZbh#Ozw==}Zu zGUhs5U>Yiofia0lqKA+SOUO3|`^)*#=o&K}VDg9->ly+->aR8d_e-PS$O6=KL&~E) zma!8vhW5+$9%_@DhPw>)sUusgnbdM~fBC&M2FDx&coHswa>7{BU-m09x}Ldl3``r_ zV&P=eE;Ojcz>g-@$#1<e2&6Gvx*@Uv>7F-5G!%O4k zP4^qahXw%}Xoxv3j3Lx8%bw}fU_0tc$K(DGHRu*E4^o3#fHlre`?&XX17s9IPc@XC zg_%PQKEZH2V8jni=nc?m@H{n8i7g!sQc#zBHf|EqAU@)iH$GrY9#aS~2Mzort~I106|29_}C?{OsTC@?QDn#?Exo3Rn#1b_n+Xk#7DL_7ndPN`61 zFR*N2bY4e=uq0sqRv1EDqybwC%)VZp8tr$_!j2iINmQ4OI`8?o*#j?#)Yxc$*!4&O z*iTbs5S2$$<%sRb_jLC-ak9K%yU{m1gyZtba_M$sNY8pYo{DWJ2|%Giq$kFTr^x3} zA4tM+Fs;Qx7P1Q|nFee-Fm7TiJ{MRKFr<>xe12esz_7hKjjab(0PMgJR%glP6!Yd3#?x2JQ3Il zV52aib|J(0h<6Un_RXc+P5Y;G9%iT9vzt( z?W5Q!LjA@ITC5%RFk*Ll7Y6bCsGHi$%O1v4u9c|v;FkYCHIGB{qo~iCfqESCdDB&h zWP4!5Sr}l{T~2iR1MzXsESOG9v3#d>eCC3Y~3)m;L!gTH}mpx*{2XX)ot2$+E z2LnJgNpYr5qiLKC=Vko8iUYE(=nXvW%C;fr1C|P`^%+wtwFlOo8lsTQOkfj$WfE|G z^jW9Rko>4v--?;6SP!gj&fguS04oA^7+5cP>q6`b7Zl^>#bIC-7t0OBM$dLlI4-@U z#cHAYE;3YXq=wI(0Bo*o|EMt~CJ~vSDU(yx#6JGE+ z=k4}I!eQs2gSqnD$BZd`^Kd-jvKDI{c!hgfZ=JICg3*{0Cx5&iOYY;?s)hGH58Y?U_t30=29EcDi@FnZ8IZ4w+Tu|cd%Nsg zLgI0}_;z_o2~Mc#^fx=J#Tt!iW6bZat`qMpF$RpGhpJ9ip0XBUZWwdALn1a_t?oPpkFsSahyD+8sHGjJ9LA! z8LLiob(;&i_WBJTA09lp(gmKEy2}4Ni3yv49NO{@?@6{%L$yP|)D@xgF$sg5dT@<< zDU!%VQHW2}(R`wZeb*m8WnF_~Dqj3G01IKX>~yw(t_@Dd)_69y#^>Aj5oyxKVIa!T zrzz+x2Xh0SvR6EMZ%V_Ra(AiGZNPLK(@!}?ppFU!SRIt5XKFses$+Z;E59$rW{sYE z8wY6*l0SxamHl=aU9Y3pd6aJZJ6Djp)xhXEmDVf7QDDUyMsM!eu3;S}BUQA*DE#Sl z2<7sjoksV-1ROSoTWwa&bYKk{mJO_4!}5Tg0Oq7MQgtJ+V;WWr?5Kv(>jvt=tw5VR zN$(6e490d4M1=$%23Fe&qhY8ARs)Q4=jqf*4<_}FXsb|fU~wAe0~Tvz)B}nSf2jcd zTjjr=GDZaG38vo=l<`yV3ut)nAo8Q|g$bY2P zZFkLNa#b4E-UvD68Dq$qjX3TQX(`vEjz*}%G;9-FVbo(WLQIF~tE>i9`7LK9w%WY^#kBS(7p<#z`4|;TO4BuqlW852tHX;!`b3Z+0%_IkY*+q_g z))*L=3vkuPr>xG@@NNVIUBJPJ()?`1D9=5lPW|W>-C{d&sf&`a7b2M=%zB`mm`Q0W ztl5n%(wq25ZIh_J9lmmgV^#0|fT}4_(ovVt9=}DX8I2j}E2wS$nBc3t=pCOdRfM{xnQ{*T+0LO#IZ>ylprhA~)|HE}o7z{}?9L_c!kxF8)Kem%dIQ z`0$`jm@In-n_uo-yT=&m3Lv4ykN5%Dmu~Z8Lp%`%*0L}YA$*&G!#54{YeRs^=ml4U zMvZ+M%=d%YZNq)Q1bE_QpbxmrPr}9PE^zL5n;(RWQj&Hw%zQOmJV(-gH_W%fMUjca z&rS1%aPgCujvGz$nQ)R~ddnf4dfDs(zTIV(%cAFv3j>j7ne)W?xI2wHV=}6Ux!g5I zF+WbsM_uNNVRk*MbWT491A{k!F63_&(AsjuB6^1N?KKor!C?Pq)YM5A98St7B6Xy1t`>SrjAob(kZ> z`yI`S7;&;A7~aK5McexI{~V(PMc279fJ4bplz59&t#+9eQ6lIb09U)sswh$CK3|CE z!_4|9@m1JFd~3!q%c4XJY5F#FjG88%BlUg{H*v$GG$KZbS0l{QDDh(ivdLGGW?huH zgA{$Iomm?t>gjM#d$Tc0)RM~gN14G6wnpAZzjGDF^ ztNaULW}!Wp29JYzfV!ai;dh5sgyBoj_z2*^fv(>7kvnd6o4>imlWw!#?b;q@z8NN7 zBNluIn)s-t=Pu&=(PcgtCSImGU^8~RGC%i--EQ+8k7#t8`#s`z3Z{1uSRPS}kn)Ja z@XL;P#O4U|Umo#Ag!zO=d>2W$)$Xzyj|fJYuX@CLQRYKH5W+sRUTl8j7F%8BDpBDw z1N#k8=Q59kiEU)U3vP2co{uAr&0!|$Fi*a9iI2jF!wSO?LQ2jcaAujm#E7p*=U3e3 ze_}+7+x$L891Ala@lfbtNi)qmJ)(sU_k^2PjChD{V}281N{@Ig()>4CV-U|0W$n$+ zV#JR$ie*vey&kcp0}g9Cm>LAIZ%x8QWyy%f^zun_o68!(B5_-uJq3y*p>%-j>&mmm{99J9DEe zP`tq&dJ&}c38kK?|1R}8o$IsiQJ;NG1ylb{g**S(9ma}+lJy|%Lvcxjsh?>*(*i|R z;MtsCs)oTP)v%ap0aH)2!pr!x-3I^pxShWYQwk->w2W!W9);I4wVCi=n%!_nIFm4}ECNbB)__;7l2o_a$}Q^~Gu<&TtpKDSOr!Bc_Eo02Z>K6i~N_ z7QVX`;AjC)+IR}%sj6B88848VYoNB+sBq+7yS#`0NnE;o1J%<)Ts<1A2$e8Us&>L{ zh=N5=#+`5+%J>+@vt;}yMt4_Gj{n3M*`vBZRaY@r1#=b4Tfx;Mc%Q=0QxPWq;_8sx zgVuOD_bcK`c~Wr=V6JVTq?%uL`jo2osOoq$rn3KZ^+c-nJ+ENwu6u47kq|3#7hdF%+<6yQL}WpnW|Ih z{2pZrYj`797sxlL+WVTSK8Nl5H&rrK%4o{%g6}UrsZ*{Bu(3-}14~ zjd`QI_SO?VkxHoo#%bF{#oJEdK{@IWyj~`!9Wv&-J-^AP4jJ=$)Hf-v0`|aL z?H%s;FYwg5aLKd2Fh=wYMkr||oELUQDK=k}ybblPV!7uF6*g$qBgml~kFKfw*+Fra z$xeq+?LSuuvmX&g^=zC_lRN!#B2@>|RdpRTMLERPS#mj5doNbiGci_F&c{qqtsgyX z%*UgPt}l%n-JToenlFu?5oFgLfz!Ni%Lk4aBYM=mryAeM=1#>47&R`CUx5u_-|645 z+IMvCkbmQW?m({ULVSc117iDhrUC{rUe9<7a&BlFrK90{d)bgLO$SRfRC;vqU^Q*7vd4d=VmFuRtWuz ziM{_>&~)G=sQ#(8Lvv#vh3{ZN2D`L|@uwE34w4iRO^hF5{B_3X_r(n|>fqt46jH*1 zUPJ}qld=^)fg7~zr|?@CAI11p!2fAzmI9}t3G&c53gs~#nqvfP5l+QzsGyF^xPyV* zK{?}}GVYA!aTb)$9neJpD!((occJ?14CPR-QYhtgtOOLpSX5BQXAonHpS?;>N8GrQ850QT=5!L;Gs?OlMAWkF>bj#Z)WtP@_$IL6y9 zlYqMe82h8#vB?eYcN!eCU4+h5q2~%IR(@c9x^_;b1Hzkd=ag!Mg2fWx|D@>6%wK(8 zm^vZf#|=K>iaTyl0Aj>0XTVp~!IO+T)9*~ie`Wj-^Jg;tey#%O>M0d^R*O6l`r9xy z|F&?0Csr#)x?oCWC*y-|R-e}^BEDt(X~yqneCS}M=(t-HKvyQIOl5rOt?Dyfc%(9G zF#0FUoU>3T(_M!K|Kz%rEU4}-CBXUrM#eoG97NF#j5}wyPHi!8@`Nv-11Y*B2j2gJ4+2h}3%;OyX^ygHofGxxEH{3b;!i)`mj5i^oyno)DlySBc2uq; zoO%kZ8FW|IQ(ZT1L)gC_WHJp8~C-3 zH!|+ihTsXtBQ=Gp7?1l;TTgrs+*b5b)iL%BcIkxuaRBiv>c^^zJGden6*OjL+L*0n z{8(e#4(Fg3UTFDPK@&4LzQEyaGgSuZ;172>$d~Q&C zvTer!#^bbL+{Sp7=80!)`K*Oawu}f1pB7^Fdd;qbz{xJ>N~RMjzA;MwydT@DGgbat zkBbqrQB78Oo0JvwO-3p=+tseS6nVxbfj7ZSeH6s2F$meLLYO$`AR$@bDC@jPvQ-=XAm6LDH{{0tQ;t#%!&L?)hSYvxGcq*@vFXH+_} z3O6x-jutjs7%$aSc#7qCzEq|wLvg1`@lO&VE#K~EL5bQ#InH>NHq~3?o?ngbGbW5v zc7(L(nZbDeskZiA1)S_lv7eC?Vj0`FjBtCwd5Bw9X=ym*;F^L59Epaqbgv@fcL%>x z0rWjBDlum&4T8TYfS!hmXZ_X z&C8isB1ulBmVBo%9<-w?2H%X}jD|dk%0Kkzn(;_2!oCJho)Ei~ zqDxqzKOFogrTGcQyPT~Q^|u~S+EfqZ3ZK^Tg}|u;KVR2g&w{RDyzX1ov6IVhVmWEr z-s?W#6k*QoD<^k;2fT-!sI;8j4(B#%b|vD7npX3&1JQc)P&bzwr0@pzV&-4P{MFjl<6g!+nujVF&uP6*Qgj^QiUQ5mzX7M! z$GO=U#~n|^Zj6Q|q`5ka@kGtlD;O`*wl*7pPa{|O@|COUn`cyBb~?~<^=FKGHCO)% z+>WMclh0GC)oQEK)r_ZWad(Nhhb&*#6w$qI!?l|K)ng=>REQA;7 z(yyh%wfs9}tO}%8OZ0x)!E)GM=g7k20R9 z`RYaB6s2C?Bc&_-g)xZ?bIO(>VeMyhw;|a2sxoo_*X95xuhwfb=_bbWwJBUca_qgq z3(S$I`Muh~HSc}Ncu?d2gYh`+^f~f;rCFpVrw?$9T0jVGn?F@m2;Yrv+qkK0;#Djt zUt0n4oDQ@pRlsUcc}XZcH*Kfkpc8tc1IVdv8lW$_-DYVia&@M*4ojro1=D#p#+K@H(FsAGTOmUUWw zb5B-1c~`2IPClgf`>Ajk%N$u+fZYz9oKUQJpWgIGx{C%S5zD1rUS$4bnls;J{(6>= zOB;4McZw}PAd0kW5c5@q@U-?Cn$UB#)NwuUAnIArcE+pu9zrHN^F_u}c#mo@|3TpW z`4}(x#w2t7EIXYtx{q}s^2p>gEfaSJZV#8e{QbT9ok6%gr^a*3L`~-m#QM;A}=87wyQ|0WaF=xrc4QH9j^v%hw3|ue=+9a>F`4x|HVqnmP>?OX3e-GE51Dv{a9?!{Sd^hul`0gBQ zE-ss{x-8X_?^4EVH9QC$@+S!|UrCL3IzRyWXP>k)^z(;`F=_o@*B-~(^pMj&_5h6`9 zF!Cbhz!YBYdT@i4z*YF&M@O(!Y*Ag&H_oXv0w+^Swf$n}ne3U{72iyr8{L5uf1_sl zNXC8IRGp~g;2Ifky0297#CmR!tgS*Nj34E&bmnA*5`@cx%1HxR&VQJ{Kuc>KkwwYi z>Lp|_QhG5rn1~A7Vr^n&FrK9;vtm%j_ zTg7aSg3rNkTfk2#eZ>Z}u$(mQ(oNS{%CHn|Xodq1ki~V{YIrU;DAFvx3^;XMFki*W z4(^zq;vhK%tt~^{M&{4re2RMvakGNOjZOn?7TnAH^&cyK`Z6??9gLT8P=_lR z8(Ss6{wHM^-+>W7_vQ|Av?vvG(16y583XAEs@3xf!aa%cz{y6xwxhU!@qEqpMUKS4 zR_3VHrewL(Qrkkj&$w5M&u>X0G)w1IGJ%a9nxXJw?Hbx@;Ly06@SJwPYH>F;u#K%# zEW)D=bR*;GnwvV}?2uGQsa9^8!QP1@++JRX;)s?IKR>zYxbJ4*zFSBvPw-bZEb47@+x+bwJA}&=8>b_K(yvl-xFkXFF z;VF!t1DrgUrOk4{Z>$pL>=4yKLED0*o2K#BoJz8Y%15TDzA5{vCWQ9It zJl#-3Hky})9@s7nw_W|CG8I1{W|z^ZAiVfyC5T?6LuH1%HQekT$VN5kRiNpc$9PCf z`1dkiqy^`bjOS|`saJqg_r4U>?*NXapA|n`rmfq`x&f~ywN?kDxI0*`Iw&}w7 zBH&~|v9nc=L+6V?jY+6r768$fXW-(pj7MN5c7u;6hFPpj|#m* zm=vnjR-l;6c|=bt{&mDmA(Mg%YLKpFiYpnf(@tG)VBD{{dL!dG+R9YQc$T&|eI2+< zC61qPNX`x7O9@mq+W+I`#T6VKS`;KO?$s`mjAOi7i{@#JS81kPrtpBs)J7=}6{Ju> zit_3P9*p&j2Y**iWLP}N9URka-@|yMcB=9|<34*jV(;NZ!BEn9dFVjkt8TmTO89Fuh){;wMvli?^2`Ei50rpk)ut8t-$HJj^Dnn zbDj`EZtx*D$kC?4A;!zJtaB2$?Zbt!^OVZTn)inRr$DNo!U4lJPGbHnO|{Dzuh1fX zHOa9T*^SJRsg3_LjOS<)D;-?p|CaHf#xLf>Iap-Nc#(A?vo~-I3Km%{V~$l7B2Al& zvlx%mhCR>0H8};07ii8eVLZ{E60PRSJ6ut(&GsLFD_0jF@wsvtao?*(#2fEzg9268ce5I9Y>QY|`uW4uh8YMri99rM?X1eQ^| z1c6h>)qIs8icl~9JXfm@sA6$)R^`16d{@1bVqz@c#f-XUwrKvjBOql^t{ zvo{$yrSE#aEbnE0KXBX2zbS7z2E52}GBt%hwfVWReT6YF@LJVng%%-aF&?McIvY53 zSI9^C-M_Rq6P#?zgv``+-c$s$D z_dLc6>_JDuh-3>gxFSWHLphA+YuSD^<8j&&xt;N9Z4h5}@Yej1==^h3sDSKnow6~g zof`~iyjJtcRK`6Vz$A@I7UPjx;H?BsgBRj!JGd}sm%9{yKoo1XKZOc=+VlBsJ8lqu zy;8JF%R}86PuHT!2b?;t8>|A}*+5wAdA?#i zSzF)#Qg}cd(;7r!Eu#+fi$qrfC+`SNp;e66X<6W2#>+JMPciPXCoe8nIBB4oD+;vC zb%ODHZ4z}@u7*9mzZ%9t?DKfS?R|+4NA`efd14lDGST^NwliAKGOlmJ!d56b`?WFZ z&Umr5aE($pzEh@c3oqsdwOS%t$atLQ!!?Z8X$IWSc)b>o&oEwOhg+-F;&rY_*9PNr z;P%wvd&UjQmH7EbWpTPTNvAPhr7de&j0an!5#F@RUHTWDpR|tYW#|m>OjB3cO&6; zG!-yM-Os8?B>U=9#=Vo25%k(0D!&1z=u6XbbC;E>r}R&h9Op{hNZ`buti|~xg%1&> z+RVFz1$jPfE66Vo^uVRN5X;Ngg77fo$Fwp0gT;lk8*>q>l)m-68h#w5>`MktLs;BT zIf5Su7gqs?9oQ>r(HT?~B2UZT_cQL*?5lA2wb=Q9@d9lT`-bs48*df;VK*wz)@#$K zH*g9n{fUV)nLng?Xa?h%S}tA4c(8R4QuMFk4(dvkizX`1i7niqqICn*?PT1eMgOae z@6!^{0pPT3JFjSPmhJdFL_ft+krsO?sIX&F>)_fY0k%J05b@3(n8SLBJ7#IAghO-GQ;tss* zLuc7}mibdwsaf;}%Q?*a$83eLxHt{|*QRD~b z)NZ2O+y|*Bo$HTjVYis^^w!G;{2u^LsRggMu}5R78X9qs`IEKn)OXD9*X|d^ueIj~ z-oATCX_U@`>qiBRP_1U*U5w{wDW}`R%J8zglz=l>&ZDXWk)_H1oaLn04!QL2;HgIi zc~HM^&>gj6bL;6t;D(jt=fohY<3kT^>{XlZ0Qh;!PIh(I(ATz-iJ1i=dDUMm>S(fBtqUZN$XV#ZT6IWHF0RtvKLaC=0xrwg_KrzeflXSY2$ewO7FX<6+( z#&@;$5c(HKxC0NrtEhyB`Z(j>jcNx;uSKLXWSt6)^jg(%vVz5G;1pshT8M3Byh2Nl zF9Nq8ZpqO!J-`jhw2Acx+*Q+3&OUCCsI5JpFrKC<`h$aOaqqrUg|XoM zdMz8!AGp2d*@M(-KAg=JUTuxJm<4%1a@itc6%p4nf2790hVe!%I<~Q#Hjh5hO1y&` z6lfNN7?0D!?=!}WwN?8U>VT5d_EXBO?myo-FQci7N6O~Z!Zf0 zheMP25OKH>Z7J+_CXX|JP_y+_#%r~`-{+2eE!>(&KJACoKXKcl>Gu(+WMFGT!`rAi zXF1~`E!%AZPE*Z!zg(sgBbtDdOY{fZI&Dz6$3D*+B%GITiP5N_r+)M=gq=$b$XDhA z&Qah!;)RkG+L_f?j5lgA-asu$nKYFTVg@QL&AXMHI4vJ^XWXxaCcV53a^{JU_8it) zZjh`E%Qn?O1ew1*d*^HB&(u0@AbvYAnwcZ0nbK{eQn^6O6K4V^6Ftk+cy{HUE@u7; zZMnOiaiIm?I)%>@`I>55xq(LufKuQT0L6R>26@jeLpCWzGqn!R1+Gj?XAX~M;zFmT z7PB`|OZ4PBp-h~_J#A$EBF*_b7%$K)*{kpo!mD*~kQ*dw)AdK-w#o~en4?O|O}*|> z#tJRfi~&xofb-5m5376)^T%lcwg$Lz&KBkfX?g!i#>=$Oe~s}(ZM*Xk<5ikXzX2y_ z7C)(+*`Bj<^u6|Q;;smvC_5pWjS8A`nOcTf1)Kzl2qlPq8I{V5jAxyv@JI!VBP^#@ zGwe5;pP7U_cbM5eU>2x8E3}b~W8AL=^>E9aV+i@=1bg$t;4Z7-pth=t=UfC)Q|I4PsgXt%wML3!GQaePeTFaJNkV# zD(ivM7=$!`Y*YOB;(_+`e(x=+L8-Q*8pU|NCg?(kUz;*l0{^F}x0LyP`eq=XD^j#< z@hIaJT2^?C@l1{iCt9i*Kc?}251bUrnyfrzZz^bW+`Uj)T(8Z8vw%|rk9IvLo%tKJ zu)c=*Q?gVC1#0CG8<{^@Q>X;EdNT4Q)nGYKsF%4xoi@e?WV{a{^9T1+f4k~{UV=_# z*j8mnrWR?F7Bkyh0hay&5(CcL9trT7eSmk zk+e-I_BDdJZEtLip+IrE8 zagV0KxeC8rgtTcthZ}gcY<(T$$F!|;fblXdn58^03PboUs_hl9k8=Ixtnb-HO5YSM z8_Z$6Li6Mb;Bl3b-mxSLw_mdoJW?M8Ta$0b7%0o zKcqCP(gt}HaM+5=sNAs{FMI=)8{}ydBHIz9;VYD&|M5h}9n4>^jqJmW$Jx$rb;|lG zDkyZEcTqd*vgcv-ati(1)_s86qpSIL1mlgG#S|=4p9Y#<){0eJ0B+C3rOKjVLY3ppU#5AWN%40U z!5@^%rg4KPc>sDX==-QryI5Ofk{D0c`k%#koo2_ijF)NGH*c}K2|UQv_1dI;mhoyW zJ-o$uy0#d9!FZO|{jb0&V9K6Tv(?#G^nJ`W4_Du{^g2#eh)Au2S&S!Z9V}*CXyX(F zPUGR{^M`%x-WQoa)1HHYzpuwubAyofkY0z!)j;^Q0i3{ik(OQNFkY;!lG%=&)}BWH z;wG-BYFz<*BjaApvSP;TwNtW}fs@4r+QkL4gd<6t7=3}OFB@tbqOshdTAPIDGcL3t zn8$dnHp5l{Cxtw@F5CGhcnCHFw^!V6+>>m``7-S{ET~4?ko<@7L@nlfJ%J8r@{gU2 zBg!**T4ueH@l4HEH#sf)+{+w^n)jb^IL5xl9O>HHdysLDw#EL@X&EqfD6Q%>M|NR6 zsD;!h;N-A+el+zucG!iC2l?v(ix^+ca*k=%6(}4RceU7jm<5IScDTWU-e*A`jsH95 zujW@3I1hOPBtgLDz9boEGlef!nG0xa!i0 zq8FGySv&DMK>YSrGwf-lTBhdup1|osP1+YKf`hEvEa23W_&}M+PgjXs7!UE{?3@#9 zWBK)3irr)L+vgM0Ld=t=P5(nIv!1`CLBC~4W$-SgvrikAbL7Mnv%71nO#-hDRGRua zsAlw|id1%RYp)jl{{n7XmZmIwjYlv18P!{yHhA&Ci9elJvjIxHn5OvgWd$wAUde*; zwZZVSAn$9c<6$i5Tjnp)!Z>`lQm9_rZzKSxvr~~lLpBIs?PNhKxq;9uxEr{Ng6+(a zsfm1r@iJ{>KB1Pdy{tw#30KMN@-uLXnktT(bjHtkR;iq)nUVq=*^JIA$EGt+P+R*J zFCROBbK4b{LYt0ZgN zspHfVzREAu6=to6UHnwxnb`xYqG%2iF{Y z593*OzpeIbPjN+&=Cysm?a04Z&8!x$a?wHNuhZt`apte)cg|nV9zE&EX&v~qUt9K^ za*)P7+Lrl#;G|HHpAb&rsrx+hM`}a1A2{V{{WZV+p6C5qu@-A%Q9)zx)jW~L z_%UrExE44mBzQ$$z!vWVZg>2G@?1RQhgnW_gLeP?C$31-EC?@G9Tb1BOzp~oh5;u< zQ?wkD#{Bvvn=2gt(}vAal9q5qj@I#=jE6LfOBpZHR;HJL+p~09_ZO6Eel1+b0wHjZdG>b3lt!FZOo1}$McUyHwu zjHhTjpc3GZBISGLs9fb?qdo%OS>@HhFWfe$jhI=XbW7Ik=*M`RwhNp9oW{fVs&YsI z_qB=f;_(W72&nj)~d*EE%cC}_f zGUHw?gJ%FI13cww7DVzGKgPJ=ZQxoqppoU|{brnDLy=q&^{TQs$eX5E#xIhcrkmYI zJ%eh}t3r#(cNj0#7K9^qGuIjNQM3*$culp=(Pq_Z#*b;^yNU6j=C)$SJz6e%88~^t zH&}VWxzaM`b=xSMC-8l5Kf7lsD#)BXZ5;1n+^Z$mN0lIsFRsE&)Z@l9krq-`apF^XTvMKtdZ#Vg#P zOjGDR#tXELzh*q7W$}}Yr)xvj@n6oB7R^P;sGuPz*6=xu3vG;-04D>2b#6N}=W>8< zWd24i2|Whft9Z5y3hNknjro!_Lk|I`Z}V4Z-{v>pRQ;9lePL&!>}EV=uiKW6&7@r{ z;ABshwxV>Y3_Ox0gsqU&b!Q?rKOU8 z+x&_LKM1{hCN4<)$-K2%*m&OJ=vbmA5dDHRm3ZK!<1uYMoW*#WHb`?=j{c(YYZQM# z#Az8Ij|F9EiSus8%QQtF&Uj@s!q4L&<3(S0rnKt^`ge&UN;QGv1iSo+txOxj;W}c>_2NS(c^drgJ~D z$Gb|Qpyr`u;Px_{uf_K)ZcwecZUy7{nkO~@w>#!o;gJz_%zsRi)4=@2L&C^@JebUu zMZB*xP1n+EZ^o-NmyTt;R13ygj0ZKtt^-b<`}^hMi&W3IaDx<0&;!72%d{(JKLe+e z@%&oD7Ld#aOx&*w@M#nJD&Xp(z?aOCqnX&?aG1S5VBWwe9MRlN({f}g<9^K@S&Ua` zX=5cxgxOx+-6XQM4=}D@9D7d5nI{^xlaKefK~Ourt5*&16D7(Wk=#MphsprIHV(ak ztMoIHIlNlzr#ZN`pkBs!j>f-~B*H}fHDY%$f1S2IKCJM0B1?PXg|>GwduJk!qn8YF;=OL9b;zxJLEVTP;2!pCwjlF|->v#iIVa zq_0|O7N=#{845>+)qHg|H>lG_z<(j3;ZECX?}?X3}Edq!+dj*4X{x%A+=Ucd81JrA5=rz{$6Dyh(nBY)APNIQcf2 zeH*kWzRBRpe6OUfRjSieAmsnvlH>D>bOxG zi+;d~znJ%T_5`G4dM;Ji7nLu=5$P7v_GK?R9PJOXko5k0*UU5Djg|9_@Mw7=*X$_! z=9=y0gEyFO$yEvAz2*EH%sBZ#uGy{UoZL~q8*&z`SeQNEpSxn(MRVqlo0GF3d*O=7 z(vu6OtXwm3?;E-1I@bW5bqrcL%#$b2SukzR`EuSf=6Kg+xp|ct2eRiGvnR-}Yi+Xm zBQrtzZZ-$W&b8*H(tii^I$IKpbz#7vh2d^=^%i`5$#@;z= z%rm;nw|+MJhbzrw);0(#{s1jkZ8pD>@BD1`lLg7)KKbev)7o3J)x0WF&UnO}yZ4P^ zb9k6s&?P*fRnvj8tV?*r-sw-64@St@_nEW*e;78g-{kqDeDl*5+>kSW>9XvF@WuS; zSB;uHdGZo*?cxR5^W}nYqsLzJ8FP!#EqBz|`STYnUcBt;1-a~Zcu#(1gvUp)Lv0(w zCr?ftHF?$EEqlyf?f1UA&-^m7b1SExKYH@aIllSwji1eQ`Q2OQ6nWthv#kW#^I7xU zy;I*d=SRxV%FK>?n?5qXb;thSyB|GymHer|Jd@mQ%5DeE-}lCSV*ci8hnjb z-tX)gev|S4BO(*zWq+D6dk^#r|HhCnA2%=mKMuz8dtXTizq!4v{Mj7fIL`B#Iry|q z7s+S4gh%cz7#aTmCPcmb19q+O_C;oFH<`CLSg|QEF?DcEUu46k$5o*RDT6EYw%@X0 zV`F40Sv>ubEl>h>_S%+L)1~a#+!%YNC)%;;3&QS~gwxX(0)>SnQXthUj1KXc{>Y9^ zPc~-*L>xwI3PX#05H)e5@N@@zHUZulhasxK^yH2F!qW@v*%WwTmyXUj4wME9Z@@16 z0VvD~yV7*WbV&y`bHM}GA!Z%`X$FEF(-R%o^f_VoU{*|@2~@?o;yy%n#rB&HZ0?M_ r3f*AE3<@A>x~>zOHWx!YD_HEswdwP0S;VGSI03`&h3WKJPHbub;&NTJ delta 123581 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 namespace are { @@ -70,14 +71,14 @@ public: /// @brief Set compute shader (called by renderer) /// @param shader Compute shader - void set_compute_shader(const Shader &shader); + void set_compute_shader(const std::shared_ptr& shader); private: uint width_; uint height_; RayTracerConfig config_; - Shader compute_shader_; + std::shared_ptr compute_shader_; TextureHandle accumulation_texture_; BufferHandle scene_buffer_; BufferHandle material_buffer_; diff --git a/include/core/renderer.h b/include/core/renderer.h index 9040710..b0b29b6 100644 --- a/include/core/renderer.h +++ b/include/core/renderer.h @@ -57,6 +57,9 @@ public: /// @param config New configuration void set_config(const RendererConfig& config); + /// @brief Notify scene changed to rebuild acceleration + void notify_scene_changed(const Scene &scene); + private: RendererConfig config_; std::unique_ptr gbuffer_; diff --git a/include/core/shader_manager.h b/include/core/shader_manager.h index 891dccc..c48665a 100644 --- a/include/core/shader_manager.h +++ b/include/core/shader_manager.h @@ -5,6 +5,7 @@ #include "resource/shader.h" #include #include +#include namespace are { @@ -29,7 +30,7 @@ public: /// @param vertex_path Vertex shader file path /// @param fragment_path Fragment shader file path /// @return Shader object - Shader load_shader(const std::string& name, + std::shared_ptr load_shader(const std::string& name, const std::string& vertex_path, const std::string& fragment_path); @@ -37,26 +38,26 @@ public: /// @param name Shader name for caching /// @param compute_path Compute shader file path /// @return Shader object - Shader load_compute_shader(const std::string& name, + std::shared_ptr load_compute_shader(const std::string& name, const std::string& compute_path); /// @brief Get cached shader by name /// @param name Shader name /// @return Shader object (invalid if not found) - Shader get_shader(const std::string& name) const; + std::shared_ptr get_shader(const std::string& name) const; /// @brief Get G-Buffer shader /// @return G-Buffer shader - const Shader& get_gbuffer_shader() const { return gbuffer_shader_; } + const std::shared_ptr& get_gbuffer_shader() const { return gbuffer_shader_; } /// @brief Get ray tracing compute shader /// @return Ray tracing shader - const Shader& get_raytracing_shader() const { return raytracing_shader_; } + const std::shared_ptr& get_raytracing_shader() const { return raytracing_shader_; } private: - std::unordered_map shader_cache_; - Shader gbuffer_shader_; - Shader raytracing_shader_; + std::unordered_map> shader_cache_; + std::shared_ptr gbuffer_shader_; + std::shared_ptr raytracing_shader_; bool initialized_; diff --git a/include/resource/shader.h b/include/resource/shader.h index 89e8175..25ea338 100644 --- a/include/resource/shader.h +++ b/include/resource/shader.h @@ -12,6 +12,12 @@ class Shader { public: /// @brief Constructor Shader(); + + Shader(const Shader&) = delete; + Shader& operator=(const Shader&) = delete; + + Shader(Shader&& other) noexcept; + Shader& operator=(Shader&& other) noexcept; /// @brief Destructor ~Shader(); diff --git a/shaders/raytracing.comp b/shaders/raytracing.comp index 52b9d93..a34c5eb 100644 --- a/shaders/raytracing.comp +++ b/shaders/raytracing.comp @@ -22,7 +22,7 @@ layout(binding = 0, rgba32f) uniform readonly image2D g_position; layout(binding = 1, rgba32f) uniform readonly image2D g_normal; layout(binding = 2, rgba8) uniform readonly image2D g_albedo; -// New: material params + material id +// Material params + material id (for primary hit fast-path) layout(binding = 5, rgba32f) uniform readonly image2D g_material; layout(binding = 6, r32ui) uniform readonly uimage2D g_material_id; @@ -96,7 +96,6 @@ uniform uint u_frame_count; uniform uint u_samples_per_pixel; uniform uint u_max_depth; uniform uint u_light_count; -uniform vec3 u_camera_position; uniform mat4 u_inv_view_projection; uniform bool u_enable_accumulation; uniform bool u_use_bvh; @@ -234,7 +233,6 @@ bool intersect_triangle(Ray ray, TriangleGpu tri, inout HitInfo hit) { float t = dot(e2, qvec) * inv_det; if (t < EPSILON || t >= hit.t) return false; - // Interpolate normal/uv float w = 1.0 - u - v; vec3 n0 = tri.n0.xyz; vec3 n1 = tri.n1.xyz; @@ -265,7 +263,6 @@ HitInfo trace_ray_bvh(Ray ray) { return hit; } - // Small fixed stack uint stack[64]; int sp = 0; stack[sp++] = 0u; @@ -288,11 +285,8 @@ HitInfo trace_ray_bvh(Ray ray) { intersect_triangle(ray, tri, hit); } } else { - // Interior: push children uint left = left_first; uint right = left_first + 1u; - - // Depth-first; no sorting (simple) if (sp < 63) stack[sp++] = right; if (sp < 63) stack[sp++] = left; } @@ -330,9 +324,7 @@ bool trace_any_bvh(Ray ray, float t_max) { if (count > 0u) { for (uint i = 0u; i < count; ++i) { TriangleGpu tri = bvh_tris[left_first + i]; - if (intersect_triangle(ray, tri, hit)) { - return true; - } + if (intersect_triangle(ray, tri, hit)) return true; } } else { uint left = left_first; @@ -345,6 +337,45 @@ bool trace_any_bvh(Ray ray, float t_max) { return false; } +// ============================================================================ +// Primary-ray fast path via G-Buffer +// ============================================================================ + +/** + * @brief Read primary hit from G-Buffer if current pixel has geometry + * @note Uses g_position.w as "valid" marker (your gbuffer writes 1.0 on hits, clear is 0). + */ +HitInfo trace_primary_gbuffer(Ray ray, ivec2 pixel_coords) { + HitInfo hit; + hit.hit = false; + hit.t = MAX_FLOAT; + hit.position = vec3(0.0); + hit.normal = vec3(0.0, 1.0, 0.0); + hit.texcoord = vec2(0.0); + hit.material_id = 0u; + + vec4 pos = imageLoad(g_position, pixel_coords); + if (pos.w <= 0.5) { + return hit; + } + + vec3 p = pos.xyz; + vec3 n = normalize(imageLoad(g_normal, pixel_coords).xyz); + + // integer material id + uint mid = imageLoad(g_material_id, pixel_coords).r; + + hit.hit = true; + hit.position = p; + hit.normal = n; + hit.material_id = mid; + + // For RR/any debug usage; path tracing uses this as starting point only. + hit.t = length(p - ray.origin); + + return hit; +} + // ============================================================================ // Material + scattering // ============================================================================ @@ -429,7 +460,6 @@ ScatterResult scatter_ray(Ray ray_in, HitInfo hit, Material mat, inout uint seed vec3 eval_direct_lighting(HitInfo hit, Material mat, inout uint seed) { if (u_light_count == 0u) return vec3(0.0); - // sample one light uint light_idx = uint(random_float(seed) * float(u_light_count)) % u_light_count; Light light = lights[light_idx]; @@ -455,18 +485,15 @@ vec3 eval_direct_lighting(HitInfo hit, Material mat, inout uint seed) { float n_dot_l = max(dot(hit.normal, L), 0.0); if (n_dot_l <= 0.0) return vec3(0.0); - // shadow ray Ray shadow_ray; shadow_ray.origin = hit.position + hit.normal * EPSILON; shadow_ray.direction = L; float t_max = (light.type == LIGHT_POINT) ? (dist - EPSILON) : MAX_FLOAT; - if (trace_any_bvh(shadow_ray, t_max)) { - return vec3(0.0); - } + if (trace_any_bvh(shadow_ray, t_max)) return vec3(0.0); float pdf_light = 1.0 / float(u_light_count); - vec3 brdf = mat.albedo * INV_PI; // diffuse direct only (simple) + vec3 brdf = mat.albedo * INV_PI; return brdf * radiance * n_dot_l / max(pdf_light, EPSILON); } @@ -489,15 +516,52 @@ Material fetch_material(uint material_id) { } vec3 environment_color(vec3 dir) { - // simple dark sky return vec3(0.1, 0.1, 0.15); } -vec3 trace_path(Ray ray, inout uint seed) { +Ray generate_camera_ray_center(ivec2 pixel_coords, ivec2 image_size) { + vec2 uv = (vec2(pixel_coords) + vec2(0.5)) / vec2(image_size); + vec2 ndc = uv * 2.0 - 1.0; + + vec4 p_near = u_inv_view_projection * vec4(ndc, 0.0, 1.0); + vec4 p_far = u_inv_view_projection * vec4(ndc, 1.0, 1.0); + vec3 near_ws = p_near.xyz / p_near.w; + vec3 far_ws = p_far.xyz / p_far.w; + + Ray r; + r.origin = near_ws; + r.direction = normalize(far_ws - near_ws); + return r; +} + +/** + * @brief Trace path with primary-ray G-Buffer acceleration + */ +vec3 trace_path_primary_gbuffer(ivec2 pixel_coords, ivec2 image_size, inout uint seed) { + Ray ray = generate_camera_ray_center(pixel_coords, image_size); + vec3 radiance = vec3(0.0); vec3 throughput = vec3(1.0); - for (uint depth = 0u; depth < u_max_depth; ++depth) { + // Depth 0: try G-Buffer hit first + HitInfo hit0 = trace_primary_gbuffer(ray, pixel_coords); + if (hit0.hit) { + Material mat0 = fetch_material(hit0.material_id); + + radiance += throughput * mat0.emission; + if (mat0.type == MATERIAL_DIFFUSE) { + radiance += throughput * eval_direct_lighting(hit0, mat0, seed); + } + + ScatterResult sc0 = scatter_ray(ray, hit0, mat0, seed); + if (!sc0.scattered) return radiance; + + throughput *= sc0.attenuation; + ray = sc0.scattered_ray; + } + + // Subsequent bounces: BVH + for (uint depth = (hit0.hit ? 1u : 0u); depth < u_max_depth; ++depth) { HitInfo hit = trace_ray_bvh(ray); if (!hit.hit) { radiance += throughput * environment_color(ray.direction); @@ -506,10 +570,7 @@ vec3 trace_path(Ray ray, inout uint seed) { Material mat = fetch_material(hit.material_id); - // emission radiance += throughput * mat.emission; - - // direct light (only for diffuse to keep simple) if (mat.type == MATERIAL_DIFFUSE) { radiance += throughput * eval_direct_lighting(hit, mat, seed); } @@ -519,7 +580,6 @@ vec3 trace_path(Ray ray, inout uint seed) { throughput *= sc.attenuation; - // RR if (depth > 3u) { float p = max(throughput.r, max(throughput.g, throughput.b)); p = clamp(p, 0.0, 0.95); @@ -544,12 +604,10 @@ void main() { uint seed = base_seed + u_frame_count * 719393u; vec3 color = vec3(0.0); - - // Multi-sample uint spp = max(u_samples_per_pixel, 1u); + for (uint s = 0u; s < spp; ++s) { - Ray cam_ray = generate_camera_ray(pixel_coords, image_size, seed); - color += trace_path(cam_ray, seed); + color += trace_path_primary_gbuffer(pixel_coords, image_size, seed); } color /= float(spp); diff --git a/src/core/bvh.cpp b/src/core/bvh.cpp index e1c747e..7639f9a 100644 --- a/src/core/bvh.cpp +++ b/src/core/bvh.cpp @@ -135,6 +135,11 @@ void BVH::build_recursive_(uint node_idx, uint first_prim, uint prim_count) { int axis; float split_pos; float split_cost = find_best_split_(first_prim, prim_count, axis, split_pos); + if(split_cost == std::numeric_limits::max()) { + node.left_first_ = first_prim; + node.count_ = prim_count; + return; + } // Check if split is beneficial float no_split_cost = prim_count * bounds.surface_area(); @@ -180,6 +185,7 @@ void BVH::build_recursive_(uint node_idx, uint first_prim, uint prim_count) { float BVH::find_best_split_(uint first_prim, uint prim_count, int& axis, float& split_pos) { float best_cost = std::numeric_limits::max(); + axis = 0, split_pos = 0.0f; AABB centroid_bounds = calculate_centroid_bounds_(first_prim, prim_count); diff --git a/src/core/raytracer.cpp b/src/core/raytracer.cpp index 4525357..e110708 100644 --- a/src/core/raytracer.cpp +++ b/src/core/raytracer.cpp @@ -1,319 +1,315 @@ #include "core/raytracer.h" -#include "utils/logger.h" #include "basic/constants.h" +#include "utils/logger.h" #include namespace are { -RayTracer::RayTracer(uint width, uint height, const RayTracerConfig& config) - : width_(width) - , height_(height) - , config_(config) - , accumulation_texture_(INVALID_HANDLE) - , scene_buffer_(INVALID_HANDLE) - , material_buffer_(INVALID_HANDLE) - , light_buffer_(INVALID_HANDLE) - , bvh_(nullptr) - , bvh_built_(false) - , frame_count_(0) - , initialized_(false) { +RayTracer::RayTracer(uint width, uint height, const RayTracerConfig &config) + : width_(width) + , height_(height) + , config_(config) + , accumulation_texture_(INVALID_HANDLE) + , scene_buffer_(INVALID_HANDLE) + , material_buffer_(INVALID_HANDLE) + , light_buffer_(INVALID_HANDLE) + , bvh_(nullptr) + , bvh_built_(false) + , frame_count_(0) + , initialized_(false) { } RayTracer::~RayTracer() { - release(); + release(); } bool RayTracer::initialize() { - if (initialized_) { - Logger::warning("RayTracer already initialized"); - return true; - } - - // Create accumulation texture - glGenTextures(1, &accumulation_texture_); - glBindTexture(GL_TEXTURE_2D, accumulation_texture_); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width_, height_, 0, GL_RGBA, GL_FLOAT, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - // Create shader storage buffers - glGenBuffers(1, &material_buffer_); - glGenBuffers(1, &light_buffer_); - - // Load compute shader - Logger::info("Loading ray tracing compute shader in RayTracer..."); - if (!compute_shader_.load_compute("shaders/raytracing.comp")) { - Logger::error("Failed to load ray tracing compute shader in RayTracer"); - return false; - } - Logger::info("Ray tracing compute shader loaded in RayTracer"); - - // Initialize BVH if enabled - if (config_.use_bvh_) { - bvh_ = std::make_unique(); - } - - initialized_ = true; - Logger::info("RayTracer initialized successfully"); - return true; + if (initialized_) { + Logger::warning("RayTracer already initialized"); + return true; + } + + // Create accumulation texture + glGenTextures(1, &accumulation_texture_); + glBindTexture(GL_TEXTURE_2D, accumulation_texture_); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width_, height_, 0, GL_RGBA, GL_FLOAT, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + // Create shader storage buffers + glGenBuffers(1, &material_buffer_); + glGenBuffers(1, &light_buffer_); + + // Initialize BVH if enabled + if (config_.use_bvh_) { + bvh_ = std::make_unique(); + } + + initialized_ = true; + Logger::info("RayTracer initialized successfully"); + return true; } void RayTracer::release() { - if (!initialized_) return; - - if (accumulation_texture_ != INVALID_HANDLE) { - glDeleteTextures(1, &accumulation_texture_); - accumulation_texture_ = INVALID_HANDLE; - } - - if (material_buffer_ != INVALID_HANDLE) { - glDeleteBuffers(1, &material_buffer_); - material_buffer_ = INVALID_HANDLE; - } - - if (light_buffer_ != INVALID_HANDLE) { - glDeleteBuffers(1, &light_buffer_); - light_buffer_ = INVALID_HANDLE; - } - - bvh_node_buffer_.release(); - bvh_triangle_buffer_.release(); - - compute_shader_.release(); - - bvh_.reset(); - bvh_built_ = false; - - initialized_ = false; - Logger::info("RayTracer released"); + if (!initialized_) + return; + + if (accumulation_texture_ != INVALID_HANDLE) { + glDeleteTextures(1, &accumulation_texture_); + accumulation_texture_ = INVALID_HANDLE; + } + + if (material_buffer_ != INVALID_HANDLE) { + glDeleteBuffers(1, &material_buffer_); + material_buffer_ = INVALID_HANDLE; + } + + if (light_buffer_ != INVALID_HANDLE) { + glDeleteBuffers(1, &light_buffer_); + light_buffer_ = INVALID_HANDLE; + } + + bvh_node_buffer_.release(); + bvh_triangle_buffer_.release(); + + bvh_.reset(); + bvh_built_ = false; + + initialized_ = false; + Logger::info("RayTracer released"); } -bool RayTracer::rebuild_bvh(const Scene& scene) { - if (!config_.use_bvh_) { - Logger::warning("BVH is disabled in configuration"); - return false; - } - - if (!bvh_) { - bvh_ = std::make_unique(); - } - - Logger::info("Building BVH for ray tracing..."); - - if (!bvh_->build(scene.get_meshes())) { - Logger::error("Failed to build BVH"); - return false; - } - - if (!bvh_->upload_to_gpu(bvh_node_buffer_, bvh_triangle_buffer_)) { - Logger::error("Failed to upload BVH to GPU"); - return false; - } - - bvh_built_ = true; - Logger::info("BVH built and uploaded successfully"); - return true; +bool RayTracer::rebuild_bvh(const Scene &scene) { + if (!config_.use_bvh_) { + Logger::warning("BVH is disabled in configuration"); + return false; + } + + if (!bvh_) { + bvh_ = std::make_unique(); + } + + Logger::info("Building BVH for ray tracing..."); + + if (!bvh_->build(scene.get_meshes())) { + Logger::error("Failed to build BVH"); + return false; + } + + if (!bvh_->upload_to_gpu(bvh_node_buffer_, bvh_triangle_buffer_)) { + Logger::error("Failed to upload BVH to GPU"); + return false; + } + + bvh_built_ = true; + Logger::info("BVH built and uploaded successfully"); + return true; } -void RayTracer::trace(const Scene& scene, const GBuffer& gbuffer, TextureHandle output_texture) { - if (!initialized_) { - Logger::error("RayTracer not initialized"); - return; - } - - if (!compute_shader_.is_valid()) { - Logger::error("Ray tracing compute shader not loaded"); - return; - } - - // Build BVH if enabled and not built yet - if (config_.use_bvh_ && !bvh_built_) { - rebuild_bvh(scene); - } - - // Upload scene data - upload_scene_data_(scene); - - // Use compute shader - compute_shader_.use(); - - // Bind G-Buffer textures - bind_gbuffer_(gbuffer); - - // Bind output and accumulation textures - glBindImageTexture(3, output_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); - glBindImageTexture(4, accumulation_texture_, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); - - // Bind BVH buffers if enabled - if (config_.use_bvh_ && bvh_built_) { - bvh_node_buffer_.bind_base(2); - bvh_triangle_buffer_.bind_base(3); - compute_shader_.set_bool("u_use_bvh", true); - compute_shader_.set_uint("u_bvh_node_count", bvh_->get_node_count()); - } else { - compute_shader_.set_bool("u_use_bvh", false); - } - - // Set uniforms - compute_shader_.set_uint("u_frame_count", frame_count_); - compute_shader_.set_uint("u_samples_per_pixel", config_.samples_per_pixel_); - compute_shader_.set_uint("u_max_depth", config_.max_depth_); - compute_shader_.set_uint("u_light_count", static_cast(scene.get_lights().size())); - compute_shader_.set_bool("u_enable_accumulation", config_.enable_accumulation_); - - // Set camera data - const Camera& camera = scene.get_camera(); - compute_shader_.set_vec3("u_camera_position", camera.get_position()); - - Mat4 inv_vp = glm::inverse(camera.get_view_projection_matrix()); - compute_shader_.set_mat4("u_inv_view_projection", inv_vp); - - // Dispatch compute shader - uint num_groups_x = (width_ + COMPUTE_GROUP_SIZE_X - 1) / COMPUTE_GROUP_SIZE_X; - uint num_groups_y = (height_ + COMPUTE_GROUP_SIZE_Y - 1) / COMPUTE_GROUP_SIZE_Y; - - glDispatchCompute(num_groups_x, num_groups_y, 1); - - // Memory barrier - glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - - // Increment frame count for accumulation - if (config_.enable_accumulation_) { - frame_count_++; - } +void RayTracer::trace(const Scene &scene, const GBuffer &gbuffer, TextureHandle output_texture) { + if (!initialized_) { + Logger::error("RayTracer not initialized"); + return; + } + + if (!compute_shader_->is_valid()) { + Logger::error("Ray tracing compute shader not loaded"); + return; + } + + // Build BVH if enabled and not built yet + if (config_.use_bvh_ && !bvh_built_) { + rebuild_bvh(scene); + } + + // Upload scene data + upload_scene_data_(scene); + + // Use compute shader + if (!compute_shader_ || !compute_shader_->is_valid()) { + Logger::error("Ray tracing compute shader not set or invalid"); + return; + } + compute_shader_->use(); + + // Bind G-Buffer textures + bind_gbuffer_(gbuffer); + + // Bind output and accumulation textures + glBindImageTexture(3, output_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); + glBindImageTexture(4, accumulation_texture_, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); + + // Bind BVH buffers if enabled + if (config_.use_bvh_ && bvh_built_) { + bvh_node_buffer_.bind_base(2); + bvh_triangle_buffer_.bind_base(3); + compute_shader_->set_bool("u_use_bvh", true); + compute_shader_->set_uint("u_bvh_node_count", bvh_->get_node_count()); + } else { + compute_shader_->set_bool("u_use_bvh", false); + } + + // Set uniforms + compute_shader_->set_uint("u_frame_count", frame_count_); + compute_shader_->set_uint("u_samples_per_pixel", config_.samples_per_pixel_); + compute_shader_->set_uint("u_max_depth", config_.max_depth_); + compute_shader_->set_uint("u_light_count", static_cast(scene.get_lights().size())); + compute_shader_->set_bool("u_enable_accumulation", config_.enable_accumulation_); + + // Set camera data + const Camera &camera = scene.get_camera(); + compute_shader_->set_vec3("u_camera_position", camera.get_position()); + + Mat4 inv_vp = glm::inverse(camera.get_view_projection_matrix()); + compute_shader_->set_mat4("u_inv_view_projection", inv_vp); + + // Dispatch compute shader + uint num_groups_x = (width_ + COMPUTE_GROUP_SIZE_X - 1) / COMPUTE_GROUP_SIZE_X; + uint num_groups_y = (height_ + COMPUTE_GROUP_SIZE_Y - 1) / COMPUTE_GROUP_SIZE_Y; + + glDispatchCompute(num_groups_x, num_groups_y, 1); + + // Memory barrier + glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); + + // Increment frame count for accumulation + if (config_.enable_accumulation_) { + frame_count_++; + } } void RayTracer::resize(uint width, uint height) { - if (width == width_ && height == height_) return; - - width_ = width; - height_ = height; - - if (initialized_) { - // Recreate accumulation texture - if (accumulation_texture_ != INVALID_HANDLE) { - glDeleteTextures(1, &accumulation_texture_); - } - - glGenTextures(1, &accumulation_texture_); - glBindTexture(GL_TEXTURE_2D, accumulation_texture_); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width_, height_, 0, GL_RGBA, GL_FLOAT, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - reset_accumulation(); - } + if (width == width_ && height == height_) + return; + + width_ = width; + height_ = height; + + if (initialized_) { + // Recreate accumulation texture + if (accumulation_texture_ != INVALID_HANDLE) { + glDeleteTextures(1, &accumulation_texture_); + } + + glGenTextures(1, &accumulation_texture_); + glBindTexture(GL_TEXTURE_2D, accumulation_texture_); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width_, height_, 0, GL_RGBA, GL_FLOAT, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + reset_accumulation(); + } } void RayTracer::reset_accumulation() { - frame_count_ = 0; + frame_count_ = 0; } -void RayTracer::set_config(const RayTracerConfig& config) { - bool bvh_changed = (config.use_bvh_ != config_.use_bvh_); - - config_ = config; - reset_accumulation(); - - if (bvh_changed) { - if (config_.use_bvh_ && !bvh_) { - bvh_ = std::make_unique(); - bvh_built_ = false; - } else if (!config_.use_bvh_) { - bvh_.reset(); - bvh_built_ = false; - } - } +void RayTracer::set_config(const RayTracerConfig &config) { + bool bvh_changed = (config.use_bvh_ != config_.use_bvh_); + + config_ = config; + reset_accumulation(); + + if (bvh_changed) { + if (config_.use_bvh_ && !bvh_) { + bvh_ = std::make_unique(); + bvh_built_ = false; + } else if (!config_.use_bvh_) { + bvh_.reset(); + bvh_built_ = false; + } + } } -void RayTracer::upload_scene_data_(const Scene& scene) { - // Upload materials - const auto& materials = scene.get_materials(); - if (!materials.empty()) { - struct MaterialData { - Vec3 albedo; - float metallic; - Vec3 emission; - float roughness; - int type; - float ior; - Vec2 padding; - }; - - std::vector material_data; - material_data.reserve(materials.size()); - - for (const auto& mat : materials) { - MaterialData data; - data.albedo = mat->get_albedo(); - data.metallic = mat->get_metallic(); - data.emission = mat->get_emission(); - data.roughness = mat->get_roughness(); - data.type = static_cast(mat->get_type()); - data.ior = mat->get_ior(); - material_data.push_back(data); - } - - glBindBuffer(GL_SHADER_STORAGE_BUFFER, material_buffer_); - glBufferData(GL_SHADER_STORAGE_BUFFER, - material_data.size() * sizeof(MaterialData), - material_data.data(), GL_DYNAMIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, material_buffer_); - } - - // Upload lights - const auto& lights = scene.get_lights(); - if (!lights.empty()) { - struct LightData { - Vec3 position; - int type; - Vec3 direction; - float intensity; - Vec3 color; - float range; - Vec2 spot_angles; - Vec2 padding; - }; - - std::vector light_data; - light_data.reserve(lights.size()); - - for (const auto& light : lights) { - LightData data; - data.position = light->get_position(); - data.type = static_cast(light->get_type()); - data.direction = light->get_direction(); - data.intensity = light->get_intensity(); - data.color = light->get_color(); - data.range = light->get_range(); - data.spot_angles = Vec2(light->get_inner_angle(), light->get_outer_angle()); - light_data.push_back(data); - } - - glBindBuffer(GL_SHADER_STORAGE_BUFFER, light_buffer_); - glBufferData(GL_SHADER_STORAGE_BUFFER, - light_data.size() * sizeof(LightData), - light_data.data(), GL_DYNAMIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, light_buffer_); - } +void RayTracer::upload_scene_data_(const Scene &scene) { + // Upload materials + const auto &materials = scene.get_materials(); + if (!materials.empty()) { + struct MaterialData { + Vec3 albedo; + float metallic; + Vec3 emission; + float roughness; + int type; + float ior; + Vec2 padding; + }; + + std::vector material_data; + material_data.reserve(materials.size()); + + for (const auto &mat : materials) { + MaterialData data; + data.albedo = mat->get_albedo(); + data.metallic = mat->get_metallic(); + data.emission = mat->get_emission(); + data.roughness = mat->get_roughness(); + data.type = static_cast(mat->get_type()); + data.ior = mat->get_ior(); + material_data.push_back(data); + } + + glBindBuffer(GL_SHADER_STORAGE_BUFFER, material_buffer_); + glBufferData(GL_SHADER_STORAGE_BUFFER, + material_data.size() * sizeof(MaterialData), + material_data.data(), GL_DYNAMIC_DRAW); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, material_buffer_); + } + + // Upload lights + const auto &lights = scene.get_lights(); + if (!lights.empty()) { + struct LightData { + Vec3 position; + int type; + Vec3 direction; + float intensity; + Vec3 color; + float range; + Vec2 spot_angles; + Vec2 padding; + }; + + std::vector light_data; + light_data.reserve(lights.size()); + + for (const auto &light : lights) { + LightData data; + data.position = light->get_position(); + data.type = static_cast(light->get_type()); + data.direction = light->get_direction(); + data.intensity = light->get_intensity(); + data.color = light->get_color(); + data.range = light->get_range(); + data.spot_angles = Vec2(light->get_inner_angle(), light->get_outer_angle()); + light_data.push_back(data); + } + + glBindBuffer(GL_SHADER_STORAGE_BUFFER, light_buffer_); + glBufferData(GL_SHADER_STORAGE_BUFFER, + light_data.size() * sizeof(LightData), + light_data.data(), GL_DYNAMIC_DRAW); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, light_buffer_); + } } -void RayTracer::bind_gbuffer_(const GBuffer& gbuffer) { - glBindImageTexture(0, gbuffer.get_texture(GBUFFER_POSITION), 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); - glBindImageTexture(1, gbuffer.get_texture(GBUFFER_NORMAL), 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); - glBindImageTexture(2, gbuffer.get_texture(GBUFFER_ALBEDO), 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8); +void RayTracer::bind_gbuffer_(const GBuffer &gbuffer) { + glBindImageTexture(0, gbuffer.get_texture(GBUFFER_POSITION), 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); + glBindImageTexture(1, gbuffer.get_texture(GBUFFER_NORMAL), 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); + glBindImageTexture(2, gbuffer.get_texture(GBUFFER_ALBEDO), 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8); - glBindImageTexture(5, gbuffer.get_texture(GBUFFER_MATERIAL), 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); - glBindImageTexture(6, gbuffer.get_texture(GBUFFER_MATERIAL_ID), 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI); + glBindImageTexture(5, gbuffer.get_texture(GBUFFER_MATERIAL), 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); + glBindImageTexture(6, gbuffer.get_texture(GBUFFER_MATERIAL_ID), 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI); } -void RayTracer::set_compute_shader(const Shader& shader) { - compute_shader_ = shader; - Logger::info("Compute shader set for RayTracer"); +void RayTracer::set_compute_shader(const std::shared_ptr &shader) { + compute_shader_ = shader; + Logger::info("Compute shader set for RayTracer"); } } // namespace are diff --git a/src/core/renderer.cpp b/src/core/renderer.cpp index 056c6d3..bb1d2ec 100644 --- a/src/core/renderer.cpp +++ b/src/core/renderer.cpp @@ -53,13 +53,13 @@ bool Renderer::initialize() { } // Pass compute shader to ray tracer - const Shader& rt_shader = shader_manager_->get_raytracing_shader(); - if (!rt_shader.is_valid()) { - Logger::error("Ray tracing shader is invalid"); - return false; - } - raytracer_->set_compute_shader(rt_shader); - + const auto& rt_shader = shader_manager_->get_raytracing_shader(); + if (!rt_shader || !rt_shader->is_valid()) { + Logger::error("Ray tracing shader is invalid"); + return false; + } + raytracer_->set_compute_shader(rt_shader); + // Initialize screen blit screen_blit_ = std::make_unique(); if (!screen_blit_->initialize()) { @@ -116,8 +116,12 @@ RenderStats Renderer::render(const Scene& scene, TextureHandle output_texture) { // Phase 1: G-Buffer pass auto gbuffer_start = std::chrono::high_resolution_clock::now(); - const Shader& gbuffer_shader = shader_manager_->get_gbuffer_shader(); - gbuffer_->render(scene, gbuffer_shader); + const auto& gbuffer_shader = shader_manager_->get_gbuffer_shader(); + if (!gbuffer_shader || !gbuffer_shader->is_valid()) { + Logger::error("G-Buffer shader is invalid"); + return stats; + } + gbuffer_->render(scene, *gbuffer_shader); auto gbuffer_end = std::chrono::high_resolution_clock::now(); stats.gbuffer_time_ms_ = std::chrono::duration(gbuffer_end - gbuffer_start).count(); @@ -202,4 +206,9 @@ void Renderer::set_config(const RendererConfig &config) { } } +void Renderer::notify_scene_changed(const Scene &scene) { + raytracer_->reset_accumulation(); + raytracer_->rebuild_bvh(scene); +} + } // namespace are diff --git a/src/core/shader_manager.cpp b/src/core/shader_manager.cpp index 88cd629..6c9c48f 100644 --- a/src/core/shader_manager.cpp +++ b/src/core/shader_manager.cpp @@ -31,83 +31,77 @@ bool ShaderManager::initialize() { void ShaderManager::release() { if (!initialized_) return; - - gbuffer_shader_.release(); - raytracing_shader_.release(); - + for (auto& pair : shader_cache_) { - pair.second.release(); + if (pair.second) pair.second->release(); } shader_cache_.clear(); - + + gbuffer_shader_.reset(); + raytracing_shader_.reset(); + initialized_ = false; Logger::info("ShaderManager released"); } -Shader ShaderManager::load_shader(const std::string& name, - const std::string& vertex_path, - const std::string& fragment_path) { - // Check cache +std::shared_ptr ShaderManager::load_shader(const std::string& name, + const std::string& vertex_path, + const std::string& fragment_path) { auto it = shader_cache_.find(name); if (it != shader_cache_.end()) { Logger::info("Shader '" + name + "' loaded from cache"); return it->second; } - - // Load shader - Shader shader; - if (!shader.load(vertex_path, fragment_path)) { + + auto shader = std::make_shared(); + if (!shader->load(vertex_path, fragment_path)) { Logger::error("Failed to load shader '" + name + "'"); - return Shader(); + return nullptr; } - + shader_cache_[name] = shader; Logger::info("Shader '" + name + "' loaded successfully"); return shader; } -Shader ShaderManager::load_compute_shader(const std::string& name, - const std::string& compute_path) { - // Check cache +std::shared_ptr ShaderManager::load_compute_shader(const std::string& name, + const std::string& compute_path) { auto it = shader_cache_.find(name); if (it != shader_cache_.end()) { Logger::info("Compute shader '" + name + "' loaded from cache"); return it->second; } - - // Load shader - Shader shader; - if (!shader.load_compute(compute_path)) { + + auto shader = std::make_shared(); + if (!shader->load_compute(compute_path)) { Logger::error("Failed to load compute shader '" + name + "'"); - return Shader(); + return nullptr; } - + shader_cache_[name] = shader; Logger::info("Compute shader '" + name + "' loaded successfully"); return shader; } -Shader ShaderManager::get_shader(const std::string& name) const { +std::shared_ptr ShaderManager::get_shader(const std::string& name) const { auto it = shader_cache_.find(name); - if (it != shader_cache_.end()) { - return it->second; - } - + if (it != shader_cache_.end()) return it->second; + Logger::warning("Shader '" + name + "' not found in cache"); - return Shader(); + return nullptr; } bool ShaderManager::load_builtin_shaders_() { - // Load G-Buffer shader - if (!gbuffer_shader_.load("shaders/gbuffer.vert", "shaders/gbuffer.frag")) { + gbuffer_shader_ = std::make_shared(); + if (!gbuffer_shader_->load("shaders/gbuffer.vert", "shaders/gbuffer.frag")) { Logger::error("Failed to load G-Buffer shader"); return false; } shader_cache_["gbuffer"] = gbuffer_shader_; - // Load ray tracing compute shader Logger::info("Loading ray tracing compute shader..."); - if (!raytracing_shader_.load_compute("shaders/raytracing.comp")) { + raytracing_shader_ = std::make_shared(); + if (!raytracing_shader_->load_compute("shaders/raytracing.comp")) { Logger::error("Failed to load ray tracing shader"); return false; } diff --git a/src/resource/shader.cpp b/src/resource/shader.cpp index 73aa0f5..ae7e62a 100644 --- a/src/resource/shader.cpp +++ b/src/resource/shader.cpp @@ -11,10 +11,29 @@ Shader::Shader() : handle_(INVALID_HANDLE) { } +Shader::Shader(Shader&& other) noexcept + : handle_(other.handle_) + , uniform_cache_(std::move(other.uniform_cache_)) { + other.handle_ = INVALID_HANDLE; + other.uniform_cache_.clear(); +} + Shader::~Shader() { // Don't auto-release, let user control lifetime } +Shader& Shader::operator=(Shader&& other) noexcept { + if (this == &other) return *this; + + release(); + handle_ = other.handle_; + uniform_cache_ = std::move(other.uniform_cache_); + + other.handle_ = INVALID_HANDLE; + other.uniform_cache_.clear(); + return *this; +} + bool Shader::load(const std::string& vertex_path, const std::string& fragment_path) { std::string vertex_source = read_file_(vertex_path); std::string fragment_source = read_file_(fragment_path);