From ba05c094398591bc38021ba87ed38bcd05aa0291 Mon Sep 17 00:00:00 2001 From: Erik Cowley Date: Mon, 9 Oct 2023 00:12:00 -0400 Subject: [PATCH] Add rudimentary collision detection --- Makefile | 7 ++-- collisions.cpp | 48 ++++++++++++++++++++++++++++ collisions.h | 8 +++++ maze.png | Bin 0 -> 45283 bytes snowland.cpp | 85 +++++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 136 insertions(+), 12 deletions(-) create mode 100644 collisions.cpp create mode 100644 collisions.h create mode 100644 maze.png diff --git a/Makefile b/Makefile index ff9fea4..079ab69 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -snowland: glad.o snowland.o stb_image.o - g++ -o snowland glad.o snowland.o stb_image.o -ldl -lglfw -std=c++17 +snowland: glad.o snowland.o stb_image.o collisions.o + g++ -o snowland glad.o snowland.o stb_image.o collisions.o -ldl -lglfw -std=c++17 glad.o: glad.c g++ -c -o glad.o glad.c @@ -10,5 +10,8 @@ snowland.o: snowland.cpp stb_image.o: stb_image.c g++ -c -o stb_image.o stb_image.c -std=c++17 +collisions.o: collisions.cpp + g++ -c -o collisions.o collisions.cpp -std=c++17 + clean: rm -f *.o snowland diff --git a/collisions.cpp b/collisions.cpp new file mode 100644 index 0000000..ce1c453 --- /dev/null +++ b/collisions.cpp @@ -0,0 +1,48 @@ +#include + +float abs(float x) { + if (x < 0) { + return -x; + } + return x; +} + +int signbit(float x) { + if (x < 0) { + return 1; + } + return 0; +} + +int getIntersection(glm::vec3 vec_start, glm::vec3 vec_stop, glm::vec3 P1, glm::vec3 P2, glm::vec3 P3) { + + glm::vec3 lba = vec_start - vec_stop; + glm::vec3 v01 = P2 - P1; + glm::vec3 v02 = P3 - P1; + glm::vec3 cross12 = glm::cross(v01, v02); + float det = glm::dot(lba, cross12); + if (abs(det) < 0.0000001) { + return 0; + } + + glm::vec3 diff_start = vec_start - P1; + float tn = glm::dot(cross12, diff_start); + if (signbit(tn) != signbit(det) || abs(det) < abs(tn)) { + return 0; + } + + glm::vec3 coefU = glm::cross(v02, lba); + float un = glm::dot(coefU, diff_start); + if (signbit(un) != signbit(det) || abs(det) < abs(un)) { + return 0; + } + + glm::vec3 coefV = glm::cross(lba, v01); + float vn = glm::dot(coefV, diff_start); + if (signbit(vn) != signbit(det) || abs(det) < abs(vn)) { + return 0; + } + + return 1; + +} diff --git a/collisions.h b/collisions.h new file mode 100644 index 0000000..e6e44d5 --- /dev/null +++ b/collisions.h @@ -0,0 +1,8 @@ +#ifndef COLLISIONS_H +#define COLLISIONS_H + +#include + +int getIntersection(glm::vec3 vec_start, glm::vec3 vec_stop, glm::vec3 P1, glm::vec3 P2, glm::vec3 P3); + +#endif diff --git a/maze.png b/maze.png new file mode 100644 index 0000000000000000000000000000000000000000..a21986fb3623a30f6f13e85dba0fed92bac96aa2 GIT binary patch literal 45283 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̴Z#3=4b;U?@a=6*sHyX%xO(TWlJHioheij?C zPK&HraGY+)2St%n!>%Dn6!R=^!*?iY8?4+<(|f++*-(=kuAaL)+_c=`Osrqy1Q4`f z7|3yAs)uHoL>{`^T%y1JuLF%BHJG zgC%Q8tPo2#dw8bb@C zviq8DA%kJN^U_s%U(Lz>l$V}g{9BW_$1He!;QHujs6b7nNsmJJqcg&?*sJ@`_-6`) zB^?>Up~NiN5aw42m3$imeupJRMb%ok@6Eu?2LyxrTSAU=3u#h`Q6hK@yD%2k>F*|X z&iut0Cv#*R$|IbXW9d&kw1v|$)RJuXE*pIm-gCdHS5z&@QDU`_FW&NEY`fZes0B{3i~sIo@}uyiKX7^Bh8Tu#SJ_D>oGj97`pc7Dy7UM4|q85 z?4;8StD=($Cv4Q{n^DoJF`g&nQr_3kY@-?w(qW)4R=sT-Pw(=?`hhl}A0)kS91*p?kRGJ?)-gK0qHHM(XMFoU zYTQj~uNlRe7>yAfUhvUQgl;=JF5wY#1Qnp z!R}_4!2p2k3z#qD@AtI-PiKTbAcxssaLa&Y!ULM$d4Ke`HX<5c0cG!~chyGl&>EN%3U!d~)V~Xg^C$E^QTAyD)<^t{2_W{;GzXM{PL&NK^bxMrX452AKD(pnR!2_8~~z;b&eY2MuJloZjkFTt5K|L0g8Suf+>tEcsN{XIzMMy?;g&IH3~}B;XL1LkI2=gI~U~k zKwWKaHX_EjA&!5lJwq&ZwY!p@@~mv>JHBv4pV3D0T{JDeR{4!3e`hl8&SG3H6G>qA z5#O&?@Oujk0m~O=cyczt?V zAFu@HBDl>x_a?~bY8Q!?6m54DCvx0*BcmpgJ;WE+ve|rcRg}~By zYMXM*t49NPtHowKdiClJ;m>jsxPHB<)p%z3I*${3&d|CDzx``NKg!#nvOP5JD7)sB z9>nZpzR9b^Qx4(UTD;^2LiUb^&|{iIUT{;Upa1)zXtY$WRLB0e+ArOpy!I<4T!aOt z)1ZvRAa^VrBmk4(G~-1z`_loJ0ESG#M|aF8Buo5p(E|X7DT1e)FS|2{pEIVg5b?Xr zuiwAvGQIT(ao@M?BEn*(&FZQ65zNg*r2jQD$pzX4|o^WSN`Ww{T| z-{6u^)G)c%fw6{}rMmh*%sldof0x)w5>rbrO_ty?jwVyf%VvlIk1Bd*xM!GsSjxjC z$gr{ujH>49{GY@7Z%@s?;0ZAmrSM17}BZu^$y$|Wx+yYvsy6g7LpJ)wIO}6H*wWbFzqN}z@4OxlBOa$l) zLS_V2Fd8!OPPQI{*Cu89(G~o37>UKPwSLo`c8jaI^S{TTYd&8;P}?+)Ropsu0D1MV zSQT$L2!ASGdK;Ztw)!UNJgS}x9bxCBl&{#+iPj;iyo27jNC8mpWo+O}t18kTVJ+D_ z>S-67aCr(~jN&IFB9sXuN$FJCI<<-+Uk5D&SNkp5AC%fYwy*g^`n%@L~h<5 zC4hKjQzd)BnZt|DYilYA=)uDlVK^0QcjRPS^IaT`sWUe7a%p;KA^Yx9Kh5Vov)#q5 zNd$WOa`$s&D$bOscDt{-XZ7T%evM6P<=|&+F;zDn;1!w%&{`fxAyI2xK zn+$9WFBJEy;Dyv940p@rDi?=E_73ooX6L;RYD{vyiXnHpTTPW4;?;7tf8XhQOts8j3w!dT5U7!ky_ z{}KS0Mt`!l{VuXudf#^?qW#gqFo)&+*?e&kNa!4wJplc)CJ$hKPW{sw01M;)zHj|b z`tkf3fMQq;fk+?F8JLTb@*J@28j1|?1faPdeXdryAJ)@cF&)9v*=WL@aUHTOCO!^ z36mzw8(APEA3MByY@kW1&^ejaxOVFq1TEafbr2?gMGE*;H!G6Xp(~+xZWTV)7I%gpHhK z>=gWH|CEBObx|1xqOUgXRXN;0MMz7Bq;n*!da`oSlVMOlt5c_vyRNI^ByxNACYxOk zp=!w%B?OzSnerE&9Y3%9kwKdn+J zIyuL?FaYv7m1eXsdD%FeK3^luvL>VWHR`&WQEk4lav7J(89AGC6F>Bm50WUx@7hoy zWuTz9pXXY7nf7ye9k?UaMuh!tFnCDdd0%66HuoB_ETtpXX;U-ZWQQTLcr(~z!~M}8=Kl04hZdI+^nM16=TpFwKa1nI*An6`B~s zuamxsqSdg1HE$?PO`B4DO;FbD@@DOx%FnHQkr0a z^_6fx$j51R_IfK6Zg0*8K`lTAzR}SwL^E!cID;?A+ATP?p38m z(7I7uxj0FpPKeD|AGJfqPaP*+0pG=k*Q2+h^gek-&G+eZ$uxGo<(kKnu@>+Nggk`etysjpUn;_Ov2b?D#qb#mIMlSrARhKlaIt`~jl&9@^>`>(EZ7v{a_mmo0?%lSEs~CfcUxCf9 z5uVwv3vrk&8XS4}F%POhO`3x8Y1Y()82M&uqd#33@%e{>9bsnyPJ@d;yeoVwBR)6( z_A(XP^5F{W0zCEF>AZa}wI7%hs4fvXDT&Fi&`siB2K2Z+9#o>7&R4y6r`O+3j4I0r zuo`%m;G#3aaQ=HeVOo}f-I@`vfCAYpTua(-R(B@vl3$WLV-H#mjNfueq{{!EP;twn zQIwIt5YC)OC~z;-x^wVbDV^UM(F{vWZ!bGAWF%JORJ*eag;+&DtE?GbM|h{eiEpZ$ zyK%al5^9|e%2m`GsA;rZ@d=D*#l;@bs8?9}Sy?3;xnf!F9Mk?4sZkx@;Wke{uWuKj zp6Y|-8poiA`Pfz*r?f@#FTr`(&-8D%P_~M8_qZu*CkWbZHVQ9SHJQ=53wzdniI@r$ znD9MYe0#;6RZYWjhZPUicKQ~S$dg-FF;Rp4GntKJ(?B7Dx%8A{`Ss4`S5Ue z!zLnpyzY)-JiM(e!mB8oYoZvm85K^eH)X+LH8H9eO!iEND>RD5;4)L07}~UX{mKtP zyInx~eCQoNT+{1q*HF%D_*kG|Ezdoj zeKhCG&^}~<0ZVslna{js%$DO?V<2!Hc)_8Zj5>gX3_(PlGnq7D)Qzih@iIvuK2#_k zdJ5oK?wKpBj?=9?kznyoAh?-RRa_+;Ta?ZtBeS+k(DuEeur1u*u=6|03k0h%`Ai5n zeL5^)W()E4opvi8lT8?ydjv8}hbX^*w403GjNxGzLV@YAh|@P_RX4WI-TJEqu~l<= zYc<+#8_WviJ%Xs1YGzc7x-;v{n1rV>2^u1Jg_oX-^$Rt<2ouTMev9OLiP4|VdR4Bj z?sd=>moRPCrCw$S%lHhiRf$?!?WKLIxaY-8m#fw7@NerI^57Brnf7^E=WDFE5h*%` zojs+Bub4~(wt&{# zoKySPmbu5La8!V4^UFr<71IaPWK7ZVt$BIXLTl|%#+)UZ(BRGDi-E0W#K^fogT@EP z?+KfF`GWRmLpt!L7s0a!*K460%=3iLJb~cn-o*Y#Hv26zx>)=daYH$OsqW=rm~B+@ ztY|Ksu;c0fb1eVff7iM}eMtn6lmCA0ykTfSHCUnM=15Ao(UjE3IgVeY-+iw8d~-}^ zrMONFYu(`6rPCBe9G3F72_)5#F}t;2s-F2E*UVM!_$*$wsWQNtoLCy z`wTzvn|B&{)_qi&>nUTfC!-cTy!K9~lD+Vqu%2D)r%Wjs#by$hBm`#0{Hk=xORAmQ z^kJQjXzQC^i3-DA?q=p;<;zC;IndkRwYKI^X*n#Fujl`^rqQ4n^yYZAAlj*hUiU~B zjB!46xfhqX!0WgpH#*Ox(L+%`Vx@;qE+s?kBO($V_X8OR-QY4-c4sXET}iTYAX-UA zGMNAFgGhP*=Qs;tka|pVBNFefyjpB*y1$9?0 zfwm=I^Kpd5C5sB{a%8=KNDwy&UL%~ZPSb342=-ni>Wj9m=38KhCew@Vn~8<^cdyOR zaN7poH)!EQS|7dMMh8m`E=k%`gbIlp z0$@2%)sKv182DL?7k+o>@-Iy*5G|;8>P|rPe(&6QrWEn)L;RAw))8OW+dbsCU{?v^ zV2Jn#$Z!pi177-lansx=h8Qk*RH^W%viIgSg5v9C{#R#V`u(%&I|VjUe}!W@Qx0>* zrnsUQ_an840m#$xVVA}Eh-J>ho5urmVuCJXp@OQ)!eQC>s-_pGEaMVk$)PjUyd7e( zA*({8*&12XYCqBGH|_1D`;CX`Z;4*j_Q3p_s-xR9ef^%UcUh;u8o)bd&8GPy_)Mou zOKF4OC*@|av+80hkH@-*RtoxWE$#}j7R1m-nQ}gd%UB1VR97zO1wcqd9w=vKU!aqqC! zs2|0NI#1rE@kQIukbv;h5f?ruLNmq*{wfnyo5O6zy2&#%Vv8N|P!C@|<*zng7&*gf z{>IW1>=wntM(K7h4QH^45w4P<3rJt8;thqriHLVDRAyoFxJ<+ZDinjZF2B8MyLLQZ zjAsNYY*oVFC?P=vUPKV^a+>AuR`-5D!r9Zkr4T>7Lko0U=iRU~wLh86Y{j=fUT!`W zu{1ZaNNvqI2gx*6Jp}ToSom!XLV-fWP0frQ8Aj|Qy%_uZzaY6Ca~lQN8wX32VK*nw zCY`$3y?W%Eu0y5+iDj|y%vfz&U0b}j8r_;K$aW1c`8f1x6*=&3UB0DvoNM*%(S76g zNIeJ~hD`CEov54}nr#nM$?XW9m*D%`6E^CEj(6fu>Z*8dPiz$|3F59!*4$D=F2la%Hp;Gh?knH2@ zpwl@{WIfECO33b0_lxX(= zZG?3SIUnn>S;i+jnvG}KA;`Sumb7y>MJl+L9JsF`+Peb=Q&pi6@7T<%-K_<3C!Ax$ zC{6}K5pZ}@hzkh?HWIM-!BjjP0oNt`pb%XE_Zvoy9)6YA&8YW}PKBjnuUD$kH$y!+ z%J`(;W4ciXEHBp%JbZJblYg^c@@k-przeg@uBKqTGckx}RE?qkHtHLu z+4f#!baFaoiSvE8{>)PH!Q}M!E9z4N8CDa4Jy-TmFQg^R_noHT>>@CRLbYQik6E_P z-KV*e8+X}@o@wcG4842fT2$tFW0k*R#NKB~>RxCVPsCx%s4vCMUpfYI&P$eyz0GcY zUAFd1BSl+xcS2V-s0rw@Uy%eD?49qlq67^=jn7hsuq_MY3gri;?}Y@0K3G^deX4=h3JCX42Ex>Cnae&;_>SvmeaAQK^I;#xXa{4+acL23E6LI7Y!1r;U-^2or9yL7RI3>p0bFsfa< zvR}QGZN^+poP$}Ve6~n2z^}lr2kok1MidRy^4ZoVYi5;i9VM#v&93#gbJuUhvK$(R z?A-fo1hZGEgbN&e{Se~r=kC#CuE zcT)={mm|72{9$&ZlGF?_as#$)*%lV@zlo6#FfH!jD>3Dq4w2UdbC+JQMEgc7a>y*m zFDh>(%NZNT7>adsFd$G}tTtXco^&+glgfL(pV=2Z3wm%xK{tF*t=~_p@v3P%&odU4 z)uNv)py6ju7aBBbtHYtrfX4JtTdZxzlBw9qozybC=I#kjTDVV?51X1Z5J*t_KU95V zcwJq$_HNTyjT_sxoyN9p+ib(ewryueJ85Ivwr%H2pXWXAIp6xV*1p!Yf6X<=9Jfa9 zjo5L9o?;?17eTENI!egPI<;ful!7dby7;W@pU64I!k8%%Y=gbdPX0)84o-`)dZ)%Q zrRs!m29L`~n5PdqKt(kmmi6q^Pj_q<^SoBl)WWAg$@Ev_Fkx{WPI)*A-oFrVB%cwMFKTiQdAM;Gv|C;(fjRd3w}Z95if&M) z)ZyaG+TWv+X8|E?$BP@Dj>9x!9V-gVWcqF`k@!thH3bDf9}NjL-0Y<+*FClL=J)gI zkH^+^=PEIp1w|O~<*QR@S>dxamOC}16%_m0@X+R5Dj9>qa5?K#F@b_Z6`%o?C?2?C zrA)d5y?43p(kgpM6(pdrGFaDdvOpC@NG_JG_M z)DM4ioKr}BwYS}Yw3AN*6_VNw_khY+iJmyW&o%j*J3c>*U z362w}9_s;0B*i;mw&$Dp*Ky>ZCBZ2<@F5)gpn%i?`sQFkVV?msPy(NQ1_BiAz`2eH z-6z@v4x5-ZLGYEM2iLQ}vNod-+ubR)XUC1ZBe$y`SnB4noA|~So1;;;paq7rMZ<)b zJG5IcI+PR0Bo(JIyNjR*no@p^!&?RaiXRPDzulNlK07WGOb!u|6Z5 zZGnhM<-$99R#3b2{HZ^F5bqDxZv(Ub$kj7FoT_9?t$y}9%Qjo@P0!SGrocGo%&gAS zYPlbk?Tt-Zn0%TPQF@gsEGD&^e1)fV{~1=;p_eES9@=HZ{&5=KP>dh4#wtTp+;=^} z;jX-H`N}POSneL?`-EJSJwH7#tWkm6P=VuKpH0qg5-rfQ9e6e)YOM7&ZN*qBA%vII zSNddh5-OEe`Itw(f^D*gF8^B?mu=X~eCDjr*4k~7wxyop)!BrLDU1(skp)rM&2eP} zd+WNngDSmZSzt7L_~_MLrs>a+SJeT??@7%Xpsg-EdOT@q@=Ev87?C#xsT!`w!Tdg- zHiZ3SrQuJ_{a|bLBg@r_WkFrJpM-uaP{PaN*z6JVWdf$xX2`%6T!MnCmuZTyB{c4ebP3HSj2jl8Kd+Kn$V!Y? zqgkvrr}mKJ$A@aJGam1*IK(yvnf1GjEw;0R+-g?}$GNae_-tnfHB4-1PI_%GYEQc) zmpKM1PwpkPk0W2}>59DJX6vg(r2}=bD6a)hn${ip=&F~qgtdi$B0GY=_Zl|gR4KTt z-jT*#U7%+zT}Fk#H1BNl?ne{fk&RNfpXiE$f6l9ruVNv1*r@tyyGZKf+MnO?Jv$f- z$Hkla2GC*VKbajC_=ngnZouR?L%N|AQ@^^Bw%TWa`nSyqb-f{c?@GMgE3j5p5O6@J zLKiN+1%i5U?7{O)C88z**ZhtG_WE_OS-Ep6(pP%t&c-b*)AG09adbV1h`%)5)y3Ge5^9xB_l8+QvH zN|c(Lat6UPu}~xZ;$WjUoqW#sp(@rvUcFwb<@xF78{|gPG41rq)H?E+?9!tsst4q5wU72|4@5F-GLo z)$g?945bv`xNoFqP zUd@xwjM0*fVBs*8@fVg26Ig4BF`PDT%IGspmemb!$=C#yfIeCay6h(eZFVhlh7;&V z6#^r-6TV7T4B=$|?x#es=M^%hUsF{=&k^ltqU*Us+<3`@Je?;QR?P3Y_#vQ6XZ@I_z8+XEuPk-Col^_{- z0on4|l;SisTr{eA=^FS`8q-zUsOfQL@b_zmz6~`x8IG6k>RsMEAC&Wgd8`@oyD(Y| z*q1I#JM~KnSgAed5_Tr>D(&JT9yZuaF^TelE4nm1ASDw)ns?b4s&d8(Z8Rt8t6`%Dg;3I!zO&Bg8(-E(EU=*gA35Z`isS| zJ4}52i@0GMwrWIPs1S-yh zsphpvTHQ2WX0fN=*!AjbgyYKGWx9x~SPhxf(#EeQ=4%C3CrlGhVG7mSk z&G_5senws@ZiE6>RLO}N%L(3gqq1jAFmwZkUHW59CY>tE>sN}Q!n6vGw_m_JrU1JK zF15b#G^6e(%X;r`Dfu$zPs!E$MmS=MaVy30%BUk8c(8is;pgk0Hcc8eVR_cPH4bk3 zU2J;mU;B1Ac|G2jCG!j6EpOwEJ8z32lNevpcM5xYtaKN4E8HIpR0{G=t2!K_a5xDM zZ;!G}qLELDcc5LtEpDcU)Q^@YAt2HeL6J)xJyXw8HJ6tie)OejCOsvsi#5gTUu*;i zm%}z=S@oA)a5?+OVxTL_;k{vKaV~erobne{2!gRZ%IiE=e__oAzP-H_SxA<~xF0HY z>C4vce7PQp`%ER#>D7ErtE(Gin)TXF@5@8k6=-~SO}ABIf<=pBE`v%ma*`p%lsbw$ zOGKyvwPU&D?yi6{Jm<@QCnWBiosZ-^=%hf0UM+zNf~hQ`!BZDkPx$q0`BP!!`XocO z(ro^Z2rCFCJ&DX;eP={(?2h;`X>aZPi^WV9d*Iv4`VzXSmNYz_RT>#-!GSavkAq`$ zR#?=fc#P=>_FZ4&Y;HTy5Xo`86b?1RmH1U@$LctDX?#u9dTtav#VL-(eQol!2IRw~?xF~t$eL*)K&A8nv@jatY5Pc!Sd8V$I zu*cU(b>kP=t;op#!8DE0nWeT!S#@d**YHFci8Ob-I`9G|GP zE3m5u50j0LUxdceF;`X3!fP>UUN2)+V7|v*mdGdP-FtA8W(Aan|-ubk_5J;^$Yq?M*b4osY1=yN((|g66kT6i>wtq|243LD@(IOf6AnkLjAddx zMM(yVzrZ|!)!)7ZOYEmtAJ{)Y{ojxGe;W-fvWWvjxWB&v7!WQ9R=|?aG+WTN%GxBjxA!V(!u-{xmD3YO51}+Q&fS%@=N9xM3D5Xw=T?iP{Eu9!U|% z2~{JS?WXWOi=rHShDs*LrYi%)~SL%Q`^d8b28t3T|(LfH4zNb zA#_Hj+S83QS=YvE50I!{jo`Jf!rT9lsLyW0Km#!s}W)fV%^2Vpo+ zAM@jB8+WP@MQGeqI6AT#`@VLaK7kCFNeB-UH`1BoB5V)39hTwN2>jfCSrusXa`$4l z&r~SbqEn}Jhz2<(+MM=xqlJidDQnyB+`$iRB5Rk#l!nW(xIjx>YCdeVDqQZKcmikR zRoK_Es$zd;g4v_-U=_dF1po zX-=E`YB^5G;{E=-hFanyZz_}-`tW)eZv_W0@%ZWhaDu#`zAI4$&icuagZP@7ZIj(Uc;@c zz}R(#t482Mn@U_jG<)>b*Yv@uF*sn|jZGxn5W6>cWuM5r8!A~^$GRl+ImSN9&HbxR zpk8dLF_#Al#wbohA&~cz7><{&?-Z_F#l@dil_wKE(-j>PR5IPxH~40~uE7Nme~FDt4g-k~ z+{r=^#CsC7gcEtZb+%d_n<36Uac~FeZZ4+mQiozE?cz{SzAzgqQJvOIBvC120Nv6? zHPq;eJG}JTbEq-Bmq_-9A(qnW`jSL_Ub%WtSbNWwgvoGDNKvn(KoGeaNtZ_FQfW+9 z83Bqg^*d73?gGKiBJ<_3vW%FvYken=1CNEiq3LBBt>^xr(#kA?g^cctqo2URa!YkT zN%yC|CZuBvhH1O?O&b&`TT~VQo%>n)^5@73KiyN{FFb?lCa=!cA#>`d`KyqypO3gV zd>WkuY3@@fZ8M>3UcEyJ8kH-Skp)QmUt@N6Dk|N&W81l*$rk4#_{d@k^R({GxoyRV zc)iH!RCFc!*0(mQ5`n0&i5^>ns)IV!I71R4Wo`Kh_2x@_oLafgV}-$|z5eRmj`Ow2 zGDmNYyKkzAC9_&~`||fFa_;YCHytpa zYgPg?ZC}t)HiJ><9&uI2Il)gn#g5Q07?9ATpKWqkM@o5Hgfba>)u`xU<4a_{vV3uf z^08-^Y~{-;LabWF#z>owal=9t;ePe4gZ0s_fUk|VKQK|R(MliFKJg6j1eOgK_Q5YLt@< z4!{9qJODO|!rm3aPNGGYRfl(uE7{v;80R{M56aB5(+}O;nf}ow`D^V@sMFiCXz$_~ zoqqyw;JYire&c8E8u_$A5$(76IXi zj*tI89^jAv<-Z2Chtn@lj?pIDoQ?p1ZS*pKlW!q7Oxer?bq+cr(bd+xX&|Jv zN{zIyjjtl@hrCUBiNyPPJz$3KdKm_&z(?JkIIq(zIyBzZV=DA#i0vHS!%V~~x9nEA zdYhcv{k!8PBu=kXFfG$9B``5DwME~6NV>*&^xArZlEy%w!1sk76J^?jwPk+pB;cNp zfwZ!Vlf(@vP7T{4>R^P)jB!d3vh|N#AG~fCBeyIYkgOI3gCA3u&o|3NfADPMHHQ<& z!oozz^lao5?{w@q(A_X7qp|x;%VIE|(S$lWanvnCyC-(q%MkdDy}+5skgnp`nmy97 zgHJk8o4YFO5^>+aBUQz8%-Votif^}RN_;dmHT_5>ynR$4)P2BHYnY0=Ri-*gJESxS zKB`Zo*-8~=)9G#qqKHdzP>Ff_jn?B@M5)K6V0Dtq(9*m0 z4jIW&YQ1BwIKoo}B!&dq@?NQ4(Q`t9YHO-?5#UB4M1jSBAozshb+vb8JUd}Pn9PMI z#r}h)lyg?+q$4gtqK%z$LqS-(Rz%sw%{(4(3X&bQlR~tMlU1$Yb{T;e-XIWWQ~S|v zXO`v`NkJl5jWEA}Jl7X<{346Xb%t3`+A2Y6HAv{ypyMuHmG+czy-1`7VT^SxDCgPN zZRfRn{smX36Z(EBoX8%U)E1kskv|Vpl44k zxcvua)#B-*mLBfX!evMhZew7-XA&>N2&9|6EI8L&#F!3B+qCerjbme6ex>!$jHw&S zJ$L5O#C*6z=bgLBAEyz4Qoee0)Fs(&F8yXLZ1^wrBgZy3p=ygAP|g{d7{3sV1NJip zkC`{RQ6hqG2{>7#7Iky>Cbb7iC&;rw0R09}0Z^aNasXc`iKE?)4FGThc>33_4gmbF z`hq2<4FKGI{s0Vor=#?r7l`#Gax6R?`ojvbRtsl?*|LY)E{gQ7QOI~P$j*w+tQWP> z5#&@I+=ZftA?jWu3kb=nPpA4yQo~eSuJ*LI$>*H;-hxci`N&3ipZzDZ%>(d?3L9^Ve$H2w(0UAc*{l^Yn6d4XqI>saw6vOy_3gq;kN~ zI^8b(T&RWkFi=K$Y`(mUhrCfRvgvR(QmgNZ8wOA0hTKnziNsD?eDid}B8>v+^&`6r zFB%f}b*?^i!C4I2b9u$EesWW)yFvn`K5EXaB`?r{!EOKd7C+)CcB!Tyx<{2rg) zF2PxLC9%5So-(pfrS3p#-$#5BfLnT>$=sY$`751a*O{W`AX>V{=R0eKBjlG2kw(dA zOi#i;8K2ywIhZ0G)@1p!R$u3iS!+fk6M2&*N|By5lMFWFqyxpgE%k4;e8y_yDp-h! zsm%`3_WO~xWevZ-$ph*U&iRH;eVnDiqR2n)BW`8X7+8A6UiP>8=WhF#LHF&n){_(35BHIJPo`em5~ND`kLw;1-`1+l56%5uUi8DI`(G z;MOyoo|~hDj*e!FzNe>lkDN-MD-O+dJP*As-gJn_YBz}q?XY3&^vo*?&rBN5FDL-{ zqB|^Ab&6<7P~>D<9frFMn!b)=Y4^k@9yBz$VJTTN-*NjK#5w47`g8{Gzu4WTe162i*QcZ1)FHMq)ORu> z5KuUEIzKoohyqNhf4`NI7f9;sxvANYD)J;K-P?myMimyC)_Ej;xz08)71coO0h1aX ze@f{R%J;P5-gisV4W>{fo=rRUoM8rlC*8TN7Joy7lqG})Lh@J1D~~7jZ4FWQINI*_ zr>zFPGt%6M@$3j>kwb`y{DD#;tnUkGvhN_x&17GArjgu>4Hg1&1Y11}oQ|X~FoyO4 z6=}+$fUNv}&paUS{p#lp-Nt>JuP&2AXyg$=u)b}@Q}PzUZ8Q{)1POZ~-QjJ!g7y2S zD_EyYEIQ=SL}XDa^WX!E;z$roG$oseVWiIM@CNxC$$)h|Z*W18ZMu_VCzv=9_KQ4_h^s69?w z|CiGIxHcrAZyIGefumUtGcOW3j{k^DPA|-}K!j19Qr$6&f&1SQA#Cof2XETc8htlj zX}u}M5F}aWT`}X_Q*+|`YLnE5KgsRb?b0NVF3b5c|FQq-IrKPNXs(uQ>#HUzR%O|e z;cy<#v!4Cim-l4&Ir7I~>@bVo^3ajYDC?R(*yg~gP5N~j^QD!O7?jFh^#konCJDJNpo1V&Ga#vWrD^LOU4KPaDf6^3|3_n=b$%ja_V(1Sc5i{vvrP%{cwWIIzSEm| zT~W=5sf|c11T2016Vxv&@>Z8IYlS889-li1kI`SmZ=8CxmZ~xn+H*Z)+`=_RrZP@} zHyq|o>rvlRsf#v3%)rabUIy3g5fAnnWQ#d6S45hARHwS^wK;jcWTcI;5&7j(8sFFf zg61^NuebBODUzj^buCgT$1$%d6nk6K-YP>Es3(qvVPhLInQgfF zB?VK{wY&2lb)buMqlI-YC)Nu;%d|Wjrd^4`q++~r=_C5 zb13#>YJMR~CP&KD)qUur`_ktN?%D>hJ_&Pg;|g#451S_4bC9F@?w`Q0#OVY4-$79* z0<>RCX7I-tUwqvpe$0K^CQIhOLKVn|x;1Cf*m!GQ=sxqkOvT6JBJX*`e4yP2G7n_h z<>>2$TBo;r2KM74ys4BXa@#jQ*>Qya`_ca&p~CMNXy@j_F+E=XfXP2-&#)gapysSc zp4+moAkq8d3%+5R2eDe3pvFhvb4=gVhdc)3;kE!r2jNk~`Fv&@Oj?ij0(axXwlgJ$ zWyV%Y9|}2Zfwp7kUii8xHP_5x3WW8qxrw+tD^ed;>(@hGu;XQ_s<7gjIY`C0U3lBD zz>)9O9I1-lZzL=PK20c0p!&oahsY6Hvc2MK`&DT-@z=) z>#^_9hbLk52*cIK;TY^K%F^%8&q^su7`XDRJxwo<<6{eHt3LG@l?F&r<3|$v8jl_M zRoDS$!V=D>(9Tq$!8cN2Px0wkxE)q(r9-qepv`cjViqjxeqaUnN+`H*E0UL-%l=B< zE71L3zzjyk)!qQZ&6q$F3E5}GB2D-18%jgm7quffeV=e$?Hx{=r~{QL-&FCkAHVKD zv?IF_7<&FFTS8=-g*xWd*Sg^j-Avz=)30~%=)STqr4(zLpwelSOxB`lMedHwa0od=a7m>M`Z+*HU~QwEn5C6GRm%(7b9B^ z*ufzhdeg7vI=hlh60_ACTSUvOFfR6)rDVxJrUStFEU9Nq1;u?aDZ_}gg&GnI$`a!y z<|H6OfPQY_R11IQ({EJ08OXdxG#qawJ7#mu7EN)#+LFtPFfvn3(RHMjSOF3;Xy#Hb z-k+ZZR!nOQy?ZKv>i`>S@G6B_Hn!k zSWBG{7p~2)3*dM8>6O&d?LfU!u|bW*mpI~-e%P12#h@~3W$Om`?cd})#Q}EE8Jd9e ztl+6`zg&d0XQKJaNAl)FfAz9DK{&92vUBv#&HbJk05?~P1Bo!KM6zjs9-`n!s#VR8 z5vf4kmwlC;vAs&WsaE!2c6F($?Ab_hIXGML?Rotq3vS09p2yU^8Iuqvd{Vnuph9KZ zX5J2;;6uW3K`mD}cDw9Q1fHva@Hzpu-SgxP(d??9g#l&A7;#c#|2C4APxzCriam$9 zo0EWhui!2>l;bQK9DR}9qjZw)o|IT|>zAcirxTX9tPFyLCslpM7q+g%E{189W&G?7 z_p2TjhdTbp_4W1b%bLe1VD^bx!bDaUN{_867(#*kP!8ffL&wMLr)SQx3Su=Q&F?|2 z5HvgvmMC%j2}BS*$B*g~O>Ht#N9G?4!#}wIeKKY_xNll-;Ys~}5Op40gWx%YO3_s+-jOZNgA!>m(jmx47bo$Za2_Ma?W#x`ZT8fG< zUPa-|m+LQPd-j6^zl?{SFE`bKdSt4;lPCUuXwIM}sWbM8{;Z~R1KgUem&}_M57V_U z-53;8pNN_+EIC3wijU+hI*>2PpvXcuFBeF+OD2DWJ?74LkTT5u7Nq;lmeF?*v-=#C zB1YQjU#)GNrCPQn@)H)K1?!4QliAZrK3`X%1QE2-4VcSy zF580m=!(l|%`i&`2~3yDO7Xoh`Xz8!hnA3Yzo-BWJ`7!ofG1pO2Z#JDSO8=oE}wzw zlviwKKWJsJ#c{aHGZG`#YAJ>OYiUMhyt&am%HGm0ODQF3{%wzg;~s?97r^h#>!-~v z{n^i7TCB>iot{FVGY|Dk?9xLhnZk8{Zw*S}oR zUv8I={PK(5KP?pCH$Cx(cZ2Y^mPE%+e7AD3CWS?Rre$9h``5$SUxky+n4A~`HIu&@ zsGnUGqg<|%_rvU71Kspg?2y)LJEMIt_EeRY;uJ7lYYr>WAp*{)Pm=en&l@(XU?&FL zPha?icETP&Nw;ti8oo01>l6`VwBBv^eDbCYm#tjmS)}avwn=E>**W7Q5Tl1pZl_|^ zNVkN`4In6|tjhD;GV1WqbnPRmQ_I?@%mN8lPfB_H0d5{-v)vU`SKpq}MRfNqNak8% z_D-|VsFm#Z^4t;|X9SDQIQLuxRimB!!3^9MtS1)iYbApcW+i(STxdWJSqACMtk*dn zoqERl97&2eSFvQI_w!9k;Eoe0;C05!ad1kyn=2M;7|SNW2b6pNewwieRo0OytdD|1 zKgN0fdiKQ=dUI*BMWv5?z6@Pu`p1EzE&EyX6$x@&^hxT6N2BdK>XE)4xPh(w{m2L; z!vfgvZ^7+H*Tuc7Dt|m;gULH-e@isOE?aF*ZJv@{dun_$rm$h(U4=^=8aArFBX;Z^ zt(Fq?od?<9=w#>YM|wHoI^+$;i=DaLY8$T#wnqY12=uG(7x|EfyvpwTfSoN{tUEd} z;w!394CE6~1~T`%GGlR+dwfjKJ)?;y&oqgiRGt@_LbI$b#f*rd8wUKAk;nW?Rh&RC z-ESPDe|X*SUCcM|)L*AU`0U1i0q;-w)u9D)@UI2hj*WM#Y9aIsBK%@dKPIVe^sT{l zAOJ)m{*8M4yOfa4H?{;0cOke#W&Xwn`?3Z!T?Su7$z#2SMs_<6y3O%>Im%B$ZFy;{ z*+(cWWuPJ4*BbjawQ@+3(M}x8U>W;{oam@_L2y=ACy7>%FL3EM#CM*ACMGkiWtm;+ z(xyBNyll>dg{V%ySo_Z3A3C+<@Rn=6%KLuvXsH}=2z>K6{+`#?==uXSDdkae(>{BB zXT)~4WUP*^)aw3~FJK~VG<^O$=;V7Zb{oE^An0pFz{aJ2xk_4 zyaSXv3?1z80FIc=#=Ta4x@~85ug%e|YRr}~`bJtZ6kB8yMoCE}?`fR1CuW@1Iv=$F*(WA!1D_$lVrV4A-CqJ@j zg9I+4bi`|%AyFGsk%cw21}Zo;B%(^>5g9JC-<2K&$Gp87SCGbiRrh#?E6lCo_dMpH ztrWM0nE7m`Fa6Y0qa>LHnr48BkcU&cV zcoaj>w8we9H3`D3_3%5b*nQioV1#3V<)S=`wpLu2U`ZKYTYu%g%Eh*OSI82mUck=M zD{IPKSj6b#$d(a(M4jXN6F|?9XwUOt5MD9TE-w+T;1yTvH^q?(dN8-dvus$iIvzcV zl1wumBLDp1D#7?6*gzWF>}T$ikC^o1ukHEB*bl3`3hH} zr%Ft^@KfqO+fbch*cmXX9VV6?)mn@EYKYlicoIk-R~~=0^OAhfox4MijjM?DKP9={0Vp$_MZVPYP=50i z;S{~$AHu<*!Tk6C07DLgVjT9qpMCcLa4P>;U`ZzWKgnJGBj5o5_KDXaH4j^K7V&{~ zc1@KW#Vq57rkOrAQau-crW$I21-h&nj1`8ub#eMJL!&pr6D7&JsqnE{Z zeyblk>_UR242-wHp5IlD)Td^HEXP8NEz{~$)N+BTo< zN?;oq8e|$txB<4lOQ@=cn0z{j3tT8;6a@{G~-^^dQor9i2z z%D)7YU|B(M9#rVJ!haUPXUBd)!yupN&bkZ?B(eIb@I{m zUUZ1+N&VA@wsmL^gbO60GuHmFTm@!^Gi;;pVhfG6_?*M?xry$JvFsBPO*P0Lkdc$n zoJ;Km(d&$}Z*|gsyHPNfw^)^YZ6oI=Vl)Eb6|gAwxrRfFNkpy>zIHUD&gmA$ivx7V z!^5S`sAdl&pzXb&7#+x@e){r7vRig>)m9;M{8+$FB%D*w;%FFQ<&-%|8)i?rcgm8Y z$>uYkBu^;ZW``-*0)o3YFvp#OA+le^BXjaxDDm%fQF9$`wR;$fRL`w&t!ZyTzn$kv z85HIoBKR(ED8djG*Nc7{wbD zd^7yCk8)5+P7}sDi1X?=IC8(uYm&?MwESV~aKE~8L_0Wn4LX%=r(7}dF*Qk?yt1N1 zSz7I$*a%?Lc%-OiY0y}={JEYBzOo@;SN=(JQ2hS;htFi$dR=~X#k4kyqAweSMoB!EYo>$3(uzp( z5Vs{E9W3~w=CsD@V82|Fm7?p%O0+t?H?T$CGQKyf_u{?k7|Dz9W2HId)8>fPHqp;J z7IQ}GA{o7>KPxYxjKzZSksoY{t3?!GF_|~ScxxX)M*syI^>)>QjII4oL6rIF1%U~D zGi~q)By4FKikTg@zA0VLieCF0zXz@)Yq?2x{JffW_?=n%FLC4!!Y3Q?N zv#QCLd*NK?EVE3c?Oqqu6!6tP3wCCVn#WOu)U9d0y_)bp36|!_0o~U;C zom1Hz|6c8n1eLZL<@)Y`32w#NeVvA2U8jLOT7gGO6S##x(BNjh!x>UlNZ09 zbpxwoygkF{9x^VmV-#av90K5VY4?IJeZzk0j8f-UD4AU#vn`{a`M*Uw2luyya-407hKOi+NCI ztw}x$e7rVuT>rzMwV?0h*3$+WBXpeWpAMhMi>sI!>7V7fw<7b4X{BaQyO_}7h^c70 zV~SyLMg;g5*#^qJ(*h{cNL@}W=F^Hp2A_`>Gib$@YXb{s$ zCZiGB8t`##O7?MV8a;AMVEGL%pYHMsy#XC>bHQ#YH5nmc_OqiCUvF%EjCQK z566a+Q*pfJC!y5hGHN+hz#L_eWDC*#{v4&~ZxtA+ym~QIYK8S4rT8&JAzR0#Ah)C0 zv^Hb9a=o5f2MmtnG)QET+OJy?sbI4Q^|qAB($9ezP7cxCD$iQPADFYG_p|#nDY7Dk zY1?l2sO48;eCP%=nWBtK*l#~J&eUtr}_le3AlmOi96B9LH4aj zjRSm^{TSk64BHGukgj2!18|G%1-!ka;w&PpdwsgNS+YxaFD6@f1aKjhx_FOokCB4= zbd4!EJnr$cn_TpiY9cpc2gE-MfVEPa8s--l&qpj@me^-*eH)2+ZHMagz_oj*1k3U+ zgwBWhunO5%U&m%-BPRsLMbEnjf8@O=@xzTj>#_&@Tc|09vHC`_tp|CR7I534`5P4l zEB{XG1Ng81?*t?cmH=BFm-P-`X9P{>B!`_Ow=Z@iCEW$1H&4f~wbgm@HkNk-nZ7xZ zbTHNDpMERoYK6RY2`E6mYDvIm?YpmP>0SAPny0E-@YZGhEyph8m0J$spME!O4AQd@ zEuw}X4u>H4eGmKSUeer(VMtv&{20pvLMtlq`)fmo?w5b8OI!}0Oz+=ofOC4?k@KT6 zQv`%>PqIJ)PRNp?dRnD`E$bNNle2iW)8y?;4%)Ulu(|5iOG9F}QxTGlm4HH(m(#qc z#XbDNFP@`dZ#&fr1~l>zQAy|x&o;jb`s2xq!pM6o+aHh$TPi#ID)n`Z_h_bnydhLA!LZbz{D|K5bnNUKNNywXKwoou>L)uWs8MP>D#vwW_bZJbXjt z@oi(IIr>CGNaBR$yBYhq6EPS%Qc#^ZI|;q+CRPKc!CBRWR z4%f}qNX<&=Q2U25?u96idB-K38;z0J1XhYuyFIHp{Z<1q1u9_qcetLpgG?i0`m&y{ zV`ciGP=b*hYAkhHXWdUq*%#48EAMtE zx`<&?c))++8_qQ`SorMEr3BMdeVqg{LAyF+x84rEc@nC2Jw##~{yuLB38s{pfqN)< z^=l@$kg0>PH}Le2nt9QAs-rV? zLg6?n!V2qf<1TiFM?bk*UwC+l{IUbt?@jdTFIk2kOCS$Jl8J)0dcQ^`5wn92b@gur z{kO*Al1vPTZ%<(iOf!Z)yv|#_&8ongZIvFt6+gMqlr^ajYC+ENf3K5#GsH|_Vsw1L z=iC<3^)fFTW=-5rSFZFs#_)-Bp~mTGz?q?`-Pii<@rC8nu`X@@HD(LK$vSTzN|vo1 zAqux6VaaSrQwBGb&ICU-$Ty*|^Oo_Uac(vWjW#eaHGW*D)fHlVdy!t(V?1B4<^GB9 zQ;gT?{NdI2J;jpYFxbaqK`mQ6gta;xPYUv-C5(RB!a~Dw=OfOUCNI@K9e%g2#!N>J zPWXh<{jGkkbl)or!$nHStld+@;xgh($rKfj9hQA6wvR}Pb;DE^`(T)sbwvL=$Z z5uP{Ob!EV#Wos@?ZDfA5E1jpWwtK9;qKOr!L#mRQqEa5PJHD)Q6*8ROvtvkhp+jM`0=m8%|Y@7fm%N>^MKAPKjcCF z!}IhP(aI*K-gE8SqzV;Lj_20%xbc(bFmh==ps>*HO@csQ=Y?JeCK_3A9ja1=Y-uIT zbg$!m8qGkwo~jDMv^E*pU4FJAt_IQ!@!WFG%A9G_mA02<;qGhu3GHcpZrP~s^~Roe zVZ<Id_=(9TX!Kcb!Hs`K*06>)Ta(AN&u~SDD>A+}~6_)}b#>#U@maP2-zY%%AK}d3J=|Xg`UWu& zumDgQ`m`bH{x$ZVFX8ARM>yR)lDhf8vg-9ES-8pOz()3tLZSv(I*eT;SU5vytkJW- zJtmk*mV`qXX(Nk~`z@+kv7U_asXf9s0a|>H`=Ga-QS~4gnT9xxpA6-sj zT{)_z%8hi$vVv;<5!9w?`srZ3vJ8K_duDU(-dMOWop}NI)_CKPK;7v8+CH{xgPtp= zqD;CN=ISME2c?XkJOO0db+FFhBh3Cq+yGQ~YUE(BiaD7ImOF>SH^jpVB;H1YdPwHr z_CK@gOO|Qa%{(r9#erdbc%re6rZzPCtkdZ|h$*IX6S=)xkSA~7M&L#u~%Mcgjs+!o}_L;YZ-R$Ok2^hw8^4V(Kkf45a}yr zl8N7MwqVu#cQE-=n+I131U7cq%#e`bCmxW*+ycD1$VBL}N5+9eTA`s3SUisq61nE7 z@HJ|CUkFdijW(~;`80_yYOIYK5o~gxiNwZ7_kaQtl&=%-LbCxnuYI8A6PluxVVnYf zh2T?k6GkBsoR(P8C(TTU9o=&{l90_%7fcON50A|l=^Qo2J7;ZNPY9fbFNQgJiQF@% zP4?RT`t|we;_qN8kgkoy^~x&E-M`JI3UurD=X-$Gdkp&u`16J`t;;EK?*z)50RL@m z22F5)Kykf1fDe7a@aKP*o<0~(QS-Aj3nt3wvD`{+#>eurrza5moCnP!SNdn|epF^O z)r0EkPs=F7kdctdR$Y3?X@Qw^er0@@kVju*ab(OgsBG}uj^h%SPos-}-&tRUfGPX! zw=%lP!^kBRF}{*7hs4s4(Kxz(+y*mw!UH!p-iVUkMC=)<|V0nMhS z+4%YUfe@?)-ItK0i+a3;k2%Jv&2M3jWz!4&6~(?3Dr1~*Ao3m$&d&+L=P9jVUBh7ZpkdoDoQrQV2H{`VqQPK0KIt-2@mqH z(5CZNhjQ%arD+r?W40o}owj*w>h*+op>rOOl&MEh{ITT01>kVzKTErjq>*@>SFV*V zE$BCNj`viNAso$9;YbJ>iWrlTz__Kyz;%Dsx|w`2?!$_ai`8Bu4|q#{$EY7Ihahwv z(POm}%KUQ!(_qy99o)&VC!%GVbzXn3vYv51CL!x))!~mwVHtwC`}En62`ijxgc6sO zs&z-P9`+YBIK5iN!o^nI*@ca6URA#q8ZYA;w_C~)ZEFOs)pCqZJTl>(yM-#K2B?cd zwt*3uE&c3LkF;QW8C5cu()Dw_mGy#b7MNy?;YwbQOp7|QA{sCfYHB9WA3H@o4)gN_ zE%#Sx^9<_?U%o|GYZt;yk1Um(j>wjkx6_K>Fo+^ArcYhhXh2E9E2YK$ghB!J?7;1&j5QT9%KjQf*nYv*(AJ`nn=CTto*tfF%LJ@ zUoO-@c#NYRBuUou45H0i5{dD6s_@!s?Kj2_WN5KG#!8YDs6rm_hUv&BF*}f|_-D+5 zs`w=!iEbW_MF6jZo)mQY?3r*icm|Z;5dI&El!s+Im(qqVo)~!M^{I7`?f4-_3hLFR zw&}>r^|et?1a{(^Yu|w!yOjjT?NHXk>KNA9QGqdP={F5?q5#!z!B&dwGV`hG95riN z19^RY6j}tUa2P=@7ep0y+d3s2rV5U0pK6BO^fygv^EI zGc|k!Z#f&3$87dt_iQMqPrSScO>AFm7@PYYpWp!wv9_yyJKtU;6+7L05~D*vCPy@$ zp=SmV*`1P+?(QYkz#LKumIGo}9+lG~bCj-#l-*IX?9Mm#410|-JyRyrm$f}{9gxa5 z??EO)#~9SSh(6(BNGZbP9FrScw^zHLbUt9>efyx<7%4;P3A}6ND$PW$-vJ^k&)i{l{I)<$AgjUrw=zjVT6j>!h9m@^?&?}e1064D?emG;&{{5@} zO0>4X3WeeVk?WJ^?}ebpYoPAZ$3s`dc?FoA86Ji8&Z?nxKRG_Zg z8h*`M+;piu$Hq4t`5gNn?)=VDD$bt}YdLtup6{7}mubZoHlnXtU|*MyW7u+0Zr?j; z`0!!}5$ZkuXkgjctnkUS9O99_7de|xkC8nD0LZ=Mq$D(PiPIrt30_HtmN(l)d84T! z7X(3rIKM(Upj|hmIY9fUIhpGXNe{bmuh?~qFaw8FIAQ(yGob0zEL@rNfV%btDo^{g!!fkxu5v|fAg|}x z@h*yYS8nXYYzgAz1SeKF@e7;V{WIGP!I8&^EJ-11n8cWe8F0UUMJ+CL(6`P;&YO#p z=aI7#D47S$BIE|$b@z2UrzzE&dJ2q{Pij%2dQ0tf$-i>ldHJ>usz`5(v0?Bg54&i# znGd@(RqfSbJw~@1Sb%$L@)@MEu!2w*}(Df@=%HrlYle+{om|RRu3C0^aKq|0N zn?24qGs0%J*K8eL(xL)}^NEb>vB}3-sN~RBvq|1FVoFz}V$J_7*!=XeN~2TIPk*0z z;Lw0QpF@VxaUzO9+r79Y472nJKEtFkCFA?bP217>UWu-YLvFoJUo>J&K0ET>xDV;E znrX{vu3lfG-$i@~G2Jw>od_11@GtXFO^o_p_GjjlC;AtcxD|usk=hdjt4k)Orhai@ zHO`DNo#|R8KWZVi7}9aKo{ob`T^;Z3Mi&)@t`sIxP5)wbgEMNgtccHGC5LaL(iO;^Cxr_tR zPv4V@Bm?Df`RMM-uhu_k$CqJx;kkxtlv^aIODqFm0Ka%b5Gbk~Ei8#N{&s5XoY2e$ zVp+ic?-Keq+oAFQ5yJm{O7^(4g)4qpWvMhF-UziqPh_}hhnrQtsM)G-*gq*GiQbjA zp&ZWytA$F-l7M#`Z%46W@w(_=lgO8BuuI~S=*a{kZJL1x6Dr+fjOCbcv~rnaYtGQDzV^{_8;3hn11RG91Z6T)T36f zk1{_k9i;xnMb3xc?$#i|4x_$B~CrP((l$TP^ zU_NH5ezSYSaZ`D$3aRR#Q1>I=E+sjuf<#BWl!2iF(A1lDS*!>DT5A4BHTnX!h_W5d zP{S23afkj1n(OTdqy4MQ9Dc#c1U|$x;&94J-%e%JRF9h6Ci0Td+HNliWy&8GO0sJ|MJ?@1sF3@HFE%TMa@Wi3uGNziU(6>; zkLsxB-)v)}M%2Y3>0tPR#ZI~G2N6^}8Nyd+oDRI4vE~@E%93WWPZUW};J&W5@=&z@ zx+EHQ_(Xw_gYTj6oANww&}r50l9gVN9d zfn6do_S_GX_+3VM$2`SF`ywqD1N?@*%3gZ&cEs@Ui6Q|_V%D#2!>pdQxmg!AP!x?m z8+BWY5#XK}%VkFB+ypytsQJEF99J>pgqx25%Ra0pFIu0>0RruPcfq|H-H6t^8h9$Hg%Yv~=-_>%}iPMaAN{8Cp3 zmX{*Um+p9%a{ut4RvGy;d!@=FA0KIxs%Gk^p{w6{_a1*k^H&i?M_L&@YvYzJP;9xf zc#s-$93DTLP}k_QD7w4!{Ts^yz5o~H4oy{tvH^z=b8_wy*FqgV)F^w8D?(9=@0fcO zAI8mtWAVn#Tud6Rb$%vG=f*{u$eI;VU)Zfksei^E-nPw9P72F_k^Qw zLqNoT3A%UPom^qBeuusnz0X7G<2Quk#b)`tJLc)@ln-Mw`m7$3kJW49mEBe6T~)T5 zID4vk>U;K7QBSeUB7&GRh7?d(xvuLqxX`SMizIrd^*RE|eUQIE`4boQN01ZCN?&HR z39qH18Em6Vug}Xvw|JHLMuXJ$hVw=>4Lu1C-xs&T!baM#vl{WR2Ccdsjlurs1;e1K z2t~H$_x(#_#nc>Yw*mR$uSeqSh6Rm~Wqh3av{hMBGhy`R3UBme6XuMEn~?e3&J#fpq)fZ8QLY7TK5ue%nsol%FY~fGxA8A7>t01(uUnJ zjg93h1=vwlFW*rBBDVYoPpp;|t=@Koyp-Bhq*qtHJ(kTs0`WUCR7|jVORFcE6?H*i zv@*Ba{lGlwElaPzv&VZR%M-F?A7lcks6JrIu7=nK9R^S@TkuthZo2I})({?f(SRRI z0tQfu4Co!jwy6bQ8?P{QLT1~eeDVQ+PWY-}Q5dyt*!OQJg3dnRe~bU;!=kYMYbGI% z(YvDw04z4vpNs98{pH2|vw1$>L_`I6uTK8U9P!JH5X$NzxOplpMK$od+knZ63!y~z zH>612lX%Nr7m`!mv(?D)gJDIIx1_k9B4l}%#XYN-Uku0b5@A7B)rFubbwX-+o0A_7 z*I8WUrYGHDDu^sOEBV+An*Qum%$kX$55Dyn#+EHthQsU;Q}y}QFpQ|wc@W15VPO{~pdgp603e$posE!ffKJ(LENX8@E zoP=3KaI* zGzE-f^CXkxtAD?OTV@>Az{inanPZp$ePG4G{_rA!u=r&74(^R^=`4?>WCtCK-O9oQ zSEjC3bNPYc1RVo}px-R(UE9HXI!^fQ(!?~ zN{`V3nej#1B9g@8sk#a=23^?BB6JM59sdC0h?3}L>T3Z0HlNpM+Q%;4Sp4Q&`qS}O zdcN5ML6IHXhk72hKwZ3c3r1kIm8&uAOUvocPu?}A#hh-X28|u%YgcowC1N3F!W{g3pveJ>nUZ`1E53r+w5tR2*%O$b)s zUT{FDopk3>vqFk)vv|Sb0iRsG(ZV7eOmOUL2)Y$%i}t6IK#5(Lyo{Yq+vw zZW(mNveR;-kui3^GhUMhKY&fiv{Gs!WQ?M-$D1o{B|{A+f-E98t0l+Z^Z?vD#8MJ6 zV8@{K>0VV?j)Jz9XkXCyj_h%;+|@_3l&XrJ$qF2*be8AWq)C_}uwppS=mCz>8d}|7 zHcYfQnOPY57PQpkF8hb`aBp%diV>GGjD{{wOXx@hOKy=owKE^4H^{hRWh~~TYnW0> z(HMBa8b>mf9DSZrTk=pJ6Pg}+G&D-r_1Y_(w2%_?k(ISCjd^MVez9G!~+T6uE zXf|Q!8Ed!sv!x{0m3y_5*g2`5e|q(>TAi3lNd{Gu{2tEw>}};CB|iCx3qd$Fu3z_9 zfu6lvv3PjphZ-2 zt^?_8sl5mt(#E9KN|Qp!Dc9>WoN%Zfh{15!%q97X$QGlW*EvO%VfwDPs1*NPZI7hBD7vxT{%07Ly&m>!$vzx{+}J^|7%A3 z?@{JIkRbr+I;(g47XI(;K`%hPM6@ie)}$HZEUlWQipkS$FMfaL0HgW`Q@0_}DuQ|W z@vOsV@2GY#@($*{dP4Z>S{;-tvYJLFw>zb6uccF62N`01Z>uG4jEX3!qoA~=G5DsP zhiU$U=dINA6Ve7XY33uNl;Pa|U~~J^X2JFItBRS0Oxmk_!ndJ3Qz%%#uoY%Ju&!<1 zvstyD?N?h33x6j(C1IEqs^R3mJ|V%Co#Trp<8#8ctv&Dfq*Z;lX`Vr)AjK6G zgRP(_mM@#Wax0iE%<5f7aj%^i7Ru;Uhy`Nqf{JZ2HUF5dr-MFGH`ch3(pO)lZbUM( zTg#;bGxBVb$jlN&5Em%(r$Djev(q)XLETHl^M%f9+-=FGCFPFTeuBw8|0(#4pNeV+ zG~e^0@e0LNUW}hH@$g=u*UW#~1;eZ;T>{2_|C#EEqN>`_p<+v108J`3fpR>AqO*{2 zaOl-P7CD0k`=;g{4vvj@#dDPsVeQP5S~d43CN_OtXRo_{#Izu#+B>gBch*9dyQcBt zMa+#CG)q?Ab#g6x_cjWiV;x?by>o&|hAzFRIQXLXGY4C>x3wKDGz<2s{R4{l<#{_}s za*n{iuL-^?4gW^O=ab03fZmC6TwSE_=QRfokWKR@9gP4KweGD1@#sn;5eG|~V7~1U zT3}jAjvMoJQrdWO^K0KjYV6D}sH1Du+y2FXZfy3TO4YF-$ZF5R%z|RhZPQHdT zi}0zo)e$Z)+HifLBnvP0;zl!JDCiPDE|`<8&V;{qE#^SH4@c%+fOQ#_cB{D7a);Sy ztkyI*E(gc_8Ly+JD@1Lfr*X~oee~oSix?Sae)yp1#6e2j=Memq;j|KXL!;7R&=Rf> zQ@ekE=Ix4=sEKkGqvxqLY)?J*x4Qb|zWGY|fJJ~ySYk;L4Du$s8l;fwFyGh5IU^sQ zNFLaMPp+PGxvQ46Czl|Tk$p|lOKxO8>+>v%RuVD>7V@wBzkm966v zS5exAw~QD^OW>mzy5kHm;_iwdAW~5_+_auzUiKaBH!JC|G3a^tEef;8wmE%3mY{B( zvVH^VB=TfB;m@c(qp-5Cuiq15CSR=ZO751ha7N?ttHy4BESuuCtd2*&jHM=^J94}? zC!?-LR&qXxuF;)^^cD;cUK;OEEUPIc1^n)E48al6NYanG>sQ>XNT}#Yq&MS7-ShT3 z%}-VfLH;VYhEE8mK(#+HxHtJ0hsOKygkh7(QC-xjc2g^RK3x;-t3s2-aFG^vOHdlB zgNRO&Z8}#QW$6&e`fdE~Y19NxhJ03})Eo(3x?1XMGFq#88hv%W$?vXyXTf-Lm_Pf% z7PgCfT&7HS9(&nZIPUwSL6P?R7}M?seJw>>i?Ze{0XI3^A0yZy&T+?e51#(lpNUWM zj^{H3m#VT2-5}Xv?aR3#BTEiqRvY8Z-rj=bKZ@?0gn-h$4P2wVWM3+m#%0#jYI1US zF!jFtu4THMs^dNR@^s|40TGS%vL`D%f1)hWp0a&FFj$eKYk1IpTJRFiVf%5ainxmG z&so!0nRg>x5L}OA{~Sb#{O7VnafxI3KgMA6MTAB(}RcFfbiP=P!@dt=*jgRDhZMm01JFXx5c@%|Y+ zD-)Bo7;PGG=DEC`%)17&Ers{i@RJCvBtjsFZl+FSfEljYCiVt#-~aEQU~i^Z0?8fY z(H%ecW3Y9FWQPq_<|Yh4oa7CFB3FFCi)8V`HmVzm=&bBynRxwU_tQK4Tj)lDb3{Qt z6LjACZ;12xZ1w-U;sOAa$rb#2$ra?mzb#r`16QM!MMwCBfxFCt(TUplsZmIU#cOD2 zG>bv?eh|qpI%~rH7wYFUfA_Oh?a7MA+lO_62GEV0LU42@!8U`ri?I1YettgeL0K9< zy#yo+brVg6x%T~pEOf*T=A4D>6vGzB|a#OlwTjaq5j5S}^yg_tj;!AP}#ATI!kGGGnXTt2e z#?%{E&fM}bix@5qPCXX>3p6$OSoS-=Y<9NI@RSkjvMg!dw~)mZ+mqDjqVC%r?ut8f zW{WDE&G&x*NHhy3{oqWtKqz{033O%0J#&jX zQfu5Xh8JDi-ttbHF@DJ!uQa1QROGGcP0Zm{A^-Yk(x+Sh#w;{Ca^kE=&%#X+yU}N? zbUSNw7a>z>5mPoG?PZ`9Y-tSI&~WfX2ZAxMD}q(H_miOWm3kjUS^mi{XmXPy89H|L zEs96lx!J-;3q)#d$gooAtgv>~6-%2w$aS#>>I8R1c?0qs^|o;@_}5AFBfuAFFfKc!s@UQs5uqH{HHfa4ZWji!cpf3sIRT~5-L5R!#3@(n)#+Db zGJ=c4Z|@Ci`dH9KuL-JUP{6vulTNc;b9~+R7vPWfpo;ho!*9$h0d#uanXYw;ONyUx zoDjO^%XiCI4|5;WC){gXsZ>kdABs%+CH==`yY>jaBK-O}5^v~-E9o)JA!1hSVzThQ zCWvffUkUHJa_#i9#2C*~`L9d9{(_TOzwXnc7iQX0Lo$+>Bx3gN8e!5z&uOid-J#UN z=t~DQZTM6&gN+e8>g6jA)P{S`_@5l8r1Hx#`Tge|F-bh8Ik(M50VWaKMVGzv@G_PX zhE8sm262StlF6fdLJ;AHR$jr;XnX~jf@O?O2Ha}zZ7#uSD9fo~Eb>g!v%PP^SQuq# zF0Y0MXo#;PD?g~fLUMo^oF1hQKHUQ-?B|f|k^cb|ld?PICcpRY8bi2U0i7_6J|0b3 z`kP;d@!l|Jb+Ip5(Q3UsJRlic-XOLphK{6Q7f?TaW70`#&^3$dJoAa=<()8Yzd16W zp}(5*UIDYz)(}c`@EL4mF)!a3Ryc;rmuv-zJ&EYI_ptfoE9JyH87OhtOPFR?H&SQF ze>;1lr9Ck<24_G^lOr4ablqUkT7BL)8RntAvBZ_i$sFUblL<-8=Pe!p_Hp&s-ZDVI z+1(3=!(H8z2{N66*Z5*OQjU6v`h^;MgA_YMqYscX%>EJA*@L>|yFDYPd$c;>&(qXz znYN8>Lg7&xav-~{e!MdV8^-&WcUp0F({m8!ss7;~|C8vlMgLtC z|0;5QLWb7Ozw8mT{`au|vP=GA?aTP((AWPB)lg55f`AFG52kTV8mXzt0ed4_icDtv z+;)WW(zg(6pT(Jq3gB5zjHjN1n^FSy(wLO>{!mZaIwY$1FeQf4*8+PYMmn0aN+to7 z-Ae16<)c_;XXINwXX;fY^EpunFf>@wk>Lh)S^_n|8)TAH^M;(<3thCYut!*tMu@p< zQD$0)(5WFIZcMPOgC*XGXTs$hZDO$nZ827?f_L|~B+EqLQ&vU~hd0p+0q;(kV`|gG z%9cF#rCo0fJ6$EuXhEao6Vl4f<%cE3JRY~$75Gh2aDaQwdup-5XGPi<9buw6zidba zJI@&sGPt1`O?f68mQ4D(30WeQ@ZPcF^Gy%p zHD<}LeYO|Vxazog=gAN!#Dz7L0@j+M*@-(w%s{uIC*8L73-ck8SLO%Uq27#543?$r z?zwT?SGc>mYKMiIgXgz@LT?O|Da+33u9Gh45fTtq=T-mt2*Joz?tS0CxR zl*cmeO=Q^bQv1+Y+ zK?0H7%AIEiBuP$?U%Nl{i{_%_X=OW^5Tx_2G#n6tNhS1fM&wcRM!(V@$gY$&PUlJK z`|2q|9oNhS(yLdg{si-2wujR~Sm73~``Jn+gQse*4@u~TdsW7tY7&UTze)bk_SAp3 z%85GNL<_$PM+sOzPW05yTQHuqqt?_q^+UkKeCZZ zMIx4Hv9lghb}Y__K;{z_yTTXgUibxQ$JBNgJLkCbodO2NruL4JmM{;W{BxbpN{+~v zOPtmr8B6g7B@2k86&`&=DHDmWol)T`GZJ^1UBI=Ps^ytN!?~Th*7PO=-l}DF6gG(p zS6D4Dci4JXLci||)`G_`D@sC3VKbwFWwDG7p;D!dfJspy6<=lkZeH*HqJ*`qDklEZb><*wAEAjx2G!kvx&yEI=f(#dx};Slbfaf$>ld)a)z?QGjzZSBdBsB z`_bFm76+p&!TVJ@?tUCmFZK`b4er0ZebFt?*~S0d;@srQZ&V|G)u==z@%n?!R0M?U z<+R_d-K(OJZ6azupp?XZ #include +#include + +#include "collisions.h" void framebuffer_size_callback(GLFWwindow* window, int width, int height); void mouse_callback(GLFWwindow* window, double xpos, double ypos); @@ -47,6 +50,68 @@ const char *viewposC = "viewPos"; const char *lightcolorC = "lightColor"; const char *objectcolorC = "objectColor"; +int num_walls; +float *wall_vertices; + +glm::vec3 getNormalFromIndex(int ix) { + return glm::vec3( + wall_vertices[ix * 6 * 6 + 3], + wall_vertices[ix * 6 * 6 + 4], + wall_vertices[ix * 6 * 6 + 5] + ); +} + +glm::vec3 getVec3FromIndices(int ix, int jx) { + return glm::vec3( + wall_vertices[ix * 6 * 6 + jx * 6], + wall_vertices[ix * 6 * 6 + jx * 6 + 1], + wall_vertices[ix * 6 * 6 + jx * 6 + 2] + ); +} + +glm::vec3 checkIntersection(glm::vec3 movement) { + + glm::vec3 vec_start, vec_stop, p1, p2, p3, res; + int gotX = 0, gotZ = 0; + vec_start = player_pos; + vec_stop = vec_start + movement * 10.0f; + res.x = movement.x; + res.y = movement.y; + res.z = movement.z; + + for (int ix = 0; ix < num_walls; ix++) { + glm::vec3 norm = getNormalFromIndex(ix); + if (gotX && gotZ) { + break; + } + if (!gotX) { + if ((movement.x > 0 && norm.x < 0) || (movement.x < 0 && norm.x > 0)) { + p1 = getVec3FromIndices(ix, 1); + p2 = getVec3FromIndices(ix, 0); + p3 = getVec3FromIndices(ix, 2); + if (getIntersection(vec_start, vec_stop, p1, p2, p3)) { + gotX = 1; + res.x = -movement.x; + } + } + } + if (!gotZ) { + if ((movement.z > 0 && norm.z < 0) || (movement.z < 0 && norm.z > 0)) { + p1 = getVec3FromIndices(ix, 1); + p2 = getVec3FromIndices(ix, 0); + p3 = getVec3FromIndices(ix, 2); + if (getIntersection(vec_start, vec_stop, p1, p2, p3)) { + gotZ = 1; + res.z = -movement.z; + } + } + } + } + + return res; + +} + int main() { glfwInit(); @@ -154,14 +219,13 @@ int main() fp = fopen("maze.txt", "r"); fscanf(fp, "%f %f %f %f\n", &player_pos.x, &player_pos.y, &player_pos.z, &yaw); - int num_surfaces; - fscanf(fp, "%d\n", &num_surfaces); + fscanf(fp, "%d\n", &num_walls); // num surfaces * 6 (vertices per point) * 6 (floats per point) // add 1 for floor - int num_walls = (num_surfaces) * 6 * 6; - float *wall_vertices = (float *)calloc(sizeof(float), num_surfaces * 6 * 6); + int num_walls = (num_walls) * 6 * 6; + wall_vertices = (float *)calloc(sizeof(float), num_walls * 6 * 6); // read walls - for (int i = 0; i < num_surfaces; i++) { + for (int i = 0; i < num_walls; i++) { for (int j = 0; j < 6; j++) { int vix = i*6*6 + j*6; fscanf( @@ -272,7 +336,7 @@ int main() glBindVertexArray(wallsVAO); glDrawArrays(GL_TRIANGLES, 0, num_walls); - glm::vec3 floor_color = glm::vec3(0.1f, 0.1f, 0.1f); + glm::vec3 floor_color = glm::vec3(0.0f, 0.0f, 0.0f); glUniform3fv(glGetUniformLocation(program, objectcolorC), 1, &floor_color[0]); glBindVertexArray(floorVAO); @@ -301,19 +365,20 @@ void processInput(GLFWwindow *window) glm::vec3 movement; if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { movement = glm::vec3(camera_front.x, 0.0, camera_front.z); - player_pos += glm::normalize(movement) * camera_speed_adjusted; } else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { movement = glm::vec3(-camera_front.x, 0.0, -camera_front.z); - player_pos += glm::normalize(movement) * camera_speed_adjusted; } else if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { glm::vec3 right = glm::cross(camera_front, camera_up); movement = glm::vec3(right.x, 0.0, right.z); - player_pos -= glm::normalize(movement) * camera_speed_adjusted; } else if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { glm::vec3 right = glm::cross(camera_front, camera_up); movement = glm::vec3(right.x, 0.0, right.z); - player_pos += glm::normalize(movement) * camera_speed_adjusted; + } else { + return; } + movement = glm::normalize(movement) * camera_speed_adjusted; + movement = checkIntersection(movement); + player_pos += movement; } void framebuffer_size_callback(GLFWwindow* window, int width, int height)