From 7e09031c3ee58373be4c0ead78d7bc570947278d Mon Sep 17 00:00:00 2001 From: Kevin Ngo Date: Thu, 11 Oct 2018 21:17:34 -0700 Subject: [PATCH] hook up beat hit sound --- assets/sounds/beatHit.ogg | Bin 0 -> 67054 bytes assets/sounds/saber.ogg | Bin 25165 -> 0 bytes package-lock.json | 6 +- src/components/beat-hit.js | 28 + src/components/beat.js | 4 +- src/index.html | 7 +- vendor/README.md | 2 + vendor/aframe.effects.js | 69004 +++++++++++++++++---------------- vendor/aframe.effects.js.map | 828 +- 9 files changed, 34972 insertions(+), 34907 deletions(-) create mode 100644 assets/sounds/beatHit.ogg delete mode 100644 assets/sounds/saber.ogg create mode 100644 src/components/beat-hit.js create mode 100644 vendor/README.md diff --git a/assets/sounds/beatHit.ogg b/assets/sounds/beatHit.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8dd23fd45bcb33ed64584ed341619e979e1cc00c GIT binary patch literal 67054 zcmce;byOZrvoAW35E4RgcL?qe4uRlq!QI{6H3<$0?iL&#+#QnO?ry<@2Y0wb-uK&k zpL5qbXWf5pub!rBy1HlTS5@6LJ@X)MW~Kzd0{^CnckQH4)!IlpbQmHSS35^T3#X?O zup%W-e*nPd8~oqD4KVUgJ^w2`^@IT_w~1y4)VRn0H7Py&XCyk1LEXaMoKfDtYT~ ziVN++F^Yh6|EC~fGsXmf=YT);tFJj*l9t2VW;j$|9lvo~$Z-{rz=tXP;(qn>oYKfP zzb47^|p~vaAZ2Ty)f2O=etOW?X$V zk^;3Fd^8#YwPpi#E&~m4g8t1{J}Z|``LF0CFu=FB+zIP6*<^UxYuwq-0)k3l0plk~ zNM6N|(Zu9P=9^lUS)|sP7uVSgRM8JqA^v3nU_h3q^vxnA|NoUuH4;qz?^(dSmlhBJ zvFvdm=y4zyRV43mq=)~Da4!JrR6vow%aKjoiLJ+p7tG?$B7Jc(LuWF`|53t|+5tcS zLeS+v&}H5MhM{?(xMFz!02OPc=Vu5ZbsDNe(Z zh$(sh)I88q;Y*9g!E?CVX-M6;1|XlscnW;coI2Q7V>D%}un_~Sg~p{))ix^sGv2>u zQKXwT{DXTH>=8PjYSs8k2drHiryUNxdOG*Nn~wmfH-lN6?(|P2K3`uLVvy#O#u7P4 zBE^1#^wQ)KefcUTRrL9TA}&>)^QXU(lK?;f%3mw~Px053|FPoSm@wLY>gqw30s5z+ zq+^(8uc8A*7!d+mF+DqI#b0W-GMvh|C9Lvlr#0#F;uNK5^8WECP^l!wQGzdU|2j!f zl4Czj0q7O~Q*nRDM^FjJ{zo1;CQv}50P`3NgAyyBin5BDtBppY%R+si&aBJIjL*u< z7d`Bt|J|_u%X0wGX#)QGWSn6Hq$lmOoY1R(6#O60alq(_Cg_VMm#!k09j6~UVUs^) z8$%aWV3SqC)EUEcnZPnp;?S93HMV-=KNSD~ z-=h$v|IQ-{iVRbV>{E&iD$0ESXO96}r`TjC*g#<80RR`YpDy^U2t~BmNzMHq>S2(V zc`r60ff%0?0(z2!`W57|jSxsTnG43bgCe5m4H1%Agfx!%Tq8(>`Eb&Oev`idr@iNZ z0sy>_B$FiXJK@b1KcgR659LMm-|%4jvMre*e(FvHNS?V9$;R?VZ;!Eos}u|pcwh-- zkE&5vQ%u9yhS);0Eq<~w41pwN%6~{c z1?8u{GD<3qWqUte_{Nk~vj3X|?@c1Z^oiLbg$7M@BEUj3#q1x_{4eR5{~IbZp^}^p zRn(aY-1E#XY66D}&4)UwfF!t%kIIa>gk~3`iK>{Slp#z_iA;dx?q3r6S_M-@$u&8D zk41JS4_fwm4pVk2{$H}G?6ukp@b3R6|H722K{lO4izdb?7oCPObLf9awRn&O0Dl;G zz#l;G7XTrI@uvoWaL|BFJcxQg*Er<`EjMM$gS@W_gwsGHg)(fE4Fu3UWjmDYY2^bD z2*5wqqjBm4-=2&>KmzdZa(H4NIu#jXla1Ywh{^ZJ*aqQ)(n>y=ATQW`LRlrjSOXk4 z+dKsdZK`-W4f-9pVwtDphh|f!e6fk6!RCKWa<=kzmLgbbIduqnzDM0yO z5;!jtaDj6kjvy7T3YJ06D{LbF{}_}%Bm~lxWPl(=L%|j%NJA0#Qb?jGH%?N5p>~>u zng*P(DDrAlHT!dOrxmS|<0dt&N&%qa89aEr&iX4C5deISQhW*)L?vjtah$%A4 zgAxD=zrz3|-^HSbUWt7|c%$(O$b|*C2zo%ACqNk~dMfEbpg>Rt9OwuB0ugIs0iynd z`1J}25P;(-`D(AohNW)aD+Q1|1Ntu&>wS}da>FaXoGV(8X<4G5Uq1Hiiq1DAlZ#!$6$(+~f(`KhGz5H*+WD^r@ZQI{w@Ln0 zwGd6-lRW?ODN6mP295$6=U;31TY&5Ke|ms0C`!Hhw+D(4bzU6WzkC$ng}^Wx?3?w( zob|NagXldKDBy*_@u>ecJPiPnXhMG*o-Xu6{&TgzHLwWy01o<}25O1`w5JO_@%?T1 z=R$vP1H5<^s87%@{eic%44rbUWxTNB7%VaZfk7qDfpKs?5-tIq8H5}x-YEX3R$41Y z^Ut}z4MqRO@|XPozmR@{;6Kv;f2_gG!r>$NkD-g9DVpJ`;yJ9p!XbUOl)6z#7Y@3V1c;vDAb5C}P~=U5Cf==X1?jHCPz+@N zYhP+{3?eK`yVQ+JE2lwE_!*C77zV=a#31(4$O#-z-Kwk+%OGN`F<#U13&;}A)Qw|c zRl?p4&K_MjZv!f7>+r0G*k{0?t@|ah5va{YrzfWlh=O$ESq(P={);c+flj!$uZpS> z>Ao}^KSxBB$RaHU{BZz(QXs&v3Pb^%_y8Ey3cBhV%bbRy*p}a)zf(DPni}`!DGzRl zjJ{=`G^Ci#!d(0Xr~kC*0W1K}sWHUelSa3ZTRUq>kEw_RPV26{B%9=2nk>dBpC=7> zF<3$bEsLBHai3FkEAs>*e%3ak%Q8aJEUwH$;{l&N{7HcC0s({1Vc|aLgYzsB3R*7U z{}WcY#~u|WO1hVtnVJB7ShC;^Ab>)~Dne!mk&r2T5f-)s=sSEQB?eg7IK~+nzYPG` z&JHslQ9hvrkYK@o5P(IJYgi5Ce7eO$g0Pg`H29ty=C7JsxQY3N|N;GN=S}b}T1{kIZfKO{rJOThLEa)&` zdZJ-r|J?&X{Cf&`+5>oMwVVjV!>Vt5+56l%M3}s_`o5GjY-gOUXht zW!n&%^XPrQ&rs03$-m;*uAWhrkig`_k{v!=v`K#MJIt=rBFk{!UTtWu)Xp%KWo*x} zdE9ObAn1N^xPgQWE(<(EJ`%PA=lfo zv=iuY^@1w%m2-b)8EN^rtM4Mmneg`Gw3@|@PTgV0FV?%`oS6_81N&+C0{2~XD{R~a zn^U#LiiDZc=#s~^dq-SHes7UCPCG8-EjVXMK{#Sx+^gojR)kH5kZAIhk1CpiTenax z+7yv9cXA?AmZqSkGpTralW+22rg$g!qL}0{lTF5hm47%bQMppNUHb0%6ncDUd%1*` zt>jX~8I*kT)nLUarR?{;cYqO{k|r{0y*J{y)KC}w_IX`@t#@hT;EcnPj_^%f$}Z?| zu@1{T!A|$P)NVm#CTeIj(r5EXi$*-lr7drjG^}o$p}FYB#Uf1FgN@9SD^_9}jOV&; z@h4uTWQ&_6YpxcmeN0uc9uLO{*k*PI$1$TE4R5cQ2W&CZ`*)WG_g`(rG!Lcn8u7Z{IdwCTlZ){pFIVTUI=!sS> znJRs(a~uA))=PxgN~MvZTkG$#>p#ZWI$GpAc>_(2BV5Hco>6_$!QkW3Ex{;^UKf5w zc;1+tqZFt(wn3JRVzwq5aiIBFJE4FVu|dSQC}Zh$jI0uP&dOh$!dDdW_*2bSfkK%p zh}7?{@ZEO?e2b_@{-)ncM5Om(YB|s&>dXK?wSKahgp9knX@Ui-MR{|+X*I4xvhemE z;jjGHL%yE~&tPs2O~k`8M_L?jAg3pS@Zq0CEj#!RZB_Bau%nW?6GxFIxXXW3n7+p9 zFG7CtVxX0Cnvbx$X%&k9W#LwjEh~%8YVVkHqRlC^&H6_FEfbCax~XVo<8?NthTRPt zAC0N|@At1C>EPGbZL>EOj2G@==~xrKyI;LDGs_9=shN0=&tNnWSeD;0yh7Qj(p5}m zq3f31aYFmPpm;GVG_%H0bkfCpx#K?dx{Y+}$~<1)ODL1{$KydkPVk)PLM;dVw#SmZ z)mElbO-w)A<#C{_i3%d+CpqJ&<~kAR81q+>Xs+w?A&pE0i_d zGWF&i<*qyyEeNn#4QXV#e6s@}*CE=-6T41&Xe{h1r0`co^RpN?uj_S+L@cKb*+34|m=~s2_Jc zMpsu?z-wzV)0^D>IL)@!P;l93Cn3*Y9zo0bj$plR1Fh>aRgQFdC-2wJs!Mg_pdK5Q zz%MN&zRiofXvLp%n;yiJIVTR#k~%8f$KpJ}N9L+O?=CRj^Q8`J1UGnnUl{fJlX=E$ zF1kJ|KJsZyqJs6VP=NL8Pa}4$iEK;P%{dYpgkOxPY8MZ#b3}_5ljm?PeeM9^8d~E z&Jb;RxddxlX_j1&{PEID>J7V_LG@CaeapY@;3-~f{zxQp%`68+i4C?0Zm$_EOUg32 z(3r8~fa9HuH@^yUVQp(isa6Tj*)RW-Ge2cUb6?Bx!lNx$sf~PTImRy3BP+EmPTgf)vztrPHR09-KJfZG<$pUlmwOa zd@gy9yRuSim16i}Cfjq4%4J`;#s(Vn8%hn>$%^Ws-f*)Qy>|;R&(TS~(+x_y%$UFm zj7aO_OU%G)I^m8PJ?9ECh@@7FEJmnwZuI_Iw`F$l*v%Z&cGz?mKhfgLe!MlaA9UWX zyXS7D?4$nv`tb4mJ3!FZG)_o1f>bP&RxE@$D0Vh~0JPS&Ehg=CXjZS_k8v)w3M%>~ z<9hg=8%man7Bvf(*S2jIWuH4H?&^rA291jEC9Ad*z<;clwe|5$EQqWUmL@JY>CTvNx*^L}{_la0QOlF3shK zl^&e5TUy9;iyxxiu6aMd6fAa<7HL29S{~4-cAbJNn$f-C8lG!TY9fIKNpiL60Mu8O zSV#~evLw+`c&%Yx#LOtY4FJ8(>s@zUcJ+z)?L@Diov1oL6@R&R$z-kvQo9Wb`ot{c zUI5xc#gXh#i?(#FXwlrE7e8feXZg{*zMa%tjCDlbCaB}|Cmj85{%={rwHf&|U$muOSP$opDO$O<$V0&$FgnLI=VyH75{A@(Wf$5y-15px()k_@ zC<7SrTX3oNT;v#=Y6Q_T|@#%v|i@ ze4jee-FuOP zYG+i}h`G_v-wW}&Rb8%X-f`??((~Hhd%xGXx|! zzm;d>L%yY1t1n5vGqmI5nR>%}ww98VB0r~H_KuqdE%4iDQAvnQCbxdBo01ry4H(a# z>|>Gk(~N481yWQQxnB~aEOl}&H7K+2A^z?HH@$P0yp1Tg}DU@+XMnM zL%jLKIi6D)&WpSLdA1hTz_Hj-_mS5XF6W1QiZ2;Rndceo`ZTFFZ(oF~qZZ>ODb-H6 z*(T1tw1<&_J(8NqJq~VmYt$-v{p|L0$A#a6aoc&}z57Hk<9$YfW{@DFPjCD9JG*wP zlDT;3vNH0BeffgtnaWfLFR@TfTaKqN;$er11(T}dGr+`cX1vfq-553ex!c|Gh!u}~ zh`_lQh3bMv-NI%=G2OY!uI6u94HbIb$ZX{S%p?7$B z&qca_X2$soe+|>pFSE9vti^5Y=krH>QTwqWYORoi+g+6m=o$vYsxz_<;D7NrEuX%$ zz}_!ppz?11=ZPDW7x@=V1AOI4FZX?4qX*HS^UL_k7RAkf9^#*O4$n-8Xops7TcO_G z<({VZ3R}`62a~Xf3cwl)#^f!(#8?xW{P>HcDPwZ;H>N-G*EytLwhPFWi4KT79(gs% zx7Nm&dv`^q&=v2r-?^J~w|kVf;^8lusy(w)Vv|xho=wuTQ{32w&%*#$Z13#)#3Fa( zJ{0i?zb4Y3?|6H+{?IU%GSm?mNFXJ&yHX8-Q#JmfbUuU4Ie1iKTWq!aJ;WM$0JZL2M5pL?#`E;FeW z(mXotJ7yZ_-gfqA-?vpaF>}HELb$rzC%p~XZ=16Fu+44&dBG|vSZ32Xfjyz{wGInE zv?alwBSMaQCDh4P{$Wcu!GixF?!O=oei9#H7!BcxDC5cbfY;^#ZBwa4|$9-ofw}-RH ztAp)7ooar?6?bfp&Okf=`NttinL@ zaNhE6UYd2t&V?SoH|woVQzBl68u-vYDAb-;ZwI}@`+9lf{ah_@9=pKx29>x_qWa`w zkAt(KY=z?h5+N;}kgun=>+!z3e7xIEcVyY~lq6vr9-oEYLG2a%S}R_&d~++sSd`W9 z&cOunX(|5pjmnfT9Fjz8oiJBr`t;27S#0YOUwyTcU5rDkDBWBtR`?1B)N!PUxZ&!( zhuwRIexI~KZ@ntK=5Ky1%(m>%XLY+rR_C7X@f2-_@F+Lu?RYo0_mhjpQ+^}ml93AQ zM#BM&2X2`iz&~3K-|_!@%i$SV&9i@0#cpbCf7)~S@l+T;6{1fCL)`oN-{M&$g+W za&1?{O8>6i=AB-ddrN3LV%1)&rBt1yAa;wkIX1#n&9T2UypuU|c^-s}cqcUCM@LR1Ozd?Sx zgx%Z7`$vwJ+l$lcxh30M#j{A$`WgB8aH=!xQiaV4s`-%FQfNmOk23N_Q&7?QqaNR5 zYuQHXqnogm!E0{ik8f%SzV>;yTdmQ#^+Oek)p7i|hl5Bm&J>8Ol$EUXsEDV!hbYOu z(mrfx9O9BflQkHoPak~P)22;hP)nX`@k0DiZ{QxCv!F-_$`6k5CP~Bn(rQ_AR^Y3o z8cO8NgAezf{T8ahUi%Zd;Y{m4p$>Orw}J1|(!G;;?T>Ev5sh!Rej zVK}V*&2ZSfgq$tbW~T!aiStbHiEun#asjME?CCqx$XBMYbI^y1}sSl4!baaimkm#~p9p zIrB}XyDb~yiS(YHdZX$u#Q5?hMk%R!)r@zMtQ#ktX5Q!tv-_VFI+!1HkRBI0Sl>C8 zwoP2mO`yKVd10fGz2|yci_D&R5ENok;<=ajkk}`B>E38zg5%xzX|*oU2g{Cma|-=K z@rdl_ovG2v`D(FpFBLI1taZK-=9%9qCeB5W>o8jN_%gMK+Y{XD55k%GVF^ZcdA091 z+{>mgdlDgAx3hLWxVPtyEqt84n!VlY+&xLlHzIvs0xAuzAxAUI#OTQ-=c#>lA4R2K~b}Y_9Cc$mb7mO?tnMd7~1j+9ef22Xt2V5lCMIp{OgR6+_ z$=Mj%+R%cjENQ0Uvhd?f++pGZcu@>gbR`qx>A{(t+w=04>w;mi29JP4%eC6v5@Er| z-?YbHxZ0E8waOvwiYg95D0819vN3T{Fu=bN>@?OE7O0IY_Agw*NG(c$>Bv?UpHO}c z8xmp>R=raeTqyJw#!@}KyAX;-wj{KB8fB>|>w=`DoXu!-bf|eG06e{Q`}8~>@V`kI zAoC*I%pRz5S(u&v?sZ3YLSBXUxq!{LR%AAgzCds(VAt?RgPYd%8QSrAB8!cu_k(@T z0pBt{F%|l2`BWs6`Ghh(Hs9q*`ZsRuhhfz%yCP@Z(hs457RHZi*VN9G*K@8VkbC+> ze$~tkd=_C5zmaBxHNT@Mte0C2P^zvAPO5=Gi~5;((}oz#+SSi`7ZOv2i$3uDu=?Cd zE>4&;sNYz&Hyt=Wbv=9~powxMVV)_{#~rMXl7@Mh_#BvST&1rP2VpqUu;OHu|zwRhV}4j_H;V#oGd1x z+Bm<9GtSeg%7#pe8}rpm5;^4FC@ZJjwxP6+aUwSE`2Bf)rCC8wEB$gT#Of3K3a5(0 z`y$I_v#D6sop;*g-`;SETF)5Ct>j~-&T<+}v-pMgm9W|CxV|IkWMvwE*+7nz){cY~ zh8O6uaX}f&Q!9!X)y}qjQfu~g;T^{>)D&edyU4?U*l%4OL#JPV)ZS@Xq#DcY`IW>p z(v%j(AqB9G6`L`p(X4B~`HiU05rHiRP&SfBzkD0P{F4@sP-`UexR`{`ODPFWi}V#o za}u{+GJnr&9ES|xJS|^8C}+`%f|vzk5MsnAl5-Ki(+sPg^5G8$ zPu=Op=iCyXp48}Y1W#;M>pcV1r<8Gl9lS8fzF#7;eE?uOj_&-=o;(0dQ%WIigWsb) z@Mu#deh0p#vmfTjqap$;kUB?3QBi1|%F(f(QyyJ`Myg{4!AM(MDj6(y?5DHQ?)b8B zcDF~V-jj=|*4=N#v}=X5{(BvmWS9zVo_Vd=ON8f+G9RXXRED)%9ENQZu;P36B7*NR z{*aA!RV~g?`e!<4 zQPfs*ar`P<{w_28esqv_?R{2#%kY<9f0Fl9PE%yA@mBX*>m<&dlSGlXA_f<;TrY0} zl?e`;EX&yNG(@-K5(?+ju;N*p!sFO#3X2OUXcG#eyMFXadw!Vek!e4ox5SfkA4s!w&a&x^%3U0!X}xf%*@cR(vI;GAnF>G)JKc&%!738C%z z!HgjQQKk)gNjZ~i{#*d!6>1g6>QLT-_hs7P?x#9BR5Kmw_QASUqZTM5Ri z7~wI75E!^lF;Lg)ceTD=CddBocy`U&)TJ7GjDEvm&hVh53I|oYAZl%`rsC(xi+fRZ z7$tiRGY|0bj?aN0?q0HLv-jQYC)9 zv~YUnxxZDkykw4^g@mXDPA89dm_o?`$GMr9{2E~WPM;B^aw0C>#3&7 z+IgI?Uk6Qvm1vm-sqA@@a*Qr-5c`(F7l`FaTi6@DH?YIZ6oh{i&y^B2uc~`?fAO|j z(0w_YF~r@>F6-_pHUxR-$cj}%R)HGlMo@>##Szucpo6`FUKr&vPe?rOp>Cex+bi9m zXg6mD1+!zDMIswp!`G-W6T3^lf}Lohp??I0Hi^e7n7iRx8ZJlY78>qpGa_nmm{xY~ z)W#mRapE7w^Fr4Vvxg2JGlqwRt9{{By4PM3!F+(#=b^zGRZ01#WWxizpp`@^VWW)| zD)_)05BN?p72Wo*B9F$R%z#xEChlnklM0&x@1e|?DfH&Fz&|USC>WeA!C^h&t?|ZJ+ zYs}YEgp9%e`6lRjU8;qaoXZ=K9ZU}?+S?csKtp9;PM(ZX18{hI)fo9g$c9E?hcAyE zttbRfvn?=`7B%z`tv4!Z=0e}uDru58_d>s)#L=0sa4WUv$6eyNRjaA5x2MOO#Dp}( z+Pz;;Q!mlEvQ-r~StqXSgIX!sM655>x1!5qDm&{=8p~X%1O3^Lb5e|6MT{<7IZ~FQ zaUo?YUmr>^F*SI9l&<9xl?5d**q#|D@b+{s7EkAT($MNso5Rzfhh0|XhTwG2o+r1` zgf1w$x^trAmzuSComE0|E#)z{;+V~XDD(0c57+l-8_8oCO+ES&IE%v_jQ5W*LI2BoxJ%pC%(i!3d^$fD*LVS ztmHva7>0_#e#YPIf9;&z;z zMzRE2Y6pIqI!_klThv~lsG6FDssJZ^ItZ8U#r;0E=r+P9lKf)Djj1ffoeyK#*y;oP za0-)b7;oOaVro{0$AtB4WYMC%t*bwZ41TtpGL+m&J_0Zq`#%Rz&VHnozPpn#Jl%h+ z=ilXUW%=B-X!kMB$?cey!)1sy+HV^raCF;z%xL5lbghlQ%(?Ke68p;YvhqcEWpsfE ze5u>%et5d)5;+FNuqB&%mgwYYBI(O*wC8lC+02oAHkW6Yj1uZzH|@mQYzD+?qO<$3 zws2~DtF+5*Ui+*9^r?4r9r-8N42r&6)5GZRC%$Zc(&G)5lua)4A~AnEKhn$1qig>r zI4&b1`5?lJz4Tp$oOK{QbziVyj=b|Wb!1(|Hx#6Kgm0vc-b7I_L)}v!f8W>%i@SMDUQ{G@rX|yro&E8Qy^Be1DS&oL= z;frQZf|N397tL!*{J13P?$3{9S4UFnoRZ3n2;1|6vAfHg4CI1c_d*v+c#(Ph{-er4 zxocV-`F6gKo5ksLB8e14sPKLf6K^4JYiUR-Iz`)9LdL4H>ouAXdL-$ybTDod4kDY} z^`i4UP&1S-evJ4-XCelN?~zzhqZ#ZTrD58Pi}jM};ScD_W=^6#jDtV$l4J2+<~(pn zdiJB+z7yX6x%u3!3bzv*!W2M(}u`8ky)y< zE|iO$bu^AJ%^ms><=v;`0)KqbJj)gEFK(jYUfIKwCl~S%p$0lDnz;|6qO*KPaklbz zQV_(CCp@@a9_UZ>U^{sU+XXnAS7NpaF^W*eKl724D zJ>8t{6^D`hg{V%r4*+l&&Fu)C)Ht0d9BFV-O}^k^PG!1h>cF%TZD0H3L3E;0AYEUO zDwoi{N`C%H>zv)m?V2~fOz(29BBmj^Zg)>@JSP6L+PQkhAnG;#{R?#JNA|CobTo^L zF_O6H<4{bbyp zkC~LuoC`v|)qb`5r}&rKD1X-McH*qGagYqA0Qa<(opQe%nyY;I|O zk*oHS0zY$+d#a&|1^?6u>(A%h{GARlU;Erzs63l~8ZlmQ`G=IX*l`EZvx-QiL|`)P zr`Igyn^Ccv@?^ctfZ>k3_2crsH;@p-$a;K2mwPyg{x?d5NzBNKDS6q#qN@zwFSM!k zZv>~}HMi9s2}G|EU&t5xs8UZlODf$G?v`Zu9A2EnK*AEedGk7l3AlzoS@(V196c`7 zkt->LO`m+cYI94*ec9*;_f}5ElC#g)I(4|n=(j)9zGeRpWt~kOXe?q4vUo^-+YoI| z^>eZg6(Y|bTzmc zb2e83I>CMfEd4sB*tmcwE{eS8&;7x8f_cqc#82nP23U=P_HRs1!3oiQV=MJB`**v~ z|LK=QV0!w(=xKAtt7Enw>uGZjlR@>6ioSl>VEx)-wqmkYgK^xGYY8YYYeFbz7 z0{+rM=FzY&uy6HPBy_5dMJD1VCF+~r)8?jXt|(|;NT7BUwFV_L<(mJ7)I<%?jN90- zFD1*2_CQnbnZFK59P_a{jXFzlw|vW^2<|G&b7(hJI9WL{-tsENz^0L8S5#uFqVwo2 z`fyuIOEJf@Aq028mJ+9IfyJa-^`fR%l7j-xvXi?pERJ+iKFf7T+Qd~UqGoc&zdCng zfo}Wwe86_OYB|j?xtOtewKIU6zL{-a{>>0yPGE}Ify&#plWa=D0xia#(WA$EUh#*L zE!_LrJ*Y}h#8M33ORfP&=M1A}m;UIr4;yiU!K}Hd+9p#c4FhS2v=8ym8R|iSbb~J(fo|t+aGy@`jcs zB(KYIO-k~3)7fRv+<&_gPY_P2L{(gA3Ij!^Da1l>(hx|95kj_hZ9?r}Lk-t23qmj~ z+?lEfFQSARB0^nNio*;l@o7n*g|%3(^Fst7xT(WaOxEEdVov?GR+Mm7R)!2CSbw3-D#Faf;xsY+WBi3^2N*Fcije6qCCgEuj8kack z-!?2NNzT_l-KOWiQpNWWx4z^kKfOHgDE4w}8>)>_eK#|vyG1jN@%H*$Z8h&UU4$>Q z+3QDnT_36SqUA4>o3h>IE~%A%$zh!h>*VE1tDh$5wbP^5miVE2+Ia+f<0@DdpBs-m zzgg2?koUc6R5r`rs&96ZTM!%WGqOv{pM4~M=)#4dSKq8RdLo&=RV?sis{9X zz4OL5_au)bEw0x<9qru=Le>53)~jZ(;DxP1Dg|5aqn>MDdqx*K1HF0rWx6Jrp9<)= z(!jLN+It??Z}$XRzP!`}FI?TTX7YKL#g1%n(>Zt}Sa@&RYoI zqd2#ed1au@aot^0oQV3BV@;MFQgB&!-@b#Ld&MlKceJXI!Np9%&KZC8PI9F2Ma`x@ z)ye3?n8AVGH)0Oj2+_U9_G=Th!lchKdpF#AXJ#EfEvMC*FqL<;K?!cd2Hb(e`lDTk zJ7@Frq{3aDnp;T+-?EV$(u_Lq<*e=s|!!wp4 zT@vn-7)I_N;}Mq|AJ|(Wa^4vsLRYJ8Jc)lT)vXo~7_``_t<*mz)$1AEIS{7}b!SFt z7N-dNo`vGyPo59{sQ9wy7v@mt)){TMpDX}eR!Z@Idbd4&Z>N?d~WF>>YMWVZl7g(&@$3&(( zyUrt4Ct{5nbJ*aaIu)gwUXqEH#}IUjs<-VMa9ZR`wA&tEy*a_nU%@zF)MrSSU9nQ& zxIIE6ER9$g1AK0ZoOw|!%D{zRcHU6BW8)zPgk%Q4t5hd?i>0t_=v6>%lk}_XU0>3) zNoIVED*Iq93&tlB98=A%Ca$Bd2Tm3X2+Vi360-9J%-8Du8TtrV#UZtXj=wXrIK<&6 zP?|quGBYG7Fe}RpPI(BHhT%aU^}=aXf3Vre`XwP*a^blOLnaM5nFq_lLY9E<7!^z8 z6D%+);Zqf51%*&i67q-<^iRmg zOKjrZKnx$zd4G8))lHPr!Y?b&@362O$Khrs%4H=pmIZV;C-a>rqeUrJFBj?3Qe#Ww zq)TE-)*N^rd>#+K7??2zYq6(wxXY30I2P@%ca_AvpGWu_8nBT=p|7$2D?`--LbRdL zT!#L#dR_A|D|fiX6Y&?|t4|>56O!6I(_mrD(;EEqlp*d0M>T&}Z`HcfcK@p%&B5(= ziL=dRV(mNbRMg4-Hu`po%}|mNn-xKvGM>`s?%lM3*_{}{F+wme$e@#rp?I9+;={Pl%DC@n9{46!LshG7GDw@Rz*TKi6AO%D2hx#pQo5;<61CE4ryjH{z3#$GbR)j>B zJ*__sH3sDc8Vnq1{z#7=%-}72pX;{U#sIbQCeJbvQ#r@s{Ff5jfx|fyQf{KGXTWF; ztdALt@`E;_Lc*)PUVY~_m=B_!q>Y3C)PE#5K*-|MjpEiq$a;~Zwa{CS&@{oSK= zq{iou`xKTCBt;>EXufn_hU{JH;4*w{x_s#H0t}!gDgwS|TifUCY!zIwjj=B+xOwoZ zmfBEY&%{F8CgoqdSWEQU`l<7SbYW*FL=Tbxk&AdvDOnxa-`6TKZE6Q@AUj{rOwK?T zj)qgUZg`%_5E(fpN~7ulaz{$Zl*H0u#7-UufL3Z_bHvSw*UHil4~y&G*#q~hOf9!* zsvsr~lOc}W(&Ofmh;w2rsmC`+!ERk{{A#87v-=$MSX6=0$MXmKJgjlRH}VEoIlNC0 zPe~;YCfRX_HREmlC0Wyo?7KKx?X#^O{;*rG4A&ca8U6tsMm|#Y>`d&8!cAQSdn7`t z+G&b-NBEbQW8IF{cG~S`0F3k@(TPEl} zcSPd4(TFu?+q9MUt95zUs%q|!j(*~OHtafOxCi5EUs_T$lJ(g z(#4p$(h$;*^R-MWPS5A|qq`?4_PxLy+fpmX`96?35q~^@aI$=8gBQU~n$GWYKDw&` zT*7nTc*oNp$ALctc)pek)1bIDN~t55@=dYwD9#W7)c#EpaU103T?(m*LO`6^XwcI4Vi+Lbr+L1m;g#j(-diwWClB$PMhy@>4 zM@)XQ$%()xKelk=4dKP2LgLGxe&Ry1ySgi#gW647v|ddLUQso7)alg)+YZNOuWQ#f zu_~!~TDceK{tTUtohOHgburB8=~cs|X}K>y+}_>hSLg^n17c)4EElc$n^hdEXM8yU z5h83WLy1SYUwbmanMlW;XMy@OjELM8pM>f@56yd+4pjg z>UNnd)}fH_n!U}w{T-pvHU1^@HI6aW2y318B$Q2OWY@r72KlBdD`ycZmsyz-Fsrh{ zq9fdbB_^@4?uIefRB|HOJl`Rl)Nahut%#WbVM|dZ9jd z-*?|1g2zdGGFnNLG|Ib_FX@B3)M*(nf@{2*QkER#P|tNW9v%XV@~2E)Y!Y-kDVvf9 zFG?9v#as*OCjNzE77=L)5fmy+%lH~R32CY;vY0JR^2 zhz?X11$1fmo#YcX>w`bJXUG?e(m4*1n2~-qX1YLYp>#`OzQ}e%AjEm;?{{$dPFD~a z=3S#5Wv8~H>#ZdJhZ6=gF5*E_vt0FW4-nm8gy0TQpdr1vz&dCPFM+Id9WR1%wXY*|VtOUTuGnG|+UJ`Ys5- z!vOT-_AIC5K2tcv9@C94vs+|z{1DB1%vJpcf~|1hpL*al(bcs3b@DWrB>fZw2OZ(ds@V@LZ#X08gHIKz)cBLBBK=F@+>~GM#AVV(n?pO@|H5RTiu*MYK{O2vfd0GwThuu{ zkvfUNM*!f(a-{LTQA+cEtPoemxMyj?qUlY=>wj+Dv z7j($DKbe^UoMaZ%m z%5Cq?3*Ea`x?9-}+V$=Sv>6KyV}JCPuR3QAwgow>-Z2xD5$bzSJf6BBzF$urF%6HX zB#39ZnZ9Ti=a+JoY+iiF!NjS|_x51mN52v0`*!uSqZKTy==dhx%G97nTE@DcD=}E% zzq+n6F+al33=0Ls@{&zCR!Paf?yz{(yRkb)qOhZPwD7`2Wwk!VSzPqt&yl!&my@HM z^B4Tcxy?oG!no!H_=9O>?w^St<*L1m&av6ao01N8yehjc470_vIBeqlm6dW}fB@K; zU-0^$2nlVcf>HB~PH%sI%uY*mNoHAFV5_MouH2pW!E-CUO2Wso?A&#omG+5i-rBDZ zKTo^5sXsCOvLx8=GF6!#R}!?TaC3!IJXB>lD<>P?$%9yI(Kl|GlrLM7eLII`-f-gU zw^$=hw8JvI(`RYW?l&V)#J#S(t2UBj_H~N2XQ$R?s}g~flOz@|GHh;v8nAu8BR%PO zc+#L2U@+H;!0jd**<ttr;04U(?G?CG@t(eIN9vG&l)g8X9Ps2% zPv_yaK47Kp8kD@fWg($?$1vnb!*1E{e-ogV7>DJIWr8X&;qnWQEH}bp?9gWXC^Piu zV_dk1OR8NM4h7c5Z#N_dx7N*XjOXWWlRqr13d;*gl<6IfN8KQ48P&S#XuMd88+lge z1HtW`NiI#;TNBSWF>qkNO9pjRG^k_$KP+8ia3x*Wy|ImnZQI7gw(W`SOfvDr){Sl4 z*tRjTJ+UVK@_hB4s#Se{c6Fbw+I#KQYpuN3@{At4)cSZ%;zNCvA?>sqOpKLAZdB09 zr+OvHTPQeqPJ~3fhLZ?~3^1Nh_4YvXo`AOD1?0~ai~v6thqh<#dezk<=C#$(huf7q z-(3;jyE%cCb{1>B?ZcJ?e1ecHA&1xWhN(xf{JN|tL566}+r-f#<)wh@E;M{SO~!$M z#hK}6O=13rmAH*=N8x2h_dBZdaIFwmSC;QyA$Rrb!*4C`&&oC>d^UH@nKy*{&m%?_ zlugT+Agk;Q(T^i8~t9qSN0(5%hnuT9XH`~!!6iD*s&{j&BkRyBS6b)eVY=< zwe3-Zn$~is%gYI5NZQnh7kzI3DuDj^l4QVNK;5NE1BYl?{7j7%hf3j(%AWH*0<;+` zFwXXN1E0(!F#pszbStE2wokwT;$%2`uU4G)5QWfo>RoD&e!UOCxatn(XPTwM}#0k;uTSxm(=!rBIuZr0}nC61sq!6{k) zQ#=1Q~q+Odle z1XLd{cQqcTam~nu(d3M6)7g{2m1i>g5AKe^Cbsn&!3rDGr=PJ~LeW*du$!Ob(HBFZ zO60cS*SV_n4o>frJe$W`dU1Z8#b$Yb9=e(1Lv5#eY2h-BOvFFEwreSyh)I=i5dRP} z5tD5V_-m=gCm8^3gPHl64zBgj3|@U!em1|>Lki#C4ul%Dd~Q`+mJ%>ta_Sf>&9}-< z#Z~%}CaDQOM1Tbb!1C`OBiEA*nhS4#Ke&B^C>JLt({Qj0g;xdlB`6|jL-D=b8*ko8 z>IzlLPWaLMfET*sP zgFd<;85x=L0c#}0Lg1*ywBv8M&rBbV=Ru!BdfECsEZcBY`fR%x*)aO*JGrFSPhUkn zm%8}d$s2b5(W7w}0{`Rg<)j&3p%i}Fj3h)UX`bHBdN5VlFjX>0X-vZ1Hk|Ze0HZl0 zw(-|(f2|;-51EZ)%0&n`JJyV0(9};DfWGSouKh)%nFp65Wz#4k??lepm5mNY)9A2k zjr+XqtjZ9o^=^@(wH+#B$qth+!@-;5VEfCH&TXB>Ozk|Y9a!InVFXJWxm0OHg~&Ud zE*`Fm$)iNAft^H$)%Ghpjwx#S~h{Kchh1Yu0Y6cMG!BJ?togcR@p;dwvJtN1&718 znLR1irJ$9I4&oyhyfC(zs0?6)7Ney-PCa@l=hgJmJMg&$-J&r0orcb8(j#?9EC7eH z`Pnah`a9FUemy~XGVJHHYy}-fuzHTo94n&p*1sq9%G2Lq+K7nq=g$BUGti{IPKkty zI3xgCl*6hnJuF>G!@It{L~rfRfwp*`+Ehgp$!2p&yQ-$lMz?CWq(fI%exgd?x1Gf6 zBIkE?sLHY>hX|->urQE`7**JfI2fyfnxwtuDHoS+8}HyGj%GAchlWOV7@4uCx=~dv z*McdHB}TXdnI4@fH|5-rG7C<96pkj?Vib4@((~>M!0A7>UVpme1v=$shI)1#rxui1 zRkr=hX~_PC?%JpJ?+)aqe!dg8Fm*S4%X8#YDZXsi8HdND-ZjCYoV}LpA=@Rot=X}o zfE{+q$9YS7A42p@j7^3sk?CfhRU=Cw^ZoJ9C-rj`S%e?{jnwyPvSxESaBW3RtWvlm zwDf!GXmrUU05R6#_`N=Y+;$GLQBEYckCwdC`7VC7r$%{j{3Qdq6nbCerekS{ksep0 zZ{vC&&ZN!@htfw3W7`tIFvu@0c<0l**DUQ-sj5=<6eo>Gc~9#*a5th-iEZ26R3Wu< ze0qrdWG6~9hFK-Af3}HIwn$P00-%;m4Pg=Ea5ZutJ455z_$|)FkUPZwh$Y)d3w2-h zto@ydkl^~NB?&=SYg*SYz-Xi!Qd0@~dS=*H_FTHhM7O!h@tNlr#*viX&%e%<+px~k z!Ot=-NowQxiGUnPI7Ll>vgCCzBxKR5o2G)A+B}z-SMH>Y5<`UREc_&;sk+}W>~Q|K zh5eqJhbg9sCv4E7rWD>QrodphJ29Hx7kz4xqpbF%L96HWj-G?umnO52!}1z-XJy&wVeR#V67Xh!^#@+T6Vy-DJ=X7VO!MoBt08;zJB<@vT8%*FC$ZcXyR zT}e->6`G748Cr8!bVVhG4)WoZTN$dzOBZ47E4DRW$$u~J&f_i@c;3ZUt=yP`@(^=C zLMgO4?ZxG5ri#gQWE7Hl?aS1Y$jd)P$lHHQ?PXRoVR3KjqZgkg@@>Y2Kj>sLg|eut zw83LRD4ofapIKrJj#gBb+}L}M7zEfoe|y;P1(OMtZTO|mYuCMxXBT^PR-XJ?{eE~} zfw12s_o%U;(|K3gQ4w55I$eRjq()fy5N&qCrN^LKkxO4Xk}|ML-2L{UN8}hM2y^0+ zSOFeOt%3()p6PEeJt0Mic9-~FFFQ78`NehbMht<&AZrgFz=laeA`Ud+Q5tD7+G=P- zXF`Wr$ZM#VOnvLhHMOh0xB6bbZ;DANXFK_DI~Y9VBc^3yD?g)}C3CTCH`s7{GLsUg zM{#}Kkd9rvO=xi1WQqJ!k$V*h!B$kFnx@RnVEE)WDHS#=Qaw%>X_?I7m(iS%ZmETQ1CuwU5i zD0h_7&SVyqn4i~orxP0my=`x=c7gn9?ZVUNP(Vmq1n{VhUz7QS#zP!5YhdvM;81n;o}s|&gk5s z$>SPdV+#7bE6iyR=X_Pe?vVbImJ3^2P--e{TMtsrA&ei<~pt2#NjZP==d;H1W6D8#>4hk-9R&{ff@Wj zs6o1=eu-HpwqgWD5Xow~V&QxlB418uZ&M^|MHT9ox(5x-yWaO*mk5qbnr_UNy^O7d zwNIv$G&~!e*I6uf5RN?vUOmy6jD(Owz77>5m@(wPUIrQs$4;L5|HWa3wtn(v5oiEu z&aIX5U3gnJZX0b#Hojirdqr5k?A)l_T~OEoQjI? z-)|yj+*8-gyIuo5K6QI|$q!#QM?!pkW}GdCc)Ft^`anRF8d35m3gBSX^<7I~Gpt zh@)PxNCgTsSWH*k0}Jb=j_RG`w>Kh=J)%(0&GbCR;WBt7MrT|HJb-T z&5UwRwrq~kb0J_Rc(v&f+>lpxe2}Bnc4ITGp^e08Xyv)`AvxrJjUNC%eK%Kh*qAqMd3;6tG_){4(Y<~Uh>m2t9)R}u4bt(Xttx2y-0`?BGiJ~Yi={(zbSu7} zVpuytBqXS@>}xy@h{a2k)HeoPA4KAjrPyMu-w&(sK$0cQcy8$ zXem7)1=a@>a3?`Lr55{g-%9>UkHLJ z4Bl0g)zVsG_r{AG0eZ<7AKujZfSby$E(l+&+6hryT@CeQH3Rl0Mek+iUO}i#=_SF4 zMdW_UG^SUdxyoO%vRF!XH0C)s8|dX4ht*64;Qa;FaLOs2{a7RArUW`mq6Ult`5HxD ze?3^`>(67}6@b5SC`kj;?w_n>+9>1Rcm!P#fx`Xub2$4U^;fB&*);!V@Q9nvc^P6H?`r7(BcWceEo z+L*O>$3(XtFUZ7C3ki(#EZ)pUQsR+)Zb(Fa02PZrYOLAP<<-d7^J(^T=BeOMAEw5D zdgUzHEOlk%(u*)dIsiou9#Cmg(Xo*qIEC&URk#$pzh`9s08U6SJVy8f4YI1K1S$T-aPtX{SjRk^ONO7nm;Vbs z$J>?;e`K*=kUPlob(K38*FMK+y}W@bV%!>5S89i3wm~hXM^ZH=iTn_gQGZo)vQu?7 zxeeVKg8MZ!yNYjc<5o0z^IHk}*td^lJA$4zfoO8?h$P*H4dGAb;}%6v=e;dn_A1j> zPMZ9VSfBj4!fi#zDVEeEzWJ>#fz5%yI8L-9@2`ZSwyX;20@)MZ# zeR*$^<$MG4$JR4Am7~qSw$slF0W-}JON=4S?eoo!7>m1dlGp2fx_(o4+-YsS^(l!T zZ|)B~y3B)*CAS*@6q=kxz3er+8aHj~w=Z8qE#i6l8PSt)*I6tq2(8X^mg2SGH7zUFBRm8}GP`Cb*4crMasLwUM3_hirozWXw zRbWZWkUNE)Mji97MC%yY=GXznrt0xoZ&R=6gA|)iJ~RPI3PoAA!vH$;W*^7z^Kun# zM0v9X_kih(o@h~#$pkt;L)4&orY;2(l?);xegegH)E_xcWN1{QNXo(wAxHpDa@IHa zL6tONd3Du^YYKPqp`TsNuXXnhEEU?t__cX6!A`Yh?;j;? zPEA$a_Bx=H>m`Dyl#_tr1O}Q4s>C@qn|GW=4tPe^+n2-ZNY*AG)I~9s) zYHR2RC^(f#LIEur44VP|x6Rj3D#$g}NEw1bdk~Vf<0u1_Q-V>Cq9jNG z(!vF$nlR*xhodRUZ2ztxaX|uWYD@z~NZtX9!PS5u{Uxh=;oy7zn@pfkh343IQ)es1 znt9^o7c%m%v`w{2C~^Z*7u=*6E0otWjs22X1KI8m{R1a!3+*T;q3zocdL$|Ryoe&B-WcKCi(0ii>oixWpzsGR+ ziiiBp7(DYMEtCT_+R%ad9k;?`6Q^4jnuPYAmsvFG%=xyHSOse$bZAh3jO-(a77v zj*P>>(Kb`IjP_K8>F)+DD>V@*c{x8?{|q{MMU@oavD|4ogTw1p(@f=CL9%4QBJ zA*F~AA8Lb$PP%UlRswz`i$H-0h?qhnLDYu+uQ*TgV>Si{Ms_H=&O+dclsfn_w_yVx7T(U>wO0g%RD||5o>WF!0ZgM?^ zY$Q=uJ4aEW>bPs<=a-sp@4hSSj5jx+fJZ7v#AG);)*L?G0y0;f)Rt#FPaW16j+lXb z!7`JnPZmaRH!FIEYzhG_03u)@>fsmz*_fB#cpUfKNJj72Yq2l_@Ac!#R=gUPMdYi) zz>!J`da=QjLJ_ht1vO; zbWRpUWU1HP38$hmHFy;sP#@rc9IUV~)%)W>ZRPR9));n_j0PS#Hkb_Av>wkCCnX#< z!~cGjn5ty{5_#+M)1^!w(zA@G~wt6S>c%#el z#Oqb9d=<-T($4vHaEzLh2H$=$xA*h}8QB?0oqP~rlq2awaT-k&O9}0Ub3l5Q?_%jF z_ZIKz;a?l64yfWC)j36%HfLbn3WS^0z$*4g@LcOXf9G;IqGp)%7wGuR&5RPb>GWwh zDcj@(l|j;S>F)Tm@{)eW5_KoSdY>FiHm(oEsW-QWJ+d;@zO-?5Nk@&I-XSKCu?*~ z-~09)qtHbK?5S2ku0&2xWTQl42e4S-M|xsw`qS{Zgo}AKnY$nrV!rDW{jRcEP?0Q> zAP9(iVPdH>L*8hsB{)b~S(eURz+9J`BT%${B8M07nU82UZ)v16VeK1}uWRzj62y#fOW?YXCAK*3WLo>JR=3#ON;v zd_S4oA7s?zP`-7r6F$B8k1s=vr3Bfn$DOHa0(C+b!SwEPq9_2LDvGvW|%HQu%>#7eJy)2wnK z7WmY|0;l}Os`4|FrrK3i!DszVxyxuV`}2^e2hC8hC&WNNq3}s2X?a8A6U=uGHw^rd z_O}Z8LX!RwR2*&LlM7NQSbvaJ zo@TU7HTj&I;gk$;Kjmekhq1+=T3top%gLS9goG}U7CtH%Rf8a;MimSK&)5C6O4c z@kqD2b_=VHm(u4iNBXVmk3xbqCKB5Ug{ZB4{6L?%8YLpK95fg#MKd6u7Fq&aFln}bMo`{^<8TYPp#A8~F3R`Im z%0_3%75ql^i}-0euksQ%)W#~h#LOE(YZ%_Tqdg-%KJ8ciupk+?OXkFeDs`QT@9{Vs zgsr?1!*km;wm>;4jfO%AFz|dcvjhPw+9!_kve~f%*Es!opH6$qy+4i3kB8Q_J)Ak5 z9g7ur`L&T&XB9Uy*%@CBJI0+FQ_P1`s$KlKYlbeqDIIyLg~>L*8&rj-#3NM*R_@!W zUDS`MNlb&E%@MsIJO(T?)AJk|DqJqtTp!KC_f49;4~(>5yT7Xv4r#4~ZlQ7JFS{G=dVtZTz5m;Q}6To3G-y!-V89)`lg3XHZCIJb78P=_SG}Xqc#k zV>8IO9v{0BpxHYwFN^<&F(?9y9-i-OnAN=q2r47Ql0qmUElX!>TBPE75m`sAwx~}J z+f;Tje!0N;Vngy~A01H$xyzDWszHq_yPJ(6Oxt=&=S1xuozm?|`V1-KUc65kdRLZx z&Z;?)4}yY8R{blvN#aE)XT#@D>aQ@tVumil?|UIRCikZHSr!o8eJ#Yoiu3~B;}5mE zGc#qAh5?SDuAI=QBA&zxn4-z0o9!3HUHUb zL1f{5*KY%&O0TtjvI2hwi5qXcOVzY^j)8DZ?t>(x;=%qIS9bic`-t%C__kT=;ze=w zzP}^c!_pBcr?-vCtQ^`w0q>xCQ%zI`QrKQV5ClXJJk$pKw3Z#-cLKHM?jN*~OM-rT zY0@n_ByVHIqqOK_Dg1U>#wGN}x9XZ;UciP0ccaD&&P;YQQeJkk=WTa2$(HAw@gJJ% zTfeO5e!W%C?XOXg8(Mk-?)&S%5`@^nFgemIud3Doaa%Yq+8h1O zeGN&<8AejRyr6via}Z)%sjl7p)P)dhx9G-2lGSp^l|&u$H>D3?E9IbI=C{{St?%^t!=^}Rc4SH41Bx+cP3H5 z=0-(J7d5sLe7Yx+Io=Y;6ykrBnd#R%`C9)`X8%Pb(Frvm{YRM%f8oy;j=ym5h1Gyl z-v`iOEf^JFsob`!F8R7yFJ!45w!e=3DfsMi=C=cJWR`n%^wZ>1c{GEEb9URt5APTI zf5#@%$$?e{%~G|rKQ(2_4QeVZQS9lStz(Gd-7qrLnz&Tzkae+wp_B}@Yad*5Lz`y8d$`Zm16vF12hJk&N_}5?RU5K~k5fY>y)JaB8N>2ZxjnQP zQSRJ%Q$4HS{pwEkFDX~1M{KQ#%&KZ$ujVEMmLzf+LAn)IcZZ`ucmP11wMx4e9D8T< ztr0K-4-hq9QjY#*e)n)wn?<@Q;7S2vbaTU-y!p4xaG2VUDk?Q7678?IQHWcTf2h!b zS5cx^B>Boq7d4JIFzeL8QeB1xG979vvoR?)q1tyE#$5P?r8WePeHyVTffZemUQ*s@ z!q&2Ika!}CXGtO(p=myC?fi#PyXu#D#8)3}+4k?mCh%b{oJz=}eOr~A5B>s$JQEQd zE3ip9X27AFQfWeSg5o&;EsuI@o|F1lrJ)mdF7n7e!I(Ad4uRfz=^H#I3 z?8?KV8W?`s#~-6wy1-f2B@vsH+I!LZ^`*8SJ*(~Z)WgxY%B+8!U!B{nrG8R?YHbJt(-h7`dvT(cp24J{5H{4wKo9C2v2N`Kx20UiqnT`EqQnNm6V?L(26#@1d{JZn~C12`)1T}G7!d%}I@yPHYZw|l5=XGb*7vn~#GSQ6{_ zUbdZhlB7*yjibpYhuw^b)@@Dfx;P3$b%rt8$tp`2OTNnBxeHw`VL9rfl6QB^Lb`+? zqUahl(Rp@*OiB*yb{S5p26{ht`gjlv85&-Yp)w119#%#w&1r8RAV`yP&c`8YxLE!d znQDl;adIp@c|Fh<)cG-Tpx=t652gjE0}~qajg>MN;1H3uyyVQyC!zsdz4!cEni;6X zmN^pro_Dmd_*f$nZ6&*eD#)p3%LR%9!-nk74?uT#<*!T^3>PV8nGI0HC4_#~O;Xm; zkh_Vc3FniG%H!;p;a1Gxqium{q2oC8d}f+KsS`jM6@F3o;lgB;JjF@)qorl(jvP8L zelr>11gy$^pWm&j6b?kz@ey|`*7jy9>9AxzOD`})%3e!V)y!6i_J`}Zvmevp1ezHy z2gsJk+~q{me-sQdJPUAIyw*6eAT5Av?gB_jRdv^X~fzpdqnuw0_sp)So|LvM+j&MN;D|j`1?6 zm#u0w6OJ&6fhYmsXabU$k06l!QgH^vtN!a~gLSLOTp9A5T;abNE6?dBsgy4XSNSqX z2!ibD@!BVT=UIo<2o1xiCeAm>%FKVynW=o7lko6gv7azEyGSn>bT{1JE0_){4>fMw zcA9nc{qff=BDE~SSY2D4tiwkiFi0c1C~cD_8x#Y!jvJH&035&@oZiu}Kd6{;9qGUy zEnf1qXwCj9dWgRp+q}omXsY}S-M5zDZjmhX@c6hfb`aZI@+`I8=L{>hK=rKTZ>iG6 zinFeD@Zf|y_yb`iSibi;)_ti-=CXgjX?9h87>Xd9y6{6RCwr>P9 z>fxb9?-%0;M|uD=$b12H1fJ`^$)$dX2r1_tnfj*X=J6+K2C_DFj##>fyc(!l$rI;H zB@aXjKk5bF3=c1TbovD1B~>A=jC2HV@7h(PKwmjToqG84U;1>M+MXa68TONfk`)13kt`$$a;|V)d0^$`8in-v zQPi4xX<0~*h-N}DRgzHhN}NU72gu8C_yjmQW2V=BcGR1G*lOsg;yF_n`&oopNq#j6 z<-D;v^Szm3zXH`jFY+Lx&aOeF9+n~U(7qoU&sDL^?`HE~X0bORdOr+yI07=omi>eqeL&NqO{g#MLdkN<0u z6Xib|Rp%;r%hCG=@xE?eutE^_-JVVl;h!eXY zx^QaRZd3Bj_gVla=^;O03U8(|0=>Lq{xEC4jmH#vOqxGUT*UiEqM)cS9P_1<4|XZJv4$w4)Yi9BVtF1+<-&9dXJ!Ot!`QF<+_BpZ zXJ+Qj%g-3zu64>S$4FA)JU^g@U{Fwz6ddZ&w#*zWFu;k>EaL~cWYwMg0+kWMGgc~d zsXgoA&qF?JrG=d=^rSv7Jc3-59i5{9va78w1%N*-;c?ao8f!(s2VQcrQ1Zub!m3l++b1FD$;l7BKjx+Gebbv z`fbki%V7!#xPItO;$`K1Xm_cs`j~FGwfz-)w-s%nQKHBrqLo}Q{jK0q&rB`)u8+ge zjdb60BYnwDiMKt14fpZ}v_w<2zP_R!ZL!T+Apu4fQb~expPxlf6m0?mU{9trix?TP zxUmk>6`10hNlbXGejk3;jBYK%qr^r6D{NB9V4FiShT@?B0BDKA`>`q-aJ{V-Wzmadnq4Gu&Z#7S_?h{eq;)(Ux=?7NmaX`yEZguT*1%6 zVPK1h%z~2syb+@Z*)s|DTzE7uYv`0$7?a!L}vO**egbpspa>Onq#FV)MbqjfR~USqN3|2Q~+ zEFtAtYVp4B6Hudd7@|$(b#;i)J-IEPCBw4OzE>{9oosxq}z z%|-~=T_1SvmaZfAxU3?X%1ix4vvd5mn1f>tZ!xy+@%LITq2h0Hop9qVEc%m*HFDmMO&6f*1W8WyBcS~CQc9u&@sC#yk#ns_n1?9aB+uu^fOb-g zhbsLnUOTa8n_SUW+8Y;Ia91NOwmtcVOxR;Oz^Bjgg%pL-LYM1(H&c1cC zOv;aDy z6HnIJEk?PR4~a?F!vcElw@~Qe56EV*Nl6h9mxXz?ITh(@y{`P70t82}ZUZVPc+QsA zwgdl<->2XoQA0=|RAF~j#cJnAOuhYf1G^bdnQlSeZ-vByo_{^95bWj{+ATtkXU z^ITY<#GB%O#?ql@HZG_IXv%%pc2Tvon=bB_Iq;{p`JL9QJ*k^%9vZWWTdc?`(*3Xa z?aZ>n(W+vo)A7YR*a4jcp;CSUJh zPb3Ee60aJ=7;iYIP*y2%YO~H*`{SoqvPIM#v17Eua*GRrdV*)sfrl8r`_?aJhvPt0 zSo{Z<(Zi@1)a_euqews3k`Ik(EN0DQHb$#{#h(C^-zdY<`fBMv?jzwVQu;H{^jPVz z7;xgM?})EhmW@^cwY6nHwJW}dqsbHnmXgmZ&^^8or`pzP2~=d88)Vylp^M;FmQy$u}6yu%x=pZoiu6-@?Rxd^Fd@1FuT$yJ~Pw z6|~cOvR1aTe;Ww*WKK)sRVPq}&~fn)1X6DSsVoF_-HTM5UatUiHF;cLxsadF?p&TQ zSrCRZ#LF1&!oI@Bs}Bx|8c_|nds=IFKXd2;rdhtm)Tghf>n!*ZjtE=wTPuEWuaE+L z{+mzX-1W_{iPgyZt_n>NxVWFHD#10JIizVU#kQMbH2o=v&%M<(*-sGc%L2UgR6v3Y zmV_xS@42-|Pvv4>3$5j$j)Pf5Zlfa2Hc!TAKDk81gk%kMx(T8e@RelIDNXlEDW7QD zMIH6x@V#HEWPEACc^WVG=H+O(o^+FpQaLm4ElbfGyJw%cVd?cfX5QaT-g~`9Xp*Gd zl`%wyYFE)f1vpVcF%Yp*M?aqd!0^WFx^!*EqwNZ32m8ZYdW-BdUe2feK6k@%!a-|B z2Bqi~4%rbs-Y3Z^EJ9b>04KT&r#Qc!W7^>Y$J`p)2usq7SYfD0#s@dhbS`gEwDr@f zD&Z}2M&|7rO68XvMG6s^ZVYBzM}Pqc(nXARm-K}cEu0+@GSPLhv6%m7;qxFFl^Lky zKNZNVll5SmOJBQ`?p*>pkkE)%7Yjuk6DmFX;Jvu)SQ=7RL*<0}TjsyyUNc#by9L|Z zU^~_H>u^F+r}dY zZCLzStZ)U)^3*+Pg(&siZWC3%ZaT6Uc^D}+YS7H}H{>0Qjwk9t!|E*86!>T-DnXjD zSX4VjSvc*k?XZZ?h-)GJ=gB0sO;-OToPMuu4|yu}!vEob?o^TpLnUQUo&V{Ko}po96My{;FnNbJKirB#BpYVV{`MReysf;t zcV1n-L^d*k-$FJNrrBTN?=wzoL-W=dSY}iCM-b|cr zRyj>i>}mHEFF{7e>oR&<2j3#dLPNIBTSnjuKHuL@nc*Y2=-$u4mu7gZ9)J@j0gJ}M z=%yL$ER@$Zq&EjDrt zmVs~XZOF1OPu9hhIj;P&%7~X=Ni6nzE&TN8&>%+076 znje~GiP>wcXy9n{bPv_QH%?2eH>#Uv7Y66#|Ii5@jEY9lpC7JWCGVKQuU9FvO1kxW zedIbO0^ha=`-8_-nJTEj9iOOpt4fsgS&hRx&u3AX=d*kHf5FV6Z*|1oTbU%2_g z%NNeRaBsN!db;98-wU>VaB0=~%eEKn%JK1z+(_vH25ell4yK6Yq;UG~FhKB3nJ`~W zI*BM>ri(dbJeAIM&cPU1;_E~g% zmf=2SPtrn-CJVezprQ}$a?iq9O4DiExT?knVh8DVPS6cG;;o+?Sb>Z40MI*e0 zMu%9C4eZwS=R(OS?{jVOLToMVjLLcx={ zz~&=+$%fm)8LzXCO2&Z_8p=1<_!e?gQHc@MD~&ZhEg=I}Jfls9#0q1c!BjbnXtVLp zP?mN{e4)>z!=}RI#P--Z`+dG4{727HE3e7^4h1C`V6^gazgsj#ONJggVT>blJsCWar1A4{1@QJ!)ucUY4HCE0h@7IsxWXkW9 z`j<5d!P4yy$W@6}+a&g5MRt%n`xs`M)Xpaw?kHXMY_Um4qLnoxFr&SpRUK?57tMi7SH3BSxk>T}_?`1P9)LKfflk|x3cQdPpp%%1$ zG{nmL5c1b8E(n>*_Cg><|336c~wv`Zly(U*?`!wkE# zh3gc_v>ZS(n;(kGQDO4wo{kXX`TSYeDRB0<}>Fw8+KG^`i!nll0EQLg?!nEBbqlS1`QONHS zE zlFsixHxLn^8}(NSSlSM4Zt!$AMggw_s9w0R<9v^^hF(qEPoClzgNRY@Ri3#K&dWgY zejJ3{Ga=L1M&cUXi>iR`iEl7d9w|K}`yqYVkGQ(EFw+B@fugQu1J%;cr=4a&Ag(a- zfq`MRZ`JTfCqG~T?jC@=ViWztZFOV*K&Nwqh!eV;kc-{t7DJOPiFOtu#k1Cjuzxe` z0{Uq?2F$xC79FVKAhq9xe@FjhhB({wWCVUlzjje@&A}yW2%32~eYjpa24H#k@So?T z&}f)E!~xP;r2__h|tjC`>sKh-X8YP=?PVixf`;)$1$&0;i#F z!UbtF&2vM75L&wG6Z;4>QSN1D6XaGe?&M0PjSEB2FhoD!Z67~d4Ig>XvriH-n{cZB z1^(O-(>C^+0kgxV?bD-tc*X$<-oYjXa*bZL_=8&t_}6GEVhyylA2A31BmL8<9%cMZ zH6MXKt^V?0kogix5joc5RH~;NlplD4UHsS6=%!lB*Wr(>^Y#QeR_wH#&HRUg>r8>e z*@lqBaldt!xlU}?)IY5e+p61TWy}F8Jx@3dBcTR$~DpG8QF7~5Xx@T30C%SJB z)?4*w8H}K_DJjCnQct_z(arVi693lGYt=FoA^Mv_%wF$c2LAcr^h~o1?hjunSwUE% z{SdBNsfF)4LQv;|o8jz1hQTKYyD=M+%->_AY@mezM!cT2%py>5w{mR-4BPP_wDvte zzkdn|7{teR*g?U_5K_gYOz2JZ^n^yh)v~RydCQ;A%XIYpV(TGFi?x3CNXzv8MWg0| z3wHrEohxQgt9C`5Ot{LuOe=KgoOw1_mvXho5FS!gHzSc_TCzADF)H!UTJAu(_fDdU z`0n)Kdob3+y#4(6u;{NX+toyWVyJe&fR4rnJID(OdxY(JF;bYi#7=jl19#4CVCt-M z|8Gh~PBu#C&ed7#m1FRFrDFLz5$mxtk4CiQ?hOG;9{>VTZAc}y>w9&D(qiIqggb-( zec4aELxjqq(+1UXeScqvROx4pHR+t@A{!x2bJP(UW|9b08@?628%dbTwdI;jU!1^V z1My)f!pTJOJpXR*A1OjIW}JZmJ0@W^d3K+X?wx_)qULuOJ+=>dh95RK^Yd$4I4kJE zI8k&Ok762n=5ss0>W4FH^rKJz#=gp*Yx5+xw*R?1lyT5is>$pgj1Op?=?oc5WnxqV z8>nakp~rL;(wubj9qAuViJF?{iDNg`*u_pn5j8R?zM8uwcwCJ*YGeaP`_-@g&RRt) z(}60R@8%qZNZ^|U5CS4m*Z>i55?TPj;@G>rb4j*C6ZodCV*h@s$k%f`00)2RJlpwK z^mJf4kX7DkXj9?hm`i_L*8C*vm07m$r7i?@N}JOZ6O&9~8xjOI&2l zmi)j|Y2bG0v#~Rwf=%QYx!IGWZwCkQKk_}dk0ke-BO4`tvx|6MbSNz(g+vK3ym*Fq zO3@>{W;CU=xp!?|QMJF~Q?6@3Er!7CZ*(mU^w5GPhu(Vz|3}m{M#uHV+ayh!Hg0U& zY>dXX*>GZ8lQxZQ+iq;zwrx&4ndIfa)_d!H*z4Z!cinS-XP=GYU!Evc&-nHLfA%-8 zrpk94_rMXM36>eZBh-f!!%M20@0DRwcf;u2{NAE;!=c6Mi>^kf`<9^`onmOA9A3Nq zw+V^61*X=K!_tWxq8GQzQ-n8@ydrO;9rS?)zYitdnyS~LZ=VO@(02s{N156xn|Ble z?wzSizgEKNC@ zw^CdBgmLmyspkDH?v?_unA{nwTCU||pn#cVvuU%%e7+8|1|}4>zsp2+8BPD~grNP(NG3C248LRq+0I~B|HD?xd@x6M&(^PhE&bb zi}eu66H0~DS^?eKy|c<*8U`t(O;!v>C{>f0EkTbkq(F=vC55BKkTeq<%2&MKS7p8# zpmvsz9H7yllwH3y)FoX)7?dDv@!Usvd@lx1^44?@Z)}SfYu-cQwa$uv?Bh`N0z0g9 zMUZ6A566oPUR`(;Y+8U+6JILP~r^JgYd~+@LQiA3;JX{h*(LO zMkeW1#n*XWLk3vxMPGOE$N>#*g|4UC@YwA4`cvx4<8ef;|5$pZXCs`l?q4zmC&|JV z5?E!UT8@B>aMQ6fxq8ZZ8H>7eBjigF$TE5-{-U(t8^_&N;NXO2Ckbb3iTqJ5TaBI{RE zwg!g0KVoUW&T-(%omSO{sT9>$yIgJ7Z>q5J4qc4+7tF)VQe#=o=R#wuk^-A4Posc3 z;mTwy@wAUV9SFSh7?0wEN`0*=WLPE#ib2}zN)ssy3!*_pJ@b$e8GWaZjN@^DOA2lr zb~iCAv8$0)Vjjb2#M7?=Kc%_W6LB%Ne*jiFMWL^#h#{zzqi}2vw6fAr!lRn=6UCK^ z9l@ELbtX}KX@~j;secP9XD*xl^gE(?h=)kt{<$D6n|euXl_1gu!O6UNc&%#gJj^iN zad=jCE~8vJ`}kvRrdgerYsb#Yd<_VGZQ8Ld04hAD3c4W`TR{`9W(QZBnB9A2BSp)l=5UfMW^}KWH9Y_eG4BP(dwu@U-CJMb zChaW}V;PHm_vO~Fb45>dwQL=6 zkCaRE#82gCb$;_4{!BbDQ0hY0F+g|0``kbRZkrFfkH`jYgZZ`_DlDs`Y96_oL~;eK z;_4D!(V#WP%FC3rx;#x_Y7wCfJirT8HyZw*CZn4tmSj_qnn}lnY8!a^EO}Desql(( zj+(?`zjNQe85R>vpNf;I2Tn^xm@N7+EzG>gGO(*%wTKN9C4KNz zwReyCMCXss4`yg!wu}tR14Wu8MG8JRRv)V#93jG?SlA=$!@56$$kGncz5;3w> zZQR_&RWgaIG}ls$lK^1}Ky|6HVdo?4>W@z83>bbvACu>VX<($Ml(U~Xk zXMmZv7kjo5Cue4wi!%}>R6^s{kt1`^pAE)Ixv(@R2TNTIBl_|~^7N|J4}Z$QUg31nj5XXM&-8ca&eK8crHyuut2MEi^qiHrKeLgco4b0*3k4>~S+67x8K_6ASzKsDCcuze3S`RTBOZ z^D)#H->hvjV-)O@7qPZ*K}yA{4a?A+%bgNufzIoG{RPE+w?*+0 zQxB!3@4Sl;ebFa8^H{?cXRGMdYlPInSS)HMAwXCb#+uWVf7d>T~P2oqh zI!2BMn&57_PP2CzygPB`*A=MRcaW z*5}R5X!8uCDK3$pj9xr1_(#JkVJG6Msx1)wLHA^IEr6%v&y6oB=Y4d3eABpag&6Q zy;ILEZOF;j493QKHGIMd)%(Zm2Klery_0HUxg%P%UEfVI|8DL`wZx=3#Jnt^FOjy0 zDo4~Vkdf4Uv?-=6d{+ld&9nBK%u}{?f!4rg9^Jw1x9xK$-{2=ZN4^^h48Q++rEQ4Y zh_jExL@?b=ZrF@!{leT#u&+YU`9O8J)p^IXRP^*tEEMx;p6Sbt;nkAz^6t)q`P|x5 zn&?Eec&1U}u;wi8TxR;j(#p!ot70YS&i#mf&-~}bKgUYKpW20f$df8HCsp3~@x-e? ztRpXZxd0=!XKaT%wwh>w=+w(8mUNVXQFB9%P zem}`>%~^b7x)=>buf|eVwzY0LY;T$(guDON(5SsUdI2d3r_6n2|IcC?_Wx|&hXoPp z&$`O_e{9~x2mZ5{Zhm0x151J*V}L-fTsPE_$okd6_ZBpk?q}PY2z}5`GSqa=K5ypU-@GxeN(m11c+0ahACzW&nNuk-IkN zC8nC*B(W)w0DDG4CX4>XodvmEVg$!|zL(LKQT$mm(bcu1PUNZ9?gy4eqxJ-QOVR#> z8e>OMKO<#tIBSj<7Bb5wbJ4fg84_c6*QN&bfa0>6qDf8VFNJ9Wp+)rMVqzNNoJhka zQkbF*+$wW({O)QQLiguAYA~z-t~!2ux^QRKnXxNu0J-J(LP=rcs3dDN88uG-_AE*- z{oyFioL5C_KTXm?dS0Dg_;KiW*Vw$DzxykoHu(LH2;wgeL80&|UB;*=si6sEF2*69 zh;^HysHbI=m9B>+H^F!^e%Hr7L8$;oX zN^d@9Mzv|p&f-Y&ZV{)l>d~A$ka&B+=VE42ldx;S;!eT4b8(kMI$jUdlOyU)MbtuA z{j;Or))-nx7BcJlBoRZPRg11xJE@mD(O*vif)H7o^Gd<}%#IwcP4qUgho-=#>=mq( zU(?OKoi`r2R5EBE(wMw|3e|{|!_ggu1Z1(!Gf(i=NIFkxdU;5yj_d51#RFbxLhv2O7(#5nL=yHn8Py7Q*+aO&-V2+{g)-hrFm7y>#zvv#exB*Llqr>*5oMl?S)Y?vh9S z6IV}eqA9?*@}I<`PX*pKYwn~>wcwS7aHkDEgMtGIQGv3Nx+Ty(mE76%KY=Ha^ z@gtLN*Bwdb1xEtb#6kdni@|bT1U-YnecXYK{nb4Wz|Z?K?Y$wtqXRkC^j5$bT-;VS zDG<;V=PDeVHx@lq{m18f3zWJ#K{-^Oo3sDIHPBn2t+*m4expF5Z#Itl$p-tXa->&9mf6mS1Y zsH3xVl*!_b`wFv)!d^iEuS@= z%Dv|3PRD<8Lm)B=(rI-+(A8H2?NIRWR?HS$x34G8@Ux%}cdm0Ja&YG@^TGT}D>kC$ zg})wN9T(JMG(|DLpLiWNanJ08uBnF+>doZQ>FKEAQ#GQmy{UoZI_^@nm7cQ{&vsn2 zAL5Fy>^FFr4oB1C$Mp(zH1-%Q^@>ZLt&YR3@gknRyE(T*okM5`NAZr#Y6xzmMsWG8 z51%r}Cli_VtEJDL;~up^I-GKSE6>*%byad<)>6@b3zFp8rcE6vY8XY_qRI=G7)nbU za710}LktG{ae|ILPUxYQ%!+1rq6w(X1}C6mm2N#X89k5GxyB6X)U+=qC0l=Rx<@jl zK8NhV#xm+gFg@caC64tGFw4_&dwz|fO+BfT6lN9AVr-do@J<7`9Ae^;dOymd9FtQA zR2eU!S1K!bIh)>nG_J>;SE-a|HP10?B8$2?9dlmGMl9~2V z&1KAbKlXjEf55>ESfF@GR=)dY@wRi;koD<8nrdHb3$|-5vNo>f`7b5!a&%Rqxh)+H zUdzntJEbHRb4w#~`(1pY{Be_(k$`y@s8FEHCQ|n3R<2C$G2|26T_`hVAiE!ZSi@n8 zTF4XA%2FF~#{yh+2&bMs8SIrDoVQ)p!%6*WtE#HyiEIMr6t1Xld7Z~$G%v`MN-yl`JqpEK6)?A!9FmhrnxB6)(lP;&l}{VXTg&$eYPdouj; z+i(y*{GUg|cW(K;z$nuRCnuG|%Pw$T>EP88pjMWL9~`pSO&?~M%(S^^wxGj_e*C58 zQJYKFE<4F#5=E^zJMGx=6}2rcV~kXFi)fvzPf+}a?!hIw81;MFnFx2`4^m8;RPvQz zt|SL0*snw!h^-ja@R0plrt|*BRxZxE>+=ozzx z@8b=H__Yg|O7=axE`EC2N!e7EXX(dQ{JD%6;a!XIXPHdr8_T`MLYbw61zKgL$&-?=lw%tcmUro`wAMznkL3(jr(E+==|oO6S=j91 z=AOa{=R8@>2JLPq0R?Qrby(P}*l_`(628iR+bTM5C=(*^YEzi4=ogOzTZT)SMDK8t zb30#a=XY(Dwe&HG3(9HAf|D$wzi6q|7nu&un?UFS>Bsk3)yIeW>#8xi!n6`FK;3z( zMX}`KKOb<;6_=dhRK-5cPItLZMup`tkd2GlbM-2{{C1%sp7Xh)UY^b<-%O5(qNY=g zMZ2W(4EZAkNX=jJGmqGxr9@;~?PZUkVlV&6XPS`VVcr(c=KML;kND#A7oKSmVR9Z- z8}RxNel5O>3M7QMIZwCTC_!W8L9*PglxT__1&@wwBp0gL0l@+Kk17;YZ{069ffx51 zmBsy7s{%1~44WL0Dz9w7diqX7HrGab21WR|J?}IauQYt~lApA}BSLlQwW(ob;LKL{ z$(Qcs73QxwZ6$u?Au~G7j@N-W(VxhM_)_`cv@*Nfq29H(5o>7xQT(;2u-Z&8L()E#B?)!WR8 zz9W+!Eq6It3bHX^LJ#O-iYdD)cqK!>!XqjS!SU1aN6B1Z;+UoH!0nB7M%y59Lc&oE zR8H%v?L0$*MCIrat}oRM=#tR$=!HAQW4-6JD(P)yuGWCMyglrlIACaLZ+jKQ<=d=m zYdCi-mez30u;kRT5d6>P@0QXN!@kwAM((7i(AOhzg`YpRdVjumDrc?3EBJl$p0*wM zrsA~}$;O>are*9YFq>MgFscfzTJxs*tn)5Zy(vF>%iUK(ZmU-?T8xM(h^~b9fh4Iq&M&@pKd2ZcP7{N24-yVT zCHuIc^GUFSvaD9ypQJ}ZMwcb!{FWFJ_q$~AAb}@nV0uau#& zTz9TBBjZR`8V{6+b5DKZu{{i-`^$4%eY3F9x7NnB16(LU5AfWU5gsZ$_xpz5g61;e zboa9WUsj~{eCR2IHSq?h zT9o+}F8;h-vE#d5$5~1W>d8yV0IAgaMU9Gy=F2}-z_U3XO?e1OX@wRhI`nXaPs$MrU7g#9?!&>{_BTS+Qse z%ZFUtl%%irKY4r~Mo4iLoBm0EUGtYC$EPcVX^>I+`DGX?3I-}iWuZ2idcEv=B}C~o zZy;S`>-G?NfZ;0$b#t@9+X(dtGn`jM+4&tdSnsst#xsP!8^Qk23co6I$mZz&RY5s^ zad08tRW`$~Q{|Tfeu7ggY<1ARbMeN*I?UXN?eJgmJ&HoWzbz2mb{A|#rLn5cqPI2O;*Z-gSu!O-k7Q z;@Rohq65}c??*Q6Pz}RcHf*@K)zP~hrP2h+ITIiIMEYz@dpmG4BZD=&@Vz?b)9F5f z$i}QeDjOKZ`017z+Fq311H`KNdwJ_%!Hi62OC0MMP$<(gt#dJ_Ec%rcj(Oy+Yzn3K z(=nu7?LA$NDn2Y?ZZQ?k(>nf^o4}WcunX~1+oFCeW&YCJ*=TE}DxcUHX6r!GFRiT@ z(Yak}wJ=6YOg4@j1st&)C6Y z&Yau=l(i>^Z5)-Yx(+g_45Z$_@(mUx^!xEX<)j<>70g0%s+zAKjTSc_5R7dT6}U=u zvdpq0=MwtOH5hc*hD^l1G#O`mIp#gC#i@jm#u~CP!3!S!sGi^sJ4M+F;#1w~(8ni! zemZPS{sI2}*+7BD(2oO`hEU;$vSJQ4;+KNYYZ*}JogUz$SDRGxJnPRHaE?NI01pDC z?&rz}eDHX^RrrITt8^cET}t%AMcXU=0b&|2l1nG~A^&5z>fvJ~=h>YF<8da~6*Wh1 zh+jWGJcj0_>||qERS{QZCLx4;BV5w@HsY0pnj=@mdUhx)_4ho<1g2mnDX$bM;Je&{ z;)OV8{|w8@v?FK>WxUd&YATI2p9=UcG6iG|ofa{!S5(xXKKu>R<$*Z5d*9PKGQ`R~ zwsc(ASE=KxWmIk8CG%p|$H<79v`#g8)9Kh>_K1aBacZPoXm^DvNB@4~PfEElnpu=g z#-SQp8p1$tGy_K3kVAG#O=Px$tD-kX)E}RCCQZ-E>tc0HV|(ISzqhS;N!3#ey0!); z=%YraT812rS2|Me@yY$}Q|2q0RwIRz&szIgVy4pIoIeuUeCGWkRdmI;^3z9@ozp~R zZ^z0eRnA*ziTr@oix@B^FZLxd;}MWJu5YZ0@LOGVDh4QI~gdVIO2)AvV*&j zAV%qnEh05OkvNO-j@P5N5-LOVwUOW7iFNd|DU{L2ecH;--o=T|fuuRm4uz}tkTpvw zy|dCwpn)_Cl!njP#q?7b2?esAML#Klz0xNFe96^aF=mh7l*LIYoQ;zw7vij`X$fiW z=5bNqU*?=DoOtw!9+OAHm6XYGE`tH%;WVFaEQ#=|r=D^t&$Q8CJ`b_zM&4*bgXpCq z!z~Q2LX=D?PXs2%Nyw*63f*0vZrf)tnVTD2vQmo(B1;)3v@2{Br`=|rUX0FIm+^{Y zrAjbN#Fad^+Qp_x7pn!WN+i=uF^mVlN|U}$FceI*G+d1XH!jNTRpCNB2vb?u8@L)~EhD$7YyljM;F%=33~4y$@FfEkWoiLT(8X9(5a$PP^$kjW%R>=E3IOeymoG$Znb3o8qu( z;c;s;Jp~V(dSE#cvA*}I5E}k9G;eIRBONMRNp?V8=#zL8el%8J$dS8Mojy>w)R3wO zEp6E09kd$XwcRm~#{}c}w_2llmkhb#@+jo>)Mzr2qooq|Wqj*>zkH~s$&h8z9TAxs zxsH2u$g}j4s~q(Iis`ccpMLxBSVGaupJ)9?zx|i)Hut~i_;}WT zOzjJslx_6WGK?7r_P`={55$ipz-zk)vRI5Xv3Rz99LdN#5O??L<+?dXunM>0y)djE zN+-2dPlR@roxnS?0CX$!RFkZtIw|cX`!*K<+wmypD|3!=qE*&1zpFa|R*y)C9(I}V zmUNRti#{?iT`#8GI^#wBOuSR%;xfN9lP9szq2kD|c6jV#MI{F^K!LGHRjDstkCmAv z&x{|(jQ_*;QgS17Sk4|iH03D+p=Z=wqI4zw)8puE3#6S1csoFl+Y?PP3q$Ns2b-UW zo1{)9R7eyqvuCT!RfDe_t*xZ5sEdM6*Zsnl&oVq_S@QTNur}=4j}B7QS=scxZ?#^F z4xKhw%06vLo{o$VTuL+)kN#9|ms31m%zcg(!Kks14@Awp`ZVRML&ewpd1g{S@BX*k z!AFj7zY9I0x7{31{%?s|>my>jxju_-^7bc2-j=FVnb3@F_zA2}b0x5e7|WI?zJpit zfh;z41Ei1zqJq7vm01~WnbMjPGwgX>5@ox~M zevh-CKv81X2v$4P6wFT}ON6)eTEkyg$PIMd)I2Ic?ZBh=k|%3}8%Xj$q^bzZLxeV) zHB}+hM|kbSKD&)9*x7k`9Efw6>Y$=5TZ4U414@?Tk*^TPi?#ip$X?wyf4jIJP@hJ( zW9`01TA~rcL)f8JJu3Rpr++HC(x()&1-2ioNJ2u_M)m+MOa6yRL(* z^Smo6stgXyYDtL4b@5kBdLynvf4@(ZTbP9se==8ylAqi{SJ~28#|7J31267X`r#V2 z!Rp0~$bFYv=2@O2w!uJy7rW2Oh4z$-NBo`96Y@oN3U6A@PNtoq?;U+9V06s`(mDE8 zjf1+D;XQhtp+p#zj8eadB_bigeZ9Mu5+FlmAU*nWWWdEn*KK1HJe&v&WJ`kxHmV8g2~{~52Y&OvVh6p;sbEt|3pcNiY#NNoLZjL!#| zX4_}twr=C5zJ6H=A?4Eb#!CI>GFqr$T)2dgu$pvSa_{ubjyKD72&IQ#|Ku=`!wwVE zYVdqsEn|^bE18VIiW*Yd6F!gR&CaVaV(_+H=L1KYDDyR#h=b6~lfa|rN_yN=u0hkv zw%XhlJ`~Y4De4JS((_%&vMe7jhjZm5A%X1FCsM?Tm2yr^nJU}SCNaeeSzy3OEgv;B zYi4Nv{%D6gpY6NXbgQV9>{!iFMp^Vi5x3PJH~rS(CD9wHJ{xNS5&b47-!{{VX%ptu z6*^kv`aU(`~?#o!nAaHSbP)4Pd`AwpbxgRE?oXh5q~Ysd3{vw;mQ@gKA#sp6$a(9#xwGe`}Jpiow&dUKdDp2o7ed zSmNC{Mm>00EQ(3Y@@i$Vq^|#QU;SY>dC^r0Wb7fOG!F>cO5XI=%rtTrRCK4Aon>dG zUO2I+Y|)I4GYB~4w_Gvu94r!Iu3ROZFms6iRRVS(W~z@3CtYnDwjady;M)|{geVWN z%3ech=HKNzB5gr!!Lxtk!=K}-5G%?}LGT=b;Jw#xW#XEhQ)p)A&*|SM(WWNn-9h#r z`^FEiDlIf`_Qtk_blN?8pWrp2qOV;qsC9->Xs2{gW-tXq75#i)ZBMU!zqApfCjU)h zp}@Qi?Oc}nIcB)7@7ne_wfRx7b7XzfJ9=WcTE+kve@NqwzT@DhkT_@qg-;al;R@!r zmGB!}DkdhK{Tsvek^YnMB023BFOEaKd0X+9!YSt+^Bb`G{*CGaQPXwBGdolMG%~Mu zMc-zN>@XUp^s`r`5BBEc-9V5-zXjoY)3@=>g0V~BgP+#YC0`;lfA^L=e$c#U*kApV zN|{QfKvQJkIM=eze&cQ{y07chAxwHK(6r4+KV61m}CkuYXC3(i`R? zlRR?Tsz`ly@hvH%j;r0a!qB)>dQgHPYd&6qL(rcyQ0&vItDmexXy6^*UhZ(F-_^S; z$0?v2P!DwF^Ti*}ckItm7xA*DIZa~1eZ(c?WS1BWckdH2(pPw-LYZ6vS*r;! zj*B{m#c9GDec!3m5*RWn2>jz&ei0G1Jy5+U&7^)6xG60b#en0n)lqiI9r=h^RdTO& zh)n$)ChHF{muFooF&$Rrr9s^)tKYcQs&|h6d%!)Dmv0I)deH_%I1w#wMJEj)YD~?b z_ptlkw$&u(qkw7=(RJN_jqym89*Xk0egsE|r*yrpx7PI38;D^neJ=%EGSav|>mYEcJWwHQ;ST;_BLS-?6(c8OB+CT1aT z$m|!MOR}ft-xR|lU>dfi}|Mj6j;xD=#cGy}zlRduG>%TE~-_i7ML1)Li z16j;OSVQ`!zPo%UHzk46;OL#cRmqE=Q*vZ>t`N8qZN!k*=ma!7AK-MKd^Fi!qi?H; zyM%f#5L2Cs+5_{-KnpqFucB(6A&tr|Vf4ylD6?ZStYP5RHfgeKY$DTI;DWPDo#_fw z0X{ zK6D$K!}xtUD7q8v@6;Q8&t%@(fNmXX$ivqVh5M1`$`0M@F8y$K$p@GG#`uWv>bfXo zxaCNIz3DMw&g1?Sm~w7P6vx9L;g}4d_TCf)`05+P(FYX!+(A;$(ebNj@E1=(l$v~o zdaHhJ^zV_;)d|&^X?*>h9JpETj_o7r4>Lze{y(NNT`&4x<4MN+bf5LQ<@fNTnmUKh zlJcGHI!Ch@?3e;I@66)PS`8E9BQs6iTX@Oc= zp72Zb;ZEOjL0*kUDF^Iz2`!BBagne64|elwIeijNGkhkUYxW@XzKc1Q6R#N?dYoUbm1>VAz*vIzZ)O_^ScAENb~8xqqgL8sPopAoSJ=?W)30X^uD4lpSIP{ z1r}X$Zb-dzd5=`N?{CGB;Q5vje_+W1L#srgH=3Beq-58h-Pcw{?lzX4`HYfU>yR{s zOYEGn;CLZ8tEJpJUF1lf+S{BgI{k2=#h)LI!BILX@TQa{gcbd-USf-X%A`KQBB1`} zUT};nP2?e}o7Ev+V*g;-!N`w zcjYSPrRjGZt5O+OH#>7BDa3nh1UQ=}C;VB-Tf>JUKL`}9+??U5XwTOn{0efXTW z)nx3`t)S}nE--B%XV2XoMP^Tsodt0*U;4Ky{5)k(A8rlW>vq0Ii_8w5x|wT~B{hiD zVJ|zKfQO|7FJ%hGwG{2{skGp6N|-H~N%}UAAfCue zxf@21V3&HX(F2xAzQmoCzM*smS=xF5G#h)_^7w`)3sy-Ru><@=&-zl^FdL(r(BQ)gIfQK zMj^4*Ln)Y6xR8O5P)#*j%#pGW?lg=JmGxghx8xZo4WP7(<7O9@M)%R_y zd>$UA;%D@7rseIU-R5do=c$;6{{oZNoSDhpJ6(mN&3gQ4U8R*7-8v3radxIHPw`4K zwoS!;6UAq}KAqJ~5rEj?boDUp92$qlwF;==naR<&sT9%*y9J;qI+|bJz6fMR{h?$U zsoG5hHu*B^&5DNDiVM!le%_v#g~c>rFSht$DaSETk*=t^QAqZZL}~tdOLfEWD3BET znpt@d+TcH^l&3rzIK&yS%^dK0woY*AnRu2MQ~;gFCmu>qk*%cq{L29QWhFG^Nm$dxNprV1e zbH$Kb2Uwp^`^f3e^_Hqwp&$(&5oE4~CK0`+#5DN0*}B|u6NWx&Ups_gbwqyqoKYR@ z`|i-r>sp7W>;IM)zqvd_p>JrX_k}tf%RFRQ$4jyrmtFJ1p;M@~NN+sanN}1HMIg<` zf|pjmU)6c!F-^c#KBS_7Xz6}9Pd09VyBbeK#!{}^l860G^33KZULVlPbGRf#+n2sB*ea8@;EqqNb)gC97JOdF%CXP~uwgYt zrV$p0?J+4*O&PhQ_%k`~?|Vd>S@Jdph6|=^WN7hqE9;5DO*e zxW=#Q*qfF*6A`loI=9;}OLFmqFF5@7K5m|&i6#t%Zb%_IO989Cr}Z9#jaw2oicVRl zWy$^}rP7jL&h*Qw{Fdx;_OR#@E52SWQJx>V1-ekU%e+xV!Cgrrot4`hb!kt+MAMo7 z_0;S7i#GF4)ehz}vT*T=cCL=01Nhx>qNO`GTWlA~@S%RXC}tH5wsS;;czTOZV9XG!y}qlnTo-5X^k2CGqD zLOj^8RknmJ6{5}V&(X^mu)7_B@->_20sJfQ@#NHY>jrC#@zuH0*ZqEIZ9zcYq#K-7 zOXNxn!Jwo6q{+w0706?#ePO#`Se%Jus4&+zczNqKaCs>r^aFu0#i_qv$gnNvxOHtD ziF91dpE;5+8&7bckb?{^-~7Ub#GqteyYo`sH@ zLU_5UVKhp5M1@z?O%UL$7N~vq6?FMr=ZE)vTqsCS`TK)rDk$JbUgaWW z%pjwTQNbA~YC5PdV~_d1zDNfXQO?ii5ta!OiP_(x@Nz4Azy6;Dt@i&pFociSOxlj8 z|2VMP4^)5P-v>HB(CFvB=F=XuA*|Z%iPH4!Vt?v}BrhEVT8r}e=yOYPEF$L?_C-Cz zYY4f_wpua$8y|N&FHoKW;-wB=!wY%)9_}8~GU0-8;hz*V1E z{&um#%?Fio-;pM8%m+t`pR?gB{f8IRcDi^lU52q%q9lJOaD92 zYI)cAz8;1W*G$z`J{&Jv#^A!mIDS^hkIYj9B!a0 z|G8Nwz^N5#10{9%xRdk?&O#2n;`;LqYzOrxV?h7Zoki}Q?;Jiy<@XUxJdh6+A5^G@ zlpC6oJID9b`G|mN*Y1ulIMa)v`ldgP170`Ejy;1O#Db+*=(y6mT6ItM6$XmCh2itj zRz~hXFVHdoDQ}Pr(S+IShyii>`8;y1Sz1mLh4e$}^$Ik;%g`Coj8L?ok6Iin&uSB1 zGR(FrIcRSeIsqE$SDeqI#DN;LU5QWfOO)G~-9MyvV0*njVFD6mWLH_uWWl%3FR!N3 z8Ls*3yJP4Dy06wNoS#><`WAj6Q|IKdlEMWMB=EfxJxK-5ZyYsa{8AkbZ-0Sndm>4Z zRbrS6^oA4z^n?7a6Ecx>fjdLu8%DpYy#>n-&aL2>lA!&XKcZai@ zrxd@K0VXp#`L4?g5f$pcv{N?v%77f~iV~mF7ys_~;8(5ljbvTD?pod*HBq;b&4n!k z;e=F$=d6A!zTUKKbejJ%=n7O1B+s);^s50hU>6fQT*8neY0--QgO#i~SWhI5kvz4t z6%$k5*Iaj?@jdi0j-+r`f@E&2W6JmzrZ-pTD99B+<)rBjuO-Jx%>2QJ_t)5(&(&jVzU}$J_g_;h_T8UsBYXkxF4##giZ)ctoi2~U$0Kg19%<0@imSPe)InuY@P~=O+3` z)odJEr-8ubYvp4f{f3cDM<>Sx1+fWBBWuB)`0JtDe!%Om@ zD6_7_mh`qY^DYfcsDw}5vyPQ8PagpaVE5J^=XSs7w%dcj+0QCG$Z;@}LZ?%bZ+)>} zDNa4>-2!T=oM#)pyy|a;P=S9seMX}M%xBaxkW5j3@{VvVgQ$(vqQ$xJG^idHc>DY- z;CWOo7YTNlXSYYBU_U&ISicByPAq(Uw>Swao=>eu7m7X`Jn@vAm| zWWE}8+?KNr3G4oC%Nw?43qJn#U}9JwC4s0zm>u6Ctw1ycWGcXtp`LOmr>B$7yGn`9 z!fjoZAjZ4UC5=j+Jzs74KAUe>^eLno`b`@Rk+6kpDJI~q(>C8ZVSd#8EI^qz^*0YP zn>xU|s5RVXM@vfy%}|A?(VsGmkpGSWiG zo5}R>2o(DXes(;DnD?uwY820@DmBl3#MOwf&?V15&-;SO>{Dv7Edn2E~K>w<%@eI7@u2v-!2MJko-eOw@d?6pnj7FR?4hOc=nBn zziMS)X!+*31!~r%b9QJMyW&Sy-4Hj8bm??F>0E19_}Pf{gAdv|2nRNuh3|6f=)BW* zO97?l>_+E#LAzK!%~uX&tZ`&^RtGJ*BxdA1;W>HGY9xf!aYuW;-CaXf>-u@G-+pt3 z+{l0#B5P1nJ>7@Lz6NOp%@PKeN+G275!|-;4M}J7WQqH#l34m3Sa=&IB9co0R<`DK z26OLWS3f=oa$7e^4n@UGX*;|;GZxSJTIjXlWK>>t(a6yK5JF4_d-a{oOu1&Ba_H8o zRu#ssWPZ76JA(c^nahMl-p`orZ;d0U+Xmr@+d|oLs=VKmRihewbTEtexg_>JYC$wn9@rHk&C~*}k4RQeiZg zd*nS6I$w#GP63hgeuu;v!K&iJogmv%)^UX$y>E#`$;wwBMa*0>PK+|8=r2%1j{Zc$ zPbPY~(JoEooOpH$DgoF0^DXy*1WvEP^CBCiY&>CiyX27ZNj*vQ*T!vl5bjNjaT{_0s@iz5smP;KOxq zk4#?bRomd=0<}dnL4%uzI6(oTE1N|m18X+**lYl5k8!W zUu3^y!)aQn^3&ODbZDaokt#2nqOzVd5C*UZg8QU77xZK7ibcs&g%1XG1*B1^bI%bL z6FZo00A)1KTEQxhOBTD15ad(hJ@!A7*&`eIk4O#V-l{&*z|y{h*mmKV@*(06YlhxP z@-69o98=?1XpSM>Ixhwa!_XU}E7Q7h!G#@UC3`|oTd|IZUefc-R&6#}Ak+(Bja{$m zmla#bbTxME3!2i}3eV~hG@2fFOb8|~)FEB;d3rm*_jML|_^fbhnt}VK(~jSfP~liS z*yil^kw7&LI_A;8*1EbsY8?1*Lo=hvbXfR3(%R*#X0{!pgY;;W=0d|C!(WbZ^UfoPagtpzO7zcsx+8M&*q6_-DX0>{|>qa zK!f2dH}tl29rxnLn3U8`U+3@eu?=|(v3EuMQBi)d7Lb-JNf{=PyH#MvnR4p73<5kv zZ@hiD!F-QpfwMYm3nX0VfXJuG?ce!9UQZmiFRIiorC;BkaZZRn2 zoXVcZo2BdD)w~o#<^1Mb`c4#$M1MM#zr|LD?++IyBgXSdU6M$;4IH7MrQIaH(Z*|w z3zJ0)v|{f65wZ|VJMJF9ik763kY&y~0Ms6VS^cAv{HzQ!Zw%&h%bbd{XZ*|uI_%K} z`tC~~#W~RP_e#0?wygz>?!MU38Rw@XGZm_^!J9%&e$@7)MX@E1K{AOt6bdcy@Tv6U z(0evtm~MP288HcN9&nU4(fbbt$;La>_4Fm>eN9`qyHJ=X67p4DpKiYr0R_77@N{XG z+V^_4_e?VXe5sR+(hJ2+yz`pHe*jbq47iUI%S1-jxYM?o1bkMwn$`XC^gt_t?RU(x zCv3fMr^4n1Zkd)k`Jw&m`LQ7P6mGmUxJh~YbYwlv(JkYl$24Ot!+F0{sF2qSbx?mD5;-#l%N9Wk_`=hb%?R5fbnFfiy!-B~8U zavd<|tn=lOxu`-23N96Z0+qbA?zJn-JH z5j!5TZCML9t`dX?$cmL#G;M(04L8a!yojA&f^7kv8}?T~0iMYd$K6IsEYD4=pItA; z-tk^42|xT?U*0XOK}(G-cd)v?E+ zWaCOU$-N)t5?br!ExOM6#+E!9K9`Pv!uj4d#p~a~^E70ykU0Aw?X2B#nn2(@$uusN z&pmEh7b=)~J$285d}NZN`8b|s`z^RkU>{h!5g3r!c8Wp7S-{qeg%Fku%>lLP4tDQo zS~n-54at0TNN0X@;KPCE?z(!t0Nxqop1DwbhFeH+HnXh`JjhSdUn1uuZ?lekNjdpN zR)#vj1%mf|tp#lGxz6g~3bm3b9lL+{EC}`8#4ZTh&zHsTb}UX4Q3zI?e>D6aa%ClT zAuf>@CyFHBCM#XdwC}(-|Awxm2h;rwbAeT0geIuVeZ-FbZ8a8bx{XuY5xA&8a#+8h5DOF%v&Q!5;Le+k@vR)0i1=@ zgJ*%lSDrZB;rvhH=DQl1lNsxwn{nPLze2DI=t2VaJJ{>KIR^J*IeiXrYA(AuZ#hZg z=}>LG4b7$}Er)G{64dj6l9q<@w-(GZy!z{-8Ny#go7)tFjja*BD}RkE<|j5nV~%%& z@NVUCH=0?7UYMp~Uf`D8MEm!Fqa(fxg(4I#Hm_=LtWn0&Pvqt2QsyM~J{)!wr$7?k z7`A=BT*)_|4(G!+*vvz&GyO;DDN3uwr_=p{mNuo8qeMD&4)tvfK zuFv)LPxkafLfPxC&-8ubSruXSy2aF{WjiLG^;)}N7|hvb4(%*zAIObD5qD=Qr9kZUs6sTn!F?#}df)LvWO zsHM`U9Kz6C&C=(^D|$cc&cE-j#vBKEOVg7L)T<{dueyHR!HBL7`&=M7c-AmVn|7~* zW^%c`SYmNbTZ~*a8ZZl>G7K%}+o-2GT80nA?Qpa%N8aL~=rR^^suxt^a`J9yN6xMz zvTnXvA(o^P=xV21ol}G(=!#zr42_j=PTZDc^@uhuXSHeDB8T z@x!1{fk{qX?o}2V(}V_FBK#kcs_%bEs<$NtTxnQ-*?%Ne(;IT%Q1AxG8>&`AU>5D% z#*JCL;il<#4zC=BU!tvLA>jkU_`zLLn|Em4QpQ7QrN>$H5XYY22o8-3s22 zflcB0RIzi-f_}|9Uis7F%xGaoY(mv5+U!dqQ@Ppb7AMcz5(~VQc0uctV%_1r1%>?2E_Stv&muQ1tm(YCNWod?)Mi#eMz&B}gr2mKDt9SOHpoz@J1Yl) zd48sq0n?Vm#I#=`wGg6%?`rbJX!6td=1wB=)G}+Ex1?mgNoDp!t{n;f6g&6+X9b38 zp}w;VQtrCwgZEDkcRh~F-}qRTR`1M|SfJZpE4JKtTw4%JqU0F5tQX*OvZl_}ZcuGG z?{0}#o5<8)krbuAyAzLYgSV>f+hiA8ebvSu+nq>oJ4Yra9+Cw(>v=mc)kmx8g&TCcxP3oL zG;&aZ7qIi0JRL5%4}X8uINCRqZ2jFWQ9$??YI#90F59Tr)q;)Cz&Q;k57#^76O*B= z5v!y^ln%77{|&&?6&nP+Zv*hgOQS(fb6}DG)lKI~1e45stCVPza6(cZ4R0ITR`$gE zf=`t8A2qBJANk`W*Jfn{nd|3bw9=pVNz&&YEQuY`V}!I;B=wLsGqUAh$-33ah1K0B z$N6(U83z74*r1kR#;3sGm-d1QMV`itm^Pt21pRUsZ)zP&>Pb4K%oh55FUT6YT3sXk zIB5RigK;sHnyHBE6n4h1>N9#p4=fDu@0<a){5Sc`BcNe@P%Oush=FVwMAqy;6v!4OUZ^#l~BetBq|}wbAqxq;J}bZoe@5=Y>WU7mSvAU2C};x3n>6e_ZzY%Km1Tx zLl<{OM7;k>P9TQ>CkzuA4~}uUNfz{aIDq#9X6X8SE;!$j*IS@A9}*rG-YXDKe^K*W zrgk%?m1?umFV^Jr>hb07*xYNxo$1_pE{aV)mWq z1aHZCW5rM14)g|-<*>TbwbR6Do^3Aeq*&_FMu-H1KJc08=jqxdvZXuFv(fn06B((8 zsD(8thwLI*)N#jpsXtiriPUf3#`m$D-$fv~wA5dycF)W1tmgJFw%3O-r_8V}7l=OL zFN-vj8^@B;V^g5Xj%&s?AqV$eMiiG^iOQ(ziE6O5Ep&|;5KLS0e5I@es`-@$dEr5I zV}7wI--g8FIaayw=@7e;D0stGF+HFzqEaAV-Rvd>Sr%Xu#OskZ3{q<2 zMhG}y3P-6iHW_S->!z?E8>+bkSzmfB&Cffx`KhPRt(Io4O^#T%?3cTV^ysH>NQ{&Z z;|gSFmhJt-J({`s;7VV4l6mw>^7{(9?pWaZSkW8cK2^UI(hW`P^!ntyP$G|UeLg>4 zGdgHS06S;YjM%Fy&5K(3d9Ym|mMH>(RN0g{Jw@GS2N`#|bPe8P;fpPxp`?kyj=Yu; z+3MQ_L#b7AzM&HSnyn@RtRy|9MO~@Dk$Ky#{i09t{4v*;&YZM0?3ZCOsQ7o&4x1d_ z=xzDa6lCI$Fy;sWTrn*pVZ1Z z90unwVp?gb-;H~*l@t1F&I9L)XClmbQNO}GCiL?HHjK&sfIg{BVoTNP8!yGD492Sd z4IQyi5n0O=*|!=dW*#ques(s6#-~SyJx@tCTo1K2nd&u#6sy}!?X@9KlY=L~)wd(7 zLB__X3uokT{}`&oZ8dVFrV_uP_k5yBO)Zw9YLRkU-fg{&o8r*)DSY{b4wVVH{y376 z{fRKa37aC}Bb(8?OW@b$)%b+T$uUKL8yp{B+`n-q*Aj~CQ$-a2=sVtFa`WxO zuM7#nw+Xiy7l(JhSiae`;Q#JITDt*!%9wwsXF?rL3LR8DuXRJ#EPmlQ9eCCjk0iFwU!;UML zPiW-ao71A}*3_d{5qcA&Di{0=h{s^MHPJAln0eUOn>Y(Hq_Zs|w>Ocz_JrIofqh7Q z%GU?;E1)9`4L?Wq6#LTmnzX-AV%gz9{xu$CYTX+PPOBy0H~P2hEW$5k_Ox<2{E90y z?&__1#%$mWE@yahbgMsVgD#~e8c@yM`y5dy?03^BxWZQ9xfvLWVgvVffYA)- zKK;SC?&A*2ys)uKjmmkeq7%?IXc#%Ze~ZuUT%=aznXqEl{6BL+ zBSWARRfaeWaNOav-vx(k^x4?hKR$YPcdm<`yKmCiRI!3NUJ7!g)sXKAEwuL|lSY@& z4dl>+IAg{yh3^$96s90}PTW4Qg)|%sPoF=EE}R;BOG1s14Il`PehtGZ;z2& z#5sCq?f;F93qRF3_3`){X>u!?O3uk)`41Q+4T$+L0U{m@8Oc9oD_oBasL+!R|4ylY zy-sQ6U2;ceMwm#c`TtAQU*Q`^=-5Hq-<$KDlDjZz*(EA-Zccy@Py@DWGF*HO(f!B)K zgzJneBX5ZP;XkHIap>ne+K0ToWeSBYQk6#{oiCaB^4r65FDJN^7-X&eh10|z=-F~ zga=>YPWT!l-diJW;pI$aJwuG_r;}H|8e5;2hM}F#yLp;I#-<(-oF?ZAZf22Gft`Ty zgE8I^uWsM&S>`H+TUYYs7bsmxv0S9QB1ehH zutn6bcBz2=?;0B8#sU{3a87uaSb@f7TfUvm5Wf0xKmEw~Z{~cH!9Bg|w|yG2*M6^g zlVLK<5}=!Wbm_n+>j_qq;w6rl1Ev$n=#WG6wxjYQ_FA>1diNY>;I-zT;TWXhLGpEz zRhs41m_m|G_75_@R%ow$`Zr!KYwK>V%9~y%N5)gv?(LojrGRxej1vi7e0UXaO}{@< z$8G`>0-TXMZ0+b%6QLz4@7qIsq*=`YZ=J8}@dI$piq^J96KfegNlc^osbhvv43MiX znR907UEvv)aeWhG$+sb``EmBBuueC@<^9hyVC`x&p9GnZDP#gS>6d(bo7|4XiB5?Y z1(vMX(*e^GTl1WJq~dIFG{ zER)nRjZERYF{qx8jV+-6MM<`RSg%h6yYuLpH52AT8*bw*fv$Y>2~_mC_rCmnun6e( zc!;L*Kq>njf2EX@h7}MaQ`hsF#W|Tvx4iE_6;kzVN#@3!JPvCW=~)Bo7S=Z4&1A zfmyptv)S|C15P`a+$-$%pJm;1{9A=!_TT}2fANc&d~0XZlF`YI*B;k2c>ttt>A1FO z%U0J&3v0{_t;|6JS?5ONIA`SV`n{YKKJjO4Dvdcd>q>e|5!a*HgQqiVr5Q|X&`j2} zsCM=@eqZSx-yaUK5kQ*|+y1BrROc_J>8w=z&k^I?5JIr_ov`8Esp-C7#$g84b$VMl z&(De#1`Pcp`69LZBN{Y7@}2pt^}x6uOnKSp(C|o}n#!F_ph8}_0FuxKLraAIICiT4 z)f56=)_W4npc@1vQuDYI7g;zC+Y0X;-)=a27Lw{51p+>j!)t$A^7+{H;0@lGOEn`< zHmgpgd}&xA$|Ua}J!z`U)iP=YKO`sZV(lsm)da#Mcha?3^_iY&muJlbFFFSu7ZT}T zmmk0oZh3rHO4q>6<%e-4tyRJ~W&Pe)$(g8w>SzfKVm0vOWU>BbWo-ZA`5r9b^lIT{ zzmYNU{{Ea-?_7~Ak7l=x)g}fQeY35Q5^iK3~{k0!FUu zCq=N)9eRkt{U0)F@qfvv{{rRnf(sh{Bcrn4koSh7H>AHIr_F82M+mhkpv>Qy_;k&g zDBpYYD_(j9W-G5>8C{nVXPgXnzuHxiyr=gA#jw{tP4;`Jw!;P3q4>}OtBpTb)`;q~ zxg>ri^*YfN(xgR|moN_9EKiZ8FIoVk=Qx^y+EEI+weSudG8n2b}lhiiU2C1?63 zc$e$Cv*uY*qh(FTfGS(cEt{dWFH9$f2P54-}NFJ6ktkq%#Q_Ao!DGC2qa_k}%pB0}y@otfj)#;uWFzyKdq?jAv;$ z*}M3XvtBp4%G^0>Yz=*7Cz;H|Z&U{32yE zG@w0ee#R4Cm5?GJQn6)VN`Ot2?TAp^3Nf*dAgm>Nj4)+pv*wT7-=9-KQu|ZFJGwY=fe^0d`_}p&>~K3rQTUTE>pA#JJEU zE8dZLkX=2_sn--s(f5Ym&;)7cnj2%YVc#YoZYPqv3$V_v_vYGi#vYPs!jVzdNAg23 z-w!RP{Bkv+J`$Y=TUXxpqt)^(y&G6ae|4?ythsO4_D>*kI5Sz`;4q+j_+Onl1z>rp z`#i!)^1wM1zhbEW%fwa%LL!*boyb@`xJmkL>?D{jup zmMMQt2FRkm$}Y{$L+c6HEt?SU=GsAm0f0(~FX%WS0Qt60hUA4<3cSDElu08l#Rens zAI04Lik9EfE~E83w=jFuRLp&a^z3-7y9_3mWJ!`gn1zT3j8y zt^@#mA2)tD1!nEpmqUeS?GoRqS1-fA$9a$aU+rxl7vg-USha5827|Cr{HN)C6qMd; zja$qOkaOH9bNsr|CE$9PJs6$SO>Osg+A!Q$xVYt$5Sgc`%y`8_P@@ih>^x%%Oh)Lk zraU2ZchW_uu=r5J)o#X14r-X5B+Q>Hm$%tL!6IsL#1!`-RZW3=>4A#h7emuqGY;eH z%GI$+FVYZNh2ZH`nkjN>h%%_{v~fZ;)sDnPic+Xsm18R&>%?C|_>ZB6w~O)@sEZWM zQ|&(cWy;8De$DeR%VR#vq_b3LhLYX(GxaT&)ZZVJRG|zi!LZBlyJ=P% z!6=U+Q9$?}~6kv8~EHxe+7K#t(>R$Fn~@)_KZF9j3PKLDi7yv8qJU9*v7 z%14>{`l9o-7~0C#r1CmYscWXF0`}8a=qPy%WX6-ne5Km@Rfuw2nIV6xcZRRJ@`Ks1 z`jblf$8_fPd0f=ERvezhSo<@z-hbK41ABb*(#|JyU0X2h=DdPaoiW$y=Cz8odk6PV z32NDeC!K;m6fw*LnE8I0-6f{a&{>X6wl@2cD`fcvgWEAY+t|lRW8nzC^?7gJxG9Bs zA(){OyC1k*A6wH7A~GyfSEQbiZ(OfIZI*t9|IYkqPmaJ9ThZeRxk=IavI>LmUA0nkw5aL@Rx0Z)BH#CL7Z2U(uD!{Sj}K3FYUQ$Lc75#UB10<0y^# z`t-NgX^?X$k=|Nb`CkcFQs0l}YKsmfeV6SO_Ir>isimzEr5mEMwVNLPgL1F@^#s2#OT!IPsQT4 zMcZjufNYUR(Ekf$Y~;4Tk`3!c zK#<@$@@Gy{XD~q<`Kx!dz^h{N3)sa&avL*|%O5)cFsAU8dHLmlA=`~d`uAYhn$=_2 zgZ@Qd_mL^Aofy{>h!foRm2YgnPqlV)7+-2+>H8S=r_>1Sj+i8*_hNx~3KfeRI<@SN z#zuC?JJ$_sAO@O;XdNqZRXE`Wqd%}cUgZBIKdX+sIytdj&CtRA{%Becm{dJt^XXqon=!&XT z#pG#|cOR-p9rX~ssIU9Z{KBZe?8kp|#`J3zrlm}z=1Lujv@orWv96X3uzI`O6DxGF z%x3D&(fXv%a9md0WvZ}B?Ktg@19n2L60f!ee=By5A#zOldl2Ffsd{=cBqb>pd_d?^ zU}e;cSx>8${oA*E@(%&8lyE<$4Tp=n6ApAQCi3je&sRAyuwC|cZRE|v))F|LDu&6X zs~Cv&5&XC03$twtWI68YN=x)}{iulO)p+Zoe4Xw4kpt9yPhTI2V$ zENQdnoqoPsYMrf*>xdHq?}jk=`s`iA1UCwQ9~xAmchj!tn!__;ZAC9HiA0k2s=!R> zIuXB$kEBt55!C z_UO5P@(*7l5SJE?@`}UWqrheSfmr~=c>nodEu1K?ZH>N1r$HHWhlBevp+lMUCAH3v z)G8MX%1FGrtyrf)8Bjh;2#j(Sr_XHOn;9&bQ=%3`rKH1sZW@+g?LRtBRg6*rd7sG; z-0}lBt92Gg>AzG(JkAK3TiNyV0uMuN_;K0f*x7$j#!sBlgV~U0t>dNLv!kRF%i^g) zt4D8N5(S@c+cfxaoY)v}=%AUPZM*&5@ba0Wf7YooA1@IN~ai7FM(cRbSn0dE6Jj0V%EA!91dpZrV=E zWr9)8o8o3y1XBe{PhKZF@3UaqmVoL9 zRAg6PG5mIiZ{##x+lXaj7lYbtglP(XsY5T@Bg^qo*j-y^@3?+m005I&%Q?9IXM(Q@nhy$U9%EsW;~Xc^ z+7%@Grd^n%Fr%87lU@`Ta73aTQr=H_~g2F}5Ki>G^@-}bVoeq=aM z9QqmH(e-=uW*Tg4>pP_SV;X{U@+{nYTdRwb+DI$L>$J^B`BMcdGWcBN(ph#<+y*X6 z-2qGCwD$I`fV#{=jQJ4(v`VG;$v8u&`;+!7Ua_*JR~3V9pxpL3uOW}KP`kbBWK>Lv zJSu)R%mRX2CbTjf@2o#(<89TV8R~vGSV3=x>~Qjqg*L4vlBNVGRkZ29*>K!`bYLaa zsE-76gH^ClM2fyCc0S&<@6iNVzx_vVHjI|Ne@F9u!8-W$ZMO*8wP#c_=avtpuoLWx zP~)`j!FBySsBIW63@E1|TA@qApr>=xADr2apN(r6S`v4pbs;CL~#%MghyQOrlvL?t6Wf0fU>f znz;ljgiL1og(P5O0hcAxl(pT>H_lOOoBdp9fC`iYbqe(Wdc1~ zhFvTLF~IiM)HN25LZ{(2AqhX|C%NZBJm$<8Klnm4kwXSJD{8oS1UT}bvj_8QGPRT4 z9h08Ghn$gTFm9Ce&k8aYK|7pK1Ro(1IYMLBmQmJ+`nyzFE?twGC(CC=X&Ez=SIJkU zFj<<1Jxt+Ns#tmJIsU`wSCU0yiKRi8K%8ZUMxBOS?Cmgc#1mf1Uo3U64i?5AW2y>} zHtjj_2y;PDU;7hw>A|o`Hs7pK`N$c6vvs@&uykoOXFB@jb=+|Dq1f^$z;ti1huMM6 z(Mb!L-R{3u$oXc>$}#xP)&8Wg1Y4jwOfHi z{0A*gVEr7AyYmidO+cORHT{YWtSU-+WytT+VC}Ug#xdh$I7i)T_loQz&z%@pam0K+ zaZjG2#HYje!2+=vm-NFeVp?YB-%EGhVt?N`=aeCiQpgAI`zUv9W4?n{`+Et#=2qrJ zNK64@-ebO#scB_RL^Ee~%XFD1yB1(RQ;bUoJnB54G_<9gK4NMOu=9=1%bDeVfLr_P zZzpn&@bB36W0V4Q4+|~QAl<9kcxJBwB2NxVxf^enPog56!!2q}EPYrIMg#u;H=#QH zUpndS%nxqaxViFw=%mCq8Y%e=A#X@(bA#=*{9$LsaUgAe*56BF#a4v>uN$6N7v{oZ z8PxM*f)J(W$f>^r)8tE!O1gN=oqH*rEIn`|x#F&PqLi1rTDYb;>>P+&LnJ(B$I?GZ zNW{ow85#EbUS0$C;?m;yx@zK?q9vH2pE@!2jlh)Zh(DksA%6-IMgcAOD;hEdn6~B> zV(wWWVVT4C-IV~o@o01F0PP}sCr+`zKTHL`GKYY#rovA?GJ-Fm0y!HOFGdTN=R!`A zWqHLZV}m;z9A5U{al9Ux&p%ZsFr5ew(F|>i#$0}vZkEIYz7q75~sI5$TTfD_0jk#DE zm$_xZ$wKL!E7le|8hI zgXSs#otzL3ZqXPHPFkanZ=DgTb=l%?@=AMaNySJ(SxDXe+`EHU#m8S{CZ2a|=Rr$1 z+)J%Tx^*%tcF*#|CRNK!Dl<8+akPf{%snq!)Tt$^^<9}WH!c5yZAxx3AU;7x{81Gw z5~l|7tU~u1IbwEQkNU9hH8$O);Idw8wG=LqkdPB-0ja!P9c80;M6}S(tCnOum`^~y zMY;HF{h~3s*K3zTyW*aT!DP4Es1-vBZB_NOAbx8{?jD;{vE|@wp$QUD?EVm;Op0{X zZ_Y&eXmlV)>>Bh6HGTHAp|Ps)?ql)>lo4@hn?7eiG?U3z^FNo)Uq2b@|2c(X!nPQ- z-qT+;i6n1nZXLwPuZ`BVeH#miLO5%Z*PBV(d0KQl%lPAdc=@Wm=)Cl!rA`5^2Ig?9 z*GtSicd4r7-@JNZT{r$Cfqj1v>^H{EURh_x`ANrZo2-%QIgu^?rm_=k{bY7*eWNwQ z;5l^`DSJyL=}2V+($=n5oM#0v7GwX8X?#@s1US}I-KgGt-(%_rd$bVuN=@~XTJnnP z8{dSICo(1sE|^1CR{N}^f96t(Gh-x3o=jvh(qsQF<8v6;S(foW8YjEi_s&hIAgMt0 z@fiNI^l-%%Q&XdN!MvkGd_Fxr{>gjzVrSIGJ;G^X!;`CC6US$wSuN|~A2_Q_vIYI( z64a9XlVFijZcThu5m;WKyLy*Kn_)drq3)HoZ;|55G4&hhx0a6gMb1AiuYJh91$E3p z0EBY?_i%5+s=dMgZG#C<{odZAw_Ay~CYS+d_4DVMnd2v4miD9f?D$Q0 zcX|a>cd2o+UvKrs?OU~`{aCImmbhS{ZrS-s{F2*M*6nJDZpPHmHY{JwL^`qcKG^TpmWmDVi8Fr#|ZgHt_o z3cx+JErG7H?V2llbu8 zi`xwI>#9tm4}=ZzKBC8U&x2tEzk0(~FM@>^&OS7sWfr$&qWZLL?Bti)iiuzp7>z5@ zgcFfoAUF38G1H8fC80xvd?Gz(!EWgln zJVsM2{+qCLm1Gohk0LScuqmjp$IbH2Fi5Su@7;ZZK}akgqXcLGAc9gtO1|?@*tRp# zp1iT2fy0WDDh#cM?G^oec;qH!+{5SZFc|WN75x4!zo6q=NmcB#5E%i&s3~15Y*t>8 z;$ZX8lA9d^85L(hGHQ8!G|pUGiK1j;6VxFDITf$dM&F)jS^iey_x=Hr$}t}H{9a}n z2l_{>H9FwquE7&PzFN!co-n?G-CfTtwxlDRIu%w8L%L4}TGCs;R+OPo<;atyN;K{v z?U%-PgpG@}g`=9P6ko2ng3M>s^V8t?-o?=*o=mVp86uUS@kjH8W|oXoWVgCEdv4Eu z&+9p_JSz2auWr1Ja$&zmy&y+QX2|v-rz^eC>93@@aADQZMdls*kR=1(+2e?!$kAR> zS5bUs0X8-}#FLT!!mb_+VZdEpHAxg$Ec543y^L}K(9rNVxelF357 z3dL6_EFCtZc8pzg3W_13T-K|T{n%x7fzZ#Hc=%lM2ylJneWV2kRS=gaP+mTxcHM>ZGG|{L7nFeyURS85fJIzISTN@MNT3yW2L0YCo(^{$%Dp zn!UH&^`y~*f$rcqlpo(xP5|irG#knQlyM>Ew$WFF2KgvPW zDfjMU^g?S(Ja$F*+ZH4ul(Iaph@ypscBr5^)o4>Eo?icZNP&sbIVTOGRZs`N%C5B){6t(Ip2q|f$J&YYIJ%j?=^W#yxP9U0O8b%=B8AMx+mAqQLE zU+^@yB9hfE`jBrVDB5T`7lW_TnvQ7d(y~H~HOjZk@c3pU$?`7jRT#QM$k)JDg^Voq zj`PukjO^mTd9dGi`Ee*8e{i)GaGlrb7Aw{6*!a5Z3V_0T0Q{VrppI#MfuK*zQkM%f zjV=5Eb|5~l7VN>jAO>k;2KHtCh^EdRu>r0Q6nS_!k8X6huk4qSDs|0o(c-D3lR{<5 zjl;|!8G713ZgR!D`l6wX(;R@{i=}Va&_<&`<{PK^{g*^F3^!z$A(Ew*;C+nu5}K*z z^8?VAX~r@rP=p0a^fdi7-PLUPUgyv89i_KUAn5r?t@65TYxuz|l&;*nMqLYRm)vxG zuBUUcBBk|7lnm{wjMIX3NO&|0+tE}AO&*hBpKJE=;)j%xAN1py0IYG5qz6qba{;j5 z1TZahbhTu><}{-x(B`%7)Wse`buuDeK1caXwb$>br)>j^uWt4)oYOQ}Yl}WW?;f6u z=Zg^TLp<(#&*W2mF}^rE3yAn@CbH_}SyHp1peh#B6F!s4=ZI%-%S)%W!@-go5~7Kp zaG19(nTiZbU0XVR%Y zvgr>@3as|4jQyBKH&{`$aPiCF777_#YVnMZ>6J)&M6e60@g{xpE+$M<*^e_4PxxT` zn$|rdQhu_U!hNcB*Vx}p=jO{64mRWe!_myVPY3_Gb< zJj>6q-Ub!uNh+ zh?H1uvKT-|DC3b`Pxwng5M|4d?My{@k%5*PGxirJw+1ElI}SCI|EKe>gBjoLru4_6qF&cP>ddMGOJ_{0YKEQ-C=*V#Jo z4-?{MaqfvsB__wc56+riLPBqRM+nMUK^)~ye38SYmx*x~um4qhraFi;K08IW0(!_D zB-~}LCd<*L91+FhucNV_giXwjyw{+C)3Cx3{`Y31sPfjXo(WFCEmYM269<<#yT-(F zZ5=RX5ZaNLh!JeThgqfbzx!Ir^**(3)H>({zh5fo=@A}0GFaHh0GvGbi)c@G+&6L; z?Ir`;bvGGAwW)(gEC!i8rt@ry{07WS6Ka^! z{sWwd!aNJNW@a`uIvvX%MNslalmJaSwvEW##BahQnbo zJUCHn0~qqW{95|)#4*HGPN<+c6T5qK?6KzP!`7?&H;!q6EAPG16`Da3I!~+TyNh28 z_iZbgUuy7vG_ydE6C!h)Dexo3H=oBct#W$rT~dQ1O;jS~&7OjLpHxNWAT@tX&=mGd zZw@pMg1+)Ua}a*jw)7RsTc=VSjyWaGw03J$7#+h|s%mXw1CiDA$Cg}7_7zpOVWpOR zBskF~-5dVt*+!q{Kjb~j?9Lk8lyiP@|C4CXz_*L{0(-Ukc}(r>1Gpx(4)sOZ>FZ%$ zG$(Ks@7w*l@!z!R##OnYdTk!;=p~7vptimq-8K1)_%YSRqDJuw3i{g+)4<6#LcX-z z6aD^YcY%^UNtRnPW-4JOkmU7lzKm!P&0WN?rCsa4iH}lyw|>0GN+G3+CAVLnnyXjx zoImC5q|_=V1gMV(`Z+ZcvhQf6EnMmz>K%I;?A~U4wjO#9_u>lM<3t)kLQHSAdyO*b zfJ00_gM*u)H7}~}o5?&<5y>~h&u_He_GT&cY3^7FVRnXyHz z9KXkK`lgpBmsBTq<$M_RbQCC@>zXe`=oO}qyZhzuvPR7!CeB7P((FD)Rri}tb6<$+ zlkz`lOAY!K!3l5f+IftZO#=K*Tq6-FLcJnkd2T^uPIGM*g%3+3a{U4r!bdFv2$#q*oh77X|{ry#z z4GPD&fbnm|FNwcqKTIC!Nh~bD*ixG;){MSq^8}3W8VN7RdZ3ej0G)dOxQ&{~!nb43 z5N?wGlmb<43CA4#euj$*P28`sTQoFY+FJCINcmy8gC{I~t~NSCTAc9@)ZQ2Th(f$# zB`;>IVZnR@z3^|P^7@&I*7>g)<;7poaT*hylmye@VL5-GCOC zq5HHY7JW6+L|4Z)&MNg2=W@h=`RT>=N;e14GqPIl&S%>`!g(t7nZmKW)XJ)o!=cj5 zW|h|(;%)3QR#Mh`Q_#`hZ+k=I%}4Z<0+>25yXTtAv;%&YExsAm_PTqc$l2!>v+RLk z)?gs56Q&ZM%c4 z*Th(9wsjc|edwgOi*Swa6GM{&k6_>KG?Mpg!wX{d)BWME7MwYw{=bSzcw~BIMB)1V zHGz4NT#|JyH}x;t)o3+d7{}h+&l=j_%yVzFyy9AH(VBzFO^aEgprvzf3rXA^CQ+qu_j=l-Yg!SD&KY5-%e7R!USwT%PC zL0$1rG5-GW1JdI#W9QNl=E1P9uSRKWTJj=yFFzUmDta)7Zc2FWEyjcMP7n4!WgI6f zA&z#``R26?W;`Bg@XiT(a{@8ysJXUcUKTtZR^$E&+otflj2^)X)A7?4gxjT}sO_q@ zK?n<12)A*k;{Zc2LQ-Q4n~3S{?WHf(V~=Jj=RB$b4#o*!g%%|^F(S{lU9U{|K;QFL zVrXLdhN@z|DfMyoWWw!8h8xCxdI@dpx##71stQSKED-*&h15{J*S8YUt~m<}Hmzm{ zl}K2~XTt+kryITCQkehWWzqYotN*2fFyDTn9%$|(y-`0IuT`XOur+o2j<*v9&yicd zd{T!upS7cI-14_Y9-gM=jgF~PRJ7Y%_x4RKbxv$idjrc24)|*kdeFo$uR2kTPdV`U zuI~O0=HiYbiXhG5D)Z)>++~Z>WK}LbhmaSWRFsAGc%e&-9JSbLu$`?d^cXH}?es41 zYnZ;b{K0^*jjzT>#bDcIiN)cJB5beg+~$)y%44EK&~HUkFL&>4=MT35Oqf9Y&ctI7 zn^3q^nStl`M=(#rL*%muhyKU-M#&H|_RsZWljnp^7m%a+oVb50>@_R&4}>3$u8gqX zx1pLPv^b?T23=%vka*uFZLFmG?t8urnPRH(hfvI{A8x-|rE`*O!8{^LG{-q>>7WK+ z+Va1jm^N1}t8cKrG*jnvX8Fb|+1M6@ym?ruVKIJk9Ylh%B&ZaHF>>|JnIMh zr1Iola~|;M+}|q&_hsmg_`)lPHm zp1q2&G%2>UQVwU<)XO?)SVh|cUK;AxKHETjh<7@89u%t)DH&a?@BUuvb3kh6_+Ia; ze*u9KWPCMM2azwuW6cHRMG^9FJ||t7LrHUkAIZ4;|LFtbUX$B5G;aTC8(uyB+TmX` zyz6a>2v628^5vBEI}?kNW=b{8nVXxd^=w%*B$^K&@aa?9p-H4`WRZMx%3D~i(JgAR zWq|6B)>|*89=zCs^)9qkzXe_?w_xMopQSv^CujVDLsQeY4(5*ha@~M?EOk=0bbjn( zyH?c9`o+BhR>sB?9eE>K(YfDJ&%AE|Yib)J5iaN|LHpT0pFJX?CD-zRg>tx zpeR80#flSOmtXa+mei1Hstoxn^;PNjMYuLInElyFm(AOBIeaT3t=#`sPYd3bDyIew z^o2jmOUu7;S?S0pGMSapeJn9M#w!W3w7TzbU+xJtj5 z&XKOB)Wf%z{`2cwB4{P>VWS6tn64x1qZu0TjOVWbko##zvrnk}k7YL4G~u+G&%zCA zp_h?Opb0HPs80Alzq?Z=^F_P3*Qty)H5uRu6}l4 z7uBTJox#SQ+4h&rnysUZ?+wIJL$|{0oEa7?`?vv)+K)>8A?jJ%In1!)aqj2S#A)Bn zV8;0c+wx>_aDg{Hyz8c4v{H|NAqdQ~Qqa%CFz<^{A=8shJ`tufVmmm zGo8udZqK4+ck|^8x5a_%=B8TCd4$F7-m~fW6pyQ14x*m@qb?Q7>33lkv$6t>Y}a~- zc}-B(lv9u|S=yA`xq+p{0T-316U9)pa;95;uLkW$932b~GcP&l!F4F*_pvZkxVu~D uv&fOkvUQG literal 0 HcmV?d00001 diff --git a/assets/sounds/saber.ogg b/assets/sounds/saber.ogg deleted file mode 100644 index 17fb4a33d061fea2384ce0d480fe3b302b61312b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25165 zcmeFYbyStl_bB`vx*Mc~LpRb59=cIVLb_YJCvS(t?13$bHby z_j|wZ@BOWN-?i>~|GTs1%$nFU`b*LL7v?A{CBwT2?0wM3>;YmDR=)RBqIJDiVcL&wRN`PeBx>ib+9#i z_6Gq}5z52G&BMjR#S3MA;^<`S>}u&|>EzCW1cE;Rf07znike#DGPai1FQ9UqQ27^T zmaa~w`1egJQrfEGnjX%Uu24-=uo@k#l#$eu6$ghDA_WW5PgGT9)wDFl-R^-LEiG(4 z968NjI6{#BeiMt7^fL&6210VHK>Ohz6SM&U4**Q)S#XlA6j@4A3YdK|QWWlU{ajHQ zDN+5T=CRxZ|4N{I7Q_I61i+cm(cfP%nmd&? zmD)Q^urQ!u>mh>#1z-v^VMH4DiCH8~I4PJ!P`VD$l;yZ$u$JeCVDJn6K9Z$0 z!xbFr@3f!*9GoT~pGc%wPc&LjIX*@I z&)Wj@+QObMh8bRknUaS86MqD(UERk&Q-?x;d^+K@O_oAh^1=<_Ld4MUY6QUIo+ME8 zBwCiFBE?cGyIR}q7MrRT$I%A%(FUwPAfUM1^A`Z}ZL>=MU(rf0&GLUAVKzgo01Tw% zpbO=o3%#rc{h%v5>K_UZ0U%Fd8tnb9eDZF5gKlDAly{dIPEi^Eu7dk7Cfu_f0ASpd z{VtTlAT=~NW?cDo+{72$R2M)}+*9O#9fJSJ3pf#)T&pxYI2vz)=^wJd!C^@Y(4?{c zVgdmo3$~zHAG6NKg>kaB^DBt5XL_TwvYFZ|GP3`0&|!jX6XYe!NM?V2=Ep3z2}P`| zlD|10f^5{9ifOQpY&QpIfXozxvz^XDtyt0p`|5qn+9_`*0&`I**-XvtT7Sp;M=UCg zawd9(*TEi9pR(=S(G9`ePm7%6arFDT|0+H(kZ-1oqyxDj(13UpGa{N&nq(^XS2)S} z+(RtIRB`cgN)<1kYLGFNxQG0iITQdw@%~8hzmh+q{8x&LlcHHim>b7JJkl z2X!Ctq_Ma`DQ4#fr8us6C(o@`Si!!ed0wBbBt=7srR1+hflP&3BuJu={ZW$e4A&8s zGEgi2lX0i?llTv({v%F)qf{qg0OJ%7hbFJMwwAVzr=woF$8u|!;iAXdLcrQWobiM3 z|0-Dj)*Jv-n$SNwnPL{pJ(%-SO$z-lga4&DE<}Tgl*5Vi$_@0Y)9mACd{55#rU+%# z`BXKD4X21bW=JeG1q^5SEoZbX=R7T!S}dQp2I#f?qcDHfW^KXaKQ!lFMQDZNHx-hQ z{-@^TGskZT#nUM!(d#8K`lMM$WmRP6eXS_O_%E7c6J3@OT^1R=8yU|Wm1Y~2RoPzX zFj9Na@xP7#)*N|PdN6{TBkM~4ADYv{O(_j(QvxjAr$D9WLoCb%smiYf#W5CuqKGhjMkg%x$Kn4I?#ig^pI0R-1!cmeoXo`K5{RSdm zbBYXNBNFK36pv^$$MBGvGd?PY5zTJs+dXvCiixYSP>|$k8PK5FE=L8IJv5+z48R$L zP^uzQDkFlLcOMjI097K$IN|-S1csg|J{X}mj8OJ(@&7CZ5%H-bf$^VVKtxkokSV@@ zaDiBQcx7RH;7;;?9{w9#>im!=|A7m}rwY?j{XfU_e@FPg6!_m#02FZu4)`OHDxhIQ zfD1u@h)q}$RPmG#ZmxGK=1s0b_(hjQ3^xmP=3m+YZm?&3-c(|^rRWKKxOu3PFKz#A zaRN{uuptiwR=982?fsWrgCBCLLRgAE6>5hdHWO<5p3k)MzyCNm0Kg%r030A3f&KfN ziWCR{Kq$#V540~7k}M$r+)^(O6#$YfeW?EXVgA3@{uhK0I5Pl56zY;VQ;s6Uo9n@n z*fCA?098b9au^Zh9vI>N>nQjbNKl#iEEoVhWZ;W4(daav`j${yiEZJK3%l}+Orj-d z1Vz#Efm!^#U7u3)$#Zbt%+ZCm2;lYtk{$V;>;g7Q>^M(thLiv(JO`uV+J@@Ils2 z)cpvRm9>~4c1Q3>uOus?uv9)=Gh@9QeT-38$uNZW8B)e>$C_Uou+ zN7VXTCd;p^-0!Gm8wEfEYAMxH59P~!sev5;zVtuq6sKrN?d7|B-ve%R2>1JCC^s4lXmg>^ z6yr%Lu!JT2KgAyc2m8SB{yCut#G3w-bHVt}Q_KH6zx@B1ThzC&X?_NfPJ|)C^g`o! ztLbxz<53=vHxK}5;5jW;GLn0bJ|#&>iC8LDn3*9pO+UIuDv}$mqVXtJDnEfm5+(S850A>ibFU<7An$ zpWnCI*YLA!yD8Vt>6=$KGZw`r-Pct&&(o%8@C*=Xg1M|vu7N93^J?y0{bYjoKd3Z0 zKwx`N7U(SEDhBjH!9ll-jpLY0ahpH}VB$gmjDb{=iAqEFc8OI+ZiMX28iQNgA#aTC6Yq_+mMn3!j=5f z03rg%|EB>&1P=4J2bj4x!Bg*H?=yeWiu)W`{G0x5C;<_Hm4B=55rM^j#`}XPMT7Nk z5nO%|?^i!MR*pV3-dZsPc_JPa*dLt*PiT0k^-c5oRk5xkii$PTa^ySt#fyrlG|jro zmQcwNMWx&jG!~SKuvpfTjN~+_(F_eNGd6DbSZ;aYZ7r$6`_p|003hP?5TX&mf`hRD zA(%n}0)T;u_3(o%48}=Q)RXV5BE*y{06GdH$MB*e`=Q(goaDQOvwj1dKyZRldq|@4+HT402S~BT)vh7TH3gL07QWw0HB}&kBqe05fTxTfJw>7DJZF^Jq4FH$e*1M20+lz{vJ5* z%V=nSJt#1iKmCDw4+;niq&V**P{`iJ--X=;-Fe@ID=8UR80g-??*i^Z?p*HN{E-8A zom16>FEjBRp|G%-0N_Ka7SP04SMr9*i?uNM>XTjn7Y}*EZuU0amC>uP{WNFFK>;q_ z^=(heqP{wU1pLxkVtqj*$43szh~%Uz*h?K2MG!2mYZO4JI{DUj|A6KJq~&`4l>lG0 zM{cCj0yh9?5OWU*=O#~v-*Nh^P#OzvHi<4y)L+w8WWMG-%VJNz3ewDTYD{L5dhmkx zvLmNK+|TdCd@f?cP|#}`H%^%C!zyQ|SWs_Wqp{P;V>PSLfp6wP2S-p1ullg(DP=Zt zHL}@k=SqxatWHRnE2$lx^uEWFlVmVzNsQx;(GOb90c*0U5m163rK}j&KGg<>8)7S@ zpD3>R3?3!xKO98ft*eDcrXfo5aGz%!@me4vWiBliV82u@?sG8A{G1G6S?P{4G)_dG zCh-u2n<2q@FqjESIv#YWWCwi6m_CpC41BMH*YXglw`yzG@Ux-;JzI_QHN%_dA8z9wt-Zn_yu6)1 z>$a|W6Yy&pSG?n5>6Ni1lTWJka<<#^+s7}|(#1uM53OExyo}JN5?xu@*QTOMS$q|g zYxw9GQ-`7PyCwg}uR}_OnMO&+m5VcLwR)^uNPYv_ik2RnTegXBZT6LM>#dd5Rk(VJN*5E&&1Ud}fRis>)NT>Q@zhmtzewA7q4Wby!rl4s_xNa`_Tea@-#dRqk?L zw(V-HU_Cv`U>Q+doK1+Y@>kL`z%>^k9K<$x{UUJ%Nz%&dbz@299?v8fRem<}oK-vp z(5o5giNhON=@WsZDcrA;9>e4Hxjg|+ucOT!`}n6pi4yrww{lB~=j!SUXvT>dF83myiD_T7DiR>n^yBqdG0LCL<6mFBSRV_R zy}2$Zn!kQ#TUx9M0c`vwxN-UR=4S6c8fVGJRJ|>;{}%P+<|+dB5%t)EM!nXruNQ6) z$~51>JQsIgP1H2{Q2JcZOUFj!3A7oc#e1jCa&eFT!qQf*vP0!Avt!_V;LYOU9Q;&f zSv39;?xH}q&7_trbj#!l68GyI#?u7%w^nEQ`qoIFXTyD3pXwr7+nsj?oy)MgbA&dJ zt?YR;qkhf`nU8?v`fgSlga^C~54FQfd=vnV9en%xFz(%Btd6C>b3o&u$Ff(e;ScAq*ebd@|Co9w+nE!sG;SFjB0FthwP#@m>cZZsZwLMz6nPhXS@VqW=g3%q@I z+{wmxJ|ivph6sDi;qLhMq~v50d!e;}tD5cOmdeZF$Tzq@b`N}n51vP-xBKDn@)GgK zS>s;D>(@3Lknr*@`7Ssi{%C5l8Amb~V#cq_ao=#uay01JsAgxAd*#EV=2h`7a1IQS@&e7J7{+M_qv1;nUah2zk z`t^C9ak5aY9_I;X={BY1g5k={S+@u^al`RT8TYpp(}T5scdLlbC&qrf%g=P;pEim( ziQIT|D63jWl?ux0_xmmM`RV%Fxau1W!?1624xKojcnJ^)j2BpuPqdN|^C8-%pO8Pm z#y)E9d}bA{MpV+7i4O$sY9U^99G<&7dHSAh`iIz3s}wQX)t|>+De5>JvF=#!WHET% zERS{FRJH!>%(BnOW3**ZlNCRt5ta-Zmh8|8_c*_EA1C>_@zzb?DFdl?O;NX+{FC|R z(WdA^_p;;kYn^9ufqRT=jXyIN9`!$w%kEP5ai~puvyM28Iknv$BjUs!e2S^7|7FgR z4xJQQ7|9grfvxuoU`mYuxa3IX%#eME00*@xteot}21in_>tg1KjoMaGopmD-PJI}E zY|SH=U2Xs99`VqK&PxlCA$fPpTAKRnV9bZ~x60Lb!FacD+8~~?lYJQr-5+rXG9tl9 zNqCQPjCPatOnR^fZ-EwD;53;|a%st0g5;wW@ou1Hr^BYcI}d%ctJiCZwMnh|&+;Ug znTO-r=0pBD6yKB(@#@RTkpUSA{6V?yP{s5Itd?Z6H5gV`5E6b`;Bgj(miF3}3NrE8Dw0Q0K})$Prn zYv0As)II6+=Hjg(2uf@vKWkd|_YGcRJS4r_^pdAs#!2>ING`=kECQI48t zb^*#^0dH!D+gD{%F7~IA3el!y<2LEqW9{|wdCYDR z-PyNe+4nW3hOFib?D`Lmj;kIJr4`zZAoR*M;#{-Nj}M+Iz|dx+SGJP-ECJJXaNPvz zUQL+>dRk~>vu#iJ(K12+<+a56Xe<*0qy+TZj=M5x@5@A2xmVO3!HCu;#Izd@qHjOd zyxke9OcuxycgWR@aJV^if4ZwH-tb#r@F5Oy31+6_bBYE>*5Oy|rq+cK4@ z2X+i&`?Yqo#iSV27Z|ii!e_)BQ+*|TAKJoX)Cw8+>u|!MN&};;nVCarl9VLOj;dz! z7@^DJ)_mlinsYr#WU`?p4g(ChFA-vBIuonQRanH(mh+$+R{9DYl zLc-p3pf4{M5zCVbY4Rwi+Pv(wV@8w=Zd>UtoY&Dl1)4ao_(^yp=b{g@5|FL6(RC9g zg$#})ft<(kIFYF;==H&K(H6ktJFCOm6d+i&4h|qBPyw$rAb=baQe{{GTBUYhdKXRETd2ernXay|pJ)3W@A z)}D)DZM5DG0-&%ug@j}k=8EP6c7^7QFqO(t2^@XT5~Ac&1eKHUx#(Qsrtm{C%(x4u3){ucdyJakRE!lbcPishPq4K3Dt% zKXrMgftAx`IQ~}dhIh(X^da*V<(UR6R--+Rsou42>~L+R3_b6drWW?+vL1f-)#Oj; zHcf?d?%OHM!$(5f3CL|ai&Oa&W|A8`UkT9=xkw@{Dvo_8)PZ*ID{OPw(wj66Is&~k z9cc#(Q5?n$Akxk%m1s!7vX8wFYpfGN#3xU&ae*BR=<~Aei<1FuuXR!>xPR_09p@sfW+B zh;{4uc&Lpv9(RSu#eA`}o$4xaE^%RP7&iZ95kXKq8?LF1E2|{fy1{rHX*X95uw^Jd zLDm>(M^Q9!B_dYzWUD=^8dy1WujrMP$UX5gTtB1E#!`bJ;V)wHuyJwFIiQ(w?UijoSF4l%A?pMeD=cOK-7PVN~-x7p!%%phrNLSv~LKdwf%I4oFW3= zw%oK9>}&yq&eRyzQWdcVYF9YyYj{ZJQ+5?-2DF@nrXsU|Ok6 zqM?`Squ6*jskFrGPv3AWrWzd=9$Lb%%xc;P>lN9mGwDg=(U4J}tG~){CRoYHp*u2Q zncif93+u3~7-}J%i9U3(Yfrk=wHcRsft$3hPjmPyioDSBN={ef-8N@Ab%Y;UL_wqC zF>9e?qviWE{zqq;wjDyBKiK;S8_M**UwJ6L00`^#B?Xs;BU^PO(^pLK*yoNJ>R#HB zWbBud`f3e7_3nM1)0vlqh!o$dE8>Ek_6)FdXTh1o&&=OU3V#Y~iM4D>NFHO$4k~#1 zT=G58x2Ow;v!fVhs-XgUulFG+z;BE+$Ji}y<}s7`(RuDY zWaQ^RFaT%qowOfQ@z>R$K+$CM+d#m@J{cx_!mdjmgj|M~SdnGV*dV^4c0&cV>55cN%w^cZPRzcRF|SB-bS#SQ{ac z=+C;X9Laou9zmdIWnF%2&@%OAerbw(tg151O9R#HJvid(x43i@B^HlMsx=4e$9b=n zgtGH~SOng=t~F1e{Mw=!{N?8?%ewXAn_tWF9WfaPRY249rQY_JW#jf2WCOkD(qpYw zl>7VVR(`x^)5q1sY07K`PkG%##ok&;4p30KB&Kid^^~(3osku+8_d{IK3OsgGnc2W zOk%p!tQ=wfdaUH8LdRN8S&70+j*|A!mXXo;+^OEZ)-jJ>r+-1cv_ZgL)Gue=B3#$p zVFh!BYN|ZG)-H3Rxs22Gli_5?B}b;kq|#1EgrDCC@{z$;*t?)#A{Rb{xUNiuGWLwL z0(!3MM`R5uQS#Z6^Z~iomH|_RBywzZw*l{b0zXMTaNFtmOqZxpRuBAOb{#j6Ly^fy zBco# ze?%lH3PtJ*AKpraw+{45%qeq}DvhL8KXk-}$9(7kzSH$q=|z3y$i8U``2JiWG5oC1 zyMSl@33Wf=TB^!?Rtn-9eH9s0X@Rc^HqVU!3n>;9g7F830!3LKdcFO!i#Gr!%1Z>U zN05=ucg5;eEhQ6I)%qGD`W3uts$*Vy6RYv6%3tT1j|_4@HSZm1o_4k+iuoJ$JCM+1 zIM;hvbvMew(V04NO-fRbzPKP{Pz<(xM3<&>tf8YXj!&_^=wq3i)f@h5WOGwb{p?Zj zp;F-rilhRu-!CGw_g&4CAjX^0uIKKcJ2%Ac|B-E`E>4 zmQbgIhJ>TTmT+qK>=&w*L_booL+&ajKSG({2bVf(=o=H#m#-&~ti{sAdC#zp8h>|1 z#~f>9etIIyp)=({@as%pG^RqV#!a(TSt-n>R~?w2z7CA)x9Vjy;n(Q$HYGA}sz9P| zTX!$e`$8$T9=;p^u*ot2k3|W8=~q6xlHiE_-EGbw=yX2$)YCU{*)!|=#%Jc~Z0P$L zXuxw@lLjqX%vgwfcm+<*6z=}_C;iSs7K;93!lN#pP-X0fj-!vh zyrJ-GX7#BG83u8PkL< z7Ge{JB)@vOk!h!{ys+5ZI*}bcM7&{OSL=MCRjRjK8LeB^Q~h)R`ut%N-5^e%XN{X_ zXy9qLc3p#!e^v44RZJ5%QUZ7&F6rKpS~&ZmZG?D~li1aeR}_z!1>aDV=yw8sVddE3 z(`Mw0p@XE4kzEMyF%1|!@Y_}y<%!?;+u=i7k@&T+^2i-8vGoOP0o0d5_7nF&tdKIw7>J`&K0B`8i z2LgA{P8%K?r&$@LM%;c5RQ)>P>Vi?`T-1e7Zxk)uvmd+xmP={lO>4jy(1G@7pT*t77Tp<$J^f;Wces z2;ErD)oJ~|VKwv5@1DPT!#U z{b965dL;a#b^W6~L7upE-RO$XGFgPT%&U5%t;y>YoS>6#x;Kj)FMb}E^AsL8yB@jt z)m~M-6|?W2jS;uiO>AbX`L5Ih8Mf`jmmLN@``>GMDr3jCdE7P?9 zr$u2|(r%g4{j$ZjOh+=aP{8%n6aKW(28+Zu2l!nXcSF7(63SofbSs8R1)O37@XD7R zKe}8YC(A94p;J~;AKCLj&t5`1;NCO5_y(8nr1Rau8kKR`sA#uckgA{hLZi)EO!LQ& zZ}O@=4hYV-MpiagCca2aopX%x%ZV7z#D*8Ae2Nf#^3||b|2@NWS5u{4DM3Fnix|7O ztbo>dadd2i0S}kiUdudJ6}hLy>ydT~H(OeD?mya@MC+DLD+Vpm#de#s)2AN`C|^}?{1zADWuU-02~=9Qlvxw0SmeGui?lUMls zKH?&q7I5w!aVxc}Tlo#wX$}%=jprX!Fc{8q zwSHum-g+)}aFp4sFsO-h92h%))1s{yv)RBlpn?E!g|3IK7`Sb>zjpK8{B5;?sG9fb zQ{j5!lcba1d*65;=iLpAoUMng=k~5j2n;~{lMRke z1_q(4q&YdBn$kQ{b)M_N5~b}`qoH){5z~ANB3@H0vm>)jc05wj$#b`Dtc{2W_!WF) z1Kk*whaa}H+!^N>?2allu-4z_tK;M6Xhh(3(OMH|5_=>yGZoGaX_ArPB{J!0a)!YM zG8j3YOXfT+WbB#VPfLS7FCZpvsw=Zq3Z;QDaLFLT!kT4b)wQHefn@lDZv>N^UaVZ$ z@CpvVKR>yL9q?A#L&Q_4SgrL`?o-?#07i*ZI>cg0Lgv6%9mEtrs7Q^mIVnGQ6RO0h z6HTB?u;pH|%%YO_Fwb3aH{k+5P=GJIO{)PD*AruY{QNccW1L6e<*hU>EaGmk|JU5} zWrwabgP@z5)-*Kl#bzerU)z^!z8?LrKRID~e*WcMuG7tbA;}Q4RULb>MAhcy;-%l4 z?kC8GShc4;)H6lJ1P&n}ajp+hb_d_})U{-yXg2Yx zYMg25!XxqFTD0Q>CBsFN6uR6f!8X0#+4K1_Qu%!8JuG!Ym`Fl$H^oWP_A3fc%>_b^gC^>nP!DmnbCtD&ri%y<~3m=Am zY;GR3UvrB4F3#Na77Zyp58?^Y%C#)~nRo8>OS}3v*AnaK_PqCq=Pf&vW{2>TP*zNy zSl%YRj=gbJeAK)wjnDjZIy{6WWbYvl9y7L;rIW;?jM$A8qrVZMD=#uMlj&Mj?*nWc zwaKk=FNso$QdFl{55q_$Q#uX}OiK%quu64_6Pn%0V`LHH@+)QdLUY?2wfb1_-JeL| zp|E>bdqS1b+2TTnOz`s1i3^_cRo9dcA(xVoA%3*T>DPLklrXM7446F8M(sMDe^|{^ zZ3{Hy->B;a)63P1i`D$uEI<&5k?!gx$yP_Iy zV0EAJ6+<5~HfFWNvSpMbu0!?ualrYJwUGN+oK8f``m#-|Tt+yCx|J0H0H=6FHJ_Yz z(OSTFT-|y7yZw%0HzI;!LB}|6>21cltlPEMlW)(LH-j>y`pjghmZ-mLgU`)Vj2~@N z?*^uDtDm5@%pvTTa^{02PmQy7E`QaKFs_B~;{0`%kOix2n zc{`t`mW0Ydhe2ghI3i&cvL&B%Q3!K5E7!<-RbzY%M6>r)y1vCyE_CqF44e(VuZbaF zt3=F{O<*PpXhe?l(FoFXR~u@Z1GQ)?#K@))N9ZCKB)>u_206AO0n>01yAOdf7rVkGFTz0OOlU-i8LBaEh@W`Z1PAf%s^ zvYMv>82gfc;xcdDTJW6HUhsfdJWJViUB{!VsH+#NG?-JPmkE1IQu3aQPMFjoW8=gy)D0TPLp118?kj@$pEFF z#nYQ{W{F&5*{#YGW(YUk*^>?GqM&8^TKLFPmhgZs*i)V%UtZNqjkgjDt(3G-EsayB zrMEw)Bg=PFcgj@#1Rjm&E6iz{%^g`1qdgbZ+xXOsK{~>l)z#i^3!;S~`{mj5kIYC2 z#N$cqj4~PtLm?kY6YB>o?T`__gvpY8Y||m#Bw&Wbe@0o(uPehMC;1vIx4B=BmcV?1 zX7DCR?(ZJcI<`fLyT{o;OTx(n^1TBTL}}Gd7e71~7F#DAT_@6_KDb z0Sxz^iu>0hg3$7O@;m7}**lp##XE^R*qt(%I8^VPp zd3tZLfdsjn+C7nF#GUdNA8sO_rY7YwgH8{zPbLV5&+T=h?n*b+z3;w%kbC?1Zdr&j z?pe{^7y9pp2h~gy^=-?P3>zOr-7)oYzCL?sIP5Jl;3`p~%Z|z@&GC-@a{IKmV!uJp zAIm4;lQ**|;;`tFuyrz7hN;c~q1L>qS;~p{9BtV%q^B7b;H__a1Py_gP@lB}8`m&DP>QZ{e)G6Y!)Spdb3J0%MN zuO5y~j}%7ODyMGG)*q{V3QxcmNPD2_xrWbf9~X^)(YPgJLk;co#)EGVDgeTO@7Vxh zgj=O7lT4N%$8-o>3Znk_*E)Q+@yng>~{Jv6V_3qR*llzYPa_dRB-psheTZ`Jfq#8d6Wt zW=9E(SYe$*L<)N4H(lvuKW>Hic2(1uc%bY z%FG1+Bea9JBu>?f{=svNWV){7thgg?V&zVYci*-NG*D9* z9d$BeX*e*kU}y@L@F|^7q`~atpN973+FJ}OE1LY2kJG0bgG&Hjzhx)u0T$jvlaEJNgA*UFwC8F|uI_=An339L{Mu3FN zgzmAOcs3bdqt;9^i6do*cL8}y-N(!Gmpr}Lfknd}t8_c&(ul_=JfcK4=yy}^-Z(ab z&w==p*#}g>hh)_Z{&zLCfd-u|SPf?dw>ijtkMvT#~PO8yB)nprnGe^Dad$54C? z&UtnSD=FTPIic1Rwjy$=x=x&|#Y?$aKCWJ@YI0ikgs({F-z$>dTi<^tqSFe_D`zPN};k*v&Zs3iaowyr)wh)1PO^bSfIT92=Dc|;-__4HLTDm$dUsqDI13?H$~UREV&KVv{Lf#Me}vJF93(5foC znG4?13{pQ{8ge%<2SSKl$^~MbO{OiFvB+&Q5grk>FEBGDqj{cWma4DfpwCH5BVe-; zos`@k!!lg3Dpki+5fW4PT2zdTU=H7>NW_TU#(Z6YFig z?lR=8F9QUBbYGR#zCCH}ymH#o&yI-J(_y+=rifZAxH0h-hV5qB%woO;2TkiZG{7amcTR4nZSjFr8`(9wyZvIMc0H zA(Rm+Rj6R-k+H`^Q0qWYMwzlv@q1S8o@Wwm4q#|-A)>?SCjuc) z;&M~ZzW#I_Nbuf1AnU{2?3IebUcklL@#*#_{KlEVIwxJbxMG0iot_h3UnjF>Rx-R^D^TT?Tv(}N%_!k5DfUH}Ke{0!# zSIQE;FIU6)x+s-6W!J6Iwe9ZN#7OtT>hQbayr7faJ^CwQX@}znE$iQtQ#ZwLYziL_ zNgUB68$MXhyNoYC*is4pjX3LOZLIQYpZUgFqq{}bSiK@oJAT<^C(zXVvA?kbL2w_f zYAqjw9-m`CC!;*g+c()n6~+09iNSqJ>#SlA#F*)U2CP!$#xd}oS zY%9shV51nXeR1)&@Wy)Lm&wFZ_L1ph$_wWp8{Y(5qp{b9>H6|(pPyQ%J(^S7GiX20 z6yq1ybXfBHZS@+j;q3=!YUix(3W;Vtem(6>1s4KAk87R8`t(9C?Loo|Z;uS^I4d9V z8RCdUs+L;>gREyIky5ARVG1fGJbJG0y0YZ{j8*a!AR?gRFL(_9>+7=Z)klJh`6p9 z&v`d3zevu_MFUT_1Pnrxpj=p-d>2v@`kibGkx4Ig!6Tz7HkQ-!0D{MITa0cwk^&29 zZ)t27J*n6T)(h$m_83~rkYHOh2qLXa$~F?po)io@LBNk^Rv*<8L7}ICxj5>ZW%UL* zT^y}MXupPd*6Jji$~PH$WMm@1D5~pZ;VF6{#nKzXpJKK6Wx$iuZd~~%7;MMiFQ*@z zoM4atta}qLKh`oH-b_MdIh_Hnd9cQ0H6dv|UNkd{!wq^;|vv8I+sTVSWD2ajp9u5h_k1_HEMK(v)+9 z(u%d~;Lk_BPp~_sg`|D;sjSFQ-c9y3*-b{53rE3+x))k428pm;lRq{JNY4ZDbn3t& z3Ja1w4N;%dY|)BbtUh)OY^Mo|1mz-zlUF*6!~*7;ZI)UB#p0IIw90zH|%u}E3XAZQvEA4+J3 z2a15Gp*|s$P^=8A^%tz2YwsgUMd6}=giqI-D=tLm9?_^S>egaS_@mQW*5BrL=a;p^ z5hO9cs?HW~KT{q*>)T&$*(o9?A5Z}$4sfjR`t9TKs3MH5wdh=%bN=zoZ%45oF+qnb z-Bf!iGXaiGhpFSQIxQ1-)2R>q4_^!R8pdq;sp(%Qy9+tIv=6xSigSA_{jIEXt+p`8 z%UHF+>sMhObZ0u{fHN}C2>UzWt|7j)yISU(IS^LHC%3*i>mI(8MNaa~P6vjm1r+YE zumY@>PytMn87KUHKq@O*rVSXPA!q_3X@brAlQ~47NGMy#7N1qBTctVQq>yUGRv@B1 zvq*L_=a+~0!)3L!;l9gsW1PvdX>S@d}`IV@=rwJcM9tmCop=J;$ zoTh-_CC`Ky4-^QF+BSAsRdK*U4nqRodVf}%Jf;7FE=K!erpWRM`kW}Tf1dEg&+d}} zpZNL@S(#+F+vJH}0SA86tF1N7(y0RJ_j|2#b^2pIkDa!Ql5;OvYoUYq{p~kFWk2U+ zSA9>cw10f~=HYp?6|vDMo&AQe#($IhDfQ&;&E+6>>xcDIjnrM=l<&y>r^k7z^r$;^ zm=}YR6`D!jO+>_x*|75~3wRS1e1me^TO+@5h2-cVAaH27L)NirQZ2Kz` zNzf`TD@vXfdB8MZiPSEvP%oXUKy@>=zN4q=bHgGpjgiPK>vI%mA_7*{ER#<(NG%^4 z>iMeTpi%&-d~_BHfKLk0X~^Pn!9rt4(Ft;tzO6Ph3gN)tx4^Ou5g&5~^C7FiVTBUC zkqH3#3?9HOgby@amf$xaGC~mka)SHKBQ{#haBWwpPn(l2U3 zW0Jd{l_Ad5x;wMYHE>gQuzy=)ch*poQ+TIIqaGc!HOv)q9;!;i))>*g11WW|9!7)| zSH#z(X+On?lzWddELExD(Z$T7NakRHO8T;H8;S#wrlE*<${=sgT`9FV041a=K$>)K zI7rrJQ+Cr}Qh1a)TV3RVgU0+y(5aI3TOV1Ao37S=&5mQCZLm~xg>9XPOCaSuwHX|P zNE=jW|7z+)wz@AI$(nz z(j!6W>G@Sg;7CZsrVZK63cpfxdhB4N$ptHFkeGoXQxYdQ6)I3lsUB;KG|n0mQv3{@ z4K4jo_zqAPfgn^otgtH$ql$E(dxH>)A^qX0WYN~1SGz(2keBIyvPL-S;0zz!w7iZ# z#wn&?T20oett~L#NjkW62+N)vk*AD)YH?A+UtOS4X@LR`?ELPR6{(8oBaz11a4~Xw zGYYlVZ|I$lq+M+)rJ$LvRYkLAzq>s(G~pjW)Eansu6OpeKkTt9%gMou*SN@);+^Mf zQ`i%>Sv%)rna|Dl=-nP%Y;JNX+`W@Y98~5RpBWar8)GkJ<86cb*hTaCQ6TT182679 z#(NTNdao@nqEw0@r6dt(vBWY)zf_zV+N2L3p-kLTMMGAkJNz(Wyq#Cj7ha9cNKU#8RW|)SdFeG+_jwzzDeP% z>dga{%XF0>>|)O34?-z9eoxt$(bfAYDoSIKoE4-!;aF_Jl7quILbwtKB| z5_gk5Zh3xs=~mRTtQk!adhlytX=`St`(kwe&~M0&klJcBz;n);QHh8%otp9zb1qZw z!1|;jN2GRACo%ES4Yx#IjB>74|JMrP_DLd_-CrLw@nNckH5EU#$AOQZEXLkdLR3r! zELYNxdKhu_X#hTD_T)%2V$$GDWE+@(KFS_3f_~bNYyyY!P&L9LT8jT-cN;E~`#1UG zah3rkDEODVF91S5_>XN=F(5GWm(be}M0mRcsmh!7w-0ZzobfiqD}y>6jB1-F&3Hcu zF3{w7rDA5ywSIUXWn0cl1KwbRPP)c7#=?i(DNk-%4ao*okH(EC)&55jR~`uE+Qna~ zRJIDKkBn}jQpk{fbd%J*wo*x!K{CoRWSPM*svB7%Np?eS)@)e@gCWagm$47VI(8Fd z3}(!Hqi*+}Ki>bI_dMr0&-uOQJ37uYEh$#QbvSF z)@o|AM6{K{*abiKh%gyHE}8Cl57u!fbi)gJ(=2z11E11^uSI^86E1O`NkEz0a!XV; z2(f#TLcG>wyfFEW^5JH*s)ony-j157Lq=`*SCPjJ&L!r026?WH^gXUPQwn?3{Yun0 z;_=~EHcx1@Q&xKpOmzRvLx?Im@9h=W)A-ErubBg1?>b(M3%Y)+=WJxq+xj%8n#U(v zz9?q`ytZ7B-~p8Cf^Ht$4+sbVQog8s{BMZpG^4cJTUD$^)}Ht}f8FgU8iHx98CTO_ zDew{v&0^RkB<4z=;;se&C{>HcSeY9Ja4w9vCT%E+TxKb&xTy$Cu!N!8+e594DEimd zKiESPvDm5A3F_Zjfj-}1x+#bUFuV_r-D#cuCb3CF7n*w$31b->65fx>Si3RR1td@` zutOrpS9dZ?b8%95(qDIpFy*o6nzK!BaSc#UxCB-{NiehCm_DU2MCM;vLc_E3%YvE6 z58swm{S$<5d~FUE^GzradwiH|t`^ygirx$kF^j|<`7KAiK%Ts|$8|qH{qGya8gWCh zfFw^CpdP9{#}~xC(4UG#eS#Jn1l2qvOa-u0w*Lw)e#U^A&?K=`Z~spW{}T)Y$fqeW zo`+u7B;woUt_I_AC2w+H2rbGC8qcnR#E0-sA{o%k$DfV(sM ziTj*QTw0EnX5jL&8}0;OJ6>s5R-7;W^4iVm(pQHg5|19gdhObj)c*1NwsnBOUhZG+ zeSqHviHd+m8yrWvNq^hCgucG?WiCNtliOEmlD32+SmVnI7x|i9^uT8SG$QE*YXX}V zvsDi;^Kw(PB2C+6-4tr341#}tb{Q*<-YnIxacx@V^F~h&a6Q({|4^Y-ywCK4G@ zR({{mo#r+e2@-ffzJ2M@-XS7iIe(#q^zX(#cuC>eHqnHVy&^*1U1pj~TC=d@qn0@E zlyeI&-BcB(6_&B09SbCDC204>(7=0w?LAA--cO>Bi>nU%Z)}PaFMa;BU2vpvF5duy zk!zgc{c=5=7r6d*Xpjc0m6jr|n+7#G9arJ4lMCYE2Lhc?QqX8T;LjV{Jiw0K-kawY zc@RR6!dD2)I*eHItX0oLU!5%8?&}pjTR^|XpCfbdhtmNByT1RCepkvmBYz7zK_@8~ z*;Su}dTIGl+sMS`Fe{W+s(1@rwfLE(4itc^fS}1mLyRn z%;-kH;Pe?DA>>bF&!PKYvyiqy| zK#-^lpb6Oi4W47Kp`@r+&>&x4G5}bisKW#0N78?}id)hQI{28>y5aEfVLsaPV|$~R zb6o9OdEe<7(FPH=ET+$8Yw|ssIS>*RZgBd<`cY`}PQtu=o7adUC6tgQY~6Z;O?0sl;rR(go*;_%u#ek`E^^IK! z0%1O~8vhD#H*-RDfbusRg9F@Yf`F;Nk>tYYKzaJ}=Rbi5knTEpg%5=7XmL7i#DPRo zBm#{Q-VF|_mc&F+^%TqRq^jr~shgRKpLG`|{hVe<=^Ju^B|YJr_tu!gB*GW^Q*a>T zyO07it0DQx1}95mQlhzzIV(_DnfUBe48{@f{BU_HBlBoM`?*2Im=qlxo2DrEed~3? z4mjivF*&g!WF%&L`j`@j%aP@QK2WnxlG=duxStwH+zGit5F6f8$K@k%+l;WCSVMu0 z?B~YVsB7*{s1@iTnL70fUnmIADMS@pFkOUGJ8KO*sshUM&;PUiq+k0WM^)?l&$`*j z4Io#y8r$ZFpSiRvC@^d!12x`4*ps;T#7U3Jou+(tH>aZMlvjn7T3>h_0oqku!=X{5 zQ<;Y&-!KtcO6%(m?IrR997Co~n9s7sR(FEQ9)l9kIUYz?jGCjm)e&4l>WD&a8u(7F zp=_)fSSk5=A_Au=+>#<%bSlSwvFNqyiy5GrPm;hbOV=V%ikR1%jdkjTI)e|ZW$1IS zl)8o7#^~go^`;@G;O2!tMFUpW2?l4a4%MyKra%A39H5LL*1=!7GcKTO9aB8j&LVod z?z~>i%itskVj)AIZ8XV2Y^Bsr64WyqnNeMXEJ+Aev9t-aUf6D#RXn`4ojMKE~|07|>T6IHk=R~qXvMftV~V+s`7ip|y&7S(Dww3M$d zQOs}Vj0fMg2XENd*?5voe`G&gbAp%|!1 zOy~wwXaxrP(`Xht*%aF6&aP`IXD@xY1~ri{@j-{IXye-Su@FkU_wCM}b_sAwCpunj z>~BIrPNn7%Rcp}(E2*WAB7S7ZXvPl9yD)&y4xUKpL?7Com*EHa04XF( zJN5kC#-hm^0J=Gfo>OsP9N;2u`|1bejL3b125xtUpJGb1<_qE&xeCP1qCj$|Y+ZM&Ck$Ui7GzZhH$_6Fu7H)gx+X zI(^VJTmjZFCYq9(_-SLf?q`i+?>*(8?%!oW?Ed&=zp&LiQU1BGFh3_ZBl|;2Ty)%< z_~?jW&xc0Za;H)eD3EYd7$Ec=#!|=pk%N5Bi{b^w=lo1?YkY)D7tDT{>YhRaf;!ro zH#@}r=^dlK$w#ou{yNFWS&_yI0e#y1cI?3Apm0ilBHUR9yMlFSeP?if+IPE?)|S3r zvDVSC_=Je_t1jf+Fx#=Tth4C?zYZ0oehD`G%F>pe&CGxV2Zv}_ekox zCvM&$sxdij$luT6l%*6D+~vYY9)kYaF(ISK38UOmt;T*|5m7$o&tKm341xndbN1LGX3z23Q$KsMaFD#RFk`k?BjA3zKAkS4wtkwJ2SV%vM?lbh?M>@K z6{K=sN^-8WzmLV`Q|kS^5FsECfl@^1XDdzYUyFdY-TmnBZGW=N?uOtDC%TsYH`zoj zIq6dlXvPDm|FFgb7&(Gnrq;UoO=Z2m>)O=GG5Iu|x8$UWSR6-7$EuK1TT#o_zleUq zR)7<-J9V%!CYY%KOx)D0^P_{;>~+=XnmS1`o}RKM8%wmjX2co2F;3m=n*y`Bqz1!B zdMnGuJ)qX{zZyNy6K*CA;y-XQi-qB1+|Mh5r42vy+kJQW-&0o0M#R#;{Iwf%?y75$ zk-O-+=n2(-0sIPB7C5j4gRzE}Mx)#!o#Bcc=gx*#%i++3h1x{L?I#lDl`XHnEErS7 zsAhh*_nC)`X?w8Oe8`g9Zkt6fx;)}<(tSzZ=OLeYC04TaGZ{twmfA{X{Zn`LfK%J} z>ju`F$VjvZEpzA2x4`ro`EG6fN5mKn+g7FK%i}x{7|W_4Os4)hZ|@1+=A_9B(i&W{ zKai#Vbc>QbXJG}q`)`z8Py>Rp-b4<-QHGJ;3@xens*MT`RY{k$LC@!B#Kk$L6tJ}_ zY0f&YlN<-3ur6dTZQHck!ezA~RQtCImp+g#GG-xZX1a&iq{BBe9eU33Rd8mO;!}*) zkmbteU|Xu|G+fxaCM?6v7AYXJH2E&R%G+m~4B+Qy0ALCTbVQYg+nWM>PT<<@yB)F*Uk(C#(izyWs0N@p=g|fWM}U6bv8bOChJOj10*ojd<2- zNZWiKX&MEp`yy1DP$g;i83U&++l(EG3gPpen=3Z&^L|un!gH!>=u;irO!yr$5An(y-AUUH zJENfE&g7&}IZWEa4a=?YaN$s22LCG7M-2qi(cW~f*V1iax}PdATHhGjYUjH=ct=n1 zT*@ufVfWNG@OW48->~mfTlI*27BQFy`!`y=-hN9T6&KrRA zmXTv)6#~%`#3Vf;MVIG)8;+*4=3pZ1tkW9B?)>A-v;SLDI3zSyFB|B{vf7xFv(>zk zw7RG*5qPU8#lgOo2dFS%cg=c&^!EKqe}FN4Lm*9`NLub5dsOWotBBS67-%&+zHm90 z@~&;sKA3W*48x|bQiVankksO@(!?Z8r->R_`n*RqU7K*=5Z+;{#sRK~ncldh=>B`g zP)GMxHQ7DX#RieNHWZ*t?WC>v4e%|AcQ|GqdM_Qwttq z_a9z%iG`5*bESWHnER-+kLI&&TDJSNWb~jjc@a#FW1XuG!D13%Zf>uXj17^ybwnW@kA!VxDxS7Z;Trtf|0-mbV z)aoB;mG$6sL&L+9*uA%^YK1mAZ1mW$Jg#o>xi?1pPZ+B|p&wcCdFRXh*uTk}dn-cF zl3c2>jU%h9{bfZ{vLxSGFnf6RHvF3q;U+)Vjhk(UnAyLg0Z22FnFFRu{kJ}^;#L<& z$Nb*!G$bpuOGc8}!qZ(CQ znG?&amE^BSjbc5+a<*1jhT^VkxtxvRcImV%*~v5_mqbQ?%=(Vt9eK~kofht7IO<@$ zkf|ffyZtV_*duxR68EBU(d&N`RNw()FTf!e=)CN>JIs%%v>%OrvcGFBFglQl*pYMF zV)cu&ODbh|SRnS}TJ19l)oz_#oaLPj0p>a3_XH|`PAw4}-GxTg8VOh?k7i|nV@fBq zt(Rb$jNs$(ZejCJzS8CD_Kic-g}Bu!M-~G9DAE3MaLk_02u^CvwkUSYeHS+#VE>r7 z-EcbppE4EKffvLp_gv8|bT;r-MEBd=Us7WRvSG%I>+=;SjM0AICT93o?)%S5-*raj z6wb~K%EzhP%fv&ZFh-0y-`Al{U6ACcKtvf;h4QB>4UJ3ha7Mr}^s{q0HTHnEH8)Z?fxdulAo(_q5>f%LTA=B?#Ie?~y_1g$NkrV#rSB?pOYqrn|~ z*J*L1Gi8-Y*Eqf+wBW&Q#^NUgnn6ux^0$BLVtnb6 zq;&h{qULoe9wHBSGf7Io@yLd^}1aF1D$4K6+<@xIQX=adw$*g}K?Pc{W2gMv7g#!vtrdRbEvS+Rr8G z^d+R|2s@bjT=Kjm*xeT#!n?b-XUp#;R@C!+iAaKzK7=3KO-{$}Ypp+iR8#mbIsqyS z9)LG_2hVynCKTx?^~r9kx@-7YWm53sYq@-q!)GHzhhpa@^jOvu(hU-~SQ0(8p?5K4 z%5nO0B|1JEe{mKoRi23Pi!prAo^qB+8r7@vJ>*^w;AW}r3`rsOBNp{SxU7(RUHmGB zbi2EehmU)wBu(Sp)VKFsBKbdJYas)CpI&*w++5D1C5)NS7xOu!0V|YhN7L=+JqwW! zijbwbd1D3saRs1(E$rBG;YBNFX!+cb_0em-zg5kG`C-8x;za~eG{qF)s+_g(`Gb2f zr8uSA_1SDPh!?dFIG+1U8E{2V9*9VNn4zfsZRE=nS&$6jyfrw*%a^QdlC-%o;Ra>L z);AZaGv~l80ivRw)HJM;J&f710#`4;tmgqR_(b?=KtYK>*B=VzvkWHIEo>dl8OA+IK7-Z%`zj#LI|xet0=;N^n#uXoHTvk~tV z&jj>3R~r0^G)Nzr?n>5F`)6tBCH+h9;TI@O+X_Gp`9QYU80AL&d{tuEjhO+ { + this.currentBeatEl = evt.detail; + soundPool.playSound(this.processSound); + }); + }, + + processSound: function (sound) { + this.currentBeatEl.object3D.getWorldPosition(sound.position); + console.log(sound.position); + // this.currentBeatEl.setObject3D('sound', sound); + } +}); diff --git a/src/components/beat.js b/src/components/beat.js index c437808..0839f5e 100644 --- a/src/components/beat.js +++ b/src/components/beat.js @@ -421,14 +421,14 @@ AFRAME.registerComponent('beat', { saberBoundingBox = saberEls[i].components['saber-controls'].boundingBox; if (!boundingBox || !saberBoundingBox) { break; } if (saberBoundingBox.intersectsBox(boundingBox)) { + this.el.emit('beathit', this.el); this.destroyBeat(saberEls[i]); - this.el.sceneEl.emit('beathit', null, false); break; } if (saberBoundingBox.intersectsBox(beatBoundingBox)) { + this.el.emit('beathit', this.el); this.destroyBeat(saberEls[i]); this.wrongCut(saberEls[i].getAttribute('saber-controls').hand); - this.el.sceneEl.emit('beatwrong', null, false); break; } } diff --git a/src/index.html b/src/index.html index 3d232e9..f110470 100644 --- a/src/index.html +++ b/src/index.html @@ -100,8 +100,11 @@ - - + {% include './templates/stage.html' %} {% include './templates/score.html' %} {% include './templates/menu.html' %} diff --git a/vendor/README.md b/vendor/README.md new file mode 100644 index 0000000..14a1d61 --- /dev/null +++ b/vendor/README.md @@ -0,0 +1,2 @@ +A-Frame currently derived from `overlay` branch from either Kevin or Diego's +A-Frame GitHub repositories. diff --git a/vendor/aframe.effects.js b/vendor/aframe.effects.js index 118619c..3064421 100644 --- a/vendor/aframe.effects.js +++ b/vendor/aframe.effects.js @@ -50,9 +50,9 @@ function(a){a=P(a);for(var c=v.length;c--;)for(var d=v[c],b=d.animations,f=b.len },{}],3:[function(_dereq_,module,exports){ module.exports = function numtype(num, def) { - return typeof num === 'number' - ? num - : (typeof def === 'number' ? def : 0) + return typeof num === 'number' + ? num + : (typeof def === 'number' ? def : 0) } },{}],4:[function(_dereq_,module,exports){ 'use strict' @@ -207,7 +207,7 @@ module.exports = { var value = attributes[key]; style.setAttribute('data-' + key, value); } - + if (style.sheet) { // for jsdom and IE9+ style.innerHTML = cssText; style.sheet.cssText = cssText; @@ -416,11 +416,11 @@ module.exports = function (a, b) { if (!Buffer.isBuffer(b)) return undefined; if (typeof a.equals === 'function') return a.equals(b); if (a.length !== b.length) return false; - + for (var i = 0; i < a.length; i++) { if (a[i] !== b[i]) return false; } - + return true; }; @@ -2218,7 +2218,7 @@ function isnan (val) { }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"base64-js":4,"ieee754":18,"isarray":9}],9:[function(_dereq_,module,exports){ +},{"base64-js":4,"ieee754":15,"isarray":9}],9:[function(_dereq_,module,exports){ var toString = {}.toString; module.exports = Array.isArray || function (arr) { @@ -2226,432 +2226,76 @@ module.exports = Array.isArray || function (arr) { }; },{}],10:[function(_dereq_,module,exports){ - -/** - * This is the web browser implementation of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = _dereq_('./debug'); -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.storage = 'undefined' != typeof chrome - && 'undefined' != typeof chrome.storage - ? chrome.storage.local - : localstorage(); - -/** - * Colors. - */ - -exports.colors = [ - 'lightseagreen', - 'forestgreen', - 'goldenrod', - 'dodgerblue', - 'darkorchid', - 'crimson' -]; - -/** - * Currently only WebKit-based Web Inspectors, Firefox >= v31, - * and the Firebug extension (any Firefox version) are known - * to support "%c" CSS customizations. - * - * TODO: add a `localStorage` variable to explicitly enable/disable colors - */ - -function useColors() { - // is webkit? http://stackoverflow.com/a/16459606/376773 - return ('WebkitAppearance' in document.documentElement.style) || - // is firebug? http://stackoverflow.com/a/398120/376773 - (window.console && (console.firebug || (console.exception && console.table))) || - // is firefox >= v31? - // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); -} - -/** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. - */ - -exports.formatters.j = function(v) { - return JSON.stringify(v); -}; - - -/** - * Colorize log arguments if enabled. - * - * @api public - */ - -function formatArgs() { - var args = arguments; - var useColors = this.useColors; - - args[0] = (useColors ? '%c' : '') - + this.namespace - + (useColors ? ' %c' : ' ') - + args[0] - + (useColors ? '%c ' : ' '); - - if (!useColors) return args; - - var c = 'color: ' + this.color; - args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); - - // the final "%c" is somewhat tricky, because there could be other - // arguments passed either before or after the %c, so we need to - // figure out the correct index to insert the CSS into - var index = 0; - var lastC = 0; - args[0].replace(/%[a-z%]/g, function(match) { - if ('%%' === match) return; - index++; - if ('%c' === match) { - // we only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; - } - }); - - args.splice(lastC, 0, c); - return args; -} - -/** - * Invokes `console.log()` when available. - * No-op when `console.log` is not a "function". - * - * @api public - */ - -function log() { - // this hackery is required for IE8/9, where - // the `console.log` function doesn't have 'apply' - return 'object' === typeof console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); -} - -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ - -function save(namespaces) { - try { - if (null == namespaces) { - exports.storage.removeItem('debug'); - } else { - exports.storage.debug = namespaces; - } - } catch(e) {} -} - -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ - -function load() { - var r; - try { - r = exports.storage.debug; - } catch(e) {} - return r; -} - -/** - * Enable namespaces listed in `localStorage.debug` initially. - */ - -exports.enable(load()); - -/** - * Localstorage attempts to return the localstorage. - * - * This is necessary because safari throws - * when a user disables cookies/localstorage - * and you attempt to access it. - * - * @return {LocalStorage} - * @api private - */ - -function localstorage(){ - try { - return window.localStorage; - } catch (e) {} -} - -},{"./debug":11}],11:[function(_dereq_,module,exports){ - -/** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = debug; -exports.coerce = coerce; -exports.disable = disable; -exports.enable = enable; -exports.enabled = enabled; - -/** - * The currently active debug mode names, and names to skip. - */ - -exports.names = []; -exports.skips = []; - -/** - * Map of special "%n" handling functions, for the debug "format" argument. - * - * Valid key names are a single, lowercased letter, i.e. "n". - */ - -exports.formatters = {}; - -/** - * Previously assigned color. - */ - -var prevColor = 0; - -/** - * Select a color. - * - * @return {Number} - * @api private - */ - -function selectColor() { - return exports.colors[prevColor++ % exports.colors.length]; -} - -/** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public - */ - -function debug(namespace) { - - // define the `disabled` version - function disabled() { - } - disabled.enabled = false; - - // define the `enabled` version - function enabled() { - - var self = enabled; - - // add the `color` if not set - if (null == self.useColors) self.useColors = exports.useColors(); - if (null == self.color && self.useColors) self.color = selectColor(); - - var args = Array.prototype.slice.call(arguments); - - args[0] = exports.coerce(args[0]); - - if ('string' !== typeof args[0]) { - // anything else let's inspect with %o - args = ['%o'].concat(args); - } - - // apply any `formatters` transformations - var index = 0; - args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { - // if we encounter an escaped % then don't increase the array index - if (match === '%%') return match; - index++; - var formatter = exports.formatters[format]; - if ('function' === typeof formatter) { - var val = args[index]; - match = formatter.call(self, val); - - // now we need to remove `args[index]` since it's inlined in the `format` - args.splice(index, 1); - index--; - } - return match; - }); - - if ('function' === typeof exports.formatArgs) { - args = exports.formatArgs.apply(self, args); - } - var logFn = enabled.log || exports.log || console.log.bind(console); - logFn.apply(self, args); - } - enabled.enabled = true; - - var fn = exports.enabled(namespace) ? enabled : disabled; - - fn.namespace = namespace; - - return fn; -} - -/** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. - * - * @param {String} namespaces - * @api public - */ - -function enable(namespaces) { - exports.save(namespaces); - - var split = (namespaces || '').split(/[\s,]+/); - var len = split.length; - - for (var i = 0; i < len; i++) { - if (!split[i]) continue; // ignore empty strings - namespaces = split[i].replace(/\*/g, '.*?'); - if (namespaces[0] === '-') { - exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - exports.names.push(new RegExp('^' + namespaces + '$')); - } - } -} - -/** - * Disable debug output. - * - * @api public - */ - -function disable() { - exports.enable(''); -} - -/** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - -function enabled(name) { - var i, len; - for (i = 0, len = exports.skips.length; i < len; i++) { - if (exports.skips[i].test(name)) { - return false; - } - } - for (i = 0, len = exports.names.length; i < len; i++) { - if (exports.names[i].test(name)) { - return true; - } - } - return false; -} - -/** - * Coerce `val`. - * - * @param {Mixed} val - * @return {Mixed} - * @api private - */ - -function coerce(val) { - if (val instanceof Error) return val.stack || val.message; - return val; -} - -},{}],12:[function(_dereq_,module,exports){ 'use strict'; var isObj = _dereq_('is-obj'); var hasOwnProperty = Object.prototype.hasOwnProperty; var propIsEnumerable = Object.prototype.propertyIsEnumerable; function toObject(val) { - if (val === null || val === undefined) { - throw new TypeError('Sources cannot be null or undefined'); - } + if (val === null || val === undefined) { + throw new TypeError('Sources cannot be null or undefined'); + } - return Object(val); + return Object(val); } function assignKey(to, from, key) { - var val = from[key]; + var val = from[key]; - if (val === undefined || val === null) { - return; - } + if (val === undefined || val === null) { + return; + } - if (hasOwnProperty.call(to, key)) { - if (to[key] === undefined || to[key] === null) { - throw new TypeError('Cannot convert undefined or null to object (' + key + ')'); - } - } + if (hasOwnProperty.call(to, key)) { + if (to[key] === undefined || to[key] === null) { + throw new TypeError('Cannot convert undefined or null to object (' + key + ')'); + } + } - if (!hasOwnProperty.call(to, key) || !isObj(val)) { - to[key] = val; - } else { - to[key] = assign(Object(to[key]), from[key]); - } + if (!hasOwnProperty.call(to, key) || !isObj(val)) { + to[key] = val; + } else { + to[key] = assign(Object(to[key]), from[key]); + } } function assign(to, from) { - if (to === from) { - return to; - } + if (to === from) { + return to; + } - from = Object(from); + from = Object(from); - for (var key in from) { - if (hasOwnProperty.call(from, key)) { - assignKey(to, from, key); - } - } + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + assignKey(to, from, key); + } + } - if (Object.getOwnPropertySymbols) { - var symbols = Object.getOwnPropertySymbols(from); + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(from); - for (var i = 0; i < symbols.length; i++) { - if (propIsEnumerable.call(from, symbols[i])) { - assignKey(to, from, symbols[i]); - } - } - } + for (var i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(from, symbols[i])) { + assignKey(to, from, symbols[i]); + } + } + } - return to; + return to; } module.exports = function deepAssign(target) { - target = toObject(target); + target = toObject(target); - for (var s = 1; s < arguments.length; s++) { - assign(target, arguments[s]); - } + for (var s = 1; s < arguments.length; s++) { + assign(target, arguments[s]); + } - return target; + return target; }; -},{"is-obj":22}],13:[function(_dereq_,module,exports){ -/*! (C) WebReflection Mit Style License */ -(function(t,n,r,i){"use strict";function st(e,t){for(var n=0,r=e.length;n>0),o="attached",u="detached",a="extends",f="ADDITION",l="MODIFICATION",c="REMOVAL",h="DOMAttrModified",p="DOMContentLoaded",d="DOMSubtreeModified",v="<",m="=",g=/^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/,y=["ANNOTATION-XML","COLOR-PROFILE","FONT-FACE","FONT-FACE-SRC","FONT-FACE-URI","FONT-FACE-FORMAT","FONT-FACE-NAME","MISSING-GLYPH"],b=[],w=[],E="",S=n.documentElement,x=b.indexOf||function(e){for(var t=this.length;t--&&this[t]!==e;);return t},T=r.prototype,N=T.hasOwnProperty,C=T.isPrototypeOf,k=r.defineProperty,L=r.getOwnPropertyDescriptor,A=r.getOwnPropertyNames,O=r.getPrototypeOf,M=r.setPrototypeOf,_=!!r.__proto__,D=r.create||function yt(e){return e?(yt.prototype=e,new yt):this},P=M||(_?function(e,t){return e.__proto__=t,e}:A&&L?function(){function e(e,t){for(var n,r=A(t),i=0,s=r.length;i= 0) + if (idx >= 0) return font.chars[idx].height } return 0 @@ -3202,7 +2846,7 @@ function getMGlyph(font) { for (var i=0; i= 0) + if (idx >= 0) return font.chars[idx] } return 0 @@ -3212,7 +2856,7 @@ function getCapHeight(font) { for (var i=0; i= 0) + if (idx >= 0) return font.chars[idx].height } return 0 @@ -3248,7 +2892,7 @@ function findChar (array, value, start) { } return -1 } -},{"as-number":3,"word-wrapper":47,"xtend":50}],24:[function(_dereq_,module,exports){ +},{"as-number":3,"word-wrapper":44,"xtend":47}],21:[function(_dereq_,module,exports){ (function (Buffer){ var xhr = _dereq_('xhr') var noop = function(){} @@ -3282,7 +2926,7 @@ module.exports = function(opt, cb) { if (!body) return cb(new Error('no body result')) - var binary = false + var binary = false //if the response type is an array buffer, //we need to convert it into a regular Buffer object @@ -3296,9 +2940,9 @@ module.exports = function(opt, cb) { if (isBinaryFormat(body)) { binary = true //if we have a string, turn it into a Buffer - if (typeof body === 'string') + if (typeof body === 'string') body = new Buffer(body, 'binary') - } + } //we are not parsing a binary format, just ASCII/XML/etc if (!binary) { @@ -3336,7 +2980,7 @@ function getBinaryOpts(opt) { //IE10+ and other modern browsers support array buffers if (xml2) return xtend(opt, { responseType: 'arraybuffer' }) - + if (typeof self.XMLHttpRequest === 'undefined') throw new Error('your browser does not support XHR loading') @@ -3350,7 +2994,7 @@ function getBinaryOpts(opt) { }).call(this,_dereq_("buffer").Buffer) -},{"./lib/is-binary":25,"buffer":8,"parse-bmfont-ascii":27,"parse-bmfont-binary":28,"parse-bmfont-xml":29,"xhr":48,"xtend":50}],25:[function(_dereq_,module,exports){ +},{"./lib/is-binary":22,"buffer":8,"parse-bmfont-ascii":24,"parse-bmfont-binary":25,"parse-bmfont-xml":26,"xhr":45,"xtend":47}],22:[function(_dereq_,module,exports){ (function (Buffer){ var equal = _dereq_('buffer-equal') var HEADER = new Buffer([66, 77, 70, 3]) @@ -3362,7 +3006,7 @@ module.exports = function(buf) { } }).call(this,_dereq_("buffer").Buffer) -},{"buffer":8,"buffer-equal":7}],26:[function(_dereq_,module,exports){ +},{"buffer":8,"buffer-equal":7}],23:[function(_dereq_,module,exports){ /* object-assign (c) Sindre Sorhus @@ -3376,85 +3020,85 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; var propIsEnumerable = Object.prototype.propertyIsEnumerable; function toObject(val) { - if (val === null || val === undefined) { - throw new TypeError('Object.assign cannot be called with null or undefined'); - } + if (val === null || val === undefined) { + throw new TypeError('Object.assign cannot be called with null or undefined'); + } - return Object(val); + return Object(val); } function shouldUseNative() { - try { - if (!Object.assign) { - return false; - } + try { + if (!Object.assign) { + return false; + } - // Detect buggy property enumeration order in older V8 versions. + // Detect buggy property enumeration order in older V8 versions. - // https://bugs.chromium.org/p/v8/issues/detail?id=4118 - var test1 = new String('abc'); // eslint-disable-line no-new-wrappers - test1[5] = 'de'; - if (Object.getOwnPropertyNames(test1)[0] === '5') { - return false; - } + // https://bugs.chromium.org/p/v8/issues/detail?id=4118 + var test1 = new String('abc'); // eslint-disable-line no-new-wrappers + test1[5] = 'de'; + if (Object.getOwnPropertyNames(test1)[0] === '5') { + return false; + } - // https://bugs.chromium.org/p/v8/issues/detail?id=3056 - var test2 = {}; - for (var i = 0; i < 10; i++) { - test2['_' + String.fromCharCode(i)] = i; - } - var order2 = Object.getOwnPropertyNames(test2).map(function (n) { - return test2[n]; - }); - if (order2.join('') !== '0123456789') { - return false; - } + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test2 = {}; + for (var i = 0; i < 10; i++) { + test2['_' + String.fromCharCode(i)] = i; + } + var order2 = Object.getOwnPropertyNames(test2).map(function (n) { + return test2[n]; + }); + if (order2.join('') !== '0123456789') { + return false; + } - // https://bugs.chromium.org/p/v8/issues/detail?id=3056 - var test3 = {}; - 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { - test3[letter] = letter; - }); - if (Object.keys(Object.assign({}, test3)).join('') !== - 'abcdefghijklmnopqrst') { - return false; - } + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test3 = {}; + 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { + test3[letter] = letter; + }); + if (Object.keys(Object.assign({}, test3)).join('') !== + 'abcdefghijklmnopqrst') { + return false; + } - return true; - } catch (err) { - // We don't expect any of the above to throw, but better to be safe. - return false; - } + return true; + } catch (err) { + // We don't expect any of the above to throw, but better to be safe. + return false; + } } module.exports = shouldUseNative() ? Object.assign : function (target, source) { - var from; - var to = toObject(target); - var symbols; + var from; + var to = toObject(target); + var symbols; - for (var s = 1; s < arguments.length; s++) { - from = Object(arguments[s]); + for (var s = 1; s < arguments.length; s++) { + from = Object(arguments[s]); - for (var key in from) { - if (hasOwnProperty.call(from, key)) { - to[key] = from[key]; - } - } + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } - if (getOwnPropertySymbols) { - symbols = getOwnPropertySymbols(from); - for (var i = 0; i < symbols.length; i++) { - if (propIsEnumerable.call(from, symbols[i])) { - to[symbols[i]] = from[symbols[i]]; - } - } - } - } + if (getOwnPropertySymbols) { + symbols = getOwnPropertySymbols(from); + for (var i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(from, symbols[i])) { + to[symbols[i]] = from[symbols[i]]; + } + } + } + } - return to; + return to; }; -},{}],27:[function(_dereq_,module,exports){ +},{}],24:[function(_dereq_,module,exports){ module.exports = function parseBMFontAscii(data) { if (!data) throw new Error('no data provided') @@ -3502,7 +3146,7 @@ function splitLine(line, idx) { return null var space = line.indexOf(' ') - if (space === -1) + if (space === -1) throw new Error("no named row at line " + idx) var key = line.substring(0, space) @@ -3510,7 +3154,7 @@ function splitLine(line, idx) { line = line.substring(space + 1) //clear "letter" field as it is non-standard and //requires additional complexity to parse " / = symbols - line = line.replace(/letter=[\'\"]\S+[\'\"]/gi, '') + line = line.replace(/letter=[\'\"]\S+[\'\"]/gi, '') line = line.split("=") line = line.map(function(str) { return str.trim().match((/(".*?"|[^"\s]+)+(?=\s*|\s*$)/g)) @@ -3563,7 +3207,7 @@ function parseIntList(data) { return parseInt(val, 10) }) } -},{}],28:[function(_dereq_,module,exports){ +},{}],25:[function(_dereq_,module,exports){ var HEADER = [66, 77, 70] module.exports = function readBMFontBinary(buf) { @@ -3581,7 +3225,7 @@ module.exports = function readBMFontBinary(buf) { var vers = buf.readUInt8(i++) if (vers > 3) throw new Error('Only supports BMFont Binary v3 (BMFont App v1.10)') - + var target = { kernings: [], chars: [] } for (var b=0; b<5; b++) i += readBlock(target, buf, i) @@ -3597,7 +3241,7 @@ function readBlock(target, buf, i) { i += 4 switch(blockID) { - case 1: + case 1: target.info = readInfo(buf, i) break case 2: @@ -3625,11 +3269,11 @@ function readInfo(buf, i) { info.unicode = (bitField >> 6) & 1 info.italic = (bitField >> 5) & 1 info.bold = (bitField >> 4) & 1 - - //fixedHeight is only mentioned in binary spec + + //fixedHeight is only mentioned in binary spec if ((bitField >> 3) & 1) info.fixedHeight = 1 - + info.charset = buf.readUInt8(i+3) || '' info.stretchH = buf.readUInt16LE(i+4) info.aa = buf.readUInt8(i+6) @@ -3715,7 +3359,7 @@ function readKernings(buf, i, blockSize) { function readNameNT(buf, offset) { var pos=offset for (; pos 0 ) ? 1 : + x; + return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x; - }; + }; - } + } - if ( 'name' in Function.prototype === false ) { + if ( 'name' in Function.prototype === false ) { - // Missing in IE - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name + // Missing in IE + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name - Object.defineProperty( Function.prototype, 'name', { + Object.defineProperty( Function.prototype, 'name', { - get: function () { + get: function () { - return this.toString().match( /^\s*function\s*([^\(\s]*)/ )[ 1 ]; + return this.toString().match( /^\s*function\s*([^\(\s]*)/ )[ 1 ]; - } + } - } ); + } ); - } + } - if ( Object.assign === undefined ) { + if ( Object.assign === undefined ) { - // Missing in IE - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + // Missing in IE + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign - ( function () { + ( function () { - Object.assign = function ( target ) { + Object.assign = function ( target ) { - if ( target === undefined || target === null ) { + if ( target === undefined || target === null ) { - throw new TypeError( 'Cannot convert undefined or null to object' ); + throw new TypeError( 'Cannot convert undefined or null to object' ); - } + } - var output = Object( target ); + var output = Object( target ); - for ( var index = 1; index < arguments.length; index ++ ) { + for ( var index = 1; index < arguments.length; index ++ ) { - var source = arguments[ index ]; + var source = arguments[ index ]; - if ( source !== undefined && source !== null ) { + if ( source !== undefined && source !== null ) { - for ( var nextKey in source ) { + for ( var nextKey in source ) { - if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) { + if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) { - output[ nextKey ] = source[ nextKey ]; + output[ nextKey ] = source[ nextKey ]; - } + } - } + } - } + } - } + } - return output; + return output; - }; + }; - } )(); + } )(); - } + } - /** - * https://github.com/mrdoob/eventdispatcher.js/ - */ + /** + * https://github.com/mrdoob/eventdispatcher.js/ + */ - function EventDispatcher() {} + function EventDispatcher() {} - Object.assign( EventDispatcher.prototype, { + Object.assign( EventDispatcher.prototype, { - addEventListener: function ( type, listener ) { + addEventListener: function ( type, listener ) { - if ( this._listeners === undefined ) this._listeners = {}; + if ( this._listeners === undefined ) this._listeners = {}; - var listeners = this._listeners; + var listeners = this._listeners; - if ( listeners[ type ] === undefined ) { + if ( listeners[ type ] === undefined ) { - listeners[ type ] = []; + listeners[ type ] = []; - } + } - if ( listeners[ type ].indexOf( listener ) === - 1 ) { + if ( listeners[ type ].indexOf( listener ) === - 1 ) { - listeners[ type ].push( listener ); + listeners[ type ].push( listener ); - } + } - }, + }, - hasEventListener: function ( type, listener ) { + hasEventListener: function ( type, listener ) { - if ( this._listeners === undefined ) return false; + if ( this._listeners === undefined ) return false; - var listeners = this._listeners; + var listeners = this._listeners; - return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1; + return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1; - }, + }, - removeEventListener: function ( type, listener ) { + removeEventListener: function ( type, listener ) { - if ( this._listeners === undefined ) return; + if ( this._listeners === undefined ) return; - var listeners = this._listeners; - var listenerArray = listeners[ type ]; + var listeners = this._listeners; + var listenerArray = listeners[ type ]; - if ( listenerArray !== undefined ) { + if ( listenerArray !== undefined ) { - var index = listenerArray.indexOf( listener ); + var index = listenerArray.indexOf( listener ); - if ( index !== - 1 ) { + if ( index !== - 1 ) { - listenerArray.splice( index, 1 ); + listenerArray.splice( index, 1 ); - } + } - } + } - }, + }, - dispatchEvent: function ( event ) { + dispatchEvent: function ( event ) { - if ( this._listeners === undefined ) return; + if ( this._listeners === undefined ) return; - var listeners = this._listeners; - var listenerArray = listeners[ event.type ]; + var listeners = this._listeners; + var listenerArray = listeners[ event.type ]; - if ( listenerArray !== undefined ) { + if ( listenerArray !== undefined ) { - event.target = this; + event.target = this; - var array = listenerArray.slice( 0 ); + var array = listenerArray.slice( 0 ); - for ( var i = 0, l = array.length; i < l; i ++ ) { + for ( var i = 0, l = array.length; i < l; i ++ ) { - array[ i ].call( this, event ); + array[ i ].call( this, event ); - } + } - } + } - } + } - } ); - - var REVISION = '95'; - var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 }; - var CullFaceNone = 0; - var CullFaceBack = 1; - var CullFaceFront = 2; - var CullFaceFrontBack = 3; - var FrontFaceDirectionCW = 0; - var FrontFaceDirectionCCW = 1; - var BasicShadowMap = 0; - var PCFShadowMap = 1; - var PCFSoftShadowMap = 2; - var FrontSide = 0; - var BackSide = 1; - var DoubleSide = 2; - var FlatShading = 1; - var SmoothShading = 2; - var NoColors = 0; - var FaceColors = 1; - var VertexColors = 2; - var NoBlending = 0; - var NormalBlending = 1; - var AdditiveBlending = 2; - var SubtractiveBlending = 3; - var MultiplyBlending = 4; - var CustomBlending = 5; - var AddEquation = 100; - var SubtractEquation = 101; - var ReverseSubtractEquation = 102; - var MinEquation = 103; - var MaxEquation = 104; - var ZeroFactor = 200; - var OneFactor = 201; - var SrcColorFactor = 202; - var OneMinusSrcColorFactor = 203; - var SrcAlphaFactor = 204; - var OneMinusSrcAlphaFactor = 205; - var DstAlphaFactor = 206; - var OneMinusDstAlphaFactor = 207; - var DstColorFactor = 208; - var OneMinusDstColorFactor = 209; - var SrcAlphaSaturateFactor = 210; - var NeverDepth = 0; - var AlwaysDepth = 1; - var LessDepth = 2; - var LessEqualDepth = 3; - var EqualDepth = 4; - var GreaterEqualDepth = 5; - var GreaterDepth = 6; - var NotEqualDepth = 7; - var MultiplyOperation = 0; - var MixOperation = 1; - var AddOperation = 2; - var NoToneMapping = 0; - var LinearToneMapping = 1; - var ReinhardToneMapping = 2; - var Uncharted2ToneMapping = 3; - var CineonToneMapping = 4; - var UVMapping = 300; - var CubeReflectionMapping = 301; - var CubeRefractionMapping = 302; - var EquirectangularReflectionMapping = 303; - var EquirectangularRefractionMapping = 304; - var SphericalReflectionMapping = 305; - var CubeUVReflectionMapping = 306; - var CubeUVRefractionMapping = 307; - var RepeatWrapping = 1000; - var ClampToEdgeWrapping = 1001; - var MirroredRepeatWrapping = 1002; - var NearestFilter = 1003; - var NearestMipMapNearestFilter = 1004; - var NearestMipMapLinearFilter = 1005; - var LinearFilter = 1006; - var LinearMipMapNearestFilter = 1007; - var LinearMipMapLinearFilter = 1008; - var UnsignedByteType = 1009; - var ByteType = 1010; - var ShortType = 1011; - var UnsignedShortType = 1012; - var IntType = 1013; - var UnsignedIntType = 1014; - var FloatType = 1015; - var HalfFloatType = 1016; - var UnsignedShort4444Type = 1017; - var UnsignedShort5551Type = 1018; - var UnsignedShort565Type = 1019; - var UnsignedInt248Type = 1020; - var AlphaFormat = 1021; - var RGBFormat = 1022; - var RGBAFormat = 1023; - var LuminanceFormat = 1024; - var LuminanceAlphaFormat = 1025; - var RGBEFormat = RGBAFormat; - var DepthFormat = 1026; - var DepthStencilFormat = 1027; - var RGB_S3TC_DXT1_Format = 33776; - var RGBA_S3TC_DXT1_Format = 33777; - var RGBA_S3TC_DXT3_Format = 33778; - var RGBA_S3TC_DXT5_Format = 33779; - var RGB_PVRTC_4BPPV1_Format = 35840; - var RGB_PVRTC_2BPPV1_Format = 35841; - var RGBA_PVRTC_4BPPV1_Format = 35842; - var RGBA_PVRTC_2BPPV1_Format = 35843; - var RGB_ETC1_Format = 36196; - var RGBA_ASTC_4x4_Format = 37808; - var RGBA_ASTC_5x4_Format = 37809; - var RGBA_ASTC_5x5_Format = 37810; - var RGBA_ASTC_6x5_Format = 37811; - var RGBA_ASTC_6x6_Format = 37812; - var RGBA_ASTC_8x5_Format = 37813; - var RGBA_ASTC_8x6_Format = 37814; - var RGBA_ASTC_8x8_Format = 37815; - var RGBA_ASTC_10x5_Format = 37816; - var RGBA_ASTC_10x6_Format = 37817; - var RGBA_ASTC_10x8_Format = 37818; - var RGBA_ASTC_10x10_Format = 37819; - var RGBA_ASTC_12x10_Format = 37820; - var RGBA_ASTC_12x12_Format = 37821; - var LoopOnce = 2200; - var LoopRepeat = 2201; - var LoopPingPong = 2202; - var InterpolateDiscrete = 2300; - var InterpolateLinear = 2301; - var InterpolateSmooth = 2302; - var ZeroCurvatureEnding = 2400; - var ZeroSlopeEnding = 2401; - var WrapAroundEnding = 2402; - var TrianglesDrawMode = 0; - var TriangleStripDrawMode = 1; - var TriangleFanDrawMode = 2; - var LinearEncoding = 3000; - var sRGBEncoding = 3001; - var GammaEncoding = 3007; - var RGBEEncoding = 3002; - var LogLuvEncoding = 3003; - var RGBM7Encoding = 3004; - var RGBM16Encoding = 3005; - var RGBDEncoding = 3006; - var BasicDepthPacking = 3200; - var RGBADepthPacking = 3201; - var TangentSpaceNormalMap = 0; - var ObjectSpaceNormalMap = 1; - - /** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - */ - - var _Math = { - - DEG2RAD: Math.PI / 180, - RAD2DEG: 180 / Math.PI, - - generateUUID: ( function () { - - // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 + } ); + + var REVISION = '95'; + var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 }; + var CullFaceNone = 0; + var CullFaceBack = 1; + var CullFaceFront = 2; + var CullFaceFrontBack = 3; + var FrontFaceDirectionCW = 0; + var FrontFaceDirectionCCW = 1; + var BasicShadowMap = 0; + var PCFShadowMap = 1; + var PCFSoftShadowMap = 2; + var FrontSide = 0; + var BackSide = 1; + var DoubleSide = 2; + var FlatShading = 1; + var SmoothShading = 2; + var NoColors = 0; + var FaceColors = 1; + var VertexColors = 2; + var NoBlending = 0; + var NormalBlending = 1; + var AdditiveBlending = 2; + var SubtractiveBlending = 3; + var MultiplyBlending = 4; + var CustomBlending = 5; + var AddEquation = 100; + var SubtractEquation = 101; + var ReverseSubtractEquation = 102; + var MinEquation = 103; + var MaxEquation = 104; + var ZeroFactor = 200; + var OneFactor = 201; + var SrcColorFactor = 202; + var OneMinusSrcColorFactor = 203; + var SrcAlphaFactor = 204; + var OneMinusSrcAlphaFactor = 205; + var DstAlphaFactor = 206; + var OneMinusDstAlphaFactor = 207; + var DstColorFactor = 208; + var OneMinusDstColorFactor = 209; + var SrcAlphaSaturateFactor = 210; + var NeverDepth = 0; + var AlwaysDepth = 1; + var LessDepth = 2; + var LessEqualDepth = 3; + var EqualDepth = 4; + var GreaterEqualDepth = 5; + var GreaterDepth = 6; + var NotEqualDepth = 7; + var MultiplyOperation = 0; + var MixOperation = 1; + var AddOperation = 2; + var NoToneMapping = 0; + var LinearToneMapping = 1; + var ReinhardToneMapping = 2; + var Uncharted2ToneMapping = 3; + var CineonToneMapping = 4; + var UVMapping = 300; + var CubeReflectionMapping = 301; + var CubeRefractionMapping = 302; + var EquirectangularReflectionMapping = 303; + var EquirectangularRefractionMapping = 304; + var SphericalReflectionMapping = 305; + var CubeUVReflectionMapping = 306; + var CubeUVRefractionMapping = 307; + var RepeatWrapping = 1000; + var ClampToEdgeWrapping = 1001; + var MirroredRepeatWrapping = 1002; + var NearestFilter = 1003; + var NearestMipMapNearestFilter = 1004; + var NearestMipMapLinearFilter = 1005; + var LinearFilter = 1006; + var LinearMipMapNearestFilter = 1007; + var LinearMipMapLinearFilter = 1008; + var UnsignedByteType = 1009; + var ByteType = 1010; + var ShortType = 1011; + var UnsignedShortType = 1012; + var IntType = 1013; + var UnsignedIntType = 1014; + var FloatType = 1015; + var HalfFloatType = 1016; + var UnsignedShort4444Type = 1017; + var UnsignedShort5551Type = 1018; + var UnsignedShort565Type = 1019; + var UnsignedInt248Type = 1020; + var AlphaFormat = 1021; + var RGBFormat = 1022; + var RGBAFormat = 1023; + var LuminanceFormat = 1024; + var LuminanceAlphaFormat = 1025; + var RGBEFormat = RGBAFormat; + var DepthFormat = 1026; + var DepthStencilFormat = 1027; + var RGB_S3TC_DXT1_Format = 33776; + var RGBA_S3TC_DXT1_Format = 33777; + var RGBA_S3TC_DXT3_Format = 33778; + var RGBA_S3TC_DXT5_Format = 33779; + var RGB_PVRTC_4BPPV1_Format = 35840; + var RGB_PVRTC_2BPPV1_Format = 35841; + var RGBA_PVRTC_4BPPV1_Format = 35842; + var RGBA_PVRTC_2BPPV1_Format = 35843; + var RGB_ETC1_Format = 36196; + var RGBA_ASTC_4x4_Format = 37808; + var RGBA_ASTC_5x4_Format = 37809; + var RGBA_ASTC_5x5_Format = 37810; + var RGBA_ASTC_6x5_Format = 37811; + var RGBA_ASTC_6x6_Format = 37812; + var RGBA_ASTC_8x5_Format = 37813; + var RGBA_ASTC_8x6_Format = 37814; + var RGBA_ASTC_8x8_Format = 37815; + var RGBA_ASTC_10x5_Format = 37816; + var RGBA_ASTC_10x6_Format = 37817; + var RGBA_ASTC_10x8_Format = 37818; + var RGBA_ASTC_10x10_Format = 37819; + var RGBA_ASTC_12x10_Format = 37820; + var RGBA_ASTC_12x12_Format = 37821; + var LoopOnce = 2200; + var LoopRepeat = 2201; + var LoopPingPong = 2202; + var InterpolateDiscrete = 2300; + var InterpolateLinear = 2301; + var InterpolateSmooth = 2302; + var ZeroCurvatureEnding = 2400; + var ZeroSlopeEnding = 2401; + var WrapAroundEnding = 2402; + var TrianglesDrawMode = 0; + var TriangleStripDrawMode = 1; + var TriangleFanDrawMode = 2; + var LinearEncoding = 3000; + var sRGBEncoding = 3001; + var GammaEncoding = 3007; + var RGBEEncoding = 3002; + var LogLuvEncoding = 3003; + var RGBM7Encoding = 3004; + var RGBM16Encoding = 3005; + var RGBDEncoding = 3006; + var BasicDepthPacking = 3200; + var RGBADepthPacking = 3201; + var TangentSpaceNormalMap = 0; + var ObjectSpaceNormalMap = 1; + + /** + * @author alteredq / http://alteredqualia.com/ + * @author mrdoob / http://mrdoob.com/ + */ + + var _Math = { + + DEG2RAD: Math.PI / 180, + RAD2DEG: 180 / Math.PI, + + generateUUID: ( function () { + + // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 - var lut = []; + var lut = []; - for ( var i = 0; i < 256; i ++ ) { + for ( var i = 0; i < 256; i ++ ) { - lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 ); + lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 ); - } + } - return function generateUUID() { + return function generateUUID() { - var d0 = Math.random() * 0xffffffff | 0; - var d1 = Math.random() * 0xffffffff | 0; - var d2 = Math.random() * 0xffffffff | 0; - var d3 = Math.random() * 0xffffffff | 0; - var uuid = lut[ d0 & 0xff ] + lut[ d0 >> 8 & 0xff ] + lut[ d0 >> 16 & 0xff ] + lut[ d0 >> 24 & 0xff ] + '-' + - lut[ d1 & 0xff ] + lut[ d1 >> 8 & 0xff ] + '-' + lut[ d1 >> 16 & 0x0f | 0x40 ] + lut[ d1 >> 24 & 0xff ] + '-' + - lut[ d2 & 0x3f | 0x80 ] + lut[ d2 >> 8 & 0xff ] + '-' + lut[ d2 >> 16 & 0xff ] + lut[ d2 >> 24 & 0xff ] + - lut[ d3 & 0xff ] + lut[ d3 >> 8 & 0xff ] + lut[ d3 >> 16 & 0xff ] + lut[ d3 >> 24 & 0xff ]; + var d0 = Math.random() * 0xffffffff | 0; + var d1 = Math.random() * 0xffffffff | 0; + var d2 = Math.random() * 0xffffffff | 0; + var d3 = Math.random() * 0xffffffff | 0; + var uuid = lut[ d0 & 0xff ] + lut[ d0 >> 8 & 0xff ] + lut[ d0 >> 16 & 0xff ] + lut[ d0 >> 24 & 0xff ] + '-' + + lut[ d1 & 0xff ] + lut[ d1 >> 8 & 0xff ] + '-' + lut[ d1 >> 16 & 0x0f | 0x40 ] + lut[ d1 >> 24 & 0xff ] + '-' + + lut[ d2 & 0x3f | 0x80 ] + lut[ d2 >> 8 & 0xff ] + '-' + lut[ d2 >> 16 & 0xff ] + lut[ d2 >> 24 & 0xff ] + + lut[ d3 & 0xff ] + lut[ d3 >> 8 & 0xff ] + lut[ d3 >> 16 & 0xff ] + lut[ d3 >> 24 & 0xff ]; - // .toUpperCase() here flattens concatenated strings to save heap memory space. - return uuid.toUpperCase(); + // .toUpperCase() here flattens concatenated strings to save heap memory space. + return uuid.toUpperCase(); - }; + }; - } )(), + } )(), - clamp: function ( value, min, max ) { + clamp: function ( value, min, max ) { - return Math.max( min, Math.min( max, value ) ); + return Math.max( min, Math.min( max, value ) ); - }, + }, - // compute euclidian modulo of m % n - // https://en.wikipedia.org/wiki/Modulo_operation + // compute euclidian modulo of m % n + // https://en.wikipedia.org/wiki/Modulo_operation - euclideanModulo: function ( n, m ) { + euclideanModulo: function ( n, m ) { - return ( ( n % m ) + m ) % m; + return ( ( n % m ) + m ) % m; - }, + }, - // Linear mapping from range to range + // Linear mapping from range to range - mapLinear: function ( x, a1, a2, b1, b2 ) { + mapLinear: function ( x, a1, a2, b1, b2 ) { - return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 ); + return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 ); - }, + }, - // https://en.wikipedia.org/wiki/Linear_interpolation + // https://en.wikipedia.org/wiki/Linear_interpolation - lerp: function ( x, y, t ) { + lerp: function ( x, y, t ) { - return ( 1 - t ) * x + t * y; + return ( 1 - t ) * x + t * y; - }, + }, - // http://en.wikipedia.org/wiki/Smoothstep + // http://en.wikipedia.org/wiki/Smoothstep - smoothstep: function ( x, min, max ) { + smoothstep: function ( x, min, max ) { - if ( x <= min ) return 0; - if ( x >= max ) return 1; + if ( x <= min ) return 0; + if ( x >= max ) return 1; - x = ( x - min ) / ( max - min ); + x = ( x - min ) / ( max - min ); - return x * x * ( 3 - 2 * x ); + return x * x * ( 3 - 2 * x ); - }, + }, - smootherstep: function ( x, min, max ) { + smootherstep: function ( x, min, max ) { - if ( x <= min ) return 0; - if ( x >= max ) return 1; + if ( x <= min ) return 0; + if ( x >= max ) return 1; - x = ( x - min ) / ( max - min ); + x = ( x - min ) / ( max - min ); - return x * x * x * ( x * ( x * 6 - 15 ) + 10 ); + return x * x * x * ( x * ( x * 6 - 15 ) + 10 ); - }, + }, - // Random integer from interval + // Random integer from interval - randInt: function ( low, high ) { + randInt: function ( low, high ) { - return low + Math.floor( Math.random() * ( high - low + 1 ) ); + return low + Math.floor( Math.random() * ( high - low + 1 ) ); - }, + }, - // Random float from interval + // Random float from interval - randFloat: function ( low, high ) { + randFloat: function ( low, high ) { - return low + Math.random() * ( high - low ); + return low + Math.random() * ( high - low ); - }, + }, - // Random float from <-range/2, range/2> interval + // Random float from <-range/2, range/2> interval - randFloatSpread: function ( range ) { + randFloatSpread: function ( range ) { - return range * ( 0.5 - Math.random() ); + return range * ( 0.5 - Math.random() ); - }, + }, - degToRad: function ( degrees ) { + degToRad: function ( degrees ) { - return degrees * _Math.DEG2RAD; + return degrees * _Math.DEG2RAD; - }, + }, - radToDeg: function ( radians ) { + radToDeg: function ( radians ) { - return radians * _Math.RAD2DEG; + return radians * _Math.RAD2DEG; - }, + }, - isPowerOfTwo: function ( value ) { + isPowerOfTwo: function ( value ) { - return ( value & ( value - 1 ) ) === 0 && value !== 0; + return ( value & ( value - 1 ) ) === 0 && value !== 0; - }, + }, - ceilPowerOfTwo: function ( value ) { + ceilPowerOfTwo: function ( value ) { - return Math.pow( 2, Math.ceil( Math.log( value ) / Math.LN2 ) ); + return Math.pow( 2, Math.ceil( Math.log( value ) / Math.LN2 ) ); - }, + }, - floorPowerOfTwo: function ( value ) { + floorPowerOfTwo: function ( value ) { - return Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) ); + return Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) ); - } + } - }; + }; - /** - * @author mrdoob / http://mrdoob.com/ - * @author philogb / http://blog.thejit.org/ - * @author egraether / http://egraether.com/ - * @author zz85 / http://www.lab4games.net/zz85/blog - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author philogb / http://blog.thejit.org/ + * @author egraether / http://egraether.com/ + * @author zz85 / http://www.lab4games.net/zz85/blog + */ - function Vector2( x, y ) { + function Vector2( x, y ) { - this.x = x || 0; - this.y = y || 0; + this.x = x || 0; + this.y = y || 0; - } + } - Object.defineProperties( Vector2.prototype, { + Object.defineProperties( Vector2.prototype, { - "width": { + "width": { - get: function () { + get: function () { - return this.x; + return this.x; - }, + }, - set: function ( value ) { + set: function ( value ) { - this.x = value; + this.x = value; - } + } - }, + }, - "height": { + "height": { - get: function () { + get: function () { - return this.y; + return this.y; - }, + }, - set: function ( value ) { + set: function ( value ) { - this.y = value; + this.y = value; - } + } - } + } - } ); + } ); - Object.assign( Vector2.prototype, { + Object.assign( Vector2.prototype, { - isVector2: true, + isVector2: true, - set: function ( x, y ) { + set: function ( x, y ) { - this.x = x; - this.y = y; + this.x = x; + this.y = y; - return this; + return this; - }, + }, - setScalar: function ( scalar ) { + setScalar: function ( scalar ) { - this.x = scalar; - this.y = scalar; + this.x = scalar; + this.y = scalar; - return this; + return this; - }, + }, - setX: function ( x ) { + setX: function ( x ) { - this.x = x; + this.x = x; - return this; + return this; - }, + }, - setY: function ( y ) { + setY: function ( y ) { - this.y = y; + this.y = y; - return this; + return this; - }, + }, - setComponent: function ( index, value ) { + setComponent: function ( index, value ) { - switch ( index ) { + switch ( index ) { - case 0: this.x = value; break; - case 1: this.y = value; break; - default: throw new Error( 'index is out of range: ' + index ); + case 0: this.x = value; break; + case 1: this.y = value; break; + default: throw new Error( 'index is out of range: ' + index ); - } + } - return this; + return this; - }, + }, - getComponent: function ( index ) { + getComponent: function ( index ) { - switch ( index ) { + switch ( index ) { - case 0: return this.x; - case 1: return this.y; - default: throw new Error( 'index is out of range: ' + index ); + case 0: return this.x; + case 1: return this.y; + default: throw new Error( 'index is out of range: ' + index ); - } + } - }, + }, - clone: function () { + clone: function () { - return new this.constructor( this.x, this.y ); + return new this.constructor( this.x, this.y ); - }, + }, - copy: function ( v ) { + copy: function ( v ) { - this.x = v.x; - this.y = v.y; + this.x = v.x; + this.y = v.y; - return this; + return this; - }, + }, - add: function ( v, w ) { + add: function ( v, w ) { - if ( w !== undefined ) { + if ( w !== undefined ) { - console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); - return this.addVectors( v, w ); + console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + return this.addVectors( v, w ); - } + } - this.x += v.x; - this.y += v.y; + this.x += v.x; + this.y += v.y; - return this; + return this; - }, + }, - addScalar: function ( s ) { + addScalar: function ( s ) { - this.x += s; - this.y += s; + this.x += s; + this.y += s; - return this; + return this; - }, + }, - addVectors: function ( a, b ) { + addVectors: function ( a, b ) { - this.x = a.x + b.x; - this.y = a.y + b.y; + this.x = a.x + b.x; + this.y = a.y + b.y; - return this; + return this; - }, + }, - addScaledVector: function ( v, s ) { + addScaledVector: function ( v, s ) { - this.x += v.x * s; - this.y += v.y * s; + this.x += v.x * s; + this.y += v.y * s; - return this; + return this; - }, + }, - sub: function ( v, w ) { + sub: function ( v, w ) { - if ( w !== undefined ) { + if ( w !== undefined ) { - console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); - return this.subVectors( v, w ); + console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + return this.subVectors( v, w ); - } + } - this.x -= v.x; - this.y -= v.y; + this.x -= v.x; + this.y -= v.y; - return this; + return this; - }, + }, - subScalar: function ( s ) { + subScalar: function ( s ) { - this.x -= s; - this.y -= s; + this.x -= s; + this.y -= s; - return this; + return this; - }, + }, - subVectors: function ( a, b ) { + subVectors: function ( a, b ) { - this.x = a.x - b.x; - this.y = a.y - b.y; + this.x = a.x - b.x; + this.y = a.y - b.y; - return this; + return this; - }, + }, - multiply: function ( v ) { + multiply: function ( v ) { - this.x *= v.x; - this.y *= v.y; + this.x *= v.x; + this.y *= v.y; - return this; + return this; - }, + }, - multiplyScalar: function ( scalar ) { + multiplyScalar: function ( scalar ) { - this.x *= scalar; - this.y *= scalar; + this.x *= scalar; + this.y *= scalar; - return this; + return this; - }, + }, - divide: function ( v ) { + divide: function ( v ) { - this.x /= v.x; - this.y /= v.y; + this.x /= v.x; + this.y /= v.y; - return this; + return this; - }, + }, - divideScalar: function ( scalar ) { + divideScalar: function ( scalar ) { - return this.multiplyScalar( 1 / scalar ); + return this.multiplyScalar( 1 / scalar ); - }, + }, - applyMatrix3: function ( m ) { + applyMatrix3: function ( m ) { - var x = this.x, y = this.y; - var e = m.elements; + var x = this.x, y = this.y; + var e = m.elements; - this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ]; - this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ]; + this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ]; + this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ]; - return this; + return this; - }, + }, - min: function ( v ) { + min: function ( v ) { - this.x = Math.min( this.x, v.x ); - this.y = Math.min( this.y, v.y ); + this.x = Math.min( this.x, v.x ); + this.y = Math.min( this.y, v.y ); - return this; + return this; - }, + }, - max: function ( v ) { + max: function ( v ) { - this.x = Math.max( this.x, v.x ); - this.y = Math.max( this.y, v.y ); + this.x = Math.max( this.x, v.x ); + this.y = Math.max( this.y, v.y ); - return this; + return this; - }, + }, - clamp: function ( min, max ) { + clamp: function ( min, max ) { - // assumes min < max, componentwise + // assumes min < max, componentwise - this.x = Math.max( min.x, Math.min( max.x, this.x ) ); - this.y = Math.max( min.y, Math.min( max.y, this.y ) ); + this.x = Math.max( min.x, Math.min( max.x, this.x ) ); + this.y = Math.max( min.y, Math.min( max.y, this.y ) ); - return this; + return this; - }, + }, - clampScalar: function () { + clampScalar: function () { - var min = new Vector2(); - var max = new Vector2(); + var min = new Vector2(); + var max = new Vector2(); - return function clampScalar( minVal, maxVal ) { + return function clampScalar( minVal, maxVal ) { - min.set( minVal, minVal ); - max.set( maxVal, maxVal ); + min.set( minVal, minVal ); + max.set( maxVal, maxVal ); - return this.clamp( min, max ); + return this.clamp( min, max ); - }; + }; - }(), + }(), - clampLength: function ( min, max ) { + clampLength: function ( min, max ) { - var length = this.length(); + var length = this.length(); - return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); + return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); - }, + }, - floor: function () { + floor: function () { - this.x = Math.floor( this.x ); - this.y = Math.floor( this.y ); + this.x = Math.floor( this.x ); + this.y = Math.floor( this.y ); - return this; + return this; - }, + }, - ceil: function () { + ceil: function () { - this.x = Math.ceil( this.x ); - this.y = Math.ceil( this.y ); + this.x = Math.ceil( this.x ); + this.y = Math.ceil( this.y ); - return this; + return this; - }, + }, - round: function () { + round: function () { - this.x = Math.round( this.x ); - this.y = Math.round( this.y ); + this.x = Math.round( this.x ); + this.y = Math.round( this.y ); - return this; + return this; - }, + }, - roundToZero: function () { + roundToZero: function () { - this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); - this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); + this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); + this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); - return this; + return this; - }, + }, - negate: function () { + negate: function () { - this.x = - this.x; - this.y = - this.y; + this.x = - this.x; + this.y = - this.y; - return this; + return this; - }, + }, - dot: function ( v ) { + dot: function ( v ) { - return this.x * v.x + this.y * v.y; + return this.x * v.x + this.y * v.y; - }, + }, - cross: function ( v ) { + cross: function ( v ) { - return this.x * v.y - this.y * v.x; + return this.x * v.y - this.y * v.x; - }, + }, - lengthSq: function () { + lengthSq: function () { - return this.x * this.x + this.y * this.y; + return this.x * this.x + this.y * this.y; - }, + }, - length: function () { + length: function () { - return Math.sqrt( this.x * this.x + this.y * this.y ); + return Math.sqrt( this.x * this.x + this.y * this.y ); - }, + }, - manhattanLength: function () { + manhattanLength: function () { - return Math.abs( this.x ) + Math.abs( this.y ); + return Math.abs( this.x ) + Math.abs( this.y ); - }, + }, - normalize: function () { + normalize: function () { - return this.divideScalar( this.length() || 1 ); + return this.divideScalar( this.length() || 1 ); - }, + }, - angle: function () { + angle: function () { - // computes the angle in radians with respect to the positive x-axis + // computes the angle in radians with respect to the positive x-axis - var angle = Math.atan2( this.y, this.x ); + var angle = Math.atan2( this.y, this.x ); - if ( angle < 0 ) angle += 2 * Math.PI; + if ( angle < 0 ) angle += 2 * Math.PI; - return angle; + return angle; - }, + }, - distanceTo: function ( v ) { + distanceTo: function ( v ) { - return Math.sqrt( this.distanceToSquared( v ) ); + return Math.sqrt( this.distanceToSquared( v ) ); - }, + }, - distanceToSquared: function ( v ) { + distanceToSquared: function ( v ) { - var dx = this.x - v.x, dy = this.y - v.y; - return dx * dx + dy * dy; + var dx = this.x - v.x, dy = this.y - v.y; + return dx * dx + dy * dy; - }, + }, - manhattanDistanceTo: function ( v ) { + manhattanDistanceTo: function ( v ) { - return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ); + return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ); - }, + }, - setLength: function ( length ) { + setLength: function ( length ) { - return this.normalize().multiplyScalar( length ); + return this.normalize().multiplyScalar( length ); - }, + }, - lerp: function ( v, alpha ) { + lerp: function ( v, alpha ) { - this.x += ( v.x - this.x ) * alpha; - this.y += ( v.y - this.y ) * alpha; + this.x += ( v.x - this.x ) * alpha; + this.y += ( v.y - this.y ) * alpha; - return this; + return this; - }, + }, - lerpVectors: function ( v1, v2, alpha ) { + lerpVectors: function ( v1, v2, alpha ) { - return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); + return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); - }, + }, - equals: function ( v ) { + equals: function ( v ) { - return ( ( v.x === this.x ) && ( v.y === this.y ) ); + return ( ( v.x === this.x ) && ( v.y === this.y ) ); - }, + }, - fromArray: function ( array, offset ) { + fromArray: function ( array, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - this.x = array[ offset ]; - this.y = array[ offset + 1 ]; + this.x = array[ offset ]; + this.y = array[ offset + 1 ]; - return this; + return this; - }, + }, - toArray: function ( array, offset ) { + toArray: function ( array, offset ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - array[ offset ] = this.x; - array[ offset + 1 ] = this.y; + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; - return array; + return array; - }, + }, - fromBufferAttribute: function ( attribute, index, offset ) { + fromBufferAttribute: function ( attribute, index, offset ) { - if ( offset !== undefined ) { + if ( offset !== undefined ) { - console.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' ); + console.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' ); - } + } - this.x = attribute.getX( index ); - this.y = attribute.getY( index ); + this.x = attribute.getX( index ); + this.y = attribute.getY( index ); - return this; + return this; - }, + }, - rotateAround: function ( center, angle ) { + rotateAround: function ( center, angle ) { - var c = Math.cos( angle ), s = Math.sin( angle ); + var c = Math.cos( angle ), s = Math.sin( angle ); - var x = this.x - center.x; - var y = this.y - center.y; + var x = this.x - center.x; + var y = this.y - center.y; - this.x = x * c - y * s + center.x; - this.y = x * s + y * c + center.y; + this.x = x * c - y * s + center.x; + this.y = x * s + y * c + center.y; - return this; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author supereggbert / http://www.paulbrunt.co.uk/ - * @author philogb / http://blog.thejit.org/ - * @author jordi_ros / http://plattsoft.com - * @author D1plo1d / http://github.com/D1plo1d - * @author alteredq / http://alteredqualia.com/ - * @author mikael emtinger / http://gomo.se/ - * @author timknip / http://www.floorplanner.com/ - * @author bhouston / http://clara.io - * @author WestLangley / http://github.com/WestLangley - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author supereggbert / http://www.paulbrunt.co.uk/ + * @author philogb / http://blog.thejit.org/ + * @author jordi_ros / http://plattsoft.com + * @author D1plo1d / http://github.com/D1plo1d + * @author alteredq / http://alteredqualia.com/ + * @author mikael emtinger / http://gomo.se/ + * @author timknip / http://www.floorplanner.com/ + * @author bhouston / http://clara.io + * @author WestLangley / http://github.com/WestLangley + */ - function Matrix4() { + function Matrix4() { - this.elements = [ + this.elements = [ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 - ]; + ]; - if ( arguments.length > 0 ) { + if ( arguments.length > 0 ) { - console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' ); + console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' ); - } + } - } + } - Object.assign( Matrix4.prototype, { + Object.assign( Matrix4.prototype, { - isMatrix4: true, + isMatrix4: true, - set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { + set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { - var te = this.elements; + var te = this.elements; - te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; - te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; - te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; - te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; + te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; + te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; + te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; + te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; - return this; + return this; - }, + }, - identity: function () { + identity: function () { - this.set( + this.set( - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 - ); + ); - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new Matrix4().fromArray( this.elements ); + return new Matrix4().fromArray( this.elements ); - }, + }, - copy: function ( m ) { + copy: function ( m ) { - var te = this.elements; - var me = m.elements; + var te = this.elements; + var me = m.elements; - te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ]; - te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; - te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ]; - te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ]; + te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ]; + te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; + te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ]; + te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ]; - return this; + return this; - }, + }, - copyPosition: function ( m ) { + copyPosition: function ( m ) { - var te = this.elements, me = m.elements; + var te = this.elements, me = m.elements; - te[ 12 ] = me[ 12 ]; - te[ 13 ] = me[ 13 ]; - te[ 14 ] = me[ 14 ]; + te[ 12 ] = me[ 12 ]; + te[ 13 ] = me[ 13 ]; + te[ 14 ] = me[ 14 ]; - return this; + return this; - }, + }, - extractBasis: function ( xAxis, yAxis, zAxis ) { + extractBasis: function ( xAxis, yAxis, zAxis ) { - xAxis.setFromMatrixColumn( this, 0 ); - yAxis.setFromMatrixColumn( this, 1 ); - zAxis.setFromMatrixColumn( this, 2 ); + xAxis.setFromMatrixColumn( this, 0 ); + yAxis.setFromMatrixColumn( this, 1 ); + zAxis.setFromMatrixColumn( this, 2 ); - return this; + return this; - }, + }, - makeBasis: function ( xAxis, yAxis, zAxis ) { + makeBasis: function ( xAxis, yAxis, zAxis ) { - this.set( - xAxis.x, yAxis.x, zAxis.x, 0, - xAxis.y, yAxis.y, zAxis.y, 0, - xAxis.z, yAxis.z, zAxis.z, 0, - 0, 0, 0, 1 - ); + this.set( + xAxis.x, yAxis.x, zAxis.x, 0, + xAxis.y, yAxis.y, zAxis.y, 0, + xAxis.z, yAxis.z, zAxis.z, 0, + 0, 0, 0, 1 + ); - return this; + return this; - }, + }, - extractRotation: function () { + extractRotation: function () { - var v1 = new Vector3(); + var v1 = new Vector3(); - return function extractRotation( m ) { + return function extractRotation( m ) { - // this method does not support reflection matrices + // this method does not support reflection matrices - var te = this.elements; - var me = m.elements; + var te = this.elements; + var me = m.elements; - var scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length(); - var scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length(); - var scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length(); + var scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length(); + var scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length(); + var scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length(); - te[ 0 ] = me[ 0 ] * scaleX; - te[ 1 ] = me[ 1 ] * scaleX; - te[ 2 ] = me[ 2 ] * scaleX; - te[ 3 ] = 0; + te[ 0 ] = me[ 0 ] * scaleX; + te[ 1 ] = me[ 1 ] * scaleX; + te[ 2 ] = me[ 2 ] * scaleX; + te[ 3 ] = 0; - te[ 4 ] = me[ 4 ] * scaleY; - te[ 5 ] = me[ 5 ] * scaleY; - te[ 6 ] = me[ 6 ] * scaleY; - te[ 7 ] = 0; + te[ 4 ] = me[ 4 ] * scaleY; + te[ 5 ] = me[ 5 ] * scaleY; + te[ 6 ] = me[ 6 ] * scaleY; + te[ 7 ] = 0; - te[ 8 ] = me[ 8 ] * scaleZ; - te[ 9 ] = me[ 9 ] * scaleZ; - te[ 10 ] = me[ 10 ] * scaleZ; - te[ 11 ] = 0; + te[ 8 ] = me[ 8 ] * scaleZ; + te[ 9 ] = me[ 9 ] * scaleZ; + te[ 10 ] = me[ 10 ] * scaleZ; + te[ 11 ] = 0; - te[ 12 ] = 0; - te[ 13 ] = 0; - te[ 14 ] = 0; - te[ 15 ] = 1; + te[ 12 ] = 0; + te[ 13 ] = 0; + te[ 14 ] = 0; + te[ 15 ] = 1; - return this; + return this; - }; + }; - }(), + }(), - makeRotationFromEuler: function ( euler ) { + makeRotationFromEuler: function ( euler ) { - if ( ! ( euler && euler.isEuler ) ) { + if ( ! ( euler && euler.isEuler ) ) { - console.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' ); + console.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' ); - } + } - var te = this.elements; + var te = this.elements; - var x = euler.x, y = euler.y, z = euler.z; - var a = Math.cos( x ), b = Math.sin( x ); - var c = Math.cos( y ), d = Math.sin( y ); - var e = Math.cos( z ), f = Math.sin( z ); + var x = euler.x, y = euler.y, z = euler.z; + var a = Math.cos( x ), b = Math.sin( x ); + var c = Math.cos( y ), d = Math.sin( y ); + var e = Math.cos( z ), f = Math.sin( z ); - if ( euler.order === 'XYZ' ) { + if ( euler.order === 'XYZ' ) { - var ae = a * e, af = a * f, be = b * e, bf = b * f; + var ae = a * e, af = a * f, be = b * e, bf = b * f; - te[ 0 ] = c * e; - te[ 4 ] = - c * f; - te[ 8 ] = d; + te[ 0 ] = c * e; + te[ 4 ] = - c * f; + te[ 8 ] = d; - te[ 1 ] = af + be * d; - te[ 5 ] = ae - bf * d; - te[ 9 ] = - b * c; + te[ 1 ] = af + be * d; + te[ 5 ] = ae - bf * d; + te[ 9 ] = - b * c; - te[ 2 ] = bf - ae * d; - te[ 6 ] = be + af * d; - te[ 10 ] = a * c; + te[ 2 ] = bf - ae * d; + te[ 6 ] = be + af * d; + te[ 10 ] = a * c; - } else if ( euler.order === 'YXZ' ) { + } else if ( euler.order === 'YXZ' ) { - var ce = c * e, cf = c * f, de = d * e, df = d * f; + var ce = c * e, cf = c * f, de = d * e, df = d * f; - te[ 0 ] = ce + df * b; - te[ 4 ] = de * b - cf; - te[ 8 ] = a * d; + te[ 0 ] = ce + df * b; + te[ 4 ] = de * b - cf; + te[ 8 ] = a * d; - te[ 1 ] = a * f; - te[ 5 ] = a * e; - te[ 9 ] = - b; + te[ 1 ] = a * f; + te[ 5 ] = a * e; + te[ 9 ] = - b; - te[ 2 ] = cf * b - de; - te[ 6 ] = df + ce * b; - te[ 10 ] = a * c; + te[ 2 ] = cf * b - de; + te[ 6 ] = df + ce * b; + te[ 10 ] = a * c; - } else if ( euler.order === 'ZXY' ) { + } else if ( euler.order === 'ZXY' ) { - var ce = c * e, cf = c * f, de = d * e, df = d * f; + var ce = c * e, cf = c * f, de = d * e, df = d * f; - te[ 0 ] = ce - df * b; - te[ 4 ] = - a * f; - te[ 8 ] = de + cf * b; + te[ 0 ] = ce - df * b; + te[ 4 ] = - a * f; + te[ 8 ] = de + cf * b; - te[ 1 ] = cf + de * b; - te[ 5 ] = a * e; - te[ 9 ] = df - ce * b; + te[ 1 ] = cf + de * b; + te[ 5 ] = a * e; + te[ 9 ] = df - ce * b; - te[ 2 ] = - a * d; - te[ 6 ] = b; - te[ 10 ] = a * c; + te[ 2 ] = - a * d; + te[ 6 ] = b; + te[ 10 ] = a * c; - } else if ( euler.order === 'ZYX' ) { + } else if ( euler.order === 'ZYX' ) { - var ae = a * e, af = a * f, be = b * e, bf = b * f; + var ae = a * e, af = a * f, be = b * e, bf = b * f; - te[ 0 ] = c * e; - te[ 4 ] = be * d - af; - te[ 8 ] = ae * d + bf; + te[ 0 ] = c * e; + te[ 4 ] = be * d - af; + te[ 8 ] = ae * d + bf; - te[ 1 ] = c * f; - te[ 5 ] = bf * d + ae; - te[ 9 ] = af * d - be; + te[ 1 ] = c * f; + te[ 5 ] = bf * d + ae; + te[ 9 ] = af * d - be; - te[ 2 ] = - d; - te[ 6 ] = b * c; - te[ 10 ] = a * c; + te[ 2 ] = - d; + te[ 6 ] = b * c; + te[ 10 ] = a * c; - } else if ( euler.order === 'YZX' ) { + } else if ( euler.order === 'YZX' ) { - var ac = a * c, ad = a * d, bc = b * c, bd = b * d; + var ac = a * c, ad = a * d, bc = b * c, bd = b * d; - te[ 0 ] = c * e; - te[ 4 ] = bd - ac * f; - te[ 8 ] = bc * f + ad; + te[ 0 ] = c * e; + te[ 4 ] = bd - ac * f; + te[ 8 ] = bc * f + ad; - te[ 1 ] = f; - te[ 5 ] = a * e; - te[ 9 ] = - b * e; + te[ 1 ] = f; + te[ 5 ] = a * e; + te[ 9 ] = - b * e; - te[ 2 ] = - d * e; - te[ 6 ] = ad * f + bc; - te[ 10 ] = ac - bd * f; + te[ 2 ] = - d * e; + te[ 6 ] = ad * f + bc; + te[ 10 ] = ac - bd * f; - } else if ( euler.order === 'XZY' ) { + } else if ( euler.order === 'XZY' ) { - var ac = a * c, ad = a * d, bc = b * c, bd = b * d; + var ac = a * c, ad = a * d, bc = b * c, bd = b * d; - te[ 0 ] = c * e; - te[ 4 ] = - f; - te[ 8 ] = d * e; + te[ 0 ] = c * e; + te[ 4 ] = - f; + te[ 8 ] = d * e; - te[ 1 ] = ac * f + bd; - te[ 5 ] = a * e; - te[ 9 ] = ad * f - bc; + te[ 1 ] = ac * f + bd; + te[ 5 ] = a * e; + te[ 9 ] = ad * f - bc; - te[ 2 ] = bc * f - ad; - te[ 6 ] = b * e; - te[ 10 ] = bd * f + ac; + te[ 2 ] = bc * f - ad; + te[ 6 ] = b * e; + te[ 10 ] = bd * f + ac; - } + } - // bottom row - te[ 3 ] = 0; - te[ 7 ] = 0; - te[ 11 ] = 0; + // bottom row + te[ 3 ] = 0; + te[ 7 ] = 0; + te[ 11 ] = 0; - // last column - te[ 12 ] = 0; - te[ 13 ] = 0; - te[ 14 ] = 0; - te[ 15 ] = 1; + // last column + te[ 12 ] = 0; + te[ 13 ] = 0; + te[ 14 ] = 0; + te[ 15 ] = 1; - return this; + return this; - }, + }, - makeRotationFromQuaternion: function () { + makeRotationFromQuaternion: function () { - var zero = new Vector3( 0, 0, 0 ); - var one = new Vector3( 1, 1, 1 ); + var zero = new Vector3( 0, 0, 0 ); + var one = new Vector3( 1, 1, 1 ); - return function makeRotationFromQuaternion( q ) { + return function makeRotationFromQuaternion( q ) { - return this.compose( zero, q, one ); + return this.compose( zero, q, one ); - }; + }; - }(), + }(), - lookAt: function () { + lookAt: function () { - var x = new Vector3(); - var y = new Vector3(); - var z = new Vector3(); + var x = new Vector3(); + var y = new Vector3(); + var z = new Vector3(); - return function lookAt( eye, target, up ) { + return function lookAt( eye, target, up ) { - var te = this.elements; + var te = this.elements; - z.subVectors( eye, target ); + z.subVectors( eye, target ); - if ( z.lengthSq() === 0 ) { + if ( z.lengthSq() === 0 ) { - // eye and target are in the same position + // eye and target are in the same position - z.z = 1; + z.z = 1; - } + } - z.normalize(); - x.crossVectors( up, z ); + z.normalize(); + x.crossVectors( up, z ); - if ( x.lengthSq() === 0 ) { + if ( x.lengthSq() === 0 ) { - // up and z are parallel + // up and z are parallel - if ( Math.abs( up.z ) === 1 ) { + if ( Math.abs( up.z ) === 1 ) { - z.x += 0.0001; + z.x += 0.0001; - } else { + } else { - z.z += 0.0001; + z.z += 0.0001; - } + } - z.normalize(); - x.crossVectors( up, z ); + z.normalize(); + x.crossVectors( up, z ); - } + } - x.normalize(); - y.crossVectors( z, x ); + x.normalize(); + y.crossVectors( z, x ); - te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x; - te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y; - te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z; + te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x; + te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y; + te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z; - return this; + return this; - }; + }; - }(), + }(), - multiply: function ( m, n ) { + multiply: function ( m, n ) { - if ( n !== undefined ) { + if ( n !== undefined ) { - console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); - return this.multiplyMatrices( m, n ); + console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); + return this.multiplyMatrices( m, n ); - } + } - return this.multiplyMatrices( this, m ); + return this.multiplyMatrices( this, m ); - }, + }, - premultiply: function ( m ) { + premultiply: function ( m ) { - return this.multiplyMatrices( m, this ); + return this.multiplyMatrices( m, this ); - }, + }, - multiplyMatrices: function ( a, b ) { + multiplyMatrices: function ( a, b ) { - var ae = a.elements; - var be = b.elements; - var te = this.elements; + var ae = a.elements; + var be = b.elements; + var te = this.elements; - var a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ]; - var a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ]; - var a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ]; - var a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ]; + var a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ]; + var a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ]; + var a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ]; + var a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ]; - var b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ]; - var b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ]; - var b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ]; - var b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ]; + var b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ]; + var b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ]; + var b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ]; + var b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ]; - te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; - te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; - te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; - te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; + te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; + te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; + te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; + te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; - te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; - te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; - te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; - te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; + te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; + te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; + te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; + te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; - te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; - te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; - te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; - te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; + te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; + te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; + te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; + te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; - te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; - te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; - te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; - te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; + te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; + te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; + te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; + te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; - return this; + return this; - }, + }, - multiplyScalar: function ( s ) { + multiplyScalar: function ( s ) { - var te = this.elements; + var te = this.elements; - te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s; - te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s; - te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s; - te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s; + te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s; + te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s; + te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s; + te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s; - return this; + return this; - }, + }, - applyToBufferAttribute: function () { + applyToBufferAttribute: function () { - var v1 = new Vector3(); + var v1 = new Vector3(); - return function applyToBufferAttribute( attribute ) { + return function applyToBufferAttribute( attribute ) { - for ( var i = 0, l = attribute.count; i < l; i ++ ) { + for ( var i = 0, l = attribute.count; i < l; i ++ ) { - v1.x = attribute.getX( i ); - v1.y = attribute.getY( i ); - v1.z = attribute.getZ( i ); + v1.x = attribute.getX( i ); + v1.y = attribute.getY( i ); + v1.z = attribute.getZ( i ); - v1.applyMatrix4( this ); + v1.applyMatrix4( this ); - attribute.setXYZ( i, v1.x, v1.y, v1.z ); + attribute.setXYZ( i, v1.x, v1.y, v1.z ); - } + } - return attribute; + return attribute; - }; + }; - }(), + }(), - determinant: function () { + determinant: function () { - var te = this.elements; + var te = this.elements; - var n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ]; - var n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ]; - var n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ]; - var n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ]; + var n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ]; + var n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ]; + var n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ]; + var n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ]; - //TODO: make this more efficient - //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) + //TODO: make this more efficient + //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) - return ( - n41 * ( - + n14 * n23 * n32 - - n13 * n24 * n32 - - n14 * n22 * n33 - + n12 * n24 * n33 - + n13 * n22 * n34 - - n12 * n23 * n34 - ) + - n42 * ( - + n11 * n23 * n34 - - n11 * n24 * n33 - + n14 * n21 * n33 - - n13 * n21 * n34 - + n13 * n24 * n31 - - n14 * n23 * n31 - ) + - n43 * ( - + n11 * n24 * n32 - - n11 * n22 * n34 - - n14 * n21 * n32 - + n12 * n21 * n34 - + n14 * n22 * n31 - - n12 * n24 * n31 - ) + - n44 * ( - - n13 * n22 * n31 - - n11 * n23 * n32 - + n11 * n22 * n33 - + n13 * n21 * n32 - - n12 * n21 * n33 - + n12 * n23 * n31 - ) + return ( + n41 * ( + + n14 * n23 * n32 + - n13 * n24 * n32 + - n14 * n22 * n33 + + n12 * n24 * n33 + + n13 * n22 * n34 + - n12 * n23 * n34 + ) + + n42 * ( + + n11 * n23 * n34 + - n11 * n24 * n33 + + n14 * n21 * n33 + - n13 * n21 * n34 + + n13 * n24 * n31 + - n14 * n23 * n31 + ) + + n43 * ( + + n11 * n24 * n32 + - n11 * n22 * n34 + - n14 * n21 * n32 + + n12 * n21 * n34 + + n14 * n22 * n31 + - n12 * n24 * n31 + ) + + n44 * ( + - n13 * n22 * n31 + - n11 * n23 * n32 + + n11 * n22 * n33 + + n13 * n21 * n32 + - n12 * n21 * n33 + + n12 * n23 * n31 + ) - ); + ); - }, + }, - transpose: function () { + transpose: function () { - var te = this.elements; - var tmp; + var te = this.elements; + var tmp; - tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp; - tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp; - tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp; + tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp; + tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp; + tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp; - tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp; - tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp; - tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp; + tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp; + tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp; + tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp; - return this; + return this; - }, + }, - setPosition: function ( v ) { + setPosition: function ( v ) { - var te = this.elements; + var te = this.elements; - te[ 12 ] = v.x; - te[ 13 ] = v.y; - te[ 14 ] = v.z; + te[ 12 ] = v.x; + te[ 13 ] = v.y; + te[ 14 ] = v.z; - return this; + return this; - }, + }, - getInverse: function ( m, throwOnDegenerate ) { + getInverse: function ( m, throwOnDegenerate ) { - // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm - var te = this.elements, - me = m.elements, + // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm + var te = this.elements, + me = m.elements, - n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ], - n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ], - n13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ], - n14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ], + n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ], + n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ], + n13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ], + n14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ], - t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, - t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, - t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, - t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; + t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, + t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, + t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, + t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; - var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; + var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; - if ( det === 0 ) { + if ( det === 0 ) { - var msg = "THREE.Matrix4: .getInverse() can't invert matrix, determinant is 0"; + var msg = "THREE.Matrix4: .getInverse() can't invert matrix, determinant is 0"; - if ( throwOnDegenerate === true ) { + if ( throwOnDegenerate === true ) { - throw new Error( msg ); + throw new Error( msg ); - } else { + } else { - console.warn( msg ); + console.warn( msg ); - } + } - return this.identity(); + return this.identity(); - } + } - var detInv = 1 / det; + var detInv = 1 / det; - te[ 0 ] = t11 * detInv; - te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv; - te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv; - te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv; + te[ 0 ] = t11 * detInv; + te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv; + te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv; + te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv; - te[ 4 ] = t12 * detInv; - te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv; - te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv; - te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv; + te[ 4 ] = t12 * detInv; + te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv; + te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv; + te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv; - te[ 8 ] = t13 * detInv; - te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv; - te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv; - te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv; + te[ 8 ] = t13 * detInv; + te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv; + te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv; + te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv; - te[ 12 ] = t14 * detInv; - te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv; - te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv; - te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv; + te[ 12 ] = t14 * detInv; + te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv; + te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv; + te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv; - return this; + return this; - }, + }, - scale: function ( v ) { + scale: function ( v ) { - var te = this.elements; - var x = v.x, y = v.y, z = v.z; + var te = this.elements; + var x = v.x, y = v.y, z = v.z; - te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z; - te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z; - te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z; - te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z; + te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z; + te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z; + te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z; + te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z; - return this; + return this; - }, + }, - getMaxScaleOnAxis: function () { + getMaxScaleOnAxis: function () { - var te = this.elements; + var te = this.elements; - var scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ]; - var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ]; - var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ]; + var scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ]; + var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ]; + var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ]; - return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) ); + return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) ); - }, + }, - makeTranslation: function ( x, y, z ) { + makeTranslation: function ( x, y, z ) { - this.set( + this.set( - 1, 0, 0, x, - 0, 1, 0, y, - 0, 0, 1, z, - 0, 0, 0, 1 + 1, 0, 0, x, + 0, 1, 0, y, + 0, 0, 1, z, + 0, 0, 0, 1 - ); + ); - return this; + return this; - }, + }, - makeRotationX: function ( theta ) { + makeRotationX: function ( theta ) { - var c = Math.cos( theta ), s = Math.sin( theta ); + var c = Math.cos( theta ), s = Math.sin( theta ); - this.set( + this.set( - 1, 0, 0, 0, - 0, c, - s, 0, - 0, s, c, 0, - 0, 0, 0, 1 + 1, 0, 0, 0, + 0, c, - s, 0, + 0, s, c, 0, + 0, 0, 0, 1 - ); + ); - return this; + return this; - }, + }, - makeRotationY: function ( theta ) { + makeRotationY: function ( theta ) { - var c = Math.cos( theta ), s = Math.sin( theta ); + var c = Math.cos( theta ), s = Math.sin( theta ); - this.set( + this.set( - c, 0, s, 0, - 0, 1, 0, 0, - - s, 0, c, 0, - 0, 0, 0, 1 + c, 0, s, 0, + 0, 1, 0, 0, + - s, 0, c, 0, + 0, 0, 0, 1 - ); + ); - return this; + return this; - }, + }, - makeRotationZ: function ( theta ) { + makeRotationZ: function ( theta ) { - var c = Math.cos( theta ), s = Math.sin( theta ); + var c = Math.cos( theta ), s = Math.sin( theta ); - this.set( + this.set( - c, - s, 0, 0, - s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + c, - s, 0, 0, + s, c, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 - ); + ); - return this; + return this; - }, + }, - makeRotationAxis: function ( axis, angle ) { + makeRotationAxis: function ( axis, angle ) { - // Based on http://www.gamedev.net/reference/articles/article1199.asp + // Based on http://www.gamedev.net/reference/articles/article1199.asp - var c = Math.cos( angle ); - var s = Math.sin( angle ); - var t = 1 - c; - var x = axis.x, y = axis.y, z = axis.z; - var tx = t * x, ty = t * y; + var c = Math.cos( angle ); + var s = Math.sin( angle ); + var t = 1 - c; + var x = axis.x, y = axis.y, z = axis.z; + var tx = t * x, ty = t * y; - this.set( + this.set( - tx * x + c, tx * y - s * z, tx * z + s * y, 0, - tx * y + s * z, ty * y + c, ty * z - s * x, 0, - tx * z - s * y, ty * z + s * x, t * z * z + c, 0, - 0, 0, 0, 1 + tx * x + c, tx * y - s * z, tx * z + s * y, 0, + tx * y + s * z, ty * y + c, ty * z - s * x, 0, + tx * z - s * y, ty * z + s * x, t * z * z + c, 0, + 0, 0, 0, 1 - ); + ); - return this; + return this; - }, + }, - makeScale: function ( x, y, z ) { + makeScale: function ( x, y, z ) { - this.set( + this.set( - x, 0, 0, 0, - 0, y, 0, 0, - 0, 0, z, 0, - 0, 0, 0, 1 + x, 0, 0, 0, + 0, y, 0, 0, + 0, 0, z, 0, + 0, 0, 0, 1 - ); + ); - return this; + return this; - }, + }, - makeShear: function ( x, y, z ) { + makeShear: function ( x, y, z ) { - this.set( + this.set( - 1, y, z, 0, - x, 1, z, 0, - x, y, 1, 0, - 0, 0, 0, 1 + 1, y, z, 0, + x, 1, z, 0, + x, y, 1, 0, + 0, 0, 0, 1 - ); + ); - return this; + return this; - }, + }, - compose: function ( position, quaternion, scale ) { + compose: function ( position, quaternion, scale ) { - var te = this.elements; + var te = this.elements; - var x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; - var x2 = x + x, y2 = y + y, z2 = z + z; - var xx = x * x2, xy = x * y2, xz = x * z2; - var yy = y * y2, yz = y * z2, zz = z * z2; - var wx = w * x2, wy = w * y2, wz = w * z2; + var x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; + var x2 = x + x, y2 = y + y, z2 = z + z; + var xx = x * x2, xy = x * y2, xz = x * z2; + var yy = y * y2, yz = y * z2, zz = z * z2; + var wx = w * x2, wy = w * y2, wz = w * z2; - var sx = scale.x, sy = scale.y, sz = scale.z; + var sx = scale.x, sy = scale.y, sz = scale.z; - te[ 0 ] = ( 1 - ( yy + zz ) ) * sx; - te[ 1 ] = ( xy + wz ) * sx; - te[ 2 ] = ( xz - wy ) * sx; - te[ 3 ] = 0; + te[ 0 ] = ( 1 - ( yy + zz ) ) * sx; + te[ 1 ] = ( xy + wz ) * sx; + te[ 2 ] = ( xz - wy ) * sx; + te[ 3 ] = 0; - te[ 4 ] = ( xy - wz ) * sy; - te[ 5 ] = ( 1 - ( xx + zz ) ) * sy; - te[ 6 ] = ( yz + wx ) * sy; - te[ 7 ] = 0; + te[ 4 ] = ( xy - wz ) * sy; + te[ 5 ] = ( 1 - ( xx + zz ) ) * sy; + te[ 6 ] = ( yz + wx ) * sy; + te[ 7 ] = 0; - te[ 8 ] = ( xz + wy ) * sz; - te[ 9 ] = ( yz - wx ) * sz; - te[ 10 ] = ( 1 - ( xx + yy ) ) * sz; - te[ 11 ] = 0; + te[ 8 ] = ( xz + wy ) * sz; + te[ 9 ] = ( yz - wx ) * sz; + te[ 10 ] = ( 1 - ( xx + yy ) ) * sz; + te[ 11 ] = 0; - te[ 12 ] = position.x; - te[ 13 ] = position.y; - te[ 14 ] = position.z; - te[ 15 ] = 1; + te[ 12 ] = position.x; + te[ 13 ] = position.y; + te[ 14 ] = position.z; + te[ 15 ] = 1; - return this; + return this; - }, + }, - decompose: function () { + decompose: function () { - var vector = new Vector3(); - var matrix = new Matrix4(); + var vector = new Vector3(); + var matrix = new Matrix4(); - return function decompose( position, quaternion, scale ) { + return function decompose( position, quaternion, scale ) { - var te = this.elements; + var te = this.elements; - var sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length(); - var sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length(); - var sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length(); + var sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length(); + var sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length(); + var sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length(); - // if determine is negative, we need to invert one scale - var det = this.determinant(); - if ( det < 0 ) sx = - sx; + // if determine is negative, we need to invert one scale + var det = this.determinant(); + if ( det < 0 ) sx = - sx; - position.x = te[ 12 ]; - position.y = te[ 13 ]; - position.z = te[ 14 ]; + position.x = te[ 12 ]; + position.y = te[ 13 ]; + position.z = te[ 14 ]; - // scale the rotation part - matrix.copy( this ); + // scale the rotation part + matrix.copy( this ); - var invSX = 1 / sx; - var invSY = 1 / sy; - var invSZ = 1 / sz; + var invSX = 1 / sx; + var invSY = 1 / sy; + var invSZ = 1 / sz; - matrix.elements[ 0 ] *= invSX; - matrix.elements[ 1 ] *= invSX; - matrix.elements[ 2 ] *= invSX; + matrix.elements[ 0 ] *= invSX; + matrix.elements[ 1 ] *= invSX; + matrix.elements[ 2 ] *= invSX; - matrix.elements[ 4 ] *= invSY; - matrix.elements[ 5 ] *= invSY; - matrix.elements[ 6 ] *= invSY; + matrix.elements[ 4 ] *= invSY; + matrix.elements[ 5 ] *= invSY; + matrix.elements[ 6 ] *= invSY; - matrix.elements[ 8 ] *= invSZ; - matrix.elements[ 9 ] *= invSZ; - matrix.elements[ 10 ] *= invSZ; + matrix.elements[ 8 ] *= invSZ; + matrix.elements[ 9 ] *= invSZ; + matrix.elements[ 10 ] *= invSZ; - quaternion.setFromRotationMatrix( matrix ); + quaternion.setFromRotationMatrix( matrix ); - scale.x = sx; - scale.y = sy; - scale.z = sz; + scale.x = sx; + scale.y = sy; + scale.z = sz; - return this; + return this; - }; + }; - }(), + }(), - makePerspective: function ( left, right, top, bottom, near, far ) { + makePerspective: function ( left, right, top, bottom, near, far ) { - if ( far === undefined ) { + if ( far === undefined ) { - console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' ); + console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' ); - } + } - var te = this.elements; - var x = 2 * near / ( right - left ); - var y = 2 * near / ( top - bottom ); + var te = this.elements; + var x = 2 * near / ( right - left ); + var y = 2 * near / ( top - bottom ); - var a = ( right + left ) / ( right - left ); - var b = ( top + bottom ) / ( top - bottom ); - var c = - ( far + near ) / ( far - near ); - var d = - 2 * far * near / ( far - near ); + var a = ( right + left ) / ( right - left ); + var b = ( top + bottom ) / ( top - bottom ); + var c = - ( far + near ) / ( far - near ); + var d = - 2 * far * near / ( far - near ); - te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0; - te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0; - te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; - te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0; + te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0; + te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0; + te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; + te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0; - return this; + return this; - }, + }, - makeOrthographic: function ( left, right, top, bottom, near, far ) { + makeOrthographic: function ( left, right, top, bottom, near, far ) { - var te = this.elements; - var w = 1.0 / ( right - left ); - var h = 1.0 / ( top - bottom ); - var p = 1.0 / ( far - near ); + var te = this.elements; + var w = 1.0 / ( right - left ); + var h = 1.0 / ( top - bottom ); + var p = 1.0 / ( far - near ); - var x = ( right + left ) * w; - var y = ( top + bottom ) * h; - var z = ( far + near ) * p; + var x = ( right + left ) * w; + var y = ( top + bottom ) * h; + var z = ( far + near ) * p; - te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x; - te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y; - te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z; - te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1; + te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x; + te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y; + te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z; + te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1; - return this; + return this; - }, + }, - equals: function ( matrix ) { + equals: function ( matrix ) { - var te = this.elements; - var me = matrix.elements; + var te = this.elements; + var me = matrix.elements; - for ( var i = 0; i < 16; i ++ ) { + for ( var i = 0; i < 16; i ++ ) { - if ( te[ i ] !== me[ i ] ) return false; + if ( te[ i ] !== me[ i ] ) return false; - } + } - return true; + return true; - }, + }, - fromArray: function ( array, offset ) { + fromArray: function ( array, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - for ( var i = 0; i < 16; i ++ ) { + for ( var i = 0; i < 16; i ++ ) { - this.elements[ i ] = array[ i + offset ]; + this.elements[ i ] = array[ i + offset ]; - } + } - return this; + return this; - }, + }, - toArray: function ( array, offset ) { + toArray: function ( array, offset ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - var te = this.elements; + var te = this.elements; - array[ offset ] = te[ 0 ]; - array[ offset + 1 ] = te[ 1 ]; - array[ offset + 2 ] = te[ 2 ]; - array[ offset + 3 ] = te[ 3 ]; + array[ offset ] = te[ 0 ]; + array[ offset + 1 ] = te[ 1 ]; + array[ offset + 2 ] = te[ 2 ]; + array[ offset + 3 ] = te[ 3 ]; - array[ offset + 4 ] = te[ 4 ]; - array[ offset + 5 ] = te[ 5 ]; - array[ offset + 6 ] = te[ 6 ]; - array[ offset + 7 ] = te[ 7 ]; + array[ offset + 4 ] = te[ 4 ]; + array[ offset + 5 ] = te[ 5 ]; + array[ offset + 6 ] = te[ 6 ]; + array[ offset + 7 ] = te[ 7 ]; - array[ offset + 8 ] = te[ 8 ]; - array[ offset + 9 ] = te[ 9 ]; - array[ offset + 10 ] = te[ 10 ]; - array[ offset + 11 ] = te[ 11 ]; + array[ offset + 8 ] = te[ 8 ]; + array[ offset + 9 ] = te[ 9 ]; + array[ offset + 10 ] = te[ 10 ]; + array[ offset + 11 ] = te[ 11 ]; - array[ offset + 12 ] = te[ 12 ]; - array[ offset + 13 ] = te[ 13 ]; - array[ offset + 14 ] = te[ 14 ]; - array[ offset + 15 ] = te[ 15 ]; + array[ offset + 12 ] = te[ 12 ]; + array[ offset + 13 ] = te[ 13 ]; + array[ offset + 14 ] = te[ 14 ]; + array[ offset + 15 ] = te[ 15 ]; - return array; + return array; - } + } - } ); + } ); - /** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - * @author WestLangley / http://github.com/WestLangley - * @author bhouston / http://clara.io - */ + /** + * @author mikael emtinger / http://gomo.se/ + * @author alteredq / http://alteredqualia.com/ + * @author WestLangley / http://github.com/WestLangley + * @author bhouston / http://clara.io + */ - function Quaternion( x, y, z, w ) { + function Quaternion( x, y, z, w ) { - this._x = x || 0; - this._y = y || 0; - this._z = z || 0; - this._w = ( w !== undefined ) ? w : 1; + this._x = x || 0; + this._y = y || 0; + this._z = z || 0; + this._w = ( w !== undefined ) ? w : 1; - } + } - Object.assign( Quaternion, { + Object.assign( Quaternion, { - slerp: function ( qa, qb, qm, t ) { + slerp: function ( qa, qb, qm, t ) { - return qm.copy( qa ).slerp( qb, t ); + return qm.copy( qa ).slerp( qb, t ); - }, + }, - slerpFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { + slerpFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { - // fuzz-free, array-based Quaternion SLERP operation + // fuzz-free, array-based Quaternion SLERP operation - var x0 = src0[ srcOffset0 + 0 ], - y0 = src0[ srcOffset0 + 1 ], - z0 = src0[ srcOffset0 + 2 ], - w0 = src0[ srcOffset0 + 3 ], + var x0 = src0[ srcOffset0 + 0 ], + y0 = src0[ srcOffset0 + 1 ], + z0 = src0[ srcOffset0 + 2 ], + w0 = src0[ srcOffset0 + 3 ], - x1 = src1[ srcOffset1 + 0 ], - y1 = src1[ srcOffset1 + 1 ], - z1 = src1[ srcOffset1 + 2 ], - w1 = src1[ srcOffset1 + 3 ]; + x1 = src1[ srcOffset1 + 0 ], + y1 = src1[ srcOffset1 + 1 ], + z1 = src1[ srcOffset1 + 2 ], + w1 = src1[ srcOffset1 + 3 ]; - if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) { + if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) { - var s = 1 - t, + var s = 1 - t, - cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, + cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, - dir = ( cos >= 0 ? 1 : - 1 ), - sqrSin = 1 - cos * cos; + dir = ( cos >= 0 ? 1 : - 1 ), + sqrSin = 1 - cos * cos; - // Skip the Slerp for tiny steps to avoid numeric problems: - if ( sqrSin > Number.EPSILON ) { + // Skip the Slerp for tiny steps to avoid numeric problems: + if ( sqrSin > Number.EPSILON ) { - var sin = Math.sqrt( sqrSin ), - len = Math.atan2( sin, cos * dir ); + var sin = Math.sqrt( sqrSin ), + len = Math.atan2( sin, cos * dir ); - s = Math.sin( s * len ) / sin; - t = Math.sin( t * len ) / sin; + s = Math.sin( s * len ) / sin; + t = Math.sin( t * len ) / sin; - } + } - var tDir = t * dir; + var tDir = t * dir; - x0 = x0 * s + x1 * tDir; - y0 = y0 * s + y1 * tDir; - z0 = z0 * s + z1 * tDir; - w0 = w0 * s + w1 * tDir; + x0 = x0 * s + x1 * tDir; + y0 = y0 * s + y1 * tDir; + z0 = z0 * s + z1 * tDir; + w0 = w0 * s + w1 * tDir; - // Normalize in case we just did a lerp: - if ( s === 1 - t ) { + // Normalize in case we just did a lerp: + if ( s === 1 - t ) { - var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 ); + var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 ); - x0 *= f; - y0 *= f; - z0 *= f; - w0 *= f; + x0 *= f; + y0 *= f; + z0 *= f; + w0 *= f; - } + } - } + } - dst[ dstOffset ] = x0; - dst[ dstOffset + 1 ] = y0; - dst[ dstOffset + 2 ] = z0; - dst[ dstOffset + 3 ] = w0; + dst[ dstOffset ] = x0; + dst[ dstOffset + 1 ] = y0; + dst[ dstOffset + 2 ] = z0; + dst[ dstOffset + 3 ] = w0; - } + } - } ); + } ); - Object.defineProperties( Quaternion.prototype, { + Object.defineProperties( Quaternion.prototype, { - x: { + x: { - get: function () { + get: function () { - return this._x; + return this._x; - }, + }, - set: function ( value ) { + set: function ( value ) { - this._x = value; - this.onChangeCallback(); + this._x = value; + this.onChangeCallback(); - } + } - }, + }, - y: { + y: { - get: function () { + get: function () { - return this._y; + return this._y; - }, + }, - set: function ( value ) { + set: function ( value ) { - this._y = value; - this.onChangeCallback(); + this._y = value; + this.onChangeCallback(); - } + } - }, + }, - z: { + z: { - get: function () { + get: function () { - return this._z; + return this._z; - }, + }, - set: function ( value ) { + set: function ( value ) { - this._z = value; - this.onChangeCallback(); + this._z = value; + this.onChangeCallback(); - } + } - }, + }, - w: { + w: { - get: function () { + get: function () { - return this._w; + return this._w; - }, + }, - set: function ( value ) { + set: function ( value ) { - this._w = value; - this.onChangeCallback(); + this._w = value; + this.onChangeCallback(); - } + } - } + } - } ); + } ); - Object.assign( Quaternion.prototype, { + Object.assign( Quaternion.prototype, { - set: function ( x, y, z, w ) { + set: function ( x, y, z, w ) { - this._x = x; - this._y = y; - this._z = z; - this._w = w; + this._x = x; + this._y = y; + this._z = z; + this._w = w; - this.onChangeCallback(); + this.onChangeCallback(); - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new this.constructor( this._x, this._y, this._z, this._w ); + return new this.constructor( this._x, this._y, this._z, this._w ); - }, + }, - copy: function ( quaternion ) { + copy: function ( quaternion ) { - this._x = quaternion.x; - this._y = quaternion.y; - this._z = quaternion.z; - this._w = quaternion.w; + this._x = quaternion.x; + this._y = quaternion.y; + this._z = quaternion.z; + this._w = quaternion.w; - this.onChangeCallback(); + this.onChangeCallback(); - return this; + return this; - }, + }, - setFromEuler: function ( euler, update ) { + setFromEuler: function ( euler, update ) { - if ( ! ( euler && euler.isEuler ) ) { + if ( ! ( euler && euler.isEuler ) ) { - throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' ); + throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' ); - } + } - var x = euler._x, y = euler._y, z = euler._z, order = euler.order; + var x = euler._x, y = euler._y, z = euler._z, order = euler.order; - // http://www.mathworks.com/matlabcentral/fileexchange/ - // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ - // content/SpinCalc.m + // http://www.mathworks.com/matlabcentral/fileexchange/ + // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ + // content/SpinCalc.m - var cos = Math.cos; - var sin = Math.sin; + var cos = Math.cos; + var sin = Math.sin; - var c1 = cos( x / 2 ); - var c2 = cos( y / 2 ); - var c3 = cos( z / 2 ); + var c1 = cos( x / 2 ); + var c2 = cos( y / 2 ); + var c3 = cos( z / 2 ); - var s1 = sin( x / 2 ); - var s2 = sin( y / 2 ); - var s3 = sin( z / 2 ); + var s1 = sin( x / 2 ); + var s2 = sin( y / 2 ); + var s3 = sin( z / 2 ); - if ( order === 'XYZ' ) { + if ( order === 'XYZ' ) { - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; + this._x = s1 * c2 * c3 + c1 * s2 * s3; + this._y = c1 * s2 * c3 - s1 * c2 * s3; + this._z = c1 * c2 * s3 + s1 * s2 * c3; + this._w = c1 * c2 * c3 - s1 * s2 * s3; - } else if ( order === 'YXZ' ) { + } else if ( order === 'YXZ' ) { - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; + this._x = s1 * c2 * c3 + c1 * s2 * s3; + this._y = c1 * s2 * c3 - s1 * c2 * s3; + this._z = c1 * c2 * s3 - s1 * s2 * c3; + this._w = c1 * c2 * c3 + s1 * s2 * s3; - } else if ( order === 'ZXY' ) { + } else if ( order === 'ZXY' ) { - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; + this._x = s1 * c2 * c3 - c1 * s2 * s3; + this._y = c1 * s2 * c3 + s1 * c2 * s3; + this._z = c1 * c2 * s3 + s1 * s2 * c3; + this._w = c1 * c2 * c3 - s1 * s2 * s3; - } else if ( order === 'ZYX' ) { + } else if ( order === 'ZYX' ) { - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; + this._x = s1 * c2 * c3 - c1 * s2 * s3; + this._y = c1 * s2 * c3 + s1 * c2 * s3; + this._z = c1 * c2 * s3 - s1 * s2 * c3; + this._w = c1 * c2 * c3 + s1 * s2 * s3; - } else if ( order === 'YZX' ) { + } else if ( order === 'YZX' ) { - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; + this._x = s1 * c2 * c3 + c1 * s2 * s3; + this._y = c1 * s2 * c3 + s1 * c2 * s3; + this._z = c1 * c2 * s3 - s1 * s2 * c3; + this._w = c1 * c2 * c3 - s1 * s2 * s3; - } else if ( order === 'XZY' ) { + } else if ( order === 'XZY' ) { - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; + this._x = s1 * c2 * c3 - c1 * s2 * s3; + this._y = c1 * s2 * c3 - s1 * c2 * s3; + this._z = c1 * c2 * s3 + s1 * s2 * c3; + this._w = c1 * c2 * c3 + s1 * s2 * s3; - } + } - if ( update !== false ) this.onChangeCallback(); + if ( update !== false ) this.onChangeCallback(); - return this; + return this; - }, + }, - setFromAxisAngle: function ( axis, angle ) { + setFromAxisAngle: function ( axis, angle ) { - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm - // assumes axis is normalized + // assumes axis is normalized - var halfAngle = angle / 2, s = Math.sin( halfAngle ); + var halfAngle = angle / 2, s = Math.sin( halfAngle ); - this._x = axis.x * s; - this._y = axis.y * s; - this._z = axis.z * s; - this._w = Math.cos( halfAngle ); + this._x = axis.x * s; + this._y = axis.y * s; + this._z = axis.z * s; + this._w = Math.cos( halfAngle ); - this.onChangeCallback(); + this.onChangeCallback(); - return this; + return this; - }, + }, - setFromRotationMatrix: function ( m ) { + setFromRotationMatrix: function ( m ) { - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - var te = m.elements, + var te = m.elements, - m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], - m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], - m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ], + m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], + m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], + m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ], - trace = m11 + m22 + m33, - s; + trace = m11 + m22 + m33, + s; - if ( trace > 0 ) { + if ( trace > 0 ) { - s = 0.5 / Math.sqrt( trace + 1.0 ); + s = 0.5 / Math.sqrt( trace + 1.0 ); - this._w = 0.25 / s; - this._x = ( m32 - m23 ) * s; - this._y = ( m13 - m31 ) * s; - this._z = ( m21 - m12 ) * s; + this._w = 0.25 / s; + this._x = ( m32 - m23 ) * s; + this._y = ( m13 - m31 ) * s; + this._z = ( m21 - m12 ) * s; - } else if ( m11 > m22 && m11 > m33 ) { + } else if ( m11 > m22 && m11 > m33 ) { - s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 ); + s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 ); - this._w = ( m32 - m23 ) / s; - this._x = 0.25 * s; - this._y = ( m12 + m21 ) / s; - this._z = ( m13 + m31 ) / s; + this._w = ( m32 - m23 ) / s; + this._x = 0.25 * s; + this._y = ( m12 + m21 ) / s; + this._z = ( m13 + m31 ) / s; - } else if ( m22 > m33 ) { + } else if ( m22 > m33 ) { - s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 ); + s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 ); - this._w = ( m13 - m31 ) / s; - this._x = ( m12 + m21 ) / s; - this._y = 0.25 * s; - this._z = ( m23 + m32 ) / s; + this._w = ( m13 - m31 ) / s; + this._x = ( m12 + m21 ) / s; + this._y = 0.25 * s; + this._z = ( m23 + m32 ) / s; - } else { + } else { - s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 ); + s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 ); - this._w = ( m21 - m12 ) / s; - this._x = ( m13 + m31 ) / s; - this._y = ( m23 + m32 ) / s; - this._z = 0.25 * s; + this._w = ( m21 - m12 ) / s; + this._x = ( m13 + m31 ) / s; + this._y = ( m23 + m32 ) / s; + this._z = 0.25 * s; - } + } - this.onChangeCallback(); + this.onChangeCallback(); - return this; + return this; - }, + }, - setFromUnitVectors: function () { + setFromUnitVectors: function () { - // assumes direction vectors vFrom and vTo are normalized + // assumes direction vectors vFrom and vTo are normalized - var v1 = new Vector3(); - var r; + var v1 = new Vector3(); + var r; - var EPS = 0.000001; + var EPS = 0.000001; - return function setFromUnitVectors( vFrom, vTo ) { + return function setFromUnitVectors( vFrom, vTo ) { - if ( v1 === undefined ) v1 = new Vector3(); + if ( v1 === undefined ) v1 = new Vector3(); - r = vFrom.dot( vTo ) + 1; + r = vFrom.dot( vTo ) + 1; - if ( r < EPS ) { + if ( r < EPS ) { - r = 0; + r = 0; - if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) { + if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) { - v1.set( - vFrom.y, vFrom.x, 0 ); + v1.set( - vFrom.y, vFrom.x, 0 ); - } else { + } else { - v1.set( 0, - vFrom.z, vFrom.y ); + v1.set( 0, - vFrom.z, vFrom.y ); - } + } - } else { + } else { - v1.crossVectors( vFrom, vTo ); + v1.crossVectors( vFrom, vTo ); - } + } - this._x = v1.x; - this._y = v1.y; - this._z = v1.z; - this._w = r; + this._x = v1.x; + this._y = v1.y; + this._z = v1.z; + this._w = r; - return this.normalize(); + return this.normalize(); - }; + }; - }(), + }(), - angleTo: function ( q ) { + angleTo: function ( q ) { - return 2 * Math.acos( Math.abs( _Math.clamp( this.dot( q ), - 1, 1 ) ) ); + return 2 * Math.acos( Math.abs( _Math.clamp( this.dot( q ), - 1, 1 ) ) ); - }, + }, - rotateTowards: function ( q, step ) { + rotateTowards: function ( q, step ) { - var angle = this.angleTo( q ); + var angle = this.angleTo( q ); - if ( angle === 0 ) return this; + if ( angle === 0 ) return this; - var t = Math.min( 1, step / angle ); + var t = Math.min( 1, step / angle ); - this.slerp( q, t ); + this.slerp( q, t ); - return this; + return this; - }, + }, - inverse: function () { + inverse: function () { - // quaternion is assumed to have unit length + // quaternion is assumed to have unit length - return this.conjugate(); + return this.conjugate(); - }, + }, - conjugate: function () { + conjugate: function () { - this._x *= - 1; - this._y *= - 1; - this._z *= - 1; + this._x *= - 1; + this._y *= - 1; + this._z *= - 1; - this.onChangeCallback(); + this.onChangeCallback(); - return this; + return this; - }, + }, - dot: function ( v ) { + dot: function ( v ) { - return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; + return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; - }, + }, - lengthSq: function () { + lengthSq: function () { - return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; + return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; - }, + }, - length: function () { + length: function () { - return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w ); + return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w ); - }, + }, - normalize: function () { + normalize: function () { - var l = this.length(); + var l = this.length(); - if ( l === 0 ) { + if ( l === 0 ) { - this._x = 0; - this._y = 0; - this._z = 0; - this._w = 1; + this._x = 0; + this._y = 0; + this._z = 0; + this._w = 1; - } else { + } else { - l = 1 / l; + l = 1 / l; - this._x = this._x * l; - this._y = this._y * l; - this._z = this._z * l; - this._w = this._w * l; + this._x = this._x * l; + this._y = this._y * l; + this._z = this._z * l; + this._w = this._w * l; - } + } - this.onChangeCallback(); + this.onChangeCallback(); - return this; + return this; - }, + }, - multiply: function ( q, p ) { + multiply: function ( q, p ) { - if ( p !== undefined ) { + if ( p !== undefined ) { - console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); - return this.multiplyQuaternions( q, p ); + console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); + return this.multiplyQuaternions( q, p ); - } + } - return this.multiplyQuaternions( this, q ); + return this.multiplyQuaternions( this, q ); - }, + }, - premultiply: function ( q ) { + premultiply: function ( q ) { - return this.multiplyQuaternions( q, this ); + return this.multiplyQuaternions( q, this ); - }, + }, - multiplyQuaternions: function ( a, b ) { + multiplyQuaternions: function ( a, b ) { - // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm + // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm - var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; - var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; + var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; + var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; - this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; - this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; - this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; - this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; + this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; + this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; + this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; + this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; - this.onChangeCallback(); + this.onChangeCallback(); - return this; + return this; - }, + }, - slerp: function ( qb, t ) { + slerp: function ( qb, t ) { - if ( t === 0 ) return this; - if ( t === 1 ) return this.copy( qb ); + if ( t === 0 ) return this; + if ( t === 1 ) return this.copy( qb ); - var x = this._x, y = this._y, z = this._z, w = this._w; + var x = this._x, y = this._y, z = this._z, w = this._w; - // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ - var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; + var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; - if ( cosHalfTheta < 0 ) { + if ( cosHalfTheta < 0 ) { - this._w = - qb._w; - this._x = - qb._x; - this._y = - qb._y; - this._z = - qb._z; + this._w = - qb._w; + this._x = - qb._x; + this._y = - qb._y; + this._z = - qb._z; - cosHalfTheta = - cosHalfTheta; + cosHalfTheta = - cosHalfTheta; - } else { + } else { - this.copy( qb ); + this.copy( qb ); - } + } - if ( cosHalfTheta >= 1.0 ) { + if ( cosHalfTheta >= 1.0 ) { - this._w = w; - this._x = x; - this._y = y; - this._z = z; + this._w = w; + this._x = x; + this._y = y; + this._z = z; - return this; + return this; - } + } - var sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; + var sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; - if ( sqrSinHalfTheta <= Number.EPSILON ) { + if ( sqrSinHalfTheta <= Number.EPSILON ) { - var s = 1 - t; - this._w = s * w + t * this._w; - this._x = s * x + t * this._x; - this._y = s * y + t * this._y; - this._z = s * z + t * this._z; + var s = 1 - t; + this._w = s * w + t * this._w; + this._x = s * x + t * this._x; + this._y = s * y + t * this._y; + this._z = s * z + t * this._z; - return this.normalize(); + return this.normalize(); - } + } - var sinHalfTheta = Math.sqrt( sqrSinHalfTheta ); - var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta ); - var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, - ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; + var sinHalfTheta = Math.sqrt( sqrSinHalfTheta ); + var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta ); + var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, + ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; - this._w = ( w * ratioA + this._w * ratioB ); - this._x = ( x * ratioA + this._x * ratioB ); - this._y = ( y * ratioA + this._y * ratioB ); - this._z = ( z * ratioA + this._z * ratioB ); + this._w = ( w * ratioA + this._w * ratioB ); + this._x = ( x * ratioA + this._x * ratioB ); + this._y = ( y * ratioA + this._y * ratioB ); + this._z = ( z * ratioA + this._z * ratioB ); - this.onChangeCallback(); + this.onChangeCallback(); - return this; + return this; - }, + }, - equals: function ( quaternion ) { + equals: function ( quaternion ) { - return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w ); + return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w ); - }, + }, - fromArray: function ( array, offset ) { + fromArray: function ( array, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - this._x = array[ offset ]; - this._y = array[ offset + 1 ]; - this._z = array[ offset + 2 ]; - this._w = array[ offset + 3 ]; + this._x = array[ offset ]; + this._y = array[ offset + 1 ]; + this._z = array[ offset + 2 ]; + this._w = array[ offset + 3 ]; - this.onChangeCallback(); + this.onChangeCallback(); - return this; + return this; - }, + }, - toArray: function ( array, offset ) { + toArray: function ( array, offset ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - array[ offset ] = this._x; - array[ offset + 1 ] = this._y; - array[ offset + 2 ] = this._z; - array[ offset + 3 ] = this._w; + array[ offset ] = this._x; + array[ offset + 1 ] = this._y; + array[ offset + 2 ] = this._z; + array[ offset + 3 ] = this._w; - return array; + return array; - }, + }, - onChange: function ( callback ) { + onChange: function ( callback ) { - this.onChangeCallback = callback; + this.onChangeCallback = callback; - return this; + return this; - }, + }, - onChangeCallback: function () {} + onChangeCallback: function () {} - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author kile / http://kile.stravaganza.org/ - * @author philogb / http://blog.thejit.org/ - * @author mikael emtinger / http://gomo.se/ - * @author egraether / http://egraether.com/ - * @author WestLangley / http://github.com/WestLangley - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author kile / http://kile.stravaganza.org/ + * @author philogb / http://blog.thejit.org/ + * @author mikael emtinger / http://gomo.se/ + * @author egraether / http://egraether.com/ + * @author WestLangley / http://github.com/WestLangley + */ - function Vector3( x, y, z ) { + function Vector3( x, y, z ) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; - } + } - Object.assign( Vector3.prototype, { + Object.assign( Vector3.prototype, { - isVector3: true, + isVector3: true, - set: function ( x, y, z ) { + set: function ( x, y, z ) { - this.x = x; - this.y = y; - this.z = z; + this.x = x; + this.y = y; + this.z = z; - return this; + return this; - }, + }, - setScalar: function ( scalar ) { + setScalar: function ( scalar ) { - this.x = scalar; - this.y = scalar; - this.z = scalar; + this.x = scalar; + this.y = scalar; + this.z = scalar; - return this; + return this; - }, + }, - setX: function ( x ) { + setX: function ( x ) { - this.x = x; + this.x = x; - return this; + return this; - }, + }, - setY: function ( y ) { + setY: function ( y ) { - this.y = y; + this.y = y; - return this; + return this; - }, + }, - setZ: function ( z ) { + setZ: function ( z ) { - this.z = z; + this.z = z; - return this; + return this; - }, + }, - setComponent: function ( index, value ) { + setComponent: function ( index, value ) { - switch ( index ) { + switch ( index ) { - case 0: this.x = value; break; - case 1: this.y = value; break; - case 2: this.z = value; break; - default: throw new Error( 'index is out of range: ' + index ); + case 0: this.x = value; break; + case 1: this.y = value; break; + case 2: this.z = value; break; + default: throw new Error( 'index is out of range: ' + index ); - } + } - return this; + return this; - }, + }, - getComponent: function ( index ) { + getComponent: function ( index ) { - switch ( index ) { + switch ( index ) { - case 0: return this.x; - case 1: return this.y; - case 2: return this.z; - default: throw new Error( 'index is out of range: ' + index ); + case 0: return this.x; + case 1: return this.y; + case 2: return this.z; + default: throw new Error( 'index is out of range: ' + index ); - } + } - }, + }, - clone: function () { + clone: function () { - return new this.constructor( this.x, this.y, this.z ); + return new this.constructor( this.x, this.y, this.z ); - }, + }, - copy: function ( v ) { + copy: function ( v ) { - this.x = v.x; - this.y = v.y; - this.z = v.z; + this.x = v.x; + this.y = v.y; + this.z = v.z; - return this; + return this; - }, + }, - add: function ( v, w ) { + add: function ( v, w ) { - if ( w !== undefined ) { + if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); - return this.addVectors( v, w ); + console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + return this.addVectors( v, w ); - } + } - this.x += v.x; - this.y += v.y; - this.z += v.z; + this.x += v.x; + this.y += v.y; + this.z += v.z; - return this; + return this; - }, + }, - addScalar: function ( s ) { + addScalar: function ( s ) { - this.x += s; - this.y += s; - this.z += s; + this.x += s; + this.y += s; + this.z += s; - return this; + return this; - }, + }, - addVectors: function ( a, b ) { + addVectors: function ( a, b ) { - this.x = a.x + b.x; - this.y = a.y + b.y; - this.z = a.z + b.z; + this.x = a.x + b.x; + this.y = a.y + b.y; + this.z = a.z + b.z; - return this; + return this; - }, + }, - addScaledVector: function ( v, s ) { + addScaledVector: function ( v, s ) { - this.x += v.x * s; - this.y += v.y * s; - this.z += v.z * s; + this.x += v.x * s; + this.y += v.y * s; + this.z += v.z * s; - return this; + return this; - }, + }, - sub: function ( v, w ) { + sub: function ( v, w ) { - if ( w !== undefined ) { + if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); - return this.subVectors( v, w ); + console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + return this.subVectors( v, w ); - } + } - this.x -= v.x; - this.y -= v.y; - this.z -= v.z; + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; - return this; + return this; - }, + }, - subScalar: function ( s ) { + subScalar: function ( s ) { - this.x -= s; - this.y -= s; - this.z -= s; + this.x -= s; + this.y -= s; + this.z -= s; - return this; + return this; - }, + }, - subVectors: function ( a, b ) { + subVectors: function ( a, b ) { - this.x = a.x - b.x; - this.y = a.y - b.y; - this.z = a.z - b.z; + this.x = a.x - b.x; + this.y = a.y - b.y; + this.z = a.z - b.z; - return this; + return this; - }, + }, - multiply: function ( v, w ) { + multiply: function ( v, w ) { - if ( w !== undefined ) { + if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); - return this.multiplyVectors( v, w ); + console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); + return this.multiplyVectors( v, w ); - } + } - this.x *= v.x; - this.y *= v.y; - this.z *= v.z; + this.x *= v.x; + this.y *= v.y; + this.z *= v.z; - return this; + return this; - }, + }, - multiplyScalar: function ( scalar ) { + multiplyScalar: function ( scalar ) { - this.x *= scalar; - this.y *= scalar; - this.z *= scalar; + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; - return this; + return this; - }, + }, - multiplyVectors: function ( a, b ) { + multiplyVectors: function ( a, b ) { - this.x = a.x * b.x; - this.y = a.y * b.y; - this.z = a.z * b.z; + this.x = a.x * b.x; + this.y = a.y * b.y; + this.z = a.z * b.z; - return this; + return this; - }, + }, - applyEuler: function () { + applyEuler: function () { - var quaternion = new Quaternion(); + var quaternion = new Quaternion(); - return function applyEuler( euler ) { + return function applyEuler( euler ) { - if ( ! ( euler && euler.isEuler ) ) { + if ( ! ( euler && euler.isEuler ) ) { - console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' ); + console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' ); - } + } - return this.applyQuaternion( quaternion.setFromEuler( euler ) ); + return this.applyQuaternion( quaternion.setFromEuler( euler ) ); - }; + }; - }(), + }(), - applyAxisAngle: function () { + applyAxisAngle: function () { - var quaternion = new Quaternion(); + var quaternion = new Quaternion(); - return function applyAxisAngle( axis, angle ) { + return function applyAxisAngle( axis, angle ) { - return this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) ); + return this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) ); - }; + }; - }(), + }(), - applyMatrix3: function ( m ) { + applyMatrix3: function ( m ) { - var x = this.x, y = this.y, z = this.z; - var e = m.elements; + var x = this.x, y = this.y, z = this.z; + var e = m.elements; - this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z; - this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z; - this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z; + this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z; + this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z; + this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z; - return this; + return this; - }, + }, - applyMatrix4: function ( m ) { + applyMatrix4: function ( m ) { - var x = this.x, y = this.y, z = this.z; - var e = m.elements; + var x = this.x, y = this.y, z = this.z; + var e = m.elements; - var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); + var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); - this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w; - this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w; - this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w; + this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w; + this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w; + this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w; - return this; + return this; - }, + }, - applyQuaternion: function ( q ) { + applyQuaternion: function ( q ) { - var x = this.x, y = this.y, z = this.z; - var qx = q.x, qy = q.y, qz = q.z, qw = q.w; + var x = this.x, y = this.y, z = this.z; + var qx = q.x, qy = q.y, qz = q.z, qw = q.w; - // calculate quat * vector + // calculate quat * vector - var ix = qw * x + qy * z - qz * y; - var iy = qw * y + qz * x - qx * z; - var iz = qw * z + qx * y - qy * x; - var iw = - qx * x - qy * y - qz * z; + var ix = qw * x + qy * z - qz * y; + var iy = qw * y + qz * x - qx * z; + var iz = qw * z + qx * y - qy * x; + var iw = - qx * x - qy * y - qz * z; - // calculate result * inverse quat + // calculate result * inverse quat - this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy; - this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz; - this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx; + this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy; + this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz; + this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx; - return this; + return this; - }, + }, - project: function () { + project: function () { - var matrix = new Matrix4(); + var matrix = new Matrix4(); - return function project( camera ) { + return function project( camera ) { - matrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) ); - return this.applyMatrix4( matrix ); + matrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) ); + return this.applyMatrix4( matrix ); - }; + }; - }(), + }(), - unproject: function () { + unproject: function () { - var matrix = new Matrix4(); + var matrix = new Matrix4(); - return function unproject( camera ) { + return function unproject( camera ) { - matrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) ); - return this.applyMatrix4( matrix ); + matrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) ); + return this.applyMatrix4( matrix ); - }; + }; - }(), + }(), - transformDirection: function ( m ) { + transformDirection: function ( m ) { - // input: THREE.Matrix4 affine matrix - // vector interpreted as a direction + // input: THREE.Matrix4 affine matrix + // vector interpreted as a direction - var x = this.x, y = this.y, z = this.z; - var e = m.elements; + var x = this.x, y = this.y, z = this.z; + var e = m.elements; - this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z; - this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z; - this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z; + this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z; + this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z; + this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z; - return this.normalize(); + return this.normalize(); - }, + }, - divide: function ( v ) { + divide: function ( v ) { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z; + this.x /= v.x; + this.y /= v.y; + this.z /= v.z; - return this; + return this; - }, + }, - divideScalar: function ( scalar ) { + divideScalar: function ( scalar ) { - return this.multiplyScalar( 1 / scalar ); + return this.multiplyScalar( 1 / scalar ); - }, + }, - min: function ( v ) { + min: function ( v ) { - this.x = Math.min( this.x, v.x ); - this.y = Math.min( this.y, v.y ); - this.z = Math.min( this.z, v.z ); + this.x = Math.min( this.x, v.x ); + this.y = Math.min( this.y, v.y ); + this.z = Math.min( this.z, v.z ); - return this; + return this; - }, + }, - max: function ( v ) { + max: function ( v ) { - this.x = Math.max( this.x, v.x ); - this.y = Math.max( this.y, v.y ); - this.z = Math.max( this.z, v.z ); + this.x = Math.max( this.x, v.x ); + this.y = Math.max( this.y, v.y ); + this.z = Math.max( this.z, v.z ); - return this; + return this; - }, + }, - clamp: function ( min, max ) { + clamp: function ( min, max ) { - // assumes min < max, componentwise + // assumes min < max, componentwise - this.x = Math.max( min.x, Math.min( max.x, this.x ) ); - this.y = Math.max( min.y, Math.min( max.y, this.y ) ); - this.z = Math.max( min.z, Math.min( max.z, this.z ) ); + this.x = Math.max( min.x, Math.min( max.x, this.x ) ); + this.y = Math.max( min.y, Math.min( max.y, this.y ) ); + this.z = Math.max( min.z, Math.min( max.z, this.z ) ); - return this; + return this; - }, + }, - clampScalar: function () { + clampScalar: function () { - var min = new Vector3(); - var max = new Vector3(); + var min = new Vector3(); + var max = new Vector3(); - return function clampScalar( minVal, maxVal ) { + return function clampScalar( minVal, maxVal ) { - min.set( minVal, minVal, minVal ); - max.set( maxVal, maxVal, maxVal ); + min.set( minVal, minVal, minVal ); + max.set( maxVal, maxVal, maxVal ); - return this.clamp( min, max ); + return this.clamp( min, max ); - }; + }; - }(), + }(), - clampLength: function ( min, max ) { + clampLength: function ( min, max ) { - var length = this.length(); + var length = this.length(); - return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); + return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); - }, + }, - floor: function () { + floor: function () { - this.x = Math.floor( this.x ); - this.y = Math.floor( this.y ); - this.z = Math.floor( this.z ); + this.x = Math.floor( this.x ); + this.y = Math.floor( this.y ); + this.z = Math.floor( this.z ); - return this; + return this; - }, + }, - ceil: function () { + ceil: function () { - this.x = Math.ceil( this.x ); - this.y = Math.ceil( this.y ); - this.z = Math.ceil( this.z ); + this.x = Math.ceil( this.x ); + this.y = Math.ceil( this.y ); + this.z = Math.ceil( this.z ); - return this; + return this; - }, + }, - round: function () { + round: function () { - this.x = Math.round( this.x ); - this.y = Math.round( this.y ); - this.z = Math.round( this.z ); + this.x = Math.round( this.x ); + this.y = Math.round( this.y ); + this.z = Math.round( this.z ); - return this; + return this; - }, + }, - roundToZero: function () { + roundToZero: function () { - this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); - this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); - this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); + this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); + this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); + this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); - return this; + return this; - }, + }, - negate: function () { + negate: function () { - this.x = - this.x; - this.y = - this.y; - this.z = - this.z; + this.x = - this.x; + this.y = - this.y; + this.z = - this.z; - return this; + return this; - }, + }, - dot: function ( v ) { + dot: function ( v ) { - return this.x * v.x + this.y * v.y + this.z * v.z; + return this.x * v.x + this.y * v.y + this.z * v.z; - }, + }, - // TODO lengthSquared? + // TODO lengthSquared? - lengthSq: function () { + lengthSq: function () { - return this.x * this.x + this.y * this.y + this.z * this.z; + return this.x * this.x + this.y * this.y + this.z * this.z; - }, + }, - length: function () { + length: function () { - return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); + return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); - }, + }, - manhattanLength: function () { + manhattanLength: function () { - return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ); + return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ); - }, + }, - normalize: function () { + normalize: function () { - return this.divideScalar( this.length() || 1 ); + return this.divideScalar( this.length() || 1 ); - }, + }, - setLength: function ( length ) { + setLength: function ( length ) { - return this.normalize().multiplyScalar( length ); + return this.normalize().multiplyScalar( length ); - }, + }, - lerp: function ( v, alpha ) { + lerp: function ( v, alpha ) { - this.x += ( v.x - this.x ) * alpha; - this.y += ( v.y - this.y ) * alpha; - this.z += ( v.z - this.z ) * alpha; + this.x += ( v.x - this.x ) * alpha; + this.y += ( v.y - this.y ) * alpha; + this.z += ( v.z - this.z ) * alpha; - return this; + return this; - }, + }, - lerpVectors: function ( v1, v2, alpha ) { + lerpVectors: function ( v1, v2, alpha ) { - return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); + return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); - }, + }, - cross: function ( v, w ) { + cross: function ( v, w ) { - if ( w !== undefined ) { + if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); - return this.crossVectors( v, w ); + console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); + return this.crossVectors( v, w ); - } + } - return this.crossVectors( this, v ); + return this.crossVectors( this, v ); - }, + }, - crossVectors: function ( a, b ) { + crossVectors: function ( a, b ) { - var ax = a.x, ay = a.y, az = a.z; - var bx = b.x, by = b.y, bz = b.z; + var ax = a.x, ay = a.y, az = a.z; + var bx = b.x, by = b.y, bz = b.z; - this.x = ay * bz - az * by; - this.y = az * bx - ax * bz; - this.z = ax * by - ay * bx; + this.x = ay * bz - az * by; + this.y = az * bx - ax * bz; + this.z = ax * by - ay * bx; - return this; + return this; - }, + }, - projectOnVector: function ( vector ) { + projectOnVector: function ( vector ) { - var scalar = vector.dot( this ) / vector.lengthSq(); + var scalar = vector.dot( this ) / vector.lengthSq(); - return this.copy( vector ).multiplyScalar( scalar ); + return this.copy( vector ).multiplyScalar( scalar ); - }, + }, - projectOnPlane: function () { + projectOnPlane: function () { - var v1 = new Vector3(); + var v1 = new Vector3(); - return function projectOnPlane( planeNormal ) { + return function projectOnPlane( planeNormal ) { - v1.copy( this ).projectOnVector( planeNormal ); + v1.copy( this ).projectOnVector( planeNormal ); - return this.sub( v1 ); + return this.sub( v1 ); - }; + }; - }(), + }(), - reflect: function () { + reflect: function () { - // reflect incident vector off plane orthogonal to normal - // normal is assumed to have unit length + // reflect incident vector off plane orthogonal to normal + // normal is assumed to have unit length - var v1 = new Vector3(); + var v1 = new Vector3(); - return function reflect( normal ) { + return function reflect( normal ) { - return this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) ); + return this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) ); - }; + }; - }(), + }(), - angleTo: function ( v ) { + angleTo: function ( v ) { - var theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) ); + var theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) ); - // clamp, to handle numerical problems + // clamp, to handle numerical problems - return Math.acos( _Math.clamp( theta, - 1, 1 ) ); + return Math.acos( _Math.clamp( theta, - 1, 1 ) ); - }, + }, - distanceTo: function ( v ) { + distanceTo: function ( v ) { - return Math.sqrt( this.distanceToSquared( v ) ); + return Math.sqrt( this.distanceToSquared( v ) ); - }, + }, - distanceToSquared: function ( v ) { + distanceToSquared: function ( v ) { - var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; + var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; - return dx * dx + dy * dy + dz * dz; + return dx * dx + dy * dy + dz * dz; - }, + }, - manhattanDistanceTo: function ( v ) { + manhattanDistanceTo: function ( v ) { - return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z ); + return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z ); - }, + }, - setFromSpherical: function ( s ) { + setFromSpherical: function ( s ) { - var sinPhiRadius = Math.sin( s.phi ) * s.radius; + var sinPhiRadius = Math.sin( s.phi ) * s.radius; - this.x = sinPhiRadius * Math.sin( s.theta ); - this.y = Math.cos( s.phi ) * s.radius; - this.z = sinPhiRadius * Math.cos( s.theta ); + this.x = sinPhiRadius * Math.sin( s.theta ); + this.y = Math.cos( s.phi ) * s.radius; + this.z = sinPhiRadius * Math.cos( s.theta ); - return this; + return this; - }, + }, - setFromCylindrical: function ( c ) { + setFromCylindrical: function ( c ) { - this.x = c.radius * Math.sin( c.theta ); - this.y = c.y; - this.z = c.radius * Math.cos( c.theta ); + this.x = c.radius * Math.sin( c.theta ); + this.y = c.y; + this.z = c.radius * Math.cos( c.theta ); - return this; + return this; - }, + }, - setFromMatrixPosition: function ( m ) { + setFromMatrixPosition: function ( m ) { - var e = m.elements; + var e = m.elements; - this.x = e[ 12 ]; - this.y = e[ 13 ]; - this.z = e[ 14 ]; + this.x = e[ 12 ]; + this.y = e[ 13 ]; + this.z = e[ 14 ]; - return this; + return this; - }, + }, - setFromMatrixScale: function ( m ) { + setFromMatrixScale: function ( m ) { - var sx = this.setFromMatrixColumn( m, 0 ).length(); - var sy = this.setFromMatrixColumn( m, 1 ).length(); - var sz = this.setFromMatrixColumn( m, 2 ).length(); + var sx = this.setFromMatrixColumn( m, 0 ).length(); + var sy = this.setFromMatrixColumn( m, 1 ).length(); + var sz = this.setFromMatrixColumn( m, 2 ).length(); - this.x = sx; - this.y = sy; - this.z = sz; + this.x = sx; + this.y = sy; + this.z = sz; - return this; + return this; - }, + }, - setFromMatrixColumn: function ( m, index ) { + setFromMatrixColumn: function ( m, index ) { - return this.fromArray( m.elements, index * 4 ); + return this.fromArray( m.elements, index * 4 ); - }, + }, - equals: function ( v ) { + equals: function ( v ) { - return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) ); + return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) ); - }, + }, - fromArray: function ( array, offset ) { + fromArray: function ( array, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - this.x = array[ offset ]; - this.y = array[ offset + 1 ]; - this.z = array[ offset + 2 ]; + this.x = array[ offset ]; + this.y = array[ offset + 1 ]; + this.z = array[ offset + 2 ]; - return this; + return this; - }, + }, - toArray: function ( array, offset ) { + toArray: function ( array, offset ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - array[ offset ] = this.x; - array[ offset + 1 ] = this.y; - array[ offset + 2 ] = this.z; + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; + array[ offset + 2 ] = this.z; - return array; + return array; - }, + }, - fromBufferAttribute: function ( attribute, index, offset ) { + fromBufferAttribute: function ( attribute, index, offset ) { - if ( offset !== undefined ) { + if ( offset !== undefined ) { - console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' ); + console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' ); - } + } - this.x = attribute.getX( index ); - this.y = attribute.getY( index ); - this.z = attribute.getZ( index ); + this.x = attribute.getX( index ); + this.y = attribute.getY( index ); + this.z = attribute.getZ( index ); - return this; + return this; - } + } - } ); + } ); - /** - * @author alteredq / http://alteredqualia.com/ - * @author WestLangley / http://github.com/WestLangley - * @author bhouston / http://clara.io - * @author tschw - */ + /** + * @author alteredq / http://alteredqualia.com/ + * @author WestLangley / http://github.com/WestLangley + * @author bhouston / http://clara.io + * @author tschw + */ - function Matrix3() { + function Matrix3() { - this.elements = [ + this.elements = [ - 1, 0, 0, - 0, 1, 0, - 0, 0, 1 + 1, 0, 0, + 0, 1, 0, + 0, 0, 1 - ]; + ]; - if ( arguments.length > 0 ) { + if ( arguments.length > 0 ) { - console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); + console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); - } + } - } + } - Object.assign( Matrix3.prototype, { + Object.assign( Matrix3.prototype, { - isMatrix3: true, + isMatrix3: true, - set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { + set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { - var te = this.elements; + var te = this.elements; - te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31; - te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32; - te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33; + te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31; + te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32; + te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33; - return this; + return this; - }, + }, - identity: function () { + identity: function () { - this.set( + this.set( - 1, 0, 0, - 0, 1, 0, - 0, 0, 1 + 1, 0, 0, + 0, 1, 0, + 0, 0, 1 - ); + ); - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new this.constructor().fromArray( this.elements ); + return new this.constructor().fromArray( this.elements ); - }, + }, - copy: function ( m ) { + copy: function ( m ) { - var te = this.elements; - var me = m.elements; + var te = this.elements; + var me = m.elements; - te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; - te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; - te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ]; + te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; + te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; + te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ]; - return this; + return this; - }, + }, - setFromMatrix4: function ( m ) { + setFromMatrix4: function ( m ) { - var me = m.elements; + var me = m.elements; - this.set( + this.set( - me[ 0 ], me[ 4 ], me[ 8 ], - me[ 1 ], me[ 5 ], me[ 9 ], - me[ 2 ], me[ 6 ], me[ 10 ] + me[ 0 ], me[ 4 ], me[ 8 ], + me[ 1 ], me[ 5 ], me[ 9 ], + me[ 2 ], me[ 6 ], me[ 10 ] - ); + ); - return this; + return this; - }, + }, - applyToBufferAttribute: function () { + applyToBufferAttribute: function () { - var v1 = new Vector3(); + var v1 = new Vector3(); - return function applyToBufferAttribute( attribute ) { + return function applyToBufferAttribute( attribute ) { - for ( var i = 0, l = attribute.count; i < l; i ++ ) { + for ( var i = 0, l = attribute.count; i < l; i ++ ) { - v1.x = attribute.getX( i ); - v1.y = attribute.getY( i ); - v1.z = attribute.getZ( i ); + v1.x = attribute.getX( i ); + v1.y = attribute.getY( i ); + v1.z = attribute.getZ( i ); - v1.applyMatrix3( this ); + v1.applyMatrix3( this ); - attribute.setXYZ( i, v1.x, v1.y, v1.z ); + attribute.setXYZ( i, v1.x, v1.y, v1.z ); - } + } - return attribute; + return attribute; - }; + }; - }(), + }(), - multiply: function ( m ) { + multiply: function ( m ) { - return this.multiplyMatrices( this, m ); + return this.multiplyMatrices( this, m ); - }, + }, - premultiply: function ( m ) { + premultiply: function ( m ) { - return this.multiplyMatrices( m, this ); + return this.multiplyMatrices( m, this ); - }, + }, - multiplyMatrices: function ( a, b ) { + multiplyMatrices: function ( a, b ) { - var ae = a.elements; - var be = b.elements; - var te = this.elements; + var ae = a.elements; + var be = b.elements; + var te = this.elements; - var a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ]; - var a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ]; - var a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ]; + var a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ]; + var a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ]; + var a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ]; - var b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ]; - var b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ]; - var b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ]; + var b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ]; + var b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ]; + var b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ]; - te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31; - te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32; - te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33; + te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31; + te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32; + te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33; - te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31; - te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32; - te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33; + te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31; + te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32; + te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33; - te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31; - te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32; - te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33; + te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31; + te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32; + te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33; - return this; + return this; - }, + }, - multiplyScalar: function ( s ) { + multiplyScalar: function ( s ) { - var te = this.elements; + var te = this.elements; - te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s; - te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s; - te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s; + te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s; + te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s; + te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s; - return this; + return this; - }, + }, - determinant: function () { + determinant: function () { - var te = this.elements; + var te = this.elements; - var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ], - d = te[ 3 ], e = te[ 4 ], f = te[ 5 ], - g = te[ 6 ], h = te[ 7 ], i = te[ 8 ]; + var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ], + d = te[ 3 ], e = te[ 4 ], f = te[ 5 ], + g = te[ 6 ], h = te[ 7 ], i = te[ 8 ]; - return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; + return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; - }, + }, - getInverse: function ( matrix, throwOnDegenerate ) { + getInverse: function ( matrix, throwOnDegenerate ) { - if ( matrix && matrix.isMatrix4 ) { + if ( matrix && matrix.isMatrix4 ) { - console.error( "THREE.Matrix3: .getInverse() no longer takes a Matrix4 argument." ); + console.error( "THREE.Matrix3: .getInverse() no longer takes a Matrix4 argument." ); - } + } - var me = matrix.elements, - te = this.elements, + var me = matrix.elements, + te = this.elements, - n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], - n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ], - n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ], + n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], + n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ], + n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ], - t11 = n33 * n22 - n32 * n23, - t12 = n32 * n13 - n33 * n12, - t13 = n23 * n12 - n22 * n13, + t11 = n33 * n22 - n32 * n23, + t12 = n32 * n13 - n33 * n12, + t13 = n23 * n12 - n22 * n13, - det = n11 * t11 + n21 * t12 + n31 * t13; + det = n11 * t11 + n21 * t12 + n31 * t13; - if ( det === 0 ) { + if ( det === 0 ) { - var msg = "THREE.Matrix3: .getInverse() can't invert matrix, determinant is 0"; + var msg = "THREE.Matrix3: .getInverse() can't invert matrix, determinant is 0"; - if ( throwOnDegenerate === true ) { + if ( throwOnDegenerate === true ) { - throw new Error( msg ); + throw new Error( msg ); - } else { + } else { - console.warn( msg ); + console.warn( msg ); - } + } - return this.identity(); + return this.identity(); - } + } - var detInv = 1 / det; + var detInv = 1 / det; - te[ 0 ] = t11 * detInv; - te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv; - te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv; + te[ 0 ] = t11 * detInv; + te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv; + te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv; - te[ 3 ] = t12 * detInv; - te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv; - te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv; + te[ 3 ] = t12 * detInv; + te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv; + te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv; - te[ 6 ] = t13 * detInv; - te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv; - te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv; + te[ 6 ] = t13 * detInv; + te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv; + te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv; - return this; + return this; - }, + }, - transpose: function () { + transpose: function () { - var tmp, m = this.elements; + var tmp, m = this.elements; - tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp; - tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp; - tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp; + tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp; + tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp; + tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp; - return this; + return this; - }, + }, - getNormalMatrix: function ( matrix4 ) { + getNormalMatrix: function ( matrix4 ) { - return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose(); + return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose(); - }, + }, - transposeIntoArray: function ( r ) { + transposeIntoArray: function ( r ) { - var m = this.elements; + var m = this.elements; - r[ 0 ] = m[ 0 ]; - r[ 1 ] = m[ 3 ]; - r[ 2 ] = m[ 6 ]; - r[ 3 ] = m[ 1 ]; - r[ 4 ] = m[ 4 ]; - r[ 5 ] = m[ 7 ]; - r[ 6 ] = m[ 2 ]; - r[ 7 ] = m[ 5 ]; - r[ 8 ] = m[ 8 ]; + r[ 0 ] = m[ 0 ]; + r[ 1 ] = m[ 3 ]; + r[ 2 ] = m[ 6 ]; + r[ 3 ] = m[ 1 ]; + r[ 4 ] = m[ 4 ]; + r[ 5 ] = m[ 7 ]; + r[ 6 ] = m[ 2 ]; + r[ 7 ] = m[ 5 ]; + r[ 8 ] = m[ 8 ]; - return this; + return this; - }, + }, - setUvTransform: function ( tx, ty, sx, sy, rotation, cx, cy ) { + setUvTransform: function ( tx, ty, sx, sy, rotation, cx, cy ) { - var c = Math.cos( rotation ); - var s = Math.sin( rotation ); + var c = Math.cos( rotation ); + var s = Math.sin( rotation ); - this.set( - sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx, - - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty, - 0, 0, 1 - ); + this.set( + sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx, + - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty, + 0, 0, 1 + ); - }, + }, - scale: function ( sx, sy ) { + scale: function ( sx, sy ) { - var te = this.elements; + var te = this.elements; - te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx; - te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy; + te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx; + te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy; - return this; + return this; - }, + }, - rotate: function ( theta ) { + rotate: function ( theta ) { - var c = Math.cos( theta ); - var s = Math.sin( theta ); + var c = Math.cos( theta ); + var s = Math.sin( theta ); - var te = this.elements; + var te = this.elements; - var a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ]; - var a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ]; + var a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ]; + var a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ]; - te[ 0 ] = c * a11 + s * a21; - te[ 3 ] = c * a12 + s * a22; - te[ 6 ] = c * a13 + s * a23; + te[ 0 ] = c * a11 + s * a21; + te[ 3 ] = c * a12 + s * a22; + te[ 6 ] = c * a13 + s * a23; - te[ 1 ] = - s * a11 + c * a21; - te[ 4 ] = - s * a12 + c * a22; - te[ 7 ] = - s * a13 + c * a23; + te[ 1 ] = - s * a11 + c * a21; + te[ 4 ] = - s * a12 + c * a22; + te[ 7 ] = - s * a13 + c * a23; - return this; + return this; - }, + }, - translate: function ( tx, ty ) { + translate: function ( tx, ty ) { - var te = this.elements; + var te = this.elements; - te[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ]; - te[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ]; + te[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ]; + te[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ]; - return this; + return this; - }, + }, - equals: function ( matrix ) { + equals: function ( matrix ) { - var te = this.elements; - var me = matrix.elements; + var te = this.elements; + var me = matrix.elements; - for ( var i = 0; i < 9; i ++ ) { + for ( var i = 0; i < 9; i ++ ) { - if ( te[ i ] !== me[ i ] ) return false; + if ( te[ i ] !== me[ i ] ) return false; - } + } - return true; + return true; - }, + }, - fromArray: function ( array, offset ) { + fromArray: function ( array, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - for ( var i = 0; i < 9; i ++ ) { + for ( var i = 0; i < 9; i ++ ) { - this.elements[ i ] = array[ i + offset ]; + this.elements[ i ] = array[ i + offset ]; - } + } - return this; + return this; - }, + }, - toArray: function ( array, offset ) { + toArray: function ( array, offset ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - var te = this.elements; + var te = this.elements; - array[ offset ] = te[ 0 ]; - array[ offset + 1 ] = te[ 1 ]; - array[ offset + 2 ] = te[ 2 ]; + array[ offset ] = te[ 0 ]; + array[ offset + 1 ] = te[ 1 ]; + array[ offset + 2 ] = te[ 2 ]; - array[ offset + 3 ] = te[ 3 ]; - array[ offset + 4 ] = te[ 4 ]; - array[ offset + 5 ] = te[ 5 ]; + array[ offset + 3 ] = te[ 3 ]; + array[ offset + 4 ] = te[ 4 ]; + array[ offset + 5 ] = te[ 5 ]; - array[ offset + 6 ] = te[ 6 ]; - array[ offset + 7 ] = te[ 7 ]; - array[ offset + 8 ] = te[ 8 ]; + array[ offset + 6 ] = te[ 6 ]; + array[ offset + 7 ] = te[ 7 ]; + array[ offset + 8 ] = te[ 8 ]; - return array; + return array; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author szimek / https://github.com/szimek/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author szimek / https://github.com/szimek/ + */ - var ImageUtils = { + var ImageUtils = { - getDataURL: function ( image ) { + getDataURL: function ( image ) { - var canvas; + var canvas; - if ( image instanceof HTMLCanvasElement ) { + if ( image instanceof HTMLCanvasElement ) { - canvas = image; + canvas = image; - } else { + } else { - if ( typeof OffscreenCanvas !== 'undefined' ) { + if ( typeof OffscreenCanvas !== 'undefined' ) { - canvas = new OffscreenCanvas( image.width, image.height ); + canvas = new OffscreenCanvas( image.width, image.height ); - } else { + } else { - canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); - canvas.width = image.width; - canvas.height = image.height; + canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); + canvas.width = image.width; + canvas.height = image.height; - } + } - var context = canvas.getContext( '2d' ); + var context = canvas.getContext( '2d' ); - if ( image instanceof ImageData ) { + if ( image instanceof ImageData ) { - context.putImageData( image, 0, 0 ); + context.putImageData( image, 0, 0 ); - } else { + } else { - context.drawImage( image, 0, 0, image.width, image.height ); + context.drawImage( image, 0, 0, image.width, image.height ); - } + } - } + } - if ( canvas.width > 2048 || canvas.height > 2048 ) { + if ( canvas.width > 2048 || canvas.height > 2048 ) { - return canvas.toDataURL( 'image/jpeg', 0.6 ); + return canvas.toDataURL( 'image/jpeg', 0.6 ); - } else { + } else { - return canvas.toDataURL( 'image/png' ); + return canvas.toDataURL( 'image/png' ); - } + } - } + } - }; + }; - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author szimek / https://github.com/szimek/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author szimek / https://github.com/szimek/ + */ - var textureId = 0; + var textureId = 0; - function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { + function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { - Object.defineProperty( this, 'id', { value: textureId ++ } ); + Object.defineProperty( this, 'id', { value: textureId ++ } ); - this.uuid = _Math.generateUUID(); + this.uuid = _Math.generateUUID(); - this.name = ''; + this.name = ''; - this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE; - this.mipmaps = []; + this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE; + this.mipmaps = []; - this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING; + this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING; - this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping; - this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping; + this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping; + this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping; - this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; - this.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter; + this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; + this.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter; - this.anisotropy = anisotropy !== undefined ? anisotropy : 1; + this.anisotropy = anisotropy !== undefined ? anisotropy : 1; - this.format = format !== undefined ? format : RGBAFormat; - this.type = type !== undefined ? type : UnsignedByteType; + this.format = format !== undefined ? format : RGBAFormat; + this.type = type !== undefined ? type : UnsignedByteType; - this.offset = new Vector2( 0, 0 ); - this.repeat = new Vector2( 1, 1 ); - this.center = new Vector2( 0, 0 ); - this.rotation = 0; + this.offset = new Vector2( 0, 0 ); + this.repeat = new Vector2( 1, 1 ); + this.center = new Vector2( 0, 0 ); + this.rotation = 0; - this.matrixAutoUpdate = true; - this.matrix = new Matrix3(); + this.matrixAutoUpdate = true; + this.matrix = new Matrix3(); - this.generateMipmaps = true; - this.premultiplyAlpha = false; - this.flipY = true; - this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) + this.generateMipmaps = true; + this.premultiplyAlpha = false; + this.flipY = true; + this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) - // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap. - // - // Also changing the encoding after already used by a Material will not automatically make the Material - // update. You need to explicitly call Material.needsUpdate to trigger it to recompile. - this.encoding = encoding !== undefined ? encoding : LinearEncoding; + // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap. + // + // Also changing the encoding after already used by a Material will not automatically make the Material + // update. You need to explicitly call Material.needsUpdate to trigger it to recompile. + this.encoding = encoding !== undefined ? encoding : LinearEncoding; - this.version = 0; - this.onUpdate = null; + this.version = 0; + this.onUpdate = null; - } + } - Texture.DEFAULT_IMAGE = undefined; - Texture.DEFAULT_MAPPING = UVMapping; + Texture.DEFAULT_IMAGE = undefined; + Texture.DEFAULT_MAPPING = UVMapping; - Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { + Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - constructor: Texture, + constructor: Texture, - isTexture: true, + isTexture: true, - updateMatrix: function () { + updateMatrix: function () { - this.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y ); + this.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y ); - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( source ) { + copy: function ( source ) { - this.name = source.name; + this.name = source.name; - this.image = source.image; - this.mipmaps = source.mipmaps.slice( 0 ); + this.image = source.image; + this.mipmaps = source.mipmaps.slice( 0 ); - this.mapping = source.mapping; + this.mapping = source.mapping; - this.wrapS = source.wrapS; - this.wrapT = source.wrapT; + this.wrapS = source.wrapS; + this.wrapT = source.wrapT; - this.magFilter = source.magFilter; - this.minFilter = source.minFilter; + this.magFilter = source.magFilter; + this.minFilter = source.minFilter; - this.anisotropy = source.anisotropy; + this.anisotropy = source.anisotropy; - this.format = source.format; - this.type = source.type; + this.format = source.format; + this.type = source.type; - this.offset.copy( source.offset ); - this.repeat.copy( source.repeat ); - this.center.copy( source.center ); - this.rotation = source.rotation; + this.offset.copy( source.offset ); + this.repeat.copy( source.repeat ); + this.center.copy( source.center ); + this.rotation = source.rotation; - this.matrixAutoUpdate = source.matrixAutoUpdate; - this.matrix.copy( source.matrix ); + this.matrixAutoUpdate = source.matrixAutoUpdate; + this.matrix.copy( source.matrix ); - this.generateMipmaps = source.generateMipmaps; - this.premultiplyAlpha = source.premultiplyAlpha; - this.flipY = source.flipY; - this.unpackAlignment = source.unpackAlignment; - this.encoding = source.encoding; + this.generateMipmaps = source.generateMipmaps; + this.premultiplyAlpha = source.premultiplyAlpha; + this.flipY = source.flipY; + this.unpackAlignment = source.unpackAlignment; + this.encoding = source.encoding; - return this; + return this; - }, + }, - toJSON: function ( meta ) { + toJSON: function ( meta ) { - var isRootObject = ( meta === undefined || typeof meta === 'string' ); + var isRootObject = ( meta === undefined || typeof meta === 'string' ); - if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) { + if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) { - return meta.textures[ this.uuid ]; + return meta.textures[ this.uuid ]; - } + } - var output = { + var output = { - metadata: { - version: 4.5, - type: 'Texture', - generator: 'Texture.toJSON' - }, + metadata: { + version: 4.5, + type: 'Texture', + generator: 'Texture.toJSON' + }, - uuid: this.uuid, - name: this.name, + uuid: this.uuid, + name: this.name, - mapping: this.mapping, + mapping: this.mapping, - repeat: [ this.repeat.x, this.repeat.y ], - offset: [ this.offset.x, this.offset.y ], - center: [ this.center.x, this.center.y ], - rotation: this.rotation, + repeat: [ this.repeat.x, this.repeat.y ], + offset: [ this.offset.x, this.offset.y ], + center: [ this.center.x, this.center.y ], + rotation: this.rotation, - wrap: [ this.wrapS, this.wrapT ], + wrap: [ this.wrapS, this.wrapT ], - format: this.format, - minFilter: this.minFilter, - magFilter: this.magFilter, - anisotropy: this.anisotropy, + format: this.format, + minFilter: this.minFilter, + magFilter: this.magFilter, + anisotropy: this.anisotropy, - flipY: this.flipY + flipY: this.flipY - }; + }; - if ( this.image !== undefined ) { + if ( this.image !== undefined ) { - // TODO: Move to THREE.Image + // TODO: Move to THREE.Image - var image = this.image; + var image = this.image; - if ( image.uuid === undefined ) { + if ( image.uuid === undefined ) { - image.uuid = _Math.generateUUID(); // UGH + image.uuid = _Math.generateUUID(); // UGH - } + } - if ( ! isRootObject && meta.images[ image.uuid ] === undefined ) { + if ( ! isRootObject && meta.images[ image.uuid ] === undefined ) { - var url; + var url; - if ( Array.isArray( image ) ) { + if ( Array.isArray( image ) ) { - // process array of images e.g. CubeTexture + // process array of images e.g. CubeTexture - url = []; + url = []; - for ( var i = 0, l = image.length; i < l; i ++ ) { + for ( var i = 0, l = image.length; i < l; i ++ ) { - url.push( ImageUtils.getDataURL( image[ i ] ) ); + url.push( ImageUtils.getDataURL( image[ i ] ) ); - } + } - } else { + } else { - // process single image + // process single image - url = ImageUtils.getDataURL( image ); + url = ImageUtils.getDataURL( image ); - } + } - meta.images[ image.uuid ] = { - uuid: image.uuid, - url: url - }; + meta.images[ image.uuid ] = { + uuid: image.uuid, + url: url + }; - } + } - output.image = image.uuid; + output.image = image.uuid; - } + } - if ( ! isRootObject ) { + if ( ! isRootObject ) { - meta.textures[ this.uuid ] = output; + meta.textures[ this.uuid ] = output; - } + } - return output; + return output; - }, + }, - dispose: function () { + dispose: function () { - this.dispatchEvent( { type: 'dispose' } ); + this.dispatchEvent( { type: 'dispose' } ); - }, + }, - transformUv: function ( uv ) { + transformUv: function ( uv ) { - if ( this.mapping !== UVMapping ) return; + if ( this.mapping !== UVMapping ) return; - uv.applyMatrix3( this.matrix ); + uv.applyMatrix3( this.matrix ); - if ( uv.x < 0 || uv.x > 1 ) { + if ( uv.x < 0 || uv.x > 1 ) { - switch ( this.wrapS ) { + switch ( this.wrapS ) { - case RepeatWrapping: + case RepeatWrapping: - uv.x = uv.x - Math.floor( uv.x ); - break; + uv.x = uv.x - Math.floor( uv.x ); + break; - case ClampToEdgeWrapping: + case ClampToEdgeWrapping: - uv.x = uv.x < 0 ? 0 : 1; - break; + uv.x = uv.x < 0 ? 0 : 1; + break; - case MirroredRepeatWrapping: + case MirroredRepeatWrapping: - if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) { + if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) { - uv.x = Math.ceil( uv.x ) - uv.x; + uv.x = Math.ceil( uv.x ) - uv.x; - } else { + } else { - uv.x = uv.x - Math.floor( uv.x ); + uv.x = uv.x - Math.floor( uv.x ); - } - break; + } + break; - } + } - } + } - if ( uv.y < 0 || uv.y > 1 ) { + if ( uv.y < 0 || uv.y > 1 ) { - switch ( this.wrapT ) { + switch ( this.wrapT ) { - case RepeatWrapping: + case RepeatWrapping: - uv.y = uv.y - Math.floor( uv.y ); - break; + uv.y = uv.y - Math.floor( uv.y ); + break; - case ClampToEdgeWrapping: + case ClampToEdgeWrapping: - uv.y = uv.y < 0 ? 0 : 1; - break; + uv.y = uv.y < 0 ? 0 : 1; + break; - case MirroredRepeatWrapping: + case MirroredRepeatWrapping: - if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) { + if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) { - uv.y = Math.ceil( uv.y ) - uv.y; + uv.y = Math.ceil( uv.y ) - uv.y; - } else { + } else { - uv.y = uv.y - Math.floor( uv.y ); + uv.y = uv.y - Math.floor( uv.y ); - } - break; + } + break; - } + } - } + } - if ( this.flipY ) { + if ( this.flipY ) { - uv.y = 1 - uv.y; + uv.y = 1 - uv.y; - } + } - } + } - } ); + } ); - Object.defineProperty( Texture.prototype, "needsUpdate", { + Object.defineProperty( Texture.prototype, "needsUpdate", { - set: function ( value ) { + set: function ( value ) { - if ( value === true ) this.version ++; + if ( value === true ) this.version ++; - } + } - } ); + } ); - /** - * @author supereggbert / http://www.paulbrunt.co.uk/ - * @author philogb / http://blog.thejit.org/ - * @author mikael emtinger / http://gomo.se/ - * @author egraether / http://egraether.com/ - * @author WestLangley / http://github.com/WestLangley - */ + /** + * @author supereggbert / http://www.paulbrunt.co.uk/ + * @author philogb / http://blog.thejit.org/ + * @author mikael emtinger / http://gomo.se/ + * @author egraether / http://egraether.com/ + * @author WestLangley / http://github.com/WestLangley + */ - function Vector4( x, y, z, w ) { + function Vector4( x, y, z, w ) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; - this.w = ( w !== undefined ) ? w : 1; + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = ( w !== undefined ) ? w : 1; - } + } - Object.assign( Vector4.prototype, { + Object.assign( Vector4.prototype, { - isVector4: true, + isVector4: true, - set: function ( x, y, z, w ) { + set: function ( x, y, z, w ) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; + this.x = x; + this.y = y; + this.z = z; + this.w = w; - return this; + return this; - }, + }, - setScalar: function ( scalar ) { + setScalar: function ( scalar ) { - this.x = scalar; - this.y = scalar; - this.z = scalar; - this.w = scalar; + this.x = scalar; + this.y = scalar; + this.z = scalar; + this.w = scalar; - return this; + return this; - }, + }, - setX: function ( x ) { + setX: function ( x ) { - this.x = x; + this.x = x; - return this; + return this; - }, + }, - setY: function ( y ) { + setY: function ( y ) { - this.y = y; + this.y = y; - return this; + return this; - }, + }, - setZ: function ( z ) { + setZ: function ( z ) { - this.z = z; + this.z = z; - return this; + return this; - }, + }, - setW: function ( w ) { + setW: function ( w ) { - this.w = w; + this.w = w; - return this; + return this; - }, + }, - setComponent: function ( index, value ) { + setComponent: function ( index, value ) { - switch ( index ) { + switch ( index ) { - case 0: this.x = value; break; - case 1: this.y = value; break; - case 2: this.z = value; break; - case 3: this.w = value; break; - default: throw new Error( 'index is out of range: ' + index ); + case 0: this.x = value; break; + case 1: this.y = value; break; + case 2: this.z = value; break; + case 3: this.w = value; break; + default: throw new Error( 'index is out of range: ' + index ); - } + } - return this; + return this; - }, + }, - getComponent: function ( index ) { + getComponent: function ( index ) { - switch ( index ) { + switch ( index ) { - case 0: return this.x; - case 1: return this.y; - case 2: return this.z; - case 3: return this.w; - default: throw new Error( 'index is out of range: ' + index ); + case 0: return this.x; + case 1: return this.y; + case 2: return this.z; + case 3: return this.w; + default: throw new Error( 'index is out of range: ' + index ); - } + } - }, + }, - clone: function () { + clone: function () { - return new this.constructor( this.x, this.y, this.z, this.w ); + return new this.constructor( this.x, this.y, this.z, this.w ); - }, + }, - copy: function ( v ) { + copy: function ( v ) { - this.x = v.x; - this.y = v.y; - this.z = v.z; - this.w = ( v.w !== undefined ) ? v.w : 1; + this.x = v.x; + this.y = v.y; + this.z = v.z; + this.w = ( v.w !== undefined ) ? v.w : 1; - return this; + return this; - }, + }, - add: function ( v, w ) { + add: function ( v, w ) { - if ( w !== undefined ) { + if ( w !== undefined ) { - console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); - return this.addVectors( v, w ); + console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + return this.addVectors( v, w ); - } + } - this.x += v.x; - this.y += v.y; - this.z += v.z; - this.w += v.w; + this.x += v.x; + this.y += v.y; + this.z += v.z; + this.w += v.w; - return this; + return this; - }, + }, - addScalar: function ( s ) { + addScalar: function ( s ) { - this.x += s; - this.y += s; - this.z += s; - this.w += s; + this.x += s; + this.y += s; + this.z += s; + this.w += s; - return this; + return this; - }, + }, - addVectors: function ( a, b ) { + addVectors: function ( a, b ) { - this.x = a.x + b.x; - this.y = a.y + b.y; - this.z = a.z + b.z; - this.w = a.w + b.w; + this.x = a.x + b.x; + this.y = a.y + b.y; + this.z = a.z + b.z; + this.w = a.w + b.w; - return this; + return this; - }, + }, - addScaledVector: function ( v, s ) { + addScaledVector: function ( v, s ) { - this.x += v.x * s; - this.y += v.y * s; - this.z += v.z * s; - this.w += v.w * s; + this.x += v.x * s; + this.y += v.y * s; + this.z += v.z * s; + this.w += v.w * s; - return this; + return this; - }, + }, - sub: function ( v, w ) { + sub: function ( v, w ) { - if ( w !== undefined ) { + if ( w !== undefined ) { - console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); - return this.subVectors( v, w ); + console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + return this.subVectors( v, w ); - } + } - this.x -= v.x; - this.y -= v.y; - this.z -= v.z; - this.w -= v.w; + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + this.w -= v.w; - return this; + return this; - }, + }, - subScalar: function ( s ) { + subScalar: function ( s ) { - this.x -= s; - this.y -= s; - this.z -= s; - this.w -= s; + this.x -= s; + this.y -= s; + this.z -= s; + this.w -= s; - return this; + return this; - }, + }, - subVectors: function ( a, b ) { + subVectors: function ( a, b ) { - this.x = a.x - b.x; - this.y = a.y - b.y; - this.z = a.z - b.z; - this.w = a.w - b.w; + this.x = a.x - b.x; + this.y = a.y - b.y; + this.z = a.z - b.z; + this.w = a.w - b.w; - return this; + return this; - }, + }, - multiplyScalar: function ( scalar ) { + multiplyScalar: function ( scalar ) { - this.x *= scalar; - this.y *= scalar; - this.z *= scalar; - this.w *= scalar; + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; + this.w *= scalar; - return this; + return this; - }, + }, - applyMatrix4: function ( m ) { + applyMatrix4: function ( m ) { - var x = this.x, y = this.y, z = this.z, w = this.w; - var e = m.elements; + var x = this.x, y = this.y, z = this.z, w = this.w; + var e = m.elements; - this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; - this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w; - this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w; - this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w; + this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; + this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w; + this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w; + this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w; - return this; + return this; - }, + }, - divideScalar: function ( scalar ) { + divideScalar: function ( scalar ) { - return this.multiplyScalar( 1 / scalar ); + return this.multiplyScalar( 1 / scalar ); - }, + }, - setAxisAngleFromQuaternion: function ( q ) { + setAxisAngleFromQuaternion: function ( q ) { - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm - // q is assumed to be normalized + // q is assumed to be normalized - this.w = 2 * Math.acos( q.w ); + this.w = 2 * Math.acos( q.w ); - var s = Math.sqrt( 1 - q.w * q.w ); + var s = Math.sqrt( 1 - q.w * q.w ); - if ( s < 0.0001 ) { + if ( s < 0.0001 ) { - this.x = 1; - this.y = 0; - this.z = 0; + this.x = 1; + this.y = 0; + this.z = 0; - } else { + } else { - this.x = q.x / s; - this.y = q.y / s; - this.z = q.z / s; + this.x = q.x / s; + this.y = q.y / s; + this.z = q.z / s; - } + } - return this; + return this; - }, + }, - setAxisAngleFromRotationMatrix: function ( m ) { + setAxisAngleFromRotationMatrix: function ( m ) { - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - var angle, x, y, z, // variables for result - epsilon = 0.01, // margin to allow for rounding errors - epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees + var angle, x, y, z, // variables for result + epsilon = 0.01, // margin to allow for rounding errors + epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees - te = m.elements, + te = m.elements, - m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], - m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], - m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; + m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], + m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], + m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; - if ( ( Math.abs( m12 - m21 ) < epsilon ) && - ( Math.abs( m13 - m31 ) < epsilon ) && - ( Math.abs( m23 - m32 ) < epsilon ) ) { + if ( ( Math.abs( m12 - m21 ) < epsilon ) && + ( Math.abs( m13 - m31 ) < epsilon ) && + ( Math.abs( m23 - m32 ) < epsilon ) ) { - // singularity found - // first check for identity matrix which must have +1 for all terms - // in leading diagonal and zero in other terms + // singularity found + // first check for identity matrix which must have +1 for all terms + // in leading diagonal and zero in other terms - if ( ( Math.abs( m12 + m21 ) < epsilon2 ) && - ( Math.abs( m13 + m31 ) < epsilon2 ) && - ( Math.abs( m23 + m32 ) < epsilon2 ) && - ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { + if ( ( Math.abs( m12 + m21 ) < epsilon2 ) && + ( Math.abs( m13 + m31 ) < epsilon2 ) && + ( Math.abs( m23 + m32 ) < epsilon2 ) && + ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { - // this singularity is identity matrix so angle = 0 + // this singularity is identity matrix so angle = 0 - this.set( 1, 0, 0, 0 ); + this.set( 1, 0, 0, 0 ); - return this; // zero angle, arbitrary axis + return this; // zero angle, arbitrary axis - } + } - // otherwise this singularity is angle = 180 + // otherwise this singularity is angle = 180 - angle = Math.PI; + angle = Math.PI; - var xx = ( m11 + 1 ) / 2; - var yy = ( m22 + 1 ) / 2; - var zz = ( m33 + 1 ) / 2; - var xy = ( m12 + m21 ) / 4; - var xz = ( m13 + m31 ) / 4; - var yz = ( m23 + m32 ) / 4; + var xx = ( m11 + 1 ) / 2; + var yy = ( m22 + 1 ) / 2; + var zz = ( m33 + 1 ) / 2; + var xy = ( m12 + m21 ) / 4; + var xz = ( m13 + m31 ) / 4; + var yz = ( m23 + m32 ) / 4; - if ( ( xx > yy ) && ( xx > zz ) ) { + if ( ( xx > yy ) && ( xx > zz ) ) { - // m11 is the largest diagonal term + // m11 is the largest diagonal term - if ( xx < epsilon ) { + if ( xx < epsilon ) { - x = 0; - y = 0.707106781; - z = 0.707106781; + x = 0; + y = 0.707106781; + z = 0.707106781; - } else { + } else { - x = Math.sqrt( xx ); - y = xy / x; - z = xz / x; + x = Math.sqrt( xx ); + y = xy / x; + z = xz / x; - } + } - } else if ( yy > zz ) { + } else if ( yy > zz ) { - // m22 is the largest diagonal term + // m22 is the largest diagonal term - if ( yy < epsilon ) { + if ( yy < epsilon ) { - x = 0.707106781; - y = 0; - z = 0.707106781; + x = 0.707106781; + y = 0; + z = 0.707106781; - } else { + } else { - y = Math.sqrt( yy ); - x = xy / y; - z = yz / y; + y = Math.sqrt( yy ); + x = xy / y; + z = yz / y; - } + } - } else { + } else { - // m33 is the largest diagonal term so base result on this + // m33 is the largest diagonal term so base result on this - if ( zz < epsilon ) { + if ( zz < epsilon ) { - x = 0.707106781; - y = 0.707106781; - z = 0; + x = 0.707106781; + y = 0.707106781; + z = 0; - } else { + } else { - z = Math.sqrt( zz ); - x = xz / z; - y = yz / z; + z = Math.sqrt( zz ); + x = xz / z; + y = yz / z; - } + } - } + } - this.set( x, y, z, angle ); + this.set( x, y, z, angle ); - return this; // return 180 deg rotation + return this; // return 180 deg rotation - } + } - // as we have reached here there are no singularities so we can handle normally + // as we have reached here there are no singularities so we can handle normally - var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) + - ( m13 - m31 ) * ( m13 - m31 ) + - ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize + var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) + + ( m13 - m31 ) * ( m13 - m31 ) + + ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize - if ( Math.abs( s ) < 0.001 ) s = 1; + if ( Math.abs( s ) < 0.001 ) s = 1; - // prevent divide by zero, should not happen if matrix is orthogonal and should be - // caught by singularity test above, but I've left it in just in case + // prevent divide by zero, should not happen if matrix is orthogonal and should be + // caught by singularity test above, but I've left it in just in case - this.x = ( m32 - m23 ) / s; - this.y = ( m13 - m31 ) / s; - this.z = ( m21 - m12 ) / s; - this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); + this.x = ( m32 - m23 ) / s; + this.y = ( m13 - m31 ) / s; + this.z = ( m21 - m12 ) / s; + this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); - return this; + return this; - }, + }, - min: function ( v ) { + min: function ( v ) { - this.x = Math.min( this.x, v.x ); - this.y = Math.min( this.y, v.y ); - this.z = Math.min( this.z, v.z ); - this.w = Math.min( this.w, v.w ); + this.x = Math.min( this.x, v.x ); + this.y = Math.min( this.y, v.y ); + this.z = Math.min( this.z, v.z ); + this.w = Math.min( this.w, v.w ); - return this; + return this; - }, + }, - max: function ( v ) { + max: function ( v ) { - this.x = Math.max( this.x, v.x ); - this.y = Math.max( this.y, v.y ); - this.z = Math.max( this.z, v.z ); - this.w = Math.max( this.w, v.w ); + this.x = Math.max( this.x, v.x ); + this.y = Math.max( this.y, v.y ); + this.z = Math.max( this.z, v.z ); + this.w = Math.max( this.w, v.w ); - return this; + return this; - }, + }, - clamp: function ( min, max ) { + clamp: function ( min, max ) { - // assumes min < max, componentwise + // assumes min < max, componentwise - this.x = Math.max( min.x, Math.min( max.x, this.x ) ); - this.y = Math.max( min.y, Math.min( max.y, this.y ) ); - this.z = Math.max( min.z, Math.min( max.z, this.z ) ); - this.w = Math.max( min.w, Math.min( max.w, this.w ) ); + this.x = Math.max( min.x, Math.min( max.x, this.x ) ); + this.y = Math.max( min.y, Math.min( max.y, this.y ) ); + this.z = Math.max( min.z, Math.min( max.z, this.z ) ); + this.w = Math.max( min.w, Math.min( max.w, this.w ) ); - return this; + return this; - }, + }, - clampScalar: function () { + clampScalar: function () { - var min, max; + var min, max; - return function clampScalar( minVal, maxVal ) { + return function clampScalar( minVal, maxVal ) { - if ( min === undefined ) { + if ( min === undefined ) { - min = new Vector4(); - max = new Vector4(); + min = new Vector4(); + max = new Vector4(); - } + } - min.set( minVal, minVal, minVal, minVal ); - max.set( maxVal, maxVal, maxVal, maxVal ); + min.set( minVal, minVal, minVal, minVal ); + max.set( maxVal, maxVal, maxVal, maxVal ); - return this.clamp( min, max ); + return this.clamp( min, max ); - }; + }; - }(), + }(), - clampLength: function ( min, max ) { + clampLength: function ( min, max ) { - var length = this.length(); + var length = this.length(); - return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); + return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); - }, + }, - floor: function () { + floor: function () { - this.x = Math.floor( this.x ); - this.y = Math.floor( this.y ); - this.z = Math.floor( this.z ); - this.w = Math.floor( this.w ); + this.x = Math.floor( this.x ); + this.y = Math.floor( this.y ); + this.z = Math.floor( this.z ); + this.w = Math.floor( this.w ); - return this; + return this; - }, + }, - ceil: function () { + ceil: function () { - this.x = Math.ceil( this.x ); - this.y = Math.ceil( this.y ); - this.z = Math.ceil( this.z ); - this.w = Math.ceil( this.w ); + this.x = Math.ceil( this.x ); + this.y = Math.ceil( this.y ); + this.z = Math.ceil( this.z ); + this.w = Math.ceil( this.w ); - return this; + return this; - }, + }, - round: function () { + round: function () { - this.x = Math.round( this.x ); - this.y = Math.round( this.y ); - this.z = Math.round( this.z ); - this.w = Math.round( this.w ); + this.x = Math.round( this.x ); + this.y = Math.round( this.y ); + this.z = Math.round( this.z ); + this.w = Math.round( this.w ); - return this; + return this; - }, + }, - roundToZero: function () { + roundToZero: function () { - this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); - this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); - this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); - this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); + this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); + this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); + this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); + this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); - return this; + return this; - }, + }, - negate: function () { + negate: function () { - this.x = - this.x; - this.y = - this.y; - this.z = - this.z; - this.w = - this.w; + this.x = - this.x; + this.y = - this.y; + this.z = - this.z; + this.w = - this.w; - return this; + return this; - }, + }, - dot: function ( v ) { + dot: function ( v ) { - return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; + return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; - }, + }, - lengthSq: function () { + lengthSq: function () { - return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; + return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; - }, + }, - length: function () { + length: function () { - return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); + return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); - }, + }, - manhattanLength: function () { + manhattanLength: function () { - return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w ); + return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w ); - }, + }, - normalize: function () { + normalize: function () { - return this.divideScalar( this.length() || 1 ); + return this.divideScalar( this.length() || 1 ); - }, + }, - setLength: function ( length ) { + setLength: function ( length ) { - return this.normalize().multiplyScalar( length ); + return this.normalize().multiplyScalar( length ); - }, + }, - lerp: function ( v, alpha ) { + lerp: function ( v, alpha ) { - this.x += ( v.x - this.x ) * alpha; - this.y += ( v.y - this.y ) * alpha; - this.z += ( v.z - this.z ) * alpha; - this.w += ( v.w - this.w ) * alpha; + this.x += ( v.x - this.x ) * alpha; + this.y += ( v.y - this.y ) * alpha; + this.z += ( v.z - this.z ) * alpha; + this.w += ( v.w - this.w ) * alpha; - return this; + return this; - }, + }, - lerpVectors: function ( v1, v2, alpha ) { + lerpVectors: function ( v1, v2, alpha ) { - return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); + return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); - }, + }, - equals: function ( v ) { + equals: function ( v ) { - return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) ); + return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) ); - }, + }, - fromArray: function ( array, offset ) { + fromArray: function ( array, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - this.x = array[ offset ]; - this.y = array[ offset + 1 ]; - this.z = array[ offset + 2 ]; - this.w = array[ offset + 3 ]; + this.x = array[ offset ]; + this.y = array[ offset + 1 ]; + this.z = array[ offset + 2 ]; + this.w = array[ offset + 3 ]; - return this; + return this; - }, + }, - toArray: function ( array, offset ) { + toArray: function ( array, offset ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - array[ offset ] = this.x; - array[ offset + 1 ] = this.y; - array[ offset + 2 ] = this.z; - array[ offset + 3 ] = this.w; + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; + array[ offset + 2 ] = this.z; + array[ offset + 3 ] = this.w; - return array; + return array; - }, + }, - fromBufferAttribute: function ( attribute, index, offset ) { + fromBufferAttribute: function ( attribute, index, offset ) { - if ( offset !== undefined ) { + if ( offset !== undefined ) { - console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' ); + console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' ); - } + } - this.x = attribute.getX( index ); - this.y = attribute.getY( index ); - this.z = attribute.getZ( index ); - this.w = attribute.getW( index ); + this.x = attribute.getX( index ); + this.y = attribute.getY( index ); + this.z = attribute.getZ( index ); + this.w = attribute.getW( index ); - return this; + return this; - } + } - } ); + } ); - /** - * @author szimek / https://github.com/szimek/ - * @author alteredq / http://alteredqualia.com/ - * @author Marius Kintel / https://github.com/kintel - */ + /** + * @author szimek / https://github.com/szimek/ + * @author alteredq / http://alteredqualia.com/ + * @author Marius Kintel / https://github.com/kintel + */ - /* - In options, we can specify: - * Texture parameters for an auto-generated target texture - * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers - */ - function WebGLRenderTarget( width, height, options ) { + /* + In options, we can specify: + * Texture parameters for an auto-generated target texture + * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers + */ + function WebGLRenderTarget( width, height, options ) { - this.width = width; - this.height = height; + this.width = width; + this.height = height; - this.scissor = new Vector4( 0, 0, width, height ); - this.scissorTest = false; + this.scissor = new Vector4( 0, 0, width, height ); + this.scissorTest = false; - this.viewport = new Vector4( 0, 0, width, height ); + this.viewport = new Vector4( 0, 0, width, height ); - options = options || {}; + options = options || {}; - if ( options.minFilter === undefined ) options.minFilter = LinearFilter; + if ( options.minFilter === undefined ) options.minFilter = LinearFilter; - this.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding ); + this.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding ); - this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : true; + this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : true; - this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; - this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true; - this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; + this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; + this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true; + this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; - } + } - WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { + WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - constructor: WebGLRenderTarget, + constructor: WebGLRenderTarget, - isWebGLRenderTarget: true, + isWebGLRenderTarget: true, - setSize: function ( width, height ) { + setSize: function ( width, height ) { - if ( this.width !== width || this.height !== height ) { + if ( this.width !== width || this.height !== height ) { - this.width = width; - this.height = height; + this.width = width; + this.height = height; - this.dispose(); + this.dispose(); - } + } - this.viewport.set( 0, 0, width, height ); - this.scissor.set( 0, 0, width, height ); + this.viewport.set( 0, 0, width, height ); + this.scissor.set( 0, 0, width, height ); - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( source ) { + copy: function ( source ) { - this.width = source.width; - this.height = source.height; + this.width = source.width; + this.height = source.height; - this.viewport.copy( source.viewport ); + this.viewport.copy( source.viewport ); - this.texture = source.texture.clone(); + this.texture = source.texture.clone(); - this.depthBuffer = source.depthBuffer; - this.stencilBuffer = source.stencilBuffer; - this.depthTexture = source.depthTexture; + this.depthBuffer = source.depthBuffer; + this.stencilBuffer = source.stencilBuffer; + this.depthTexture = source.depthTexture; - return this; + return this; - }, + }, - dispose: function () { + dispose: function () { - this.dispatchEvent( { type: 'dispose' } ); + this.dispatchEvent( { type: 'dispose' } ); - } + } - } ); + } ); - /** - * @author alteredq / http://alteredqualia.com - */ + /** + * @author alteredq / http://alteredqualia.com + */ - function WebGLRenderTargetCube( width, height, options ) { + function WebGLRenderTargetCube( width, height, options ) { - WebGLRenderTarget.call( this, width, height, options ); + WebGLRenderTarget.call( this, width, height, options ); - this.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5 - this.activeMipMapLevel = 0; + this.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5 + this.activeMipMapLevel = 0; - } + } - WebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype ); - WebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube; + WebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype ); + WebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube; - WebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true; + WebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true; - /** - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author alteredq / http://alteredqualia.com/ + */ - function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { + function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { - Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); + Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); - this.image = { data: data, width: width, height: height }; + this.image = { data: data, width: width, height: height }; - this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; - this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; + this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; + this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; - this.generateMipmaps = false; - this.flipY = false; - this.unpackAlignment = 1; + this.generateMipmaps = false; + this.flipY = false; + this.unpackAlignment = 1; - } + } - DataTexture.prototype = Object.create( Texture.prototype ); - DataTexture.prototype.constructor = DataTexture; + DataTexture.prototype = Object.create( Texture.prototype ); + DataTexture.prototype.constructor = DataTexture; - DataTexture.prototype.isDataTexture = true; + DataTexture.prototype.isDataTexture = true; - /** - * @author bhouston / http://clara.io - * @author WestLangley / http://github.com/WestLangley - */ + /** + * @author bhouston / http://clara.io + * @author WestLangley / http://github.com/WestLangley + */ - function Box3( min, max ) { + function Box3( min, max ) { - this.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity ); - this.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity ); + this.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity ); + this.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity ); - } + } - Object.assign( Box3.prototype, { + Object.assign( Box3.prototype, { - isBox3: true, + isBox3: true, - set: function ( min, max ) { + set: function ( min, max ) { - this.min.copy( min ); - this.max.copy( max ); + this.min.copy( min ); + this.max.copy( max ); - return this; + return this; - }, + }, - setFromArray: function ( array ) { + setFromArray: function ( array ) { - var minX = + Infinity; - var minY = + Infinity; - var minZ = + Infinity; + var minX = + Infinity; + var minY = + Infinity; + var minZ = + Infinity; - var maxX = - Infinity; - var maxY = - Infinity; - var maxZ = - Infinity; + var maxX = - Infinity; + var maxY = - Infinity; + var maxZ = - Infinity; - for ( var i = 0, l = array.length; i < l; i += 3 ) { + for ( var i = 0, l = array.length; i < l; i += 3 ) { - var x = array[ i ]; - var y = array[ i + 1 ]; - var z = array[ i + 2 ]; + var x = array[ i ]; + var y = array[ i + 1 ]; + var z = array[ i + 2 ]; - if ( x < minX ) minX = x; - if ( y < minY ) minY = y; - if ( z < minZ ) minZ = z; + if ( x < minX ) minX = x; + if ( y < minY ) minY = y; + if ( z < minZ ) minZ = z; - if ( x > maxX ) maxX = x; - if ( y > maxY ) maxY = y; - if ( z > maxZ ) maxZ = z; + if ( x > maxX ) maxX = x; + if ( y > maxY ) maxY = y; + if ( z > maxZ ) maxZ = z; - } + } - this.min.set( minX, minY, minZ ); - this.max.set( maxX, maxY, maxZ ); + this.min.set( minX, minY, minZ ); + this.max.set( maxX, maxY, maxZ ); - return this; + return this; - }, + }, - setFromBufferAttribute: function ( attribute ) { + setFromBufferAttribute: function ( attribute ) { - var minX = + Infinity; - var minY = + Infinity; - var minZ = + Infinity; + var minX = + Infinity; + var minY = + Infinity; + var minZ = + Infinity; - var maxX = - Infinity; - var maxY = - Infinity; - var maxZ = - Infinity; + var maxX = - Infinity; + var maxY = - Infinity; + var maxZ = - Infinity; - for ( var i = 0, l = attribute.count; i < l; i ++ ) { + for ( var i = 0, l = attribute.count; i < l; i ++ ) { - var x = attribute.getX( i ); - var y = attribute.getY( i ); - var z = attribute.getZ( i ); + var x = attribute.getX( i ); + var y = attribute.getY( i ); + var z = attribute.getZ( i ); - if ( x < minX ) minX = x; - if ( y < minY ) minY = y; - if ( z < minZ ) minZ = z; + if ( x < minX ) minX = x; + if ( y < minY ) minY = y; + if ( z < minZ ) minZ = z; - if ( x > maxX ) maxX = x; - if ( y > maxY ) maxY = y; - if ( z > maxZ ) maxZ = z; + if ( x > maxX ) maxX = x; + if ( y > maxY ) maxY = y; + if ( z > maxZ ) maxZ = z; - } + } - this.min.set( minX, minY, minZ ); - this.max.set( maxX, maxY, maxZ ); + this.min.set( minX, minY, minZ ); + this.max.set( maxX, maxY, maxZ ); - return this; + return this; - }, + }, - setFromPoints: function ( points ) { + setFromPoints: function ( points ) { - this.makeEmpty(); + this.makeEmpty(); - for ( var i = 0, il = points.length; i < il; i ++ ) { + for ( var i = 0, il = points.length; i < il; i ++ ) { - this.expandByPoint( points[ i ] ); + this.expandByPoint( points[ i ] ); - } + } - return this; + return this; - }, + }, - setFromCenterAndSize: function () { + setFromCenterAndSize: function () { - var v1 = new Vector3(); + var v1 = new Vector3(); - return function setFromCenterAndSize( center, size ) { + return function setFromCenterAndSize( center, size ) { - var halfSize = v1.copy( size ).multiplyScalar( 0.5 ); + var halfSize = v1.copy( size ).multiplyScalar( 0.5 ); - this.min.copy( center ).sub( halfSize ); - this.max.copy( center ).add( halfSize ); + this.min.copy( center ).sub( halfSize ); + this.max.copy( center ).add( halfSize ); - return this; + return this; - }; + }; - }(), + }(), - setFromObject: function ( object ) { + setFromObject: function ( object ) { - this.makeEmpty(); + this.makeEmpty(); - return this.expandByObject( object ); + return this.expandByObject( object ); - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( box ) { + copy: function ( box ) { - this.min.copy( box.min ); - this.max.copy( box.max ); + this.min.copy( box.min ); + this.max.copy( box.max ); - return this; + return this; - }, + }, - makeEmpty: function () { + makeEmpty: function () { - this.min.x = this.min.y = this.min.z = + Infinity; - this.max.x = this.max.y = this.max.z = - Infinity; + this.min.x = this.min.y = this.min.z = + Infinity; + this.max.x = this.max.y = this.max.z = - Infinity; - return this; + return this; - }, + }, - isEmpty: function () { + isEmpty: function () { - // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes + // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes - return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z ); + return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z ); - }, + }, - getCenter: function ( target ) { + getCenter: function ( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Box3: .getCenter() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Box3: .getCenter() target is now required' ); + target = new Vector3(); - } + } - return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); + return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); - }, + }, - getSize: function ( target ) { + getSize: function ( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Box3: .getSize() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Box3: .getSize() target is now required' ); + target = new Vector3(); - } + } - return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min ); + return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min ); - }, + }, - expandByPoint: function ( point ) { + expandByPoint: function ( point ) { - this.min.min( point ); - this.max.max( point ); + this.min.min( point ); + this.max.max( point ); - return this; + return this; - }, + }, - expandByVector: function ( vector ) { + expandByVector: function ( vector ) { - this.min.sub( vector ); - this.max.add( vector ); + this.min.sub( vector ); + this.max.add( vector ); - return this; + return this; - }, + }, - expandByScalar: function ( scalar ) { + expandByScalar: function ( scalar ) { - this.min.addScalar( - scalar ); - this.max.addScalar( scalar ); + this.min.addScalar( - scalar ); + this.max.addScalar( scalar ); - return this; + return this; - }, + }, - expandByObject: function () { + expandByObject: function () { - // Computes the world-axis-aligned bounding box of an object (including its children), - // accounting for both the object's, and children's, world transforms + // Computes the world-axis-aligned bounding box of an object (including its children), + // accounting for both the object's, and children's, world transforms - var scope, i, l; + var scope, i, l; - var v1 = new Vector3(); + var v1 = new Vector3(); - function traverse( node ) { + function traverse( node ) { - var geometry = node.geometry; + var geometry = node.geometry; - if ( geometry !== undefined ) { + if ( geometry !== undefined ) { - if ( geometry.isGeometry ) { + if ( geometry.isGeometry ) { - var vertices = geometry.vertices; + var vertices = geometry.vertices; - for ( i = 0, l = vertices.length; i < l; i ++ ) { + for ( i = 0, l = vertices.length; i < l; i ++ ) { - v1.copy( vertices[ i ] ); - v1.applyMatrix4( node.matrixWorld ); + v1.copy( vertices[ i ] ); + v1.applyMatrix4( node.matrixWorld ); - scope.expandByPoint( v1 ); + scope.expandByPoint( v1 ); - } + } - } else if ( geometry.isBufferGeometry ) { + } else if ( geometry.isBufferGeometry ) { - var attribute = geometry.attributes.position; + var attribute = geometry.attributes.position; - if ( attribute !== undefined ) { + if ( attribute !== undefined ) { - for ( i = 0, l = attribute.count; i < l; i ++ ) { + for ( i = 0, l = attribute.count; i < l; i ++ ) { - v1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld ); + v1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld ); - scope.expandByPoint( v1 ); + scope.expandByPoint( v1 ); - } + } - } + } - } + } - } + } - } + } - return function expandByObject( object ) { + return function expandByObject( object ) { - scope = this; + scope = this; - object.updateMatrixWorld( true ); + object.updateMatrixWorld( true ); - object.traverse( traverse ); + object.traverse( traverse ); - return this; + return this; - }; + }; - }(), + }(), - containsPoint: function ( point ) { + containsPoint: function ( point ) { - return point.x < this.min.x || point.x > this.max.x || - point.y < this.min.y || point.y > this.max.y || - point.z < this.min.z || point.z > this.max.z ? false : true; + return point.x < this.min.x || point.x > this.max.x || + point.y < this.min.y || point.y > this.max.y || + point.z < this.min.z || point.z > this.max.z ? false : true; - }, + }, - containsBox: function ( box ) { + containsBox: function ( box ) { - return this.min.x <= box.min.x && box.max.x <= this.max.x && - this.min.y <= box.min.y && box.max.y <= this.max.y && - this.min.z <= box.min.z && box.max.z <= this.max.z; + return this.min.x <= box.min.x && box.max.x <= this.max.x && + this.min.y <= box.min.y && box.max.y <= this.max.y && + this.min.z <= box.min.z && box.max.z <= this.max.z; - }, + }, - getParameter: function ( point, target ) { + getParameter: function ( point, target ) { - // This can potentially have a divide by zero if the box - // has a size dimension of 0. + // This can potentially have a divide by zero if the box + // has a size dimension of 0. - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Box3: .getParameter() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Box3: .getParameter() target is now required' ); + target = new Vector3(); - } + } - return target.set( - ( point.x - this.min.x ) / ( this.max.x - this.min.x ), - ( point.y - this.min.y ) / ( this.max.y - this.min.y ), - ( point.z - this.min.z ) / ( this.max.z - this.min.z ) - ); + return target.set( + ( point.x - this.min.x ) / ( this.max.x - this.min.x ), + ( point.y - this.min.y ) / ( this.max.y - this.min.y ), + ( point.z - this.min.z ) / ( this.max.z - this.min.z ) + ); - }, + }, - intersectsBox: function ( box ) { + intersectsBox: function ( box ) { - // using 6 splitting planes to rule out intersections. - return box.max.x < this.min.x || box.min.x > this.max.x || - box.max.y < this.min.y || box.min.y > this.max.y || - box.max.z < this.min.z || box.min.z > this.max.z ? false : true; + // using 6 splitting planes to rule out intersections. + return box.max.x < this.min.x || box.min.x > this.max.x || + box.max.y < this.min.y || box.min.y > this.max.y || + box.max.z < this.min.z || box.min.z > this.max.z ? false : true; - }, + }, - intersectsSphere: ( function () { + intersectsSphere: ( function () { - var closestPoint = new Vector3(); + var closestPoint = new Vector3(); - return function intersectsSphere( sphere ) { + return function intersectsSphere( sphere ) { - // Find the point on the AABB closest to the sphere center. - this.clampPoint( sphere.center, closestPoint ); + // Find the point on the AABB closest to the sphere center. + this.clampPoint( sphere.center, closestPoint ); - // If that point is inside the sphere, the AABB and sphere intersect. - return closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); + // If that point is inside the sphere, the AABB and sphere intersect. + return closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); - }; + }; - } )(), + } )(), - intersectsPlane: function ( plane ) { + intersectsPlane: function ( plane ) { - // We compute the minimum and maximum dot product values. If those values - // are on the same side (back or front) of the plane, then there is no intersection. + // We compute the minimum and maximum dot product values. If those values + // are on the same side (back or front) of the plane, then there is no intersection. - var min, max; + var min, max; - if ( plane.normal.x > 0 ) { + if ( plane.normal.x > 0 ) { - min = plane.normal.x * this.min.x; - max = plane.normal.x * this.max.x; + min = plane.normal.x * this.min.x; + max = plane.normal.x * this.max.x; - } else { + } else { - min = plane.normal.x * this.max.x; - max = plane.normal.x * this.min.x; + min = plane.normal.x * this.max.x; + max = plane.normal.x * this.min.x; - } + } - if ( plane.normal.y > 0 ) { + if ( plane.normal.y > 0 ) { - min += plane.normal.y * this.min.y; - max += plane.normal.y * this.max.y; + min += plane.normal.y * this.min.y; + max += plane.normal.y * this.max.y; - } else { + } else { - min += plane.normal.y * this.max.y; - max += plane.normal.y * this.min.y; + min += plane.normal.y * this.max.y; + max += plane.normal.y * this.min.y; - } + } - if ( plane.normal.z > 0 ) { + if ( plane.normal.z > 0 ) { - min += plane.normal.z * this.min.z; - max += plane.normal.z * this.max.z; + min += plane.normal.z * this.min.z; + max += plane.normal.z * this.max.z; - } else { + } else { - min += plane.normal.z * this.max.z; - max += plane.normal.z * this.min.z; + min += plane.normal.z * this.max.z; + max += plane.normal.z * this.min.z; - } + } - return ( min <= plane.constant && max >= plane.constant ); + return ( min <= plane.constant && max >= plane.constant ); - }, + }, - intersectsTriangle: ( function () { + intersectsTriangle: ( function () { - // triangle centered vertices - var v0 = new Vector3(); - var v1 = new Vector3(); - var v2 = new Vector3(); + // triangle centered vertices + var v0 = new Vector3(); + var v1 = new Vector3(); + var v2 = new Vector3(); - // triangle edge vectors - var f0 = new Vector3(); - var f1 = new Vector3(); - var f2 = new Vector3(); + // triangle edge vectors + var f0 = new Vector3(); + var f1 = new Vector3(); + var f2 = new Vector3(); - var testAxis = new Vector3(); + var testAxis = new Vector3(); - var center = new Vector3(); - var extents = new Vector3(); + var center = new Vector3(); + var extents = new Vector3(); - var triangleNormal = new Vector3(); + var triangleNormal = new Vector3(); - function satForAxes( axes ) { + function satForAxes( axes ) { - var i, j; + var i, j; - for ( i = 0, j = axes.length - 3; i <= j; i += 3 ) { + for ( i = 0, j = axes.length - 3; i <= j; i += 3 ) { - testAxis.fromArray( axes, i ); - // project the aabb onto the seperating axis - var r = extents.x * Math.abs( testAxis.x ) + extents.y * Math.abs( testAxis.y ) + extents.z * Math.abs( testAxis.z ); - // project all 3 vertices of the triangle onto the seperating axis - var p0 = v0.dot( testAxis ); - var p1 = v1.dot( testAxis ); - var p2 = v2.dot( testAxis ); - // actual test, basically see if either of the most extreme of the triangle points intersects r - if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) { + testAxis.fromArray( axes, i ); + // project the aabb onto the seperating axis + var r = extents.x * Math.abs( testAxis.x ) + extents.y * Math.abs( testAxis.y ) + extents.z * Math.abs( testAxis.z ); + // project all 3 vertices of the triangle onto the seperating axis + var p0 = v0.dot( testAxis ); + var p1 = v1.dot( testAxis ); + var p2 = v2.dot( testAxis ); + // actual test, basically see if either of the most extreme of the triangle points intersects r + if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) { - // points of the projected triangle are outside the projected half-length of the aabb - // the axis is seperating and we can exit - return false; + // points of the projected triangle are outside the projected half-length of the aabb + // the axis is seperating and we can exit + return false; - } + } - } + } - return true; + return true; - } + } - return function intersectsTriangle( triangle ) { + return function intersectsTriangle( triangle ) { - if ( this.isEmpty() ) { + if ( this.isEmpty() ) { - return false; + return false; - } + } - // compute box center and extents - this.getCenter( center ); - extents.subVectors( this.max, center ); + // compute box center and extents + this.getCenter( center ); + extents.subVectors( this.max, center ); - // translate triangle to aabb origin - v0.subVectors( triangle.a, center ); - v1.subVectors( triangle.b, center ); - v2.subVectors( triangle.c, center ); + // translate triangle to aabb origin + v0.subVectors( triangle.a, center ); + v1.subVectors( triangle.b, center ); + v2.subVectors( triangle.c, center ); - // compute edge vectors for triangle - f0.subVectors( v1, v0 ); - f1.subVectors( v2, v1 ); - f2.subVectors( v0, v2 ); + // compute edge vectors for triangle + f0.subVectors( v1, v0 ); + f1.subVectors( v2, v1 ); + f2.subVectors( v0, v2 ); - // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb - // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation - // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) - var axes = [ - 0, - f0.z, f0.y, 0, - f1.z, f1.y, 0, - f2.z, f2.y, - f0.z, 0, - f0.x, f1.z, 0, - f1.x, f2.z, 0, - f2.x, - - f0.y, f0.x, 0, - f1.y, f1.x, 0, - f2.y, f2.x, 0 - ]; - if ( ! satForAxes( axes ) ) { + // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb + // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation + // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) + var axes = [ + 0, - f0.z, f0.y, 0, - f1.z, f1.y, 0, - f2.z, f2.y, + f0.z, 0, - f0.x, f1.z, 0, - f1.x, f2.z, 0, - f2.x, + - f0.y, f0.x, 0, - f1.y, f1.x, 0, - f2.y, f2.x, 0 + ]; + if ( ! satForAxes( axes ) ) { - return false; + return false; - } + } - // test 3 face normals from the aabb - axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; - if ( ! satForAxes( axes ) ) { + // test 3 face normals from the aabb + axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; + if ( ! satForAxes( axes ) ) { - return false; + return false; - } + } - // finally testing the face normal of the triangle - // use already existing triangle edge vectors here - triangleNormal.crossVectors( f0, f1 ); - axes = [ triangleNormal.x, triangleNormal.y, triangleNormal.z ]; - return satForAxes( axes ); + // finally testing the face normal of the triangle + // use already existing triangle edge vectors here + triangleNormal.crossVectors( f0, f1 ); + axes = [ triangleNormal.x, triangleNormal.y, triangleNormal.z ]; + return satForAxes( axes ); - }; + }; - } )(), + } )(), - clampPoint: function ( point, target ) { + clampPoint: function ( point, target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Box3: .clampPoint() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Box3: .clampPoint() target is now required' ); + target = new Vector3(); - } + } - return target.copy( point ).clamp( this.min, this.max ); + return target.copy( point ).clamp( this.min, this.max ); - }, + }, - distanceToPoint: function () { + distanceToPoint: function () { - var v1 = new Vector3(); + var v1 = new Vector3(); - return function distanceToPoint( point ) { + return function distanceToPoint( point ) { - var clampedPoint = v1.copy( point ).clamp( this.min, this.max ); - return clampedPoint.sub( point ).length(); + var clampedPoint = v1.copy( point ).clamp( this.min, this.max ); + return clampedPoint.sub( point ).length(); - }; + }; - }(), + }(), - getBoundingSphere: function () { + getBoundingSphere: function () { - var v1 = new Vector3(); + var v1 = new Vector3(); - return function getBoundingSphere( target ) { + return function getBoundingSphere( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Box3: .getBoundingSphere() target is now required' ); - target = new Sphere(); + console.warn( 'THREE.Box3: .getBoundingSphere() target is now required' ); + target = new Sphere(); - } + } - this.getCenter( target.center ); + this.getCenter( target.center ); - target.radius = this.getSize( v1 ).length() * 0.5; + target.radius = this.getSize( v1 ).length() * 0.5; - return target; + return target; - }; + }; - }(), + }(), - intersect: function ( box ) { + intersect: function ( box ) { - this.min.max( box.min ); - this.max.min( box.max ); + this.min.max( box.min ); + this.max.min( box.max ); - // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values. - if ( this.isEmpty() ) this.makeEmpty(); + // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values. + if ( this.isEmpty() ) this.makeEmpty(); - return this; + return this; - }, + }, - union: function ( box ) { + union: function ( box ) { - this.min.min( box.min ); - this.max.max( box.max ); + this.min.min( box.min ); + this.max.max( box.max ); - return this; + return this; - }, + }, - applyMatrix4: function ( matrix ) { + applyMatrix4: function ( matrix ) { - // transform of empty box is an empty box. - if ( this.isEmpty( ) ) return this; + // transform of empty box is an empty box. + if ( this.isEmpty( ) ) return this; - var m = matrix.elements; + var m = matrix.elements; - var xax = m[ 0 ] * this.min.x, xay = m[ 1 ] * this.min.x, xaz = m[ 2 ] * this.min.x; - var xbx = m[ 0 ] * this.max.x, xby = m[ 1 ] * this.max.x, xbz = m[ 2 ] * this.max.x; - var yax = m[ 4 ] * this.min.y, yay = m[ 5 ] * this.min.y, yaz = m[ 6 ] * this.min.y; - var ybx = m[ 4 ] * this.max.y, yby = m[ 5 ] * this.max.y, ybz = m[ 6 ] * this.max.y; - var zax = m[ 8 ] * this.min.z, zay = m[ 9 ] * this.min.z, zaz = m[ 10 ] * this.min.z; - var zbx = m[ 8 ] * this.max.z, zby = m[ 9 ] * this.max.z, zbz = m[ 10 ] * this.max.z; + var xax = m[ 0 ] * this.min.x, xay = m[ 1 ] * this.min.x, xaz = m[ 2 ] * this.min.x; + var xbx = m[ 0 ] * this.max.x, xby = m[ 1 ] * this.max.x, xbz = m[ 2 ] * this.max.x; + var yax = m[ 4 ] * this.min.y, yay = m[ 5 ] * this.min.y, yaz = m[ 6 ] * this.min.y; + var ybx = m[ 4 ] * this.max.y, yby = m[ 5 ] * this.max.y, ybz = m[ 6 ] * this.max.y; + var zax = m[ 8 ] * this.min.z, zay = m[ 9 ] * this.min.z, zaz = m[ 10 ] * this.min.z; + var zbx = m[ 8 ] * this.max.z, zby = m[ 9 ] * this.max.z, zbz = m[ 10 ] * this.max.z; - this.min.x = Math.min( xax, xbx ) + Math.min( yax, ybx ) + Math.min( zax, zbx ) + m[ 12 ]; - this.min.y = Math.min( xay, xby ) + Math.min( yay, yby ) + Math.min( zay, zby ) + m[ 13 ]; - this.min.z = Math.min( xaz, xbz ) + Math.min( yaz, ybz ) + Math.min( zaz, zbz ) + m[ 14 ]; - this.max.x = Math.max( xax, xbx ) + Math.max( yax, ybx ) + Math.max( zax, zbx ) + m[ 12 ]; - this.max.y = Math.max( xay, xby ) + Math.max( yay, yby ) + Math.max( zay, zby ) + m[ 13 ]; - this.max.z = Math.max( xaz, xbz ) + Math.max( yaz, ybz ) + Math.max( zaz, zbz ) + m[ 14 ]; + this.min.x = Math.min( xax, xbx ) + Math.min( yax, ybx ) + Math.min( zax, zbx ) + m[ 12 ]; + this.min.y = Math.min( xay, xby ) + Math.min( yay, yby ) + Math.min( zay, zby ) + m[ 13 ]; + this.min.z = Math.min( xaz, xbz ) + Math.min( yaz, ybz ) + Math.min( zaz, zbz ) + m[ 14 ]; + this.max.x = Math.max( xax, xbx ) + Math.max( yax, ybx ) + Math.max( zax, zbx ) + m[ 12 ]; + this.max.y = Math.max( xay, xby ) + Math.max( yay, yby ) + Math.max( zay, zby ) + m[ 13 ]; + this.max.z = Math.max( xaz, xbz ) + Math.max( yaz, ybz ) + Math.max( zaz, zbz ) + m[ 14 ]; - return this; + return this; - }, + }, - translate: function ( offset ) { + translate: function ( offset ) { - this.min.add( offset ); - this.max.add( offset ); + this.min.add( offset ); + this.max.add( offset ); - return this; + return this; - }, + }, - equals: function ( box ) { + equals: function ( box ) { - return box.min.equals( this.min ) && box.max.equals( this.max ); + return box.min.equals( this.min ) && box.max.equals( this.max ); - } + } - } ); + } ); - /** - * @author bhouston / http://clara.io - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author bhouston / http://clara.io + * @author mrdoob / http://mrdoob.com/ + */ - function Sphere( center, radius ) { + function Sphere( center, radius ) { - this.center = ( center !== undefined ) ? center : new Vector3(); - this.radius = ( radius !== undefined ) ? radius : 0; + this.center = ( center !== undefined ) ? center : new Vector3(); + this.radius = ( radius !== undefined ) ? radius : 0; - } + } - Object.assign( Sphere.prototype, { + Object.assign( Sphere.prototype, { - set: function ( center, radius ) { + set: function ( center, radius ) { - this.center.copy( center ); - this.radius = radius; + this.center.copy( center ); + this.radius = radius; - return this; + return this; - }, + }, - setFromPoints: function () { + setFromPoints: function () { - var box = new Box3(); + var box = new Box3(); - return function setFromPoints( points, optionalCenter ) { + return function setFromPoints( points, optionalCenter ) { - var center = this.center; + var center = this.center; - if ( optionalCenter !== undefined ) { + if ( optionalCenter !== undefined ) { - center.copy( optionalCenter ); + center.copy( optionalCenter ); - } else { + } else { - box.setFromPoints( points ).getCenter( center ); + box.setFromPoints( points ).getCenter( center ); - } + } - var maxRadiusSq = 0; + var maxRadiusSq = 0; - for ( var i = 0, il = points.length; i < il; i ++ ) { + for ( var i = 0, il = points.length; i < il; i ++ ) { - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); - } + } - this.radius = Math.sqrt( maxRadiusSq ); + this.radius = Math.sqrt( maxRadiusSq ); - return this; + return this; - }; + }; - }(), + }(), - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( sphere ) { + copy: function ( sphere ) { - this.center.copy( sphere.center ); - this.radius = sphere.radius; + this.center.copy( sphere.center ); + this.radius = sphere.radius; - return this; + return this; - }, + }, - empty: function () { + empty: function () { - return ( this.radius <= 0 ); + return ( this.radius <= 0 ); - }, + }, - containsPoint: function ( point ) { + containsPoint: function ( point ) { - return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); + return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); - }, + }, - distanceToPoint: function ( point ) { + distanceToPoint: function ( point ) { - return ( point.distanceTo( this.center ) - this.radius ); + return ( point.distanceTo( this.center ) - this.radius ); - }, + }, - intersectsSphere: function ( sphere ) { + intersectsSphere: function ( sphere ) { - var radiusSum = this.radius + sphere.radius; + var radiusSum = this.radius + sphere.radius; - return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); + return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); - }, + }, - intersectsBox: function ( box ) { + intersectsBox: function ( box ) { - return box.intersectsSphere( this ); + return box.intersectsSphere( this ); - }, + }, - intersectsPlane: function ( plane ) { + intersectsPlane: function ( plane ) { - return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius; + return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius; - }, + }, - clampPoint: function ( point, target ) { + clampPoint: function ( point, target ) { - var deltaLengthSq = this.center.distanceToSquared( point ); + var deltaLengthSq = this.center.distanceToSquared( point ); - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Sphere: .clampPoint() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Sphere: .clampPoint() target is now required' ); + target = new Vector3(); - } + } - target.copy( point ); + target.copy( point ); - if ( deltaLengthSq > ( this.radius * this.radius ) ) { + if ( deltaLengthSq > ( this.radius * this.radius ) ) { - target.sub( this.center ).normalize(); - target.multiplyScalar( this.radius ).add( this.center ); + target.sub( this.center ).normalize(); + target.multiplyScalar( this.radius ).add( this.center ); - } + } - return target; + return target; - }, + }, - getBoundingBox: function ( target ) { + getBoundingBox: function ( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Sphere: .getBoundingBox() target is now required' ); - target = new Box3(); + console.warn( 'THREE.Sphere: .getBoundingBox() target is now required' ); + target = new Box3(); - } + } - target.set( this.center, this.center ); - target.expandByScalar( this.radius ); + target.set( this.center, this.center ); + target.expandByScalar( this.radius ); - return target; + return target; - }, + }, - applyMatrix4: function ( matrix ) { + applyMatrix4: function ( matrix ) { - this.center.applyMatrix4( matrix ); - this.radius = this.radius * matrix.getMaxScaleOnAxis(); + this.center.applyMatrix4( matrix ); + this.radius = this.radius * matrix.getMaxScaleOnAxis(); - return this; + return this; - }, + }, - translate: function ( offset ) { + translate: function ( offset ) { - this.center.add( offset ); + this.center.add( offset ); - return this; + return this; - }, + }, - equals: function ( sphere ) { + equals: function ( sphere ) { - return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); + return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); - } + } - } ); + } ); - /** - * @author bhouston / http://clara.io - */ + /** + * @author bhouston / http://clara.io + */ - function Plane( normal, constant ) { + function Plane( normal, constant ) { - // normal is assumed to be normalized + // normal is assumed to be normalized - this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 ); - this.constant = ( constant !== undefined ) ? constant : 0; + this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 ); + this.constant = ( constant !== undefined ) ? constant : 0; - } + } - Object.assign( Plane.prototype, { + Object.assign( Plane.prototype, { - set: function ( normal, constant ) { + set: function ( normal, constant ) { - this.normal.copy( normal ); - this.constant = constant; + this.normal.copy( normal ); + this.constant = constant; - return this; + return this; - }, + }, - setComponents: function ( x, y, z, w ) { + setComponents: function ( x, y, z, w ) { - this.normal.set( x, y, z ); - this.constant = w; + this.normal.set( x, y, z ); + this.constant = w; - return this; + return this; - }, + }, - setFromNormalAndCoplanarPoint: function ( normal, point ) { + setFromNormalAndCoplanarPoint: function ( normal, point ) { - this.normal.copy( normal ); - this.constant = - point.dot( this.normal ); + this.normal.copy( normal ); + this.constant = - point.dot( this.normal ); - return this; + return this; - }, + }, - setFromCoplanarPoints: function () { + setFromCoplanarPoints: function () { - var v1 = new Vector3(); - var v2 = new Vector3(); + var v1 = new Vector3(); + var v2 = new Vector3(); - return function setFromCoplanarPoints( a, b, c ) { + return function setFromCoplanarPoints( a, b, c ) { - var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize(); + var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize(); - // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? + // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? - this.setFromNormalAndCoplanarPoint( normal, a ); + this.setFromNormalAndCoplanarPoint( normal, a ); - return this; + return this; - }; + }; - }(), + }(), - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( plane ) { + copy: function ( plane ) { - this.normal.copy( plane.normal ); - this.constant = plane.constant; + this.normal.copy( plane.normal ); + this.constant = plane.constant; - return this; + return this; - }, + }, - normalize: function () { + normalize: function () { - // Note: will lead to a divide by zero if the plane is invalid. + // Note: will lead to a divide by zero if the plane is invalid. - var inverseNormalLength = 1.0 / this.normal.length(); - this.normal.multiplyScalar( inverseNormalLength ); - this.constant *= inverseNormalLength; + var inverseNormalLength = 1.0 / this.normal.length(); + this.normal.multiplyScalar( inverseNormalLength ); + this.constant *= inverseNormalLength; - return this; + return this; - }, + }, - negate: function () { + negate: function () { - this.constant *= - 1; - this.normal.negate(); + this.constant *= - 1; + this.normal.negate(); - return this; + return this; - }, + }, - distanceToPoint: function ( point ) { + distanceToPoint: function ( point ) { - return this.normal.dot( point ) + this.constant; + return this.normal.dot( point ) + this.constant; - }, + }, - distanceToSphere: function ( sphere ) { + distanceToSphere: function ( sphere ) { - return this.distanceToPoint( sphere.center ) - sphere.radius; + return this.distanceToPoint( sphere.center ) - sphere.radius; - }, + }, - projectPoint: function ( point, target ) { + projectPoint: function ( point, target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Plane: .projectPoint() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Plane: .projectPoint() target is now required' ); + target = new Vector3(); - } + } - return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point ); + return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point ); - }, + }, - intersectLine: function () { + intersectLine: function () { - var v1 = new Vector3(); + var v1 = new Vector3(); - return function intersectLine( line, target ) { + return function intersectLine( line, target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Plane: .intersectLine() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Plane: .intersectLine() target is now required' ); + target = new Vector3(); - } + } - var direction = line.delta( v1 ); + var direction = line.delta( v1 ); - var denominator = this.normal.dot( direction ); + var denominator = this.normal.dot( direction ); - if ( denominator === 0 ) { + if ( denominator === 0 ) { - // line is coplanar, return origin - if ( this.distanceToPoint( line.start ) === 0 ) { + // line is coplanar, return origin + if ( this.distanceToPoint( line.start ) === 0 ) { - return target.copy( line.start ); + return target.copy( line.start ); - } + } - // Unsure if this is the correct method to handle this case. - return undefined; + // Unsure if this is the correct method to handle this case. + return undefined; - } + } - var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; + var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; - if ( t < 0 || t > 1 ) { + if ( t < 0 || t > 1 ) { - return undefined; + return undefined; - } + } - return target.copy( direction ).multiplyScalar( t ).add( line.start ); + return target.copy( direction ).multiplyScalar( t ).add( line.start ); - }; + }; - }(), + }(), - intersectsLine: function ( line ) { + intersectsLine: function ( line ) { - // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. + // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. - var startSign = this.distanceToPoint( line.start ); - var endSign = this.distanceToPoint( line.end ); + var startSign = this.distanceToPoint( line.start ); + var endSign = this.distanceToPoint( line.end ); - return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 ); + return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 ); - }, + }, - intersectsBox: function ( box ) { + intersectsBox: function ( box ) { - return box.intersectsPlane( this ); + return box.intersectsPlane( this ); - }, + }, - intersectsSphere: function ( sphere ) { + intersectsSphere: function ( sphere ) { - return sphere.intersectsPlane( this ); + return sphere.intersectsPlane( this ); - }, + }, - coplanarPoint: function ( target ) { + coplanarPoint: function ( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Plane: .coplanarPoint() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Plane: .coplanarPoint() target is now required' ); + target = new Vector3(); - } + } - return target.copy( this.normal ).multiplyScalar( - this.constant ); + return target.copy( this.normal ).multiplyScalar( - this.constant ); - }, + }, - applyMatrix4: function () { + applyMatrix4: function () { - var v1 = new Vector3(); - var m1 = new Matrix3(); + var v1 = new Vector3(); + var m1 = new Matrix3(); - return function applyMatrix4( matrix, optionalNormalMatrix ) { + return function applyMatrix4( matrix, optionalNormalMatrix ) { - var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix ); + var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix ); - var referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix ); + var referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix ); - var normal = this.normal.applyMatrix3( normalMatrix ).normalize(); + var normal = this.normal.applyMatrix3( normalMatrix ).normalize(); - this.constant = - referencePoint.dot( normal ); + this.constant = - referencePoint.dot( normal ); - return this; + return this; - }; + }; - }(), + }(), - translate: function ( offset ) { + translate: function ( offset ) { - this.constant -= offset.dot( this.normal ); + this.constant -= offset.dot( this.normal ); - return this; + return this; - }, + }, - equals: function ( plane ) { + equals: function ( plane ) { - return plane.normal.equals( this.normal ) && ( plane.constant === this.constant ); + return plane.normal.equals( this.normal ) && ( plane.constant === this.constant ); - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author bhouston / http://clara.io - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author bhouston / http://clara.io + */ - function Frustum( p0, p1, p2, p3, p4, p5 ) { + function Frustum( p0, p1, p2, p3, p4, p5 ) { - this.planes = [ + this.planes = [ - ( p0 !== undefined ) ? p0 : new Plane(), - ( p1 !== undefined ) ? p1 : new Plane(), - ( p2 !== undefined ) ? p2 : new Plane(), - ( p3 !== undefined ) ? p3 : new Plane(), - ( p4 !== undefined ) ? p4 : new Plane(), - ( p5 !== undefined ) ? p5 : new Plane() + ( p0 !== undefined ) ? p0 : new Plane(), + ( p1 !== undefined ) ? p1 : new Plane(), + ( p2 !== undefined ) ? p2 : new Plane(), + ( p3 !== undefined ) ? p3 : new Plane(), + ( p4 !== undefined ) ? p4 : new Plane(), + ( p5 !== undefined ) ? p5 : new Plane() - ]; + ]; - } + } - Object.assign( Frustum.prototype, { + Object.assign( Frustum.prototype, { - set: function ( p0, p1, p2, p3, p4, p5 ) { + set: function ( p0, p1, p2, p3, p4, p5 ) { - var planes = this.planes; + var planes = this.planes; - planes[ 0 ].copy( p0 ); - planes[ 1 ].copy( p1 ); - planes[ 2 ].copy( p2 ); - planes[ 3 ].copy( p3 ); - planes[ 4 ].copy( p4 ); - planes[ 5 ].copy( p5 ); + planes[ 0 ].copy( p0 ); + planes[ 1 ].copy( p1 ); + planes[ 2 ].copy( p2 ); + planes[ 3 ].copy( p3 ); + planes[ 4 ].copy( p4 ); + planes[ 5 ].copy( p5 ); - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( frustum ) { + copy: function ( frustum ) { - var planes = this.planes; + var planes = this.planes; - for ( var i = 0; i < 6; i ++ ) { + for ( var i = 0; i < 6; i ++ ) { - planes[ i ].copy( frustum.planes[ i ] ); + planes[ i ].copy( frustum.planes[ i ] ); - } + } - return this; + return this; - }, + }, - setFromMatrix: function ( m ) { + setFromMatrix: function ( m ) { - var planes = this.planes; - var me = m.elements; - var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ]; - var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ]; - var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ]; - var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ]; + var planes = this.planes; + var me = m.elements; + var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ]; + var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ]; + var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ]; + var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ]; - planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize(); - planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize(); - planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize(); - planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize(); - planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize(); - planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize(); + planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize(); + planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize(); + planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize(); + planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize(); + planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize(); + planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize(); - return this; + return this; - }, + }, - intersectsObject: function () { + intersectsObject: function () { - var sphere = new Sphere(); + var sphere = new Sphere(); - return function intersectsObject( object ) { + return function intersectsObject( object ) { - var geometry = object.geometry; + var geometry = object.geometry; - if ( geometry.boundingSphere === null ) - geometry.computeBoundingSphere(); + if ( geometry.boundingSphere === null ) + geometry.computeBoundingSphere(); - sphere.copy( geometry.boundingSphere ) - .applyMatrix4( object.matrixWorld ); + sphere.copy( geometry.boundingSphere ) + .applyMatrix4( object.matrixWorld ); - return this.intersectsSphere( sphere ); + return this.intersectsSphere( sphere ); - }; + }; - }(), + }(), - intersectsSprite: function () { + intersectsSprite: function () { - var sphere = new Sphere(); + var sphere = new Sphere(); - return function intersectsSprite( sprite ) { + return function intersectsSprite( sprite ) { - sphere.center.set( 0, 0, 0 ); - sphere.radius = 0.7071067811865476; - sphere.applyMatrix4( sprite.matrixWorld ); + sphere.center.set( 0, 0, 0 ); + sphere.radius = 0.7071067811865476; + sphere.applyMatrix4( sprite.matrixWorld ); - return this.intersectsSphere( sphere ); + return this.intersectsSphere( sphere ); - }; + }; - }(), + }(), - intersectsSphere: function ( sphere ) { + intersectsSphere: function ( sphere ) { - var planes = this.planes; - var center = sphere.center; - var negRadius = - sphere.radius; + var planes = this.planes; + var center = sphere.center; + var negRadius = - sphere.radius; - for ( var i = 0; i < 6; i ++ ) { + for ( var i = 0; i < 6; i ++ ) { - var distance = planes[ i ].distanceToPoint( center ); + var distance = planes[ i ].distanceToPoint( center ); - if ( distance < negRadius ) { + if ( distance < negRadius ) { - return false; + return false; - } + } - } + } - return true; + return true; - }, + }, - intersectsBox: function () { + intersectsBox: function () { - var p = new Vector3(); + var p = new Vector3(); - return function intersectsBox( box ) { + return function intersectsBox( box ) { - var planes = this.planes; + var planes = this.planes; - for ( var i = 0; i < 6; i ++ ) { + for ( var i = 0; i < 6; i ++ ) { - var plane = planes[ i ]; + var plane = planes[ i ]; - // corner at max distance + // corner at max distance - p.x = plane.normal.x > 0 ? box.max.x : box.min.x; - p.y = plane.normal.y > 0 ? box.max.y : box.min.y; - p.z = plane.normal.z > 0 ? box.max.z : box.min.z; + p.x = plane.normal.x > 0 ? box.max.x : box.min.x; + p.y = plane.normal.y > 0 ? box.max.y : box.min.y; + p.z = plane.normal.z > 0 ? box.max.z : box.min.z; - if ( plane.distanceToPoint( p ) < 0 ) { + if ( plane.distanceToPoint( p ) < 0 ) { - return false; + return false; - } + } - } + } - return true; + return true; - }; + }; - }(), + }(), - containsPoint: function ( point ) { + containsPoint: function ( point ) { - var planes = this.planes; + var planes = this.planes; - for ( var i = 0; i < 6; i ++ ) { + for ( var i = 0; i < 6; i ++ ) { - if ( planes[ i ].distanceToPoint( point ) < 0 ) { + if ( planes[ i ].distanceToPoint( point ) < 0 ) { - return false; + return false; - } + } - } + } - return true; + return true; - } + } - } ); + } ); - var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif\n"; + var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif\n"; - var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif\n"; + var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif\n"; - var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif\n"; + var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif\n"; - var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif\n"; + var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif\n"; - var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; + var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; - var begin_vertex = "\nvec3 transformed = vec3( position );\n"; + var begin_vertex = "\nvec3 transformed = vec3( position );\n"; - var beginnormal_vertex = "\nvec3 objectNormal = vec3( normal );\n"; + var beginnormal_vertex = "\nvec3 objectNormal = vec3( normal );\n"; - var bsdfs = "float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tif( decayExponent > 0.0 ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\treturn distanceFalloff * maxDistanceCutoffFactor;\n#else\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n#endif\n\t}\n\treturn 1.0;\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\n\treturn specularColor * AB.x + AB.y;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n"; + var bsdfs = "float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tif( decayExponent > 0.0 ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\treturn distanceFalloff * maxDistanceCutoffFactor;\n#else\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n#endif\n\t}\n\treturn 1.0;\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\n\treturn specularColor * AB.x + AB.y;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n"; - var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif\n"; + var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif\n"; - var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif\n"; + var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif\n"; - var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif\n"; + var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif\n"; - var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvarying vec3 vViewPosition;\n#endif\n"; + var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvarying vec3 vViewPosition;\n#endif\n"; - var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n"; + var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n"; - var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif"; + var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif"; - var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif\n"; + var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif\n"; - var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; + var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; - var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif"; + var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif"; - var common = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\n"; + var common = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\n"; - var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif\n"; + var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif\n"; - var defaultnormal_vertex = "vec3 transformedNormal = normalMatrix * objectNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n"; + var defaultnormal_vertex = "vec3 transformedNormal = normalMatrix * objectNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n"; - var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif\n"; + var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif\n"; - var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif\n"; + var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif\n"; - var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif\n"; + var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif\n"; - var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif\n"; + var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif\n"; - var encodings_fragment = " gl_FragColor = linearToOutputTexel( gl_FragColor );\n"; + var encodings_fragment = " gl_FragColor = linearToOutputTexel( gl_FragColor );\n"; - var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\n\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract(Le);\n\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\n\treturn vec4( max(vRGB, 0.0), 1.0 );\n}\n"; + var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\n\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract(Le);\n\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\n\treturn vec4( max(vRGB, 0.0), 1.0 );\n}\n"; - var envmap_fragment = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif\n"; + var envmap_fragment = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif\n"; - var envmap_pars_fragment = "#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif\n"; + var envmap_pars_fragment = "#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif\n"; - var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif\n"; + var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif\n"; - var envmap_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif\n"; + var envmap_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif\n"; - var fog_vertex = "\n#ifdef USE_FOG\nfogDepth = -mvPosition.z;\n#endif"; + var fog_vertex = "\n#ifdef USE_FOG\nfogDepth = -mvPosition.z;\n#endif"; - var fog_pars_vertex = "#ifdef USE_FOG\n varying float fogDepth;\n#endif\n"; + var fog_pars_vertex = "#ifdef USE_FOG\n varying float fogDepth;\n#endif\n"; - var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif\n"; + var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif\n"; - var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif\n"; + var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif\n"; - var gradientmap_pars_fragment = "#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif\n"; + var gradientmap_pars_fragment = "#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif\n"; - var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif\n"; + var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif\n"; - var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif"; + var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif"; - var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif\n"; + var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif\n"; - var lights_pars_begin = "uniform vec3 ambientLightColor;\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t\tfloat shadowCameraNear;\n\t\tfloat shadowCameraFar;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif\n"; + var lights_pars_begin = "uniform vec3 ambientLightColor;\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t\tfloat shadowCameraNear;\n\t\tfloat shadowCameraFar;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif\n"; - var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent ));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif\n"; + var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent ));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif\n"; - var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;\n"; + var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;\n"; - var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)\n"; + var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)\n"; - var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif\n"; + var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif\n"; - var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos - halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos + halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos + halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos - halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#ifndef STANDARD\n\t\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifndef STANDARD\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\tfloat dotNL = dotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n\t#ifndef STANDARD\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}\n"; + var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos - halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos + halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos + halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos - halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#ifndef STANDARD\n\t\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifndef STANDARD\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\tfloat dotNL = dotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n\t#ifndef STANDARD\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}\n"; - var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearCoatRadiance = vec3( 0.0 );\n#endif\n"; + var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearCoatRadiance = vec3( 0.0 );\n#endif\n"; - var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), maxMipLevel );\n\t#ifndef STANDARD\n\t\tclearCoatRadiance += getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), maxMipLevel );\n\t#endif\n#endif\n"; + var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), maxMipLevel );\n\t#ifndef STANDARD\n\t\tclearCoatRadiance += getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), maxMipLevel );\n\t#endif\n#endif\n"; - var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif\n"; + var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif\n"; - var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; + var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; - var logdepthbuf_pars_fragment = "#ifdef USE_LOGDEPTHBUF\n\tuniform float logDepthBufFC;\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n#endif\n"; + var logdepthbuf_pars_fragment = "#ifdef USE_LOGDEPTHBUF\n\tuniform float logDepthBufFC;\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n#endif\n"; - var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n\tuniform float logDepthBufFC;\n#endif"; + var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n\tuniform float logDepthBufFC;\n#endif"; - var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\tgl_Position.z *= gl_Position.w;\n\t#endif\n#endif\n"; + var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\tgl_Position.z *= gl_Position.w;\n\t#endif\n#endif\n"; - var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif\n"; + var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif\n"; - var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n"; + var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n"; - var map_particle_fragment = "#ifdef USE_MAP\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n"; + var map_particle_fragment = "#ifdef USE_MAP\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n"; - var map_particle_pars_fragment = "#ifdef USE_MAP\n\tuniform mat3 uvTransform;\n\tuniform sampler2D map;\n#endif\n"; + var map_particle_pars_fragment = "#ifdef USE_MAP\n\tuniform mat3 uvTransform;\n\tuniform sampler2D map;\n#endif\n"; - var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif\n"; + var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif\n"; - var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; + var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; - var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif\n"; + var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif\n"; - var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif"; + var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif"; - var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif\n"; + var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif\n"; - var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n#endif\n"; + var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n#endif\n"; - var normal_fragment_maps = "#ifdef USE_NORMALMAP\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t#ifdef FLIP_SIDED\n\t\t\tnormal = - normal;\n\t\t#endif\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tnormal = normalize( normalMatrix * normal );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n"; + var normal_fragment_maps = "#ifdef USE_NORMALMAP\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t#ifdef FLIP_SIDED\n\t\t\tnormal = - normal;\n\t\t#endif\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tnormal = normalize( normalMatrix * normal );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n"; - var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tuniform mat3 normalMatrix;\n\t#else\n\t\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\t\tvec2 st0 = dFdx( vUv.st );\n\t\t\tvec2 st1 = dFdy( vUv.st );\n\t\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\t\tvec3 N = normalize( surf_norm );\n\t\t\tmat3 tsn = mat3( S, T, N );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy *= normalScale;\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\treturn normalize( tsn * mapN );\n\t\t}\n\t#endif\n#endif\n"; + var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tuniform mat3 normalMatrix;\n\t#else\n\t\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\t\tvec2 st0 = dFdx( vUv.st );\n\t\t\tvec2 st1 = dFdy( vUv.st );\n\t\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\t\tvec3 N = normalize( surf_norm );\n\t\t\tmat3 tsn = mat3( S, T, N );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy *= normalScale;\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\treturn normalize( tsn * mapN );\n\t\t}\n\t#endif\n#endif\n"; - var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}\n"; + var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}\n"; - var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif\n"; + var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif\n"; - var project_vertex = "vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;\n"; + var project_vertex = "vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;\n"; - var dithering_fragment = "#if defined( DITHERING )\n gl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif\n"; + var dithering_fragment = "#if defined( DITHERING )\n gl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif\n"; - var dithering_pars_fragment = "#if defined( DITHERING )\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif\n"; + var dithering_pars_fragment = "#if defined( DITHERING )\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif\n"; - var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif\n"; + var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif\n"; - var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; + var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; - var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif\n"; + var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif\n"; - var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n#endif\n"; + var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n#endif\n"; - var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif\n"; + var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif\n"; - var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}\n"; + var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}\n"; - var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif"; + var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif"; - var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif\n"; + var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif\n"; - var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif\n"; + var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif\n"; - var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n#endif\n"; + var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n#endif\n"; - var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif"; + var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif"; - var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; + var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; - var tonemapping_fragment = "#if defined( TONE_MAPPING )\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif\n"; + var tonemapping_fragment = "#if defined( TONE_MAPPING )\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif\n"; - var tonemapping_pars_fragment = "#ifndef saturate\n\t#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\n"; + var tonemapping_pars_fragment = "#ifndef saturate\n\t#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\n"; - var uv_pars_fragment = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n#endif"; + var uv_pars_fragment = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n#endif"; - var uv_pars_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif\n"; + var uv_pars_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif\n"; - var uv_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; + var uv_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; - var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; + var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; - var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif"; + var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif"; - var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif"; + var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif"; - var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif\n"; + var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif\n"; - var cube_frag = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldPosition;\nvoid main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\tgl_FragColor.a *= opacity;\n}\n"; + var cube_frag = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldPosition;\nvoid main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\tgl_FragColor.a *= opacity;\n}\n"; - var cube_vert = "varying vec3 vWorldPosition;\n#include \nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}\n"; + var cube_vert = "varying vec3 vWorldPosition;\n#include \nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}\n"; - var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n"; + var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n"; - var depth_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + var depth_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; - var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}\n"; + var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}\n"; - var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}\n"; + var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}\n"; - var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldPosition;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}\n"; + var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldPosition;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}\n"; - var equirect_vert = "varying vec3 vWorldPosition;\n#include \nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}\n"; + var equirect_vert = "varying vec3 vWorldPosition;\n#include \nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}\n"; - var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; - var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}\n"; + var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}\n"; - var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; - var meshbasic_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + var meshbasic_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; - var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; - var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; - var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; - var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; - var meshphysical_frag = "#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + var meshphysical_frag = "#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; - var meshphysical_vert = "#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}\n"; + var meshphysical_vert = "#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}\n"; - var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}\n"; + var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}\n"; - var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}\n"; + var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}\n"; - var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; - var points_vert = "uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_SIZEATTENUATION\n\t\tgl_PointSize = size * ( scale / - mvPosition.z );\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + var points_vert = "uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_SIZEATTENUATION\n\t\tgl_PointSize = size * ( scale / - mvPosition.z );\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; - var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n}\n"; + var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n}\n"; - var shadow_vert = "#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; + var shadow_vert = "#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; - var sprite_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}\n"; + var sprite_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}\n"; - var sprite_vert = "uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tvec4 mvPosition;\n\tmvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}\n"; + var sprite_vert = "uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tvec4 mvPosition;\n\tmvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}\n"; - var ShaderChunk = { - alphamap_fragment: alphamap_fragment, - alphamap_pars_fragment: alphamap_pars_fragment, - alphatest_fragment: alphatest_fragment, - aomap_fragment: aomap_fragment, - aomap_pars_fragment: aomap_pars_fragment, - begin_vertex: begin_vertex, - beginnormal_vertex: beginnormal_vertex, - bsdfs: bsdfs, - bumpmap_pars_fragment: bumpmap_pars_fragment, - clipping_planes_fragment: clipping_planes_fragment, - clipping_planes_pars_fragment: clipping_planes_pars_fragment, - clipping_planes_pars_vertex: clipping_planes_pars_vertex, - clipping_planes_vertex: clipping_planes_vertex, - color_fragment: color_fragment, - color_pars_fragment: color_pars_fragment, - color_pars_vertex: color_pars_vertex, - color_vertex: color_vertex, - common: common, - cube_uv_reflection_fragment: cube_uv_reflection_fragment, - defaultnormal_vertex: defaultnormal_vertex, - displacementmap_pars_vertex: displacementmap_pars_vertex, - displacementmap_vertex: displacementmap_vertex, - emissivemap_fragment: emissivemap_fragment, - emissivemap_pars_fragment: emissivemap_pars_fragment, - encodings_fragment: encodings_fragment, - encodings_pars_fragment: encodings_pars_fragment, - envmap_fragment: envmap_fragment, - envmap_pars_fragment: envmap_pars_fragment, - envmap_pars_vertex: envmap_pars_vertex, - envmap_physical_pars_fragment: envmap_physical_pars_fragment, - envmap_vertex: envmap_vertex, - fog_vertex: fog_vertex, - fog_pars_vertex: fog_pars_vertex, - fog_fragment: fog_fragment, - fog_pars_fragment: fog_pars_fragment, - gradientmap_pars_fragment: gradientmap_pars_fragment, - lightmap_fragment: lightmap_fragment, - lightmap_pars_fragment: lightmap_pars_fragment, - lights_lambert_vertex: lights_lambert_vertex, - lights_pars_begin: lights_pars_begin, - lights_phong_fragment: lights_phong_fragment, - lights_phong_pars_fragment: lights_phong_pars_fragment, - lights_physical_fragment: lights_physical_fragment, - lights_physical_pars_fragment: lights_physical_pars_fragment, - lights_fragment_begin: lights_fragment_begin, - lights_fragment_maps: lights_fragment_maps, - lights_fragment_end: lights_fragment_end, - logdepthbuf_fragment: logdepthbuf_fragment, - logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, - logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, - logdepthbuf_vertex: logdepthbuf_vertex, - map_fragment: map_fragment, - map_pars_fragment: map_pars_fragment, - map_particle_fragment: map_particle_fragment, - map_particle_pars_fragment: map_particle_pars_fragment, - metalnessmap_fragment: metalnessmap_fragment, - metalnessmap_pars_fragment: metalnessmap_pars_fragment, - morphnormal_vertex: morphnormal_vertex, - morphtarget_pars_vertex: morphtarget_pars_vertex, - morphtarget_vertex: morphtarget_vertex, - normal_fragment_begin: normal_fragment_begin, - normal_fragment_maps: normal_fragment_maps, - normalmap_pars_fragment: normalmap_pars_fragment, - packing: packing, - premultiplied_alpha_fragment: premultiplied_alpha_fragment, - project_vertex: project_vertex, - dithering_fragment: dithering_fragment, - dithering_pars_fragment: dithering_pars_fragment, - roughnessmap_fragment: roughnessmap_fragment, - roughnessmap_pars_fragment: roughnessmap_pars_fragment, - shadowmap_pars_fragment: shadowmap_pars_fragment, - shadowmap_pars_vertex: shadowmap_pars_vertex, - shadowmap_vertex: shadowmap_vertex, - shadowmask_pars_fragment: shadowmask_pars_fragment, - skinbase_vertex: skinbase_vertex, - skinning_pars_vertex: skinning_pars_vertex, - skinning_vertex: skinning_vertex, - skinnormal_vertex: skinnormal_vertex, - specularmap_fragment: specularmap_fragment, - specularmap_pars_fragment: specularmap_pars_fragment, - tonemapping_fragment: tonemapping_fragment, - tonemapping_pars_fragment: tonemapping_pars_fragment, - uv_pars_fragment: uv_pars_fragment, - uv_pars_vertex: uv_pars_vertex, - uv_vertex: uv_vertex, - uv2_pars_fragment: uv2_pars_fragment, - uv2_pars_vertex: uv2_pars_vertex, - uv2_vertex: uv2_vertex, - worldpos_vertex: worldpos_vertex, - - cube_frag: cube_frag, - cube_vert: cube_vert, - depth_frag: depth_frag, - depth_vert: depth_vert, - distanceRGBA_frag: distanceRGBA_frag, - distanceRGBA_vert: distanceRGBA_vert, - equirect_frag: equirect_frag, - equirect_vert: equirect_vert, - linedashed_frag: linedashed_frag, - linedashed_vert: linedashed_vert, - meshbasic_frag: meshbasic_frag, - meshbasic_vert: meshbasic_vert, - meshlambert_frag: meshlambert_frag, - meshlambert_vert: meshlambert_vert, - meshphong_frag: meshphong_frag, - meshphong_vert: meshphong_vert, - meshphysical_frag: meshphysical_frag, - meshphysical_vert: meshphysical_vert, - normal_frag: normal_frag, - normal_vert: normal_vert, - points_frag: points_frag, - points_vert: points_vert, - shadow_frag: shadow_frag, - shadow_vert: shadow_vert, - sprite_frag: sprite_frag, - sprite_vert: sprite_vert - }; - - /** - * Uniform Utilities - */ - - var UniformsUtils = { - - merge: function ( uniforms ) { - - var merged = {}; - - for ( var u = 0; u < uniforms.length; u ++ ) { - - var tmp = this.clone( uniforms[ u ] ); - - for ( var p in tmp ) { - - merged[ p ] = tmp[ p ]; - - } - - } - - return merged; - - }, - - clone: function ( uniforms_src ) { + var ShaderChunk = { + alphamap_fragment: alphamap_fragment, + alphamap_pars_fragment: alphamap_pars_fragment, + alphatest_fragment: alphatest_fragment, + aomap_fragment: aomap_fragment, + aomap_pars_fragment: aomap_pars_fragment, + begin_vertex: begin_vertex, + beginnormal_vertex: beginnormal_vertex, + bsdfs: bsdfs, + bumpmap_pars_fragment: bumpmap_pars_fragment, + clipping_planes_fragment: clipping_planes_fragment, + clipping_planes_pars_fragment: clipping_planes_pars_fragment, + clipping_planes_pars_vertex: clipping_planes_pars_vertex, + clipping_planes_vertex: clipping_planes_vertex, + color_fragment: color_fragment, + color_pars_fragment: color_pars_fragment, + color_pars_vertex: color_pars_vertex, + color_vertex: color_vertex, + common: common, + cube_uv_reflection_fragment: cube_uv_reflection_fragment, + defaultnormal_vertex: defaultnormal_vertex, + displacementmap_pars_vertex: displacementmap_pars_vertex, + displacementmap_vertex: displacementmap_vertex, + emissivemap_fragment: emissivemap_fragment, + emissivemap_pars_fragment: emissivemap_pars_fragment, + encodings_fragment: encodings_fragment, + encodings_pars_fragment: encodings_pars_fragment, + envmap_fragment: envmap_fragment, + envmap_pars_fragment: envmap_pars_fragment, + envmap_pars_vertex: envmap_pars_vertex, + envmap_physical_pars_fragment: envmap_physical_pars_fragment, + envmap_vertex: envmap_vertex, + fog_vertex: fog_vertex, + fog_pars_vertex: fog_pars_vertex, + fog_fragment: fog_fragment, + fog_pars_fragment: fog_pars_fragment, + gradientmap_pars_fragment: gradientmap_pars_fragment, + lightmap_fragment: lightmap_fragment, + lightmap_pars_fragment: lightmap_pars_fragment, + lights_lambert_vertex: lights_lambert_vertex, + lights_pars_begin: lights_pars_begin, + lights_phong_fragment: lights_phong_fragment, + lights_phong_pars_fragment: lights_phong_pars_fragment, + lights_physical_fragment: lights_physical_fragment, + lights_physical_pars_fragment: lights_physical_pars_fragment, + lights_fragment_begin: lights_fragment_begin, + lights_fragment_maps: lights_fragment_maps, + lights_fragment_end: lights_fragment_end, + logdepthbuf_fragment: logdepthbuf_fragment, + logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, + logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, + logdepthbuf_vertex: logdepthbuf_vertex, + map_fragment: map_fragment, + map_pars_fragment: map_pars_fragment, + map_particle_fragment: map_particle_fragment, + map_particle_pars_fragment: map_particle_pars_fragment, + metalnessmap_fragment: metalnessmap_fragment, + metalnessmap_pars_fragment: metalnessmap_pars_fragment, + morphnormal_vertex: morphnormal_vertex, + morphtarget_pars_vertex: morphtarget_pars_vertex, + morphtarget_vertex: morphtarget_vertex, + normal_fragment_begin: normal_fragment_begin, + normal_fragment_maps: normal_fragment_maps, + normalmap_pars_fragment: normalmap_pars_fragment, + packing: packing, + premultiplied_alpha_fragment: premultiplied_alpha_fragment, + project_vertex: project_vertex, + dithering_fragment: dithering_fragment, + dithering_pars_fragment: dithering_pars_fragment, + roughnessmap_fragment: roughnessmap_fragment, + roughnessmap_pars_fragment: roughnessmap_pars_fragment, + shadowmap_pars_fragment: shadowmap_pars_fragment, + shadowmap_pars_vertex: shadowmap_pars_vertex, + shadowmap_vertex: shadowmap_vertex, + shadowmask_pars_fragment: shadowmask_pars_fragment, + skinbase_vertex: skinbase_vertex, + skinning_pars_vertex: skinning_pars_vertex, + skinning_vertex: skinning_vertex, + skinnormal_vertex: skinnormal_vertex, + specularmap_fragment: specularmap_fragment, + specularmap_pars_fragment: specularmap_pars_fragment, + tonemapping_fragment: tonemapping_fragment, + tonemapping_pars_fragment: tonemapping_pars_fragment, + uv_pars_fragment: uv_pars_fragment, + uv_pars_vertex: uv_pars_vertex, + uv_vertex: uv_vertex, + uv2_pars_fragment: uv2_pars_fragment, + uv2_pars_vertex: uv2_pars_vertex, + uv2_vertex: uv2_vertex, + worldpos_vertex: worldpos_vertex, + + cube_frag: cube_frag, + cube_vert: cube_vert, + depth_frag: depth_frag, + depth_vert: depth_vert, + distanceRGBA_frag: distanceRGBA_frag, + distanceRGBA_vert: distanceRGBA_vert, + equirect_frag: equirect_frag, + equirect_vert: equirect_vert, + linedashed_frag: linedashed_frag, + linedashed_vert: linedashed_vert, + meshbasic_frag: meshbasic_frag, + meshbasic_vert: meshbasic_vert, + meshlambert_frag: meshlambert_frag, + meshlambert_vert: meshlambert_vert, + meshphong_frag: meshphong_frag, + meshphong_vert: meshphong_vert, + meshphysical_frag: meshphysical_frag, + meshphysical_vert: meshphysical_vert, + normal_frag: normal_frag, + normal_vert: normal_vert, + points_frag: points_frag, + points_vert: points_vert, + shadow_frag: shadow_frag, + shadow_vert: shadow_vert, + sprite_frag: sprite_frag, + sprite_vert: sprite_vert + }; + + /** + * Uniform Utilities + */ + + var UniformsUtils = { + + merge: function ( uniforms ) { + + var merged = {}; + + for ( var u = 0; u < uniforms.length; u ++ ) { + + var tmp = this.clone( uniforms[ u ] ); + + for ( var p in tmp ) { + + merged[ p ] = tmp[ p ]; + + } + + } + + return merged; + + }, + + clone: function ( uniforms_src ) { - var uniforms_dst = {}; + var uniforms_dst = {}; - for ( var u in uniforms_src ) { + for ( var u in uniforms_src ) { - uniforms_dst[ u ] = {}; + uniforms_dst[ u ] = {}; - for ( var p in uniforms_src[ u ] ) { + for ( var p in uniforms_src[ u ] ) { - var parameter_src = uniforms_src[ u ][ p ]; + var parameter_src = uniforms_src[ u ][ p ]; - if ( parameter_src && ( parameter_src.isColor || - parameter_src.isMatrix3 || parameter_src.isMatrix4 || - parameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 || - parameter_src.isTexture ) ) { + if ( parameter_src && ( parameter_src.isColor || + parameter_src.isMatrix3 || parameter_src.isMatrix4 || + parameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 || + parameter_src.isTexture ) ) { - uniforms_dst[ u ][ p ] = parameter_src.clone(); + uniforms_dst[ u ][ p ] = parameter_src.clone(); - } else if ( Array.isArray( parameter_src ) ) { + } else if ( Array.isArray( parameter_src ) ) { - uniforms_dst[ u ][ p ] = parameter_src.slice(); + uniforms_dst[ u ][ p ] = parameter_src.slice(); - } else { + } else { - uniforms_dst[ u ][ p ] = parameter_src; + uniforms_dst[ u ][ p ] = parameter_src; - } + } - } + } - } + } - return uniforms_dst; + return uniforms_dst; - } + } - }; + }; - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - var ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, - 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, - 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, - 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, - 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, - 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, - 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, - 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, - 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, - 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, - 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, - 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, - 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, - 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, - 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, - 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, - 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, - 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, - 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, - 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F, - 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, - 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, - 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, - 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; + var ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, + 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, + 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, + 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, + 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, + 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, + 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, + 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, + 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, + 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, + 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, + 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, + 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, + 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, + 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, + 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, + 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, + 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, + 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, + 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F, + 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, + 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, + 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, + 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; - function Color( r, g, b ) { + function Color( r, g, b ) { - if ( g === undefined && b === undefined ) { + if ( g === undefined && b === undefined ) { - // r is THREE.Color, hex or string - return this.set( r ); + // r is THREE.Color, hex or string + return this.set( r ); - } + } - return this.setRGB( r, g, b ); + return this.setRGB( r, g, b ); - } + } - Object.assign( Color.prototype, { + Object.assign( Color.prototype, { - isColor: true, + isColor: true, - r: 1, g: 1, b: 1, + r: 1, g: 1, b: 1, - set: function ( value ) { + set: function ( value ) { - if ( value && value.isColor ) { + if ( value && value.isColor ) { - this.copy( value ); + this.copy( value ); - } else if ( typeof value === 'number' ) { + } else if ( typeof value === 'number' ) { - this.setHex( value ); + this.setHex( value ); - } else if ( typeof value === 'string' ) { + } else if ( typeof value === 'string' ) { - this.setStyle( value ); + this.setStyle( value ); - } + } - return this; + return this; - }, + }, - setScalar: function ( scalar ) { + setScalar: function ( scalar ) { - this.r = scalar; - this.g = scalar; - this.b = scalar; + this.r = scalar; + this.g = scalar; + this.b = scalar; - return this; + return this; - }, + }, - setHex: function ( hex ) { + setHex: function ( hex ) { - hex = Math.floor( hex ); + hex = Math.floor( hex ); - this.r = ( hex >> 16 & 255 ) / 255; - this.g = ( hex >> 8 & 255 ) / 255; - this.b = ( hex & 255 ) / 255; + this.r = ( hex >> 16 & 255 ) / 255; + this.g = ( hex >> 8 & 255 ) / 255; + this.b = ( hex & 255 ) / 255; - return this; + return this; - }, + }, - setRGB: function ( r, g, b ) { + setRGB: function ( r, g, b ) { - this.r = r; - this.g = g; - this.b = b; + this.r = r; + this.g = g; + this.b = b; - return this; + return this; - }, + }, - setHSL: function () { + setHSL: function () { - function hue2rgb( p, q, t ) { + function hue2rgb( p, q, t ) { - if ( t < 0 ) t += 1; - if ( t > 1 ) t -= 1; - if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; - if ( t < 1 / 2 ) return q; - if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); - return p; + if ( t < 0 ) t += 1; + if ( t > 1 ) t -= 1; + if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; + if ( t < 1 / 2 ) return q; + if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); + return p; - } + } - return function setHSL( h, s, l ) { + return function setHSL( h, s, l ) { - // h,s,l ranges are in 0.0 - 1.0 - h = _Math.euclideanModulo( h, 1 ); - s = _Math.clamp( s, 0, 1 ); - l = _Math.clamp( l, 0, 1 ); + // h,s,l ranges are in 0.0 - 1.0 + h = _Math.euclideanModulo( h, 1 ); + s = _Math.clamp( s, 0, 1 ); + l = _Math.clamp( l, 0, 1 ); - if ( s === 0 ) { + if ( s === 0 ) { - this.r = this.g = this.b = l; + this.r = this.g = this.b = l; - } else { + } else { - var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); - var q = ( 2 * l ) - p; + var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); + var q = ( 2 * l ) - p; - this.r = hue2rgb( q, p, h + 1 / 3 ); - this.g = hue2rgb( q, p, h ); - this.b = hue2rgb( q, p, h - 1 / 3 ); + this.r = hue2rgb( q, p, h + 1 / 3 ); + this.g = hue2rgb( q, p, h ); + this.b = hue2rgb( q, p, h - 1 / 3 ); - } + } - return this; + return this; - }; + }; - }(), + }(), - setStyle: function ( style ) { + setStyle: function ( style ) { - function handleAlpha( string ) { + function handleAlpha( string ) { - if ( string === undefined ) return; + if ( string === undefined ) return; - if ( parseFloat( string ) < 1 ) { + if ( parseFloat( string ) < 1 ) { - console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' ); + console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' ); - } + } - } + } - var m; + var m; - if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) { + if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) { - // rgb / hsl + // rgb / hsl - var color; - var name = m[ 1 ]; - var components = m[ 2 ]; + var color; + var name = m[ 1 ]; + var components = m[ 2 ]; - switch ( name ) { + switch ( name ) { - case 'rgb': - case 'rgba': + case 'rgb': + case 'rgba': - if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { + if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { - // rgb(255,0,0) rgba(255,0,0,0.5) - this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255; - this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255; - this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255; + // rgb(255,0,0) rgba(255,0,0,0.5) + this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255; + this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255; + this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255; - handleAlpha( color[ 5 ] ); + handleAlpha( color[ 5 ] ); - return this; + return this; - } + } - if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { + if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { - // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) - this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100; - this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100; - this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100; + // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) + this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100; + this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100; + this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100; - handleAlpha( color[ 5 ] ); + handleAlpha( color[ 5 ] ); - return this; + return this; - } + } - break; + break; - case 'hsl': - case 'hsla': + case 'hsl': + case 'hsla': - if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { + if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { - // hsl(120,50%,50%) hsla(120,50%,50%,0.5) - var h = parseFloat( color[ 1 ] ) / 360; - var s = parseInt( color[ 2 ], 10 ) / 100; - var l = parseInt( color[ 3 ], 10 ) / 100; + // hsl(120,50%,50%) hsla(120,50%,50%,0.5) + var h = parseFloat( color[ 1 ] ) / 360; + var s = parseInt( color[ 2 ], 10 ) / 100; + var l = parseInt( color[ 3 ], 10 ) / 100; - handleAlpha( color[ 5 ] ); + handleAlpha( color[ 5 ] ); - return this.setHSL( h, s, l ); + return this.setHSL( h, s, l ); - } + } - break; + break; - } + } - } else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) { + } else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) { - // hex color + // hex color - var hex = m[ 1 ]; - var size = hex.length; + var hex = m[ 1 ]; + var size = hex.length; - if ( size === 3 ) { + if ( size === 3 ) { - // #ff0 - this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255; - this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255; - this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255; + // #ff0 + this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255; + this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255; + this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255; - return this; + return this; - } else if ( size === 6 ) { + } else if ( size === 6 ) { - // #ff0000 - this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255; - this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255; - this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255; + // #ff0000 + this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255; + this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255; + this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255; - return this; + return this; - } + } - } + } - if ( style && style.length > 0 ) { + if ( style && style.length > 0 ) { - // color keywords - var hex = ColorKeywords[ style ]; + // color keywords + var hex = ColorKeywords[ style ]; - if ( hex !== undefined ) { + if ( hex !== undefined ) { - // red - this.setHex( hex ); + // red + this.setHex( hex ); - } else { + } else { - // unknown color - console.warn( 'THREE.Color: Unknown color ' + style ); + // unknown color + console.warn( 'THREE.Color: Unknown color ' + style ); - } + } - } + } - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new this.constructor( this.r, this.g, this.b ); + return new this.constructor( this.r, this.g, this.b ); - }, + }, - copy: function ( color ) { + copy: function ( color ) { - this.r = color.r; - this.g = color.g; - this.b = color.b; + this.r = color.r; + this.g = color.g; + this.b = color.b; - return this; + return this; - }, + }, - copyGammaToLinear: function ( color, gammaFactor ) { + copyGammaToLinear: function ( color, gammaFactor ) { - if ( gammaFactor === undefined ) gammaFactor = 2.0; + if ( gammaFactor === undefined ) gammaFactor = 2.0; - this.r = Math.pow( color.r, gammaFactor ); - this.g = Math.pow( color.g, gammaFactor ); - this.b = Math.pow( color.b, gammaFactor ); + this.r = Math.pow( color.r, gammaFactor ); + this.g = Math.pow( color.g, gammaFactor ); + this.b = Math.pow( color.b, gammaFactor ); - return this; + return this; - }, + }, - copyLinearToGamma: function ( color, gammaFactor ) { + copyLinearToGamma: function ( color, gammaFactor ) { - if ( gammaFactor === undefined ) gammaFactor = 2.0; + if ( gammaFactor === undefined ) gammaFactor = 2.0; - var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0; + var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0; - this.r = Math.pow( color.r, safeInverse ); - this.g = Math.pow( color.g, safeInverse ); - this.b = Math.pow( color.b, safeInverse ); + this.r = Math.pow( color.r, safeInverse ); + this.g = Math.pow( color.g, safeInverse ); + this.b = Math.pow( color.b, safeInverse ); - return this; + return this; - }, + }, - convertGammaToLinear: function ( gammaFactor ) { + convertGammaToLinear: function ( gammaFactor ) { - this.copyGammaToLinear( this, gammaFactor ); + this.copyGammaToLinear( this, gammaFactor ); - return this; + return this; - }, + }, - convertLinearToGamma: function ( gammaFactor ) { + convertLinearToGamma: function ( gammaFactor ) { - this.copyLinearToGamma( this, gammaFactor ); + this.copyLinearToGamma( this, gammaFactor ); - return this; + return this; - }, + }, - copySRGBToLinear: function () { + copySRGBToLinear: function () { - function SRGBToLinear( c ) { + function SRGBToLinear( c ) { - return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 ); + return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 ); - } + } - return function copySRGBToLinear( color ) { + return function copySRGBToLinear( color ) { - this.r = SRGBToLinear( color.r ); - this.g = SRGBToLinear( color.g ); - this.b = SRGBToLinear( color.b ); + this.r = SRGBToLinear( color.r ); + this.g = SRGBToLinear( color.g ); + this.b = SRGBToLinear( color.b ); - return this; + return this; - }; + }; - }(), + }(), - copyLinearToSRGB: function () { + copyLinearToSRGB: function () { - function LinearToSRGB( c ) { + function LinearToSRGB( c ) { - return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055; + return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055; - } + } - return function copyLinearToSRGB( color ) { + return function copyLinearToSRGB( color ) { - this.r = LinearToSRGB( color.r ); - this.g = LinearToSRGB( color.g ); - this.b = LinearToSRGB( color.b ); + this.r = LinearToSRGB( color.r ); + this.g = LinearToSRGB( color.g ); + this.b = LinearToSRGB( color.b ); - return this; + return this; - }; + }; - }(), + }(), - convertSRGBToLinear: function () { + convertSRGBToLinear: function () { - this.copySRGBToLinear( this ); + this.copySRGBToLinear( this ); - return this; + return this; - }, + }, - convertLinearToSRGB: function () { + convertLinearToSRGB: function () { - this.copyLinearToSRGB( this ); + this.copyLinearToSRGB( this ); - return this; + return this; - }, + }, - getHex: function () { + getHex: function () { - return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0; + return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0; - }, + }, - getHexString: function () { + getHexString: function () { - return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 ); + return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 ); - }, + }, - getHSL: function ( target ) { + getHSL: function ( target ) { - // h,s,l ranges are in 0.0 - 1.0 + // h,s,l ranges are in 0.0 - 1.0 - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Color: .getHSL() target is now required' ); - target = { h: 0, s: 0, l: 0 }; + console.warn( 'THREE.Color: .getHSL() target is now required' ); + target = { h: 0, s: 0, l: 0 }; - } + } - var r = this.r, g = this.g, b = this.b; + var r = this.r, g = this.g, b = this.b; - var max = Math.max( r, g, b ); - var min = Math.min( r, g, b ); + var max = Math.max( r, g, b ); + var min = Math.min( r, g, b ); - var hue, saturation; - var lightness = ( min + max ) / 2.0; + var hue, saturation; + var lightness = ( min + max ) / 2.0; - if ( min === max ) { + if ( min === max ) { - hue = 0; - saturation = 0; + hue = 0; + saturation = 0; - } else { + } else { - var delta = max - min; + var delta = max - min; - saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); + saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); - switch ( max ) { + switch ( max ) { - case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break; - case g: hue = ( b - r ) / delta + 2; break; - case b: hue = ( r - g ) / delta + 4; break; + case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break; + case g: hue = ( b - r ) / delta + 2; break; + case b: hue = ( r - g ) / delta + 4; break; - } + } - hue /= 6; + hue /= 6; - } + } - target.h = hue; - target.s = saturation; - target.l = lightness; + target.h = hue; + target.s = saturation; + target.l = lightness; - return target; + return target; - }, + }, - getStyle: function () { + getStyle: function () { - return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')'; + return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')'; - }, + }, - offsetHSL: function () { + offsetHSL: function () { - var hsl = {}; + var hsl = {}; - return function ( h, s, l ) { + return function ( h, s, l ) { - this.getHSL( hsl ); + this.getHSL( hsl ); - hsl.h += h; hsl.s += s; hsl.l += l; + hsl.h += h; hsl.s += s; hsl.l += l; - this.setHSL( hsl.h, hsl.s, hsl.l ); + this.setHSL( hsl.h, hsl.s, hsl.l ); - return this; + return this; - }; + }; - }(), + }(), - add: function ( color ) { + add: function ( color ) { - this.r += color.r; - this.g += color.g; - this.b += color.b; + this.r += color.r; + this.g += color.g; + this.b += color.b; - return this; + return this; - }, + }, - addColors: function ( color1, color2 ) { + addColors: function ( color1, color2 ) { - this.r = color1.r + color2.r; - this.g = color1.g + color2.g; - this.b = color1.b + color2.b; + this.r = color1.r + color2.r; + this.g = color1.g + color2.g; + this.b = color1.b + color2.b; - return this; + return this; - }, + }, - addScalar: function ( s ) { + addScalar: function ( s ) { - this.r += s; - this.g += s; - this.b += s; + this.r += s; + this.g += s; + this.b += s; - return this; + return this; - }, + }, - sub: function ( color ) { + sub: function ( color ) { - this.r = Math.max( 0, this.r - color.r ); - this.g = Math.max( 0, this.g - color.g ); - this.b = Math.max( 0, this.b - color.b ); + this.r = Math.max( 0, this.r - color.r ); + this.g = Math.max( 0, this.g - color.g ); + this.b = Math.max( 0, this.b - color.b ); - return this; + return this; - }, + }, - multiply: function ( color ) { + multiply: function ( color ) { - this.r *= color.r; - this.g *= color.g; - this.b *= color.b; + this.r *= color.r; + this.g *= color.g; + this.b *= color.b; - return this; + return this; - }, + }, - multiplyScalar: function ( s ) { + multiplyScalar: function ( s ) { - this.r *= s; - this.g *= s; - this.b *= s; + this.r *= s; + this.g *= s; + this.b *= s; - return this; + return this; - }, + }, - lerp: function ( color, alpha ) { + lerp: function ( color, alpha ) { - this.r += ( color.r - this.r ) * alpha; - this.g += ( color.g - this.g ) * alpha; - this.b += ( color.b - this.b ) * alpha; + this.r += ( color.r - this.r ) * alpha; + this.g += ( color.g - this.g ) * alpha; + this.b += ( color.b - this.b ) * alpha; - return this; + return this; - }, + }, - equals: function ( c ) { + equals: function ( c ) { - return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b ); + return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b ); - }, + }, - fromArray: function ( array, offset ) { + fromArray: function ( array, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - this.r = array[ offset ]; - this.g = array[ offset + 1 ]; - this.b = array[ offset + 2 ]; + this.r = array[ offset ]; + this.g = array[ offset + 1 ]; + this.b = array[ offset + 2 ]; - return this; + return this; - }, + }, - toArray: function ( array, offset ) { + toArray: function ( array, offset ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - array[ offset ] = this.r; - array[ offset + 1 ] = this.g; - array[ offset + 2 ] = this.b; + array[ offset ] = this.r; + array[ offset + 1 ] = this.g; + array[ offset + 2 ] = this.b; - return array; + return array; - }, + }, - toJSON: function () { + toJSON: function () { - return this.getHex(); + return this.getHex(); - } + } - } ); + } ); - /** - * Uniforms library for shared webgl shaders - */ + /** + * Uniforms library for shared webgl shaders + */ - var UniformsLib = { + var UniformsLib = { - common: { + common: { - diffuse: { value: new Color( 0xeeeeee ) }, - opacity: { value: 1.0 }, + diffuse: { value: new Color( 0xeeeeee ) }, + opacity: { value: 1.0 }, - map: { value: null }, - uvTransform: { value: new Matrix3() }, + map: { value: null }, + uvTransform: { value: new Matrix3() }, - alphaMap: { value: null }, + alphaMap: { value: null }, - }, + }, - specularmap: { + specularmap: { - specularMap: { value: null }, + specularMap: { value: null }, - }, + }, - envmap: { + envmap: { - envMap: { value: null }, - flipEnvMap: { value: - 1 }, - reflectivity: { value: 1.0 }, - refractionRatio: { value: 0.98 }, - maxMipLevel: { value: 0 } + envMap: { value: null }, + flipEnvMap: { value: - 1 }, + reflectivity: { value: 1.0 }, + refractionRatio: { value: 0.98 }, + maxMipLevel: { value: 0 } - }, + }, - aomap: { + aomap: { - aoMap: { value: null }, - aoMapIntensity: { value: 1 } + aoMap: { value: null }, + aoMapIntensity: { value: 1 } - }, + }, - lightmap: { + lightmap: { - lightMap: { value: null }, - lightMapIntensity: { value: 1 } + lightMap: { value: null }, + lightMapIntensity: { value: 1 } - }, + }, - emissivemap: { + emissivemap: { - emissiveMap: { value: null } + emissiveMap: { value: null } - }, + }, - bumpmap: { + bumpmap: { - bumpMap: { value: null }, - bumpScale: { value: 1 } + bumpMap: { value: null }, + bumpScale: { value: 1 } - }, + }, - normalmap: { + normalmap: { - normalMap: { value: null }, - normalScale: { value: new Vector2( 1, 1 ) } + normalMap: { value: null }, + normalScale: { value: new Vector2( 1, 1 ) } - }, + }, - displacementmap: { + displacementmap: { - displacementMap: { value: null }, - displacementScale: { value: 1 }, - displacementBias: { value: 0 } + displacementMap: { value: null }, + displacementScale: { value: 1 }, + displacementBias: { value: 0 } - }, + }, - roughnessmap: { + roughnessmap: { - roughnessMap: { value: null } + roughnessMap: { value: null } - }, + }, - metalnessmap: { + metalnessmap: { - metalnessMap: { value: null } + metalnessMap: { value: null } - }, + }, - gradientmap: { + gradientmap: { - gradientMap: { value: null } + gradientMap: { value: null } - }, + }, - fog: { + fog: { - fogDensity: { value: 0.00025 }, - fogNear: { value: 1 }, - fogFar: { value: 2000 }, - fogColor: { value: new Color( 0xffffff ) } + fogDensity: { value: 0.00025 }, + fogNear: { value: 1 }, + fogFar: { value: 2000 }, + fogColor: { value: new Color( 0xffffff ) } - }, + }, - lights: { + lights: { - ambientLightColor: { value: [] }, + ambientLightColor: { value: [] }, - directionalLights: { value: [], properties: { - direction: {}, - color: {}, + directionalLights: { value: [], properties: { + direction: {}, + color: {}, - shadow: {}, - shadowBias: {}, - shadowRadius: {}, - shadowMapSize: {} - } }, + shadow: {}, + shadowBias: {}, + shadowRadius: {}, + shadowMapSize: {} + } }, - directionalShadowMap: { value: [] }, - directionalShadowMatrix: { value: [] }, + directionalShadowMap: { value: [] }, + directionalShadowMatrix: { value: [] }, - spotLights: { value: [], properties: { - color: {}, - position: {}, - direction: {}, - distance: {}, - coneCos: {}, - penumbraCos: {}, - decay: {}, + spotLights: { value: [], properties: { + color: {}, + position: {}, + direction: {}, + distance: {}, + coneCos: {}, + penumbraCos: {}, + decay: {}, - shadow: {}, - shadowBias: {}, - shadowRadius: {}, - shadowMapSize: {} - } }, + shadow: {}, + shadowBias: {}, + shadowRadius: {}, + shadowMapSize: {} + } }, - spotShadowMap: { value: [] }, - spotShadowMatrix: { value: [] }, + spotShadowMap: { value: [] }, + spotShadowMatrix: { value: [] }, - pointLights: { value: [], properties: { - color: {}, - position: {}, - decay: {}, - distance: {}, + pointLights: { value: [], properties: { + color: {}, + position: {}, + decay: {}, + distance: {}, - shadow: {}, - shadowBias: {}, - shadowRadius: {}, - shadowMapSize: {}, - shadowCameraNear: {}, - shadowCameraFar: {} - } }, + shadow: {}, + shadowBias: {}, + shadowRadius: {}, + shadowMapSize: {}, + shadowCameraNear: {}, + shadowCameraFar: {} + } }, - pointShadowMap: { value: [] }, - pointShadowMatrix: { value: [] }, + pointShadowMap: { value: [] }, + pointShadowMatrix: { value: [] }, - hemisphereLights: { value: [], properties: { - direction: {}, - skyColor: {}, - groundColor: {} - } }, + hemisphereLights: { value: [], properties: { + direction: {}, + skyColor: {}, + groundColor: {} + } }, - // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src - rectAreaLights: { value: [], properties: { - color: {}, - position: {}, - width: {}, - height: {} - } } + // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src + rectAreaLights: { value: [], properties: { + color: {}, + position: {}, + width: {}, + height: {} + } } - }, + }, - points: { + points: { - diffuse: { value: new Color( 0xeeeeee ) }, - opacity: { value: 1.0 }, - size: { value: 1.0 }, - scale: { value: 1.0 }, - map: { value: null }, - uvTransform: { value: new Matrix3() } - - }, - - sprite: { - - diffuse: { value: new Color( 0xeeeeee ) }, - opacity: { value: 1.0 }, - center: { value: new Vector2( 0.5, 0.5 ) }, - rotation: { value: 0.0 }, - map: { value: null }, - uvTransform: { value: new Matrix3() } - - } - - }; - - /** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - * @author mikael emtinger / http://gomo.se/ - */ - - var ShaderLib = { - - basic: { - - uniforms: UniformsUtils.merge( [ - UniformsLib.common, - UniformsLib.specularmap, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.fog - ] ), - - vertexShader: ShaderChunk.meshbasic_vert, - fragmentShader: ShaderChunk.meshbasic_frag - - }, - - lambert: { - - uniforms: UniformsUtils.merge( [ - UniformsLib.common, - UniformsLib.specularmap, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.emissivemap, - UniformsLib.fog, - UniformsLib.lights, - { - emissive: { value: new Color( 0x000000 ) } - } - ] ), - - vertexShader: ShaderChunk.meshlambert_vert, - fragmentShader: ShaderChunk.meshlambert_frag - - }, - - phong: { - - uniforms: UniformsUtils.merge( [ - UniformsLib.common, - UniformsLib.specularmap, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.emissivemap, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - UniformsLib.gradientmap, - UniformsLib.fog, - UniformsLib.lights, - { - emissive: { value: new Color( 0x000000 ) }, - specular: { value: new Color( 0x111111 ) }, - shininess: { value: 30 } - } - ] ), - - vertexShader: ShaderChunk.meshphong_vert, - fragmentShader: ShaderChunk.meshphong_frag - - }, - - standard: { - - uniforms: UniformsUtils.merge( [ - UniformsLib.common, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.emissivemap, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - UniformsLib.roughnessmap, - UniformsLib.metalnessmap, - UniformsLib.fog, - UniformsLib.lights, - { - emissive: { value: new Color( 0x000000 ) }, - roughness: { value: 0.5 }, - metalness: { value: 0.5 }, - envMapIntensity: { value: 1 } // temporary - } - ] ), - - vertexShader: ShaderChunk.meshphysical_vert, - fragmentShader: ShaderChunk.meshphysical_frag - - }, - - points: { - - uniforms: UniformsUtils.merge( [ - UniformsLib.points, - UniformsLib.fog - ] ), - - vertexShader: ShaderChunk.points_vert, - fragmentShader: ShaderChunk.points_frag - - }, - - dashed: { - - uniforms: UniformsUtils.merge( [ - UniformsLib.common, - UniformsLib.fog, - { - scale: { value: 1 }, - dashSize: { value: 1 }, - totalSize: { value: 2 } - } - ] ), - - vertexShader: ShaderChunk.linedashed_vert, - fragmentShader: ShaderChunk.linedashed_frag - - }, - - depth: { - - uniforms: UniformsUtils.merge( [ - UniformsLib.common, - UniformsLib.displacementmap - ] ), + diffuse: { value: new Color( 0xeeeeee ) }, + opacity: { value: 1.0 }, + size: { value: 1.0 }, + scale: { value: 1.0 }, + map: { value: null }, + uvTransform: { value: new Matrix3() } + + }, + + sprite: { + + diffuse: { value: new Color( 0xeeeeee ) }, + opacity: { value: 1.0 }, + center: { value: new Vector2( 0.5, 0.5 ) }, + rotation: { value: 0.0 }, + map: { value: null }, + uvTransform: { value: new Matrix3() } + + } + + }; + + /** + * @author alteredq / http://alteredqualia.com/ + * @author mrdoob / http://mrdoob.com/ + * @author mikael emtinger / http://gomo.se/ + */ + + var ShaderLib = { + + basic: { + + uniforms: UniformsUtils.merge( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.fog + ] ), + + vertexShader: ShaderChunk.meshbasic_vert, + fragmentShader: ShaderChunk.meshbasic_frag + + }, + + lambert: { + + uniforms: UniformsUtils.merge( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) } + } + ] ), + + vertexShader: ShaderChunk.meshlambert_vert, + fragmentShader: ShaderChunk.meshlambert_frag + + }, + + phong: { + + uniforms: UniformsUtils.merge( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.gradientmap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) }, + specular: { value: new Color( 0x111111 ) }, + shininess: { value: 30 } + } + ] ), + + vertexShader: ShaderChunk.meshphong_vert, + fragmentShader: ShaderChunk.meshphong_frag + + }, + + standard: { + + uniforms: UniformsUtils.merge( [ + UniformsLib.common, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.roughnessmap, + UniformsLib.metalnessmap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) }, + roughness: { value: 0.5 }, + metalness: { value: 0.5 }, + envMapIntensity: { value: 1 } // temporary + } + ] ), + + vertexShader: ShaderChunk.meshphysical_vert, + fragmentShader: ShaderChunk.meshphysical_frag + + }, + + points: { + + uniforms: UniformsUtils.merge( [ + UniformsLib.points, + UniformsLib.fog + ] ), + + vertexShader: ShaderChunk.points_vert, + fragmentShader: ShaderChunk.points_frag + + }, + + dashed: { + + uniforms: UniformsUtils.merge( [ + UniformsLib.common, + UniformsLib.fog, + { + scale: { value: 1 }, + dashSize: { value: 1 }, + totalSize: { value: 2 } + } + ] ), + + vertexShader: ShaderChunk.linedashed_vert, + fragmentShader: ShaderChunk.linedashed_frag + + }, + + depth: { + + uniforms: UniformsUtils.merge( [ + UniformsLib.common, + UniformsLib.displacementmap + ] ), - vertexShader: ShaderChunk.depth_vert, - fragmentShader: ShaderChunk.depth_frag + vertexShader: ShaderChunk.depth_vert, + fragmentShader: ShaderChunk.depth_frag - }, - - normal: { + }, + + normal: { - uniforms: UniformsUtils.merge( [ - UniformsLib.common, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - { - opacity: { value: 1.0 } - } - ] ), + uniforms: UniformsUtils.merge( [ + UniformsLib.common, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + { + opacity: { value: 1.0 } + } + ] ), - vertexShader: ShaderChunk.normal_vert, - fragmentShader: ShaderChunk.normal_frag + vertexShader: ShaderChunk.normal_vert, + fragmentShader: ShaderChunk.normal_frag - }, + }, - sprite: { + sprite: { - uniforms: UniformsUtils.merge( [ - UniformsLib.sprite, - UniformsLib.fog - ] ), + uniforms: UniformsUtils.merge( [ + UniformsLib.sprite, + UniformsLib.fog + ] ), - vertexShader: ShaderChunk.sprite_vert, - fragmentShader: ShaderChunk.sprite_frag + vertexShader: ShaderChunk.sprite_vert, + fragmentShader: ShaderChunk.sprite_frag - }, + }, - /* ------------------------------------------------------------------------- - // Cube map shader - ------------------------------------------------------------------------- */ + /* ------------------------------------------------------------------------- + // Cube map shader + ------------------------------------------------------------------------- */ - cube: { + cube: { - uniforms: { - tCube: { value: null }, - tFlip: { value: - 1 }, - opacity: { value: 1.0 } - }, + uniforms: { + tCube: { value: null }, + tFlip: { value: - 1 }, + opacity: { value: 1.0 } + }, - vertexShader: ShaderChunk.cube_vert, - fragmentShader: ShaderChunk.cube_frag + vertexShader: ShaderChunk.cube_vert, + fragmentShader: ShaderChunk.cube_frag - }, + }, - equirect: { + equirect: { - uniforms: { - tEquirect: { value: null }, - }, + uniforms: { + tEquirect: { value: null }, + }, - vertexShader: ShaderChunk.equirect_vert, - fragmentShader: ShaderChunk.equirect_frag + vertexShader: ShaderChunk.equirect_vert, + fragmentShader: ShaderChunk.equirect_frag - }, + }, - distanceRGBA: { + distanceRGBA: { - uniforms: UniformsUtils.merge( [ - UniformsLib.common, - UniformsLib.displacementmap, - { - referencePosition: { value: new Vector3() }, - nearDistance: { value: 1 }, - farDistance: { value: 1000 } - } - ] ), + uniforms: UniformsUtils.merge( [ + UniformsLib.common, + UniformsLib.displacementmap, + { + referencePosition: { value: new Vector3() }, + nearDistance: { value: 1 }, + farDistance: { value: 1000 } + } + ] ), - vertexShader: ShaderChunk.distanceRGBA_vert, - fragmentShader: ShaderChunk.distanceRGBA_frag + vertexShader: ShaderChunk.distanceRGBA_vert, + fragmentShader: ShaderChunk.distanceRGBA_frag - }, + }, - shadow: { + shadow: { - uniforms: UniformsUtils.merge( [ - UniformsLib.lights, - UniformsLib.fog, - { - color: { value: new Color( 0x00000 ) }, - opacity: { value: 1.0 } - }, - ] ), + uniforms: UniformsUtils.merge( [ + UniformsLib.lights, + UniformsLib.fog, + { + color: { value: new Color( 0x00000 ) }, + opacity: { value: 1.0 } + }, + ] ), - vertexShader: ShaderChunk.shadow_vert, - fragmentShader: ShaderChunk.shadow_frag + vertexShader: ShaderChunk.shadow_vert, + fragmentShader: ShaderChunk.shadow_frag - } + } - }; + }; - ShaderLib.physical = { + ShaderLib.physical = { - uniforms: UniformsUtils.merge( [ - ShaderLib.standard.uniforms, - { - clearCoat: { value: 0 }, - clearCoatRoughness: { value: 0 } - } - ] ), + uniforms: UniformsUtils.merge( [ + ShaderLib.standard.uniforms, + { + clearCoat: { value: 0 }, + clearCoatRoughness: { value: 0 } + } + ] ), - vertexShader: ShaderChunk.meshphysical_vert, - fragmentShader: ShaderChunk.meshphysical_frag + vertexShader: ShaderChunk.meshphysical_vert, + fragmentShader: ShaderChunk.meshphysical_frag - }; + }; - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function WebGLAnimation() { + function WebGLAnimation() { - var context = null; - var isAnimating = false; - var animationLoop = null; + var context = null; + var isAnimating = false; + var animationLoop = null; - function onAnimationFrame( time, frame ) { + function onAnimationFrame( time, frame ) { - if ( isAnimating === false ) return; + if ( isAnimating === false ) return; - animationLoop( time, frame ); + animationLoop( time, frame ); - context.requestAnimationFrame( onAnimationFrame ); + context.requestAnimationFrame( onAnimationFrame ); - } + } - return { + return { - start: function () { + start: function () { - if ( isAnimating === true ) return; - if ( animationLoop === null ) return; + if ( isAnimating === true ) return; + if ( animationLoop === null ) return; - context.requestAnimationFrame( onAnimationFrame ); + context.requestAnimationFrame( onAnimationFrame ); - isAnimating = true; + isAnimating = true; - }, + }, - stop: function () { + stop: function () { - isAnimating = false; + isAnimating = false; - }, + }, - setAnimationLoop: function ( callback ) { + setAnimationLoop: function ( callback ) { - animationLoop = callback; + animationLoop = callback; - }, + }, - setContext: function ( value ) { + setContext: function ( value ) { - context = value; + context = value; - } + } - }; + }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function WebGLAttributes( gl ) { + function WebGLAttributes( gl ) { - var buffers = new WeakMap(); + var buffers = new WeakMap(); - function createBuffer( attribute, bufferType ) { + function createBuffer( attribute, bufferType ) { - var array = attribute.array; - var usage = attribute.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW; + var array = attribute.array; + var usage = attribute.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW; - var buffer = gl.createBuffer(); + var buffer = gl.createBuffer(); - gl.bindBuffer( bufferType, buffer ); - gl.bufferData( bufferType, array, usage ); + gl.bindBuffer( bufferType, buffer ); + gl.bufferData( bufferType, array, usage ); - attribute.onUploadCallback(); + attribute.onUploadCallback(); - var type = gl.FLOAT; + var type = gl.FLOAT; - if ( array instanceof Float32Array ) { + if ( array instanceof Float32Array ) { - type = gl.FLOAT; + type = gl.FLOAT; - } else if ( array instanceof Float64Array ) { + } else if ( array instanceof Float64Array ) { - console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' ); + console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' ); - } else if ( array instanceof Uint16Array ) { + } else if ( array instanceof Uint16Array ) { - type = gl.UNSIGNED_SHORT; + type = gl.UNSIGNED_SHORT; - } else if ( array instanceof Int16Array ) { + } else if ( array instanceof Int16Array ) { - type = gl.SHORT; + type = gl.SHORT; - } else if ( array instanceof Uint32Array ) { + } else if ( array instanceof Uint32Array ) { - type = gl.UNSIGNED_INT; + type = gl.UNSIGNED_INT; - } else if ( array instanceof Int32Array ) { + } else if ( array instanceof Int32Array ) { - type = gl.INT; + type = gl.INT; - } else if ( array instanceof Int8Array ) { + } else if ( array instanceof Int8Array ) { - type = gl.BYTE; + type = gl.BYTE; - } else if ( array instanceof Uint8Array ) { + } else if ( array instanceof Uint8Array ) { - type = gl.UNSIGNED_BYTE; + type = gl.UNSIGNED_BYTE; - } + } - return { - buffer: buffer, - type: type, - bytesPerElement: array.BYTES_PER_ELEMENT, - version: attribute.version - }; + return { + buffer: buffer, + type: type, + bytesPerElement: array.BYTES_PER_ELEMENT, + version: attribute.version + }; - } + } - function updateBuffer( buffer, attribute, bufferType ) { + function updateBuffer( buffer, attribute, bufferType ) { - var array = attribute.array; - var updateRange = attribute.updateRange; + var array = attribute.array; + var updateRange = attribute.updateRange; - gl.bindBuffer( bufferType, buffer ); + gl.bindBuffer( bufferType, buffer ); - if ( attribute.dynamic === false ) { + if ( attribute.dynamic === false ) { - gl.bufferData( bufferType, array, gl.STATIC_DRAW ); + gl.bufferData( bufferType, array, gl.STATIC_DRAW ); - } else if ( updateRange.count === - 1 ) { + } else if ( updateRange.count === - 1 ) { - // Not using update ranges + // Not using update ranges - gl.bufferSubData( bufferType, 0, array ); + gl.bufferSubData( bufferType, 0, array ); - } else if ( updateRange.count === 0 ) { + } else if ( updateRange.count === 0 ) { - console.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' ); + console.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' ); - } else { + } else { - gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, - array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) ); + gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, + array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) ); - updateRange.count = - 1; // reset range + updateRange.count = - 1; // reset range - } + } - } + } - // + // - function get( attribute ) { + function get( attribute ) { - if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; + if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; - return buffers.get( attribute ); + return buffers.get( attribute ); - } + } - function remove( attribute ) { + function remove( attribute ) { - if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; + if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; - var data = buffers.get( attribute ); + var data = buffers.get( attribute ); - if ( data ) { + if ( data ) { - gl.deleteBuffer( data.buffer ); + gl.deleteBuffer( data.buffer ); - buffers.delete( attribute ); + buffers.delete( attribute ); - } + } - } + } - function update( attribute, bufferType ) { + function update( attribute, bufferType ) { - if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; + if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; - var data = buffers.get( attribute ); + var data = buffers.get( attribute ); - if ( data === undefined ) { + if ( data === undefined ) { - buffers.set( attribute, createBuffer( attribute, bufferType ) ); + buffers.set( attribute, createBuffer( attribute, bufferType ) ); - } else if ( data.version < attribute.version ) { + } else if ( data.version < attribute.version ) { - updateBuffer( data.buffer, attribute, bufferType ); + updateBuffer( data.buffer, attribute, bufferType ); - data.version = attribute.version; + data.version = attribute.version; - } + } - } + } - return { + return { - get: get, - remove: remove, - update: update + get: get, + remove: remove, + update: update - }; + }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley - * @author bhouston / http://clara.io - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author WestLangley / http://github.com/WestLangley + * @author bhouston / http://clara.io + */ - function Euler( x, y, z, order ) { + function Euler( x, y, z, order ) { - this._x = x || 0; - this._y = y || 0; - this._z = z || 0; - this._order = order || Euler.DefaultOrder; + this._x = x || 0; + this._y = y || 0; + this._z = z || 0; + this._order = order || Euler.DefaultOrder; - } + } - Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]; + Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]; - Euler.DefaultOrder = 'XYZ'; + Euler.DefaultOrder = 'XYZ'; - Object.defineProperties( Euler.prototype, { + Object.defineProperties( Euler.prototype, { - x: { + x: { - get: function () { + get: function () { - return this._x; + return this._x; - }, + }, - set: function ( value ) { + set: function ( value ) { - this._x = value; - this.onChangeCallback(); + this._x = value; + this.onChangeCallback(); - } + } - }, + }, - y: { + y: { - get: function () { + get: function () { - return this._y; + return this._y; - }, + }, - set: function ( value ) { + set: function ( value ) { - this._y = value; - this.onChangeCallback(); + this._y = value; + this.onChangeCallback(); - } + } - }, + }, - z: { + z: { - get: function () { + get: function () { - return this._z; + return this._z; - }, + }, - set: function ( value ) { + set: function ( value ) { - this._z = value; - this.onChangeCallback(); + this._z = value; + this.onChangeCallback(); - } + } - }, + }, - order: { + order: { - get: function () { + get: function () { - return this._order; + return this._order; - }, + }, - set: function ( value ) { + set: function ( value ) { - this._order = value; - this.onChangeCallback(); + this._order = value; + this.onChangeCallback(); - } + } - } + } - } ); + } ); - Object.assign( Euler.prototype, { + Object.assign( Euler.prototype, { - isEuler: true, + isEuler: true, - set: function ( x, y, z, order ) { + set: function ( x, y, z, order ) { - this._x = x; - this._y = y; - this._z = z; - this._order = order || this._order; + this._x = x; + this._y = y; + this._z = z; + this._order = order || this._order; - this.onChangeCallback(); + this.onChangeCallback(); - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new this.constructor( this._x, this._y, this._z, this._order ); + return new this.constructor( this._x, this._y, this._z, this._order ); - }, + }, - copy: function ( euler ) { + copy: function ( euler ) { - this._x = euler._x; - this._y = euler._y; - this._z = euler._z; - this._order = euler._order; + this._x = euler._x; + this._y = euler._y; + this._z = euler._z; + this._order = euler._order; - this.onChangeCallback(); + this.onChangeCallback(); - return this; + return this; - }, + }, - setFromRotationMatrix: function ( m, order, update ) { + setFromRotationMatrix: function ( m, order, update ) { - var clamp = _Math.clamp; + var clamp = _Math.clamp; - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - var te = m.elements; - var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ]; - var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ]; - var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; + var te = m.elements; + var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ]; + var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ]; + var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; - order = order || this._order; + order = order || this._order; - if ( order === 'XYZ' ) { + if ( order === 'XYZ' ) { - this._y = Math.asin( clamp( m13, - 1, 1 ) ); + this._y = Math.asin( clamp( m13, - 1, 1 ) ); - if ( Math.abs( m13 ) < 0.99999 ) { + if ( Math.abs( m13 ) < 0.99999 ) { - this._x = Math.atan2( - m23, m33 ); - this._z = Math.atan2( - m12, m11 ); + this._x = Math.atan2( - m23, m33 ); + this._z = Math.atan2( - m12, m11 ); - } else { + } else { - this._x = Math.atan2( m32, m22 ); - this._z = 0; + this._x = Math.atan2( m32, m22 ); + this._z = 0; - } + } - } else if ( order === 'YXZ' ) { + } else if ( order === 'YXZ' ) { - this._x = Math.asin( - clamp( m23, - 1, 1 ) ); + this._x = Math.asin( - clamp( m23, - 1, 1 ) ); - if ( Math.abs( m23 ) < 0.99999 ) { + if ( Math.abs( m23 ) < 0.99999 ) { - this._y = Math.atan2( m13, m33 ); - this._z = Math.atan2( m21, m22 ); + this._y = Math.atan2( m13, m33 ); + this._z = Math.atan2( m21, m22 ); - } else { + } else { - this._y = Math.atan2( - m31, m11 ); - this._z = 0; + this._y = Math.atan2( - m31, m11 ); + this._z = 0; - } + } - } else if ( order === 'ZXY' ) { + } else if ( order === 'ZXY' ) { - this._x = Math.asin( clamp( m32, - 1, 1 ) ); + this._x = Math.asin( clamp( m32, - 1, 1 ) ); - if ( Math.abs( m32 ) < 0.99999 ) { + if ( Math.abs( m32 ) < 0.99999 ) { - this._y = Math.atan2( - m31, m33 ); - this._z = Math.atan2( - m12, m22 ); + this._y = Math.atan2( - m31, m33 ); + this._z = Math.atan2( - m12, m22 ); - } else { + } else { - this._y = 0; - this._z = Math.atan2( m21, m11 ); + this._y = 0; + this._z = Math.atan2( m21, m11 ); - } + } - } else if ( order === 'ZYX' ) { + } else if ( order === 'ZYX' ) { - this._y = Math.asin( - clamp( m31, - 1, 1 ) ); + this._y = Math.asin( - clamp( m31, - 1, 1 ) ); - if ( Math.abs( m31 ) < 0.99999 ) { + if ( Math.abs( m31 ) < 0.99999 ) { - this._x = Math.atan2( m32, m33 ); - this._z = Math.atan2( m21, m11 ); + this._x = Math.atan2( m32, m33 ); + this._z = Math.atan2( m21, m11 ); - } else { + } else { - this._x = 0; - this._z = Math.atan2( - m12, m22 ); + this._x = 0; + this._z = Math.atan2( - m12, m22 ); - } + } - } else if ( order === 'YZX' ) { + } else if ( order === 'YZX' ) { - this._z = Math.asin( clamp( m21, - 1, 1 ) ); + this._z = Math.asin( clamp( m21, - 1, 1 ) ); - if ( Math.abs( m21 ) < 0.99999 ) { + if ( Math.abs( m21 ) < 0.99999 ) { - this._x = Math.atan2( - m23, m22 ); - this._y = Math.atan2( - m31, m11 ); + this._x = Math.atan2( - m23, m22 ); + this._y = Math.atan2( - m31, m11 ); - } else { + } else { - this._x = 0; - this._y = Math.atan2( m13, m33 ); + this._x = 0; + this._y = Math.atan2( m13, m33 ); - } + } - } else if ( order === 'XZY' ) { + } else if ( order === 'XZY' ) { - this._z = Math.asin( - clamp( m12, - 1, 1 ) ); + this._z = Math.asin( - clamp( m12, - 1, 1 ) ); - if ( Math.abs( m12 ) < 0.99999 ) { + if ( Math.abs( m12 ) < 0.99999 ) { - this._x = Math.atan2( m32, m22 ); - this._y = Math.atan2( m13, m11 ); + this._x = Math.atan2( m32, m22 ); + this._y = Math.atan2( m13, m11 ); - } else { + } else { - this._x = Math.atan2( - m23, m33 ); - this._y = 0; + this._x = Math.atan2( - m23, m33 ); + this._y = 0; - } + } - } else { + } else { - console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order ); + console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order ); - } + } - this._order = order; + this._order = order; - if ( update !== false ) this.onChangeCallback(); + if ( update !== false ) this.onChangeCallback(); - return this; + return this; - }, + }, - setFromQuaternion: function () { + setFromQuaternion: function () { - var matrix = new Matrix4(); + var matrix = new Matrix4(); - return function setFromQuaternion( q, order, update ) { + return function setFromQuaternion( q, order, update ) { - matrix.makeRotationFromQuaternion( q ); + matrix.makeRotationFromQuaternion( q ); - return this.setFromRotationMatrix( matrix, order, update ); + return this.setFromRotationMatrix( matrix, order, update ); - }; + }; - }(), + }(), - setFromVector3: function ( v, order ) { + setFromVector3: function ( v, order ) { - return this.set( v.x, v.y, v.z, order || this._order ); + return this.set( v.x, v.y, v.z, order || this._order ); - }, + }, - reorder: function () { + reorder: function () { - // WARNING: this discards revolution information -bhouston + // WARNING: this discards revolution information -bhouston - var q = new Quaternion(); + var q = new Quaternion(); - return function reorder( newOrder ) { + return function reorder( newOrder ) { - q.setFromEuler( this ); + q.setFromEuler( this ); - return this.setFromQuaternion( q, newOrder ); + return this.setFromQuaternion( q, newOrder ); - }; + }; - }(), + }(), - equals: function ( euler ) { + equals: function ( euler ) { - return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order ); + return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order ); - }, + }, - fromArray: function ( array ) { + fromArray: function ( array ) { - this._x = array[ 0 ]; - this._y = array[ 1 ]; - this._z = array[ 2 ]; - if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; + this._x = array[ 0 ]; + this._y = array[ 1 ]; + this._z = array[ 2 ]; + if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; - this.onChangeCallback(); + this.onChangeCallback(); - return this; + return this; - }, + }, - toArray: function ( array, offset ) { + toArray: function ( array, offset ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - array[ offset ] = this._x; - array[ offset + 1 ] = this._y; - array[ offset + 2 ] = this._z; - array[ offset + 3 ] = this._order; + array[ offset ] = this._x; + array[ offset + 1 ] = this._y; + array[ offset + 2 ] = this._z; + array[ offset + 3 ] = this._order; - return array; + return array; - }, + }, - toVector3: function ( optionalResult ) { + toVector3: function ( optionalResult ) { - if ( optionalResult ) { + if ( optionalResult ) { - return optionalResult.set( this._x, this._y, this._z ); + return optionalResult.set( this._x, this._y, this._z ); - } else { + } else { - return new Vector3( this._x, this._y, this._z ); + return new Vector3( this._x, this._y, this._z ); - } + } - }, + }, - onChange: function ( callback ) { + onChange: function ( callback ) { - this.onChangeCallback = callback; + this.onChangeCallback = callback; - return this; + return this; - }, + }, - onChangeCallback: function () {} + onChangeCallback: function () {} - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function Layers() { + function Layers() { - this.mask = 1 | 0; + this.mask = 1 | 0; - } + } - Object.assign( Layers.prototype, { + Object.assign( Layers.prototype, { - set: function ( channel ) { + set: function ( channel ) { - this.mask = 1 << channel | 0; + this.mask = 1 << channel | 0; - }, + }, - enable: function ( channel ) { + enable: function ( channel ) { - this.mask |= 1 << channel | 0; + this.mask |= 1 << channel | 0; - }, + }, - toggle: function ( channel ) { + toggle: function ( channel ) { - this.mask ^= 1 << channel | 0; + this.mask ^= 1 << channel | 0; - }, + }, - disable: function ( channel ) { + disable: function ( channel ) { - this.mask &= ~ ( 1 << channel | 0 ); + this.mask &= ~ ( 1 << channel | 0 ); - }, + }, - test: function ( layers ) { + test: function ( layers ) { - return ( this.mask & layers.mask ) !== 0; + return ( this.mask & layers.mask ) !== 0; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - * @author WestLangley / http://github.com/WestLangley - * @author elephantatwork / www.elephantatwork.ch - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author mikael emtinger / http://gomo.se/ + * @author alteredq / http://alteredqualia.com/ + * @author WestLangley / http://github.com/WestLangley + * @author elephantatwork / www.elephantatwork.ch + */ - var object3DId = 0; + var object3DId = 0; - function Object3D() { + function Object3D() { - Object.defineProperty( this, 'id', { value: object3DId ++ } ); + Object.defineProperty( this, 'id', { value: object3DId ++ } ); - this.uuid = _Math.generateUUID(); + this.uuid = _Math.generateUUID(); - this.name = ''; - this.type = 'Object3D'; + this.name = ''; + this.type = 'Object3D'; - this.parent = null; - this.children = []; + this.parent = null; + this.children = []; - this.up = Object3D.DefaultUp.clone(); + this.up = Object3D.DefaultUp.clone(); - var position = new Vector3(); - var rotation = new Euler(); - var quaternion = new Quaternion(); - var scale = new Vector3( 1, 1, 1 ); + var position = new Vector3(); + var rotation = new Euler(); + var quaternion = new Quaternion(); + var scale = new Vector3( 1, 1, 1 ); - function onRotationChange() { + function onRotationChange() { - quaternion.setFromEuler( rotation, false ); + quaternion.setFromEuler( rotation, false ); - } + } - function onQuaternionChange() { + function onQuaternionChange() { - rotation.setFromQuaternion( quaternion, undefined, false ); + rotation.setFromQuaternion( quaternion, undefined, false ); - } + } - rotation.onChange( onRotationChange ); - quaternion.onChange( onQuaternionChange ); + rotation.onChange( onRotationChange ); + quaternion.onChange( onQuaternionChange ); - Object.defineProperties( this, { - position: { - enumerable: true, - value: position - }, - rotation: { - enumerable: true, - value: rotation - }, - quaternion: { - enumerable: true, - value: quaternion - }, - scale: { - enumerable: true, - value: scale - }, - modelViewMatrix: { - value: new Matrix4() - }, - normalMatrix: { - value: new Matrix3() - } - } ); + Object.defineProperties( this, { + position: { + enumerable: true, + value: position + }, + rotation: { + enumerable: true, + value: rotation + }, + quaternion: { + enumerable: true, + value: quaternion + }, + scale: { + enumerable: true, + value: scale + }, + modelViewMatrix: { + value: new Matrix4() + }, + normalMatrix: { + value: new Matrix3() + } + } ); - this.matrix = new Matrix4(); - this.matrixWorld = new Matrix4(); + this.matrix = new Matrix4(); + this.matrixWorld = new Matrix4(); - this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; - this.matrixWorldNeedsUpdate = false; + this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; + this.matrixWorldNeedsUpdate = false; - this.layers = new Layers(); - this.visible = true; + this.layers = new Layers(); + this.visible = true; - this.castShadow = false; - this.receiveShadow = false; + this.castShadow = false; + this.receiveShadow = false; - this.frustumCulled = true; - this.renderOrder = 0; + this.frustumCulled = true; + this.renderOrder = 0; - this.userData = {}; + this.userData = {}; - } + } - Object3D.DefaultUp = new Vector3( 0, 1, 0 ); - Object3D.DefaultMatrixAutoUpdate = true; + Object3D.DefaultUp = new Vector3( 0, 1, 0 ); + Object3D.DefaultMatrixAutoUpdate = true; - Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { + Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - constructor: Object3D, + constructor: Object3D, - isObject3D: true, + isObject3D: true, - onBeforeRender: function () {}, - onAfterRender: function () {}, + onBeforeRender: function () {}, + onAfterRender: function () {}, - applyMatrix: function ( matrix ) { + applyMatrix: function ( matrix ) { - this.matrix.multiplyMatrices( matrix, this.matrix ); + this.matrix.multiplyMatrices( matrix, this.matrix ); - this.matrix.decompose( this.position, this.quaternion, this.scale ); + this.matrix.decompose( this.position, this.quaternion, this.scale ); - }, + }, - applyQuaternion: function ( q ) { + applyQuaternion: function ( q ) { - this.quaternion.premultiply( q ); + this.quaternion.premultiply( q ); - return this; + return this; - }, + }, - setRotationFromAxisAngle: function ( axis, angle ) { + setRotationFromAxisAngle: function ( axis, angle ) { - // assumes axis is normalized + // assumes axis is normalized - this.quaternion.setFromAxisAngle( axis, angle ); + this.quaternion.setFromAxisAngle( axis, angle ); - }, + }, - setRotationFromEuler: function ( euler ) { + setRotationFromEuler: function ( euler ) { - this.quaternion.setFromEuler( euler, true ); + this.quaternion.setFromEuler( euler, true ); - }, + }, - setRotationFromMatrix: function ( m ) { + setRotationFromMatrix: function ( m ) { - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - this.quaternion.setFromRotationMatrix( m ); + this.quaternion.setFromRotationMatrix( m ); - }, + }, - setRotationFromQuaternion: function ( q ) { + setRotationFromQuaternion: function ( q ) { - // assumes q is normalized + // assumes q is normalized - this.quaternion.copy( q ); + this.quaternion.copy( q ); - }, + }, - rotateOnAxis: function () { + rotateOnAxis: function () { - // rotate object on axis in object space - // axis is assumed to be normalized + // rotate object on axis in object space + // axis is assumed to be normalized - var q1 = new Quaternion(); + var q1 = new Quaternion(); - return function rotateOnAxis( axis, angle ) { + return function rotateOnAxis( axis, angle ) { - q1.setFromAxisAngle( axis, angle ); + q1.setFromAxisAngle( axis, angle ); - this.quaternion.multiply( q1 ); + this.quaternion.multiply( q1 ); - return this; + return this; - }; + }; - }(), + }(), - rotateOnWorldAxis: function () { + rotateOnWorldAxis: function () { - // rotate object on axis in world space - // axis is assumed to be normalized - // method assumes no rotated parent + // rotate object on axis in world space + // axis is assumed to be normalized + // method assumes no rotated parent - var q1 = new Quaternion(); + var q1 = new Quaternion(); - return function rotateOnWorldAxis( axis, angle ) { + return function rotateOnWorldAxis( axis, angle ) { - q1.setFromAxisAngle( axis, angle ); + q1.setFromAxisAngle( axis, angle ); - this.quaternion.premultiply( q1 ); + this.quaternion.premultiply( q1 ); - return this; + return this; - }; + }; - }(), + }(), - rotateX: function () { + rotateX: function () { - var v1 = new Vector3( 1, 0, 0 ); + var v1 = new Vector3( 1, 0, 0 ); - return function rotateX( angle ) { + return function rotateX( angle ) { - return this.rotateOnAxis( v1, angle ); + return this.rotateOnAxis( v1, angle ); - }; + }; - }(), + }(), - rotateY: function () { + rotateY: function () { - var v1 = new Vector3( 0, 1, 0 ); + var v1 = new Vector3( 0, 1, 0 ); - return function rotateY( angle ) { + return function rotateY( angle ) { - return this.rotateOnAxis( v1, angle ); + return this.rotateOnAxis( v1, angle ); - }; + }; - }(), + }(), - rotateZ: function () { + rotateZ: function () { - var v1 = new Vector3( 0, 0, 1 ); + var v1 = new Vector3( 0, 0, 1 ); - return function rotateZ( angle ) { + return function rotateZ( angle ) { - return this.rotateOnAxis( v1, angle ); + return this.rotateOnAxis( v1, angle ); - }; + }; - }(), + }(), - translateOnAxis: function () { + translateOnAxis: function () { - // translate object by distance along axis in object space - // axis is assumed to be normalized + // translate object by distance along axis in object space + // axis is assumed to be normalized - var v1 = new Vector3(); + var v1 = new Vector3(); - return function translateOnAxis( axis, distance ) { + return function translateOnAxis( axis, distance ) { - v1.copy( axis ).applyQuaternion( this.quaternion ); + v1.copy( axis ).applyQuaternion( this.quaternion ); - this.position.add( v1.multiplyScalar( distance ) ); + this.position.add( v1.multiplyScalar( distance ) ); - return this; + return this; - }; + }; - }(), + }(), - translateX: function () { + translateX: function () { - var v1 = new Vector3( 1, 0, 0 ); + var v1 = new Vector3( 1, 0, 0 ); - return function translateX( distance ) { + return function translateX( distance ) { - return this.translateOnAxis( v1, distance ); + return this.translateOnAxis( v1, distance ); - }; + }; - }(), + }(), - translateY: function () { + translateY: function () { - var v1 = new Vector3( 0, 1, 0 ); + var v1 = new Vector3( 0, 1, 0 ); - return function translateY( distance ) { + return function translateY( distance ) { - return this.translateOnAxis( v1, distance ); + return this.translateOnAxis( v1, distance ); - }; + }; - }(), + }(), - translateZ: function () { + translateZ: function () { - var v1 = new Vector3( 0, 0, 1 ); + var v1 = new Vector3( 0, 0, 1 ); - return function translateZ( distance ) { + return function translateZ( distance ) { - return this.translateOnAxis( v1, distance ); + return this.translateOnAxis( v1, distance ); - }; + }; - }(), + }(), - localToWorld: function ( vector ) { + localToWorld: function ( vector ) { - return vector.applyMatrix4( this.matrixWorld ); + return vector.applyMatrix4( this.matrixWorld ); - }, + }, - worldToLocal: function () { + worldToLocal: function () { - var m1 = new Matrix4(); + var m1 = new Matrix4(); - return function worldToLocal( vector ) { + return function worldToLocal( vector ) { - return vector.applyMatrix4( m1.getInverse( this.matrixWorld ) ); + return vector.applyMatrix4( m1.getInverse( this.matrixWorld ) ); - }; + }; - }(), + }(), - lookAt: function () { + lookAt: function () { - // This method does not support objects with rotated and/or translated parent(s) + // This method does not support objects with rotated and/or translated parent(s) - var m1 = new Matrix4(); - var vector = new Vector3(); + var m1 = new Matrix4(); + var vector = new Vector3(); - return function lookAt( x, y, z ) { + return function lookAt( x, y, z ) { - if ( x.isVector3 ) { + if ( x.isVector3 ) { - vector.copy( x ); + vector.copy( x ); - } else { + } else { - vector.set( x, y, z ); + vector.set( x, y, z ); - } + } - if ( this.isCamera ) { + if ( this.isCamera ) { - m1.lookAt( this.position, vector, this.up ); + m1.lookAt( this.position, vector, this.up ); - } else { + } else { - m1.lookAt( vector, this.position, this.up ); + m1.lookAt( vector, this.position, this.up ); - } + } - this.quaternion.setFromRotationMatrix( m1 ); + this.quaternion.setFromRotationMatrix( m1 ); - }; + }; - }(), + }(), - add: function ( object ) { + add: function ( object ) { - if ( arguments.length > 1 ) { + if ( arguments.length > 1 ) { - for ( var i = 0; i < arguments.length; i ++ ) { + for ( var i = 0; i < arguments.length; i ++ ) { - this.add( arguments[ i ] ); + this.add( arguments[ i ] ); - } + } - return this; + return this; - } + } - if ( object === this ) { + if ( object === this ) { - console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object ); - return this; + console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object ); + return this; - } + } - if ( ( object && object.isObject3D ) ) { + if ( ( object && object.isObject3D ) ) { - if ( object.parent !== null ) { + if ( object.parent !== null ) { - object.parent.remove( object ); + object.parent.remove( object ); - } + } - object.parent = this; - object.dispatchEvent( { type: 'added' } ); + object.parent = this; + object.dispatchEvent( { type: 'added' } ); - this.children.push( object ); + this.children.push( object ); - } else { + } else { - console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object ); + console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object ); - } + } - return this; + return this; - }, + }, - remove: function ( object ) { + remove: function ( object ) { - if ( arguments.length > 1 ) { + if ( arguments.length > 1 ) { - for ( var i = 0; i < arguments.length; i ++ ) { + for ( var i = 0; i < arguments.length; i ++ ) { - this.remove( arguments[ i ] ); + this.remove( arguments[ i ] ); - } + } - return this; + return this; - } + } - var index = this.children.indexOf( object ); + var index = this.children.indexOf( object ); - if ( index !== - 1 ) { + if ( index !== - 1 ) { - object.parent = null; + object.parent = null; - object.dispatchEvent( { type: 'removed' } ); + object.dispatchEvent( { type: 'removed' } ); - this.children.splice( index, 1 ); + this.children.splice( index, 1 ); - } + } - return this; + return this; - }, + }, - getObjectById: function ( id ) { + getObjectById: function ( id ) { - return this.getObjectByProperty( 'id', id ); + return this.getObjectByProperty( 'id', id ); - }, + }, - getObjectByName: function ( name ) { + getObjectByName: function ( name ) { - return this.getObjectByProperty( 'name', name ); + return this.getObjectByProperty( 'name', name ); - }, + }, - getObjectByProperty: function ( name, value ) { + getObjectByProperty: function ( name, value ) { - if ( this[ name ] === value ) return this; + if ( this[ name ] === value ) return this; - for ( var i = 0, l = this.children.length; i < l; i ++ ) { + for ( var i = 0, l = this.children.length; i < l; i ++ ) { - var child = this.children[ i ]; - var object = child.getObjectByProperty( name, value ); + var child = this.children[ i ]; + var object = child.getObjectByProperty( name, value ); - if ( object !== undefined ) { + if ( object !== undefined ) { - return object; + return object; - } + } - } + } - return undefined; + return undefined; - }, + }, - getWorldPosition: function ( target ) { + getWorldPosition: function ( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Object3D: .getWorldPosition() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Object3D: .getWorldPosition() target is now required' ); + target = new Vector3(); - } + } - this.updateMatrixWorld( true ); + this.updateMatrixWorld( true ); - return target.setFromMatrixPosition( this.matrixWorld ); + return target.setFromMatrixPosition( this.matrixWorld ); - }, + }, - getWorldQuaternion: function () { + getWorldQuaternion: function () { - var position = new Vector3(); - var scale = new Vector3(); + var position = new Vector3(); + var scale = new Vector3(); - return function getWorldQuaternion( target ) { + return function getWorldQuaternion( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' ); - target = new Quaternion(); + console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' ); + target = new Quaternion(); - } + } - this.updateMatrixWorld( true ); + this.updateMatrixWorld( true ); - this.matrixWorld.decompose( position, target, scale ); + this.matrixWorld.decompose( position, target, scale ); - return target; + return target; - }; + }; - }(), + }(), - getWorldScale: function () { + getWorldScale: function () { - var position = new Vector3(); - var quaternion = new Quaternion(); + var position = new Vector3(); + var quaternion = new Quaternion(); - return function getWorldScale( target ) { + return function getWorldScale( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Object3D: .getWorldScale() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Object3D: .getWorldScale() target is now required' ); + target = new Vector3(); - } + } - this.updateMatrixWorld( true ); + this.updateMatrixWorld( true ); - this.matrixWorld.decompose( position, quaternion, target ); + this.matrixWorld.decompose( position, quaternion, target ); - return target; + return target; - }; + }; - }(), + }(), - getWorldDirection: function () { + getWorldDirection: function () { - var quaternion = new Quaternion(); + var quaternion = new Quaternion(); - return function getWorldDirection( target ) { + return function getWorldDirection( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Object3D: .getWorldDirection() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Object3D: .getWorldDirection() target is now required' ); + target = new Vector3(); - } + } - this.getWorldQuaternion( quaternion ); + this.getWorldQuaternion( quaternion ); - return target.set( 0, 0, 1 ).applyQuaternion( quaternion ); + return target.set( 0, 0, 1 ).applyQuaternion( quaternion ); - }; + }; - }(), + }(), - raycast: function () {}, + raycast: function () {}, - traverse: function ( callback ) { + traverse: function ( callback ) { - callback( this ); + callback( this ); - var children = this.children; + var children = this.children; - for ( var i = 0, l = children.length; i < l; i ++ ) { + for ( var i = 0, l = children.length; i < l; i ++ ) { - children[ i ].traverse( callback ); + children[ i ].traverse( callback ); - } + } - }, + }, - traverseVisible: function ( callback ) { + traverseVisible: function ( callback ) { - if ( this.visible === false ) return; + if ( this.visible === false ) return; - callback( this ); + callback( this ); - var children = this.children; + var children = this.children; - for ( var i = 0, l = children.length; i < l; i ++ ) { + for ( var i = 0, l = children.length; i < l; i ++ ) { - children[ i ].traverseVisible( callback ); + children[ i ].traverseVisible( callback ); - } + } - }, + }, - traverseAncestors: function ( callback ) { + traverseAncestors: function ( callback ) { - var parent = this.parent; + var parent = this.parent; - if ( parent !== null ) { + if ( parent !== null ) { - callback( parent ); + callback( parent ); - parent.traverseAncestors( callback ); + parent.traverseAncestors( callback ); - } + } - }, + }, - updateMatrix: function () { + updateMatrix: function () { - this.matrix.compose( this.position, this.quaternion, this.scale ); + this.matrix.compose( this.position, this.quaternion, this.scale ); - this.matrixWorldNeedsUpdate = true; + this.matrixWorldNeedsUpdate = true; - }, + }, - updateMatrixWorld: function ( force ) { + updateMatrixWorld: function ( force ) { - if ( this.matrixAutoUpdate ) this.updateMatrix(); + if ( this.matrixAutoUpdate ) this.updateMatrix(); - if ( this.matrixWorldNeedsUpdate || force ) { + if ( this.matrixWorldNeedsUpdate || force ) { - if ( this.parent === null ) { + if ( this.parent === null ) { - this.matrixWorld.copy( this.matrix ); + this.matrixWorld.copy( this.matrix ); - } else { + } else { - this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); + this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); - } + } - this.matrixWorldNeedsUpdate = false; + this.matrixWorldNeedsUpdate = false; - force = true; + force = true; - } + } - // update children + // update children - var children = this.children; + var children = this.children; - for ( var i = 0, l = children.length; i < l; i ++ ) { + for ( var i = 0, l = children.length; i < l; i ++ ) { - children[ i ].updateMatrixWorld( force ); + children[ i ].updateMatrixWorld( force ); - } + } - }, + }, - toJSON: function ( meta ) { + toJSON: function ( meta ) { - // meta is a string when called from JSON.stringify - var isRootObject = ( meta === undefined || typeof meta === 'string' ); + // meta is a string when called from JSON.stringify + var isRootObject = ( meta === undefined || typeof meta === 'string' ); - var output = {}; + var output = {}; - // meta is a hash used to collect geometries, materials. - // not providing it implies that this is the root object - // being serialized. - if ( isRootObject ) { + // meta is a hash used to collect geometries, materials. + // not providing it implies that this is the root object + // being serialized. + if ( isRootObject ) { - // initialize meta obj - meta = { - geometries: {}, - materials: {}, - textures: {}, - images: {}, - shapes: {} - }; + // initialize meta obj + meta = { + geometries: {}, + materials: {}, + textures: {}, + images: {}, + shapes: {} + }; - output.metadata = { - version: 4.5, - type: 'Object', - generator: 'Object3D.toJSON' - }; + output.metadata = { + version: 4.5, + type: 'Object', + generator: 'Object3D.toJSON' + }; - } + } - // standard Object3D serialization + // standard Object3D serialization - var object = {}; + var object = {}; - object.uuid = this.uuid; - object.type = this.type; + object.uuid = this.uuid; + object.type = this.type; - if ( this.name !== '' ) object.name = this.name; - if ( this.castShadow === true ) object.castShadow = true; - if ( this.receiveShadow === true ) object.receiveShadow = true; - if ( this.visible === false ) object.visible = false; - if ( this.frustumCulled === false ) object.frustumCulled = false; - if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; - if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData; + if ( this.name !== '' ) object.name = this.name; + if ( this.castShadow === true ) object.castShadow = true; + if ( this.receiveShadow === true ) object.receiveShadow = true; + if ( this.visible === false ) object.visible = false; + if ( this.frustumCulled === false ) object.frustumCulled = false; + if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; + if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData; - object.layers = this.layers.mask; - object.matrix = this.matrix.toArray(); + object.layers = this.layers.mask; + object.matrix = this.matrix.toArray(); - if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false; + if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false; - // + // - function serialize( library, element ) { + function serialize( library, element ) { - if ( library[ element.uuid ] === undefined ) { + if ( library[ element.uuid ] === undefined ) { - library[ element.uuid ] = element.toJSON( meta ); + library[ element.uuid ] = element.toJSON( meta ); - } + } - return element.uuid; + return element.uuid; - } + } - if ( this.isMesh || this.isLine || this.isPoints ) { + if ( this.isMesh || this.isLine || this.isPoints ) { - object.geometry = serialize( meta.geometries, this.geometry ); + object.geometry = serialize( meta.geometries, this.geometry ); - var parameters = this.geometry.parameters; + var parameters = this.geometry.parameters; - if ( parameters !== undefined && parameters.shapes !== undefined ) { + if ( parameters !== undefined && parameters.shapes !== undefined ) { - var shapes = parameters.shapes; + var shapes = parameters.shapes; - if ( Array.isArray( shapes ) ) { + if ( Array.isArray( shapes ) ) { - for ( var i = 0, l = shapes.length; i < l; i ++ ) { + for ( var i = 0, l = shapes.length; i < l; i ++ ) { - var shape = shapes[ i ]; + var shape = shapes[ i ]; - serialize( meta.shapes, shape ); + serialize( meta.shapes, shape ); - } + } - } else { + } else { - serialize( meta.shapes, shapes ); + serialize( meta.shapes, shapes ); - } + } - } + } - } + } - if ( this.material !== undefined ) { + if ( this.material !== undefined ) { - if ( Array.isArray( this.material ) ) { + if ( Array.isArray( this.material ) ) { - var uuids = []; + var uuids = []; - for ( var i = 0, l = this.material.length; i < l; i ++ ) { + for ( var i = 0, l = this.material.length; i < l; i ++ ) { - uuids.push( serialize( meta.materials, this.material[ i ] ) ); + uuids.push( serialize( meta.materials, this.material[ i ] ) ); - } + } - object.material = uuids; + object.material = uuids; - } else { + } else { - object.material = serialize( meta.materials, this.material ); + object.material = serialize( meta.materials, this.material ); - } + } - } + } - // + // - if ( this.children.length > 0 ) { + if ( this.children.length > 0 ) { - object.children = []; + object.children = []; - for ( var i = 0; i < this.children.length; i ++ ) { + for ( var i = 0; i < this.children.length; i ++ ) { - object.children.push( this.children[ i ].toJSON( meta ).object ); + object.children.push( this.children[ i ].toJSON( meta ).object ); - } + } - } + } - if ( isRootObject ) { + if ( isRootObject ) { - var geometries = extractFromCache( meta.geometries ); - var materials = extractFromCache( meta.materials ); - var textures = extractFromCache( meta.textures ); - var images = extractFromCache( meta.images ); - var shapes = extractFromCache( meta.shapes ); + var geometries = extractFromCache( meta.geometries ); + var materials = extractFromCache( meta.materials ); + var textures = extractFromCache( meta.textures ); + var images = extractFromCache( meta.images ); + var shapes = extractFromCache( meta.shapes ); - if ( geometries.length > 0 ) output.geometries = geometries; - if ( materials.length > 0 ) output.materials = materials; - if ( textures.length > 0 ) output.textures = textures; - if ( images.length > 0 ) output.images = images; - if ( shapes.length > 0 ) output.shapes = shapes; + if ( geometries.length > 0 ) output.geometries = geometries; + if ( materials.length > 0 ) output.materials = materials; + if ( textures.length > 0 ) output.textures = textures; + if ( images.length > 0 ) output.images = images; + if ( shapes.length > 0 ) output.shapes = shapes; - } + } - output.object = object; + output.object = object; - return output; + return output; - // extract data from the cache hash - // remove metadata on each item - // and return as array - function extractFromCache( cache ) { + // extract data from the cache hash + // remove metadata on each item + // and return as array + function extractFromCache( cache ) { - var values = []; - for ( var key in cache ) { + var values = []; + for ( var key in cache ) { - var data = cache[ key ]; - delete data.metadata; - values.push( data ); + var data = cache[ key ]; + delete data.metadata; + values.push( data ); - } - return values; + } + return values; - } + } - }, + }, - clone: function ( recursive ) { + clone: function ( recursive ) { - return new this.constructor().copy( this, recursive ); + return new this.constructor().copy( this, recursive ); - }, + }, - copy: function ( source, recursive ) { + copy: function ( source, recursive ) { - if ( recursive === undefined ) recursive = true; + if ( recursive === undefined ) recursive = true; - this.name = source.name; + this.name = source.name; - this.up.copy( source.up ); + this.up.copy( source.up ); - this.position.copy( source.position ); - this.quaternion.copy( source.quaternion ); - this.scale.copy( source.scale ); + this.position.copy( source.position ); + this.quaternion.copy( source.quaternion ); + this.scale.copy( source.scale ); - this.matrix.copy( source.matrix ); - this.matrixWorld.copy( source.matrixWorld ); + this.matrix.copy( source.matrix ); + this.matrixWorld.copy( source.matrixWorld ); - this.matrixAutoUpdate = source.matrixAutoUpdate; - this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; + this.matrixAutoUpdate = source.matrixAutoUpdate; + this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; - this.layers.mask = source.layers.mask; - this.visible = source.visible; + this.layers.mask = source.layers.mask; + this.visible = source.visible; - this.castShadow = source.castShadow; - this.receiveShadow = source.receiveShadow; + this.castShadow = source.castShadow; + this.receiveShadow = source.receiveShadow; - this.frustumCulled = source.frustumCulled; - this.renderOrder = source.renderOrder; + this.frustumCulled = source.frustumCulled; + this.renderOrder = source.renderOrder; - this.userData = JSON.parse( JSON.stringify( source.userData ) ); + this.userData = JSON.parse( JSON.stringify( source.userData ) ); - if ( recursive === true ) { + if ( recursive === true ) { - for ( var i = 0; i < source.children.length; i ++ ) { + for ( var i = 0; i < source.children.length; i ++ ) { - var child = source.children[ i ]; - this.add( child.clone() ); + var child = source.children[ i ]; + this.add( child.clone() ); - } + } - } + } - return this; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author mikael emtinger / http://gomo.se/ - * @author WestLangley / http://github.com/WestLangley - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author mikael emtinger / http://gomo.se/ + * @author WestLangley / http://github.com/WestLangley + */ - function Camera() { + function Camera() { - Object3D.call( this ); + Object3D.call( this ); - this.type = 'Camera'; + this.type = 'Camera'; - this.matrixWorldInverse = new Matrix4(); - this.projectionMatrix = new Matrix4(); + this.matrixWorldInverse = new Matrix4(); + this.projectionMatrix = new Matrix4(); - } + } - Camera.prototype = Object.assign( Object.create( Object3D.prototype ), { + Camera.prototype = Object.assign( Object.create( Object3D.prototype ), { - constructor: Camera, + constructor: Camera, - isCamera: true, + isCamera: true, - copy: function ( source, recursive ) { + copy: function ( source, recursive ) { - Object3D.prototype.copy.call( this, source, recursive ); + Object3D.prototype.copy.call( this, source, recursive ); - this.matrixWorldInverse.copy( source.matrixWorldInverse ); - this.projectionMatrix.copy( source.projectionMatrix ); + this.matrixWorldInverse.copy( source.matrixWorldInverse ); + this.projectionMatrix.copy( source.projectionMatrix ); - return this; + return this; - }, + }, - getWorldDirection: function () { + getWorldDirection: function () { - var quaternion = new Quaternion(); + var quaternion = new Quaternion(); - return function getWorldDirection( target ) { + return function getWorldDirection( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Camera: .getWorldDirection() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Camera: .getWorldDirection() target is now required' ); + target = new Vector3(); - } + } - this.getWorldQuaternion( quaternion ); + this.getWorldQuaternion( quaternion ); - return target.set( 0, 0, - 1 ).applyQuaternion( quaternion ); + return target.set( 0, 0, - 1 ).applyQuaternion( quaternion ); - }; + }; - }(), + }(), - updateMatrixWorld: function ( force ) { + updateMatrixWorld: function ( force ) { - Object3D.prototype.updateMatrixWorld.call( this, force ); + Object3D.prototype.updateMatrixWorld.call( this, force ); - this.matrixWorldInverse.getInverse( this.matrixWorld ); + this.matrixWorldInverse.getInverse( this.matrixWorld ); - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - } + } - } ); + } ); - /** - * @author alteredq / http://alteredqualia.com/ - * @author arose / http://github.com/arose - */ + /** + * @author alteredq / http://alteredqualia.com/ + * @author arose / http://github.com/arose + */ - function OrthographicCamera( left, right, top, bottom, near, far ) { + function OrthographicCamera( left, right, top, bottom, near, far ) { - Camera.call( this ); + Camera.call( this ); - this.type = 'OrthographicCamera'; + this.type = 'OrthographicCamera'; - this.zoom = 1; - this.view = null; + this.zoom = 1; + this.view = null; - this.left = left; - this.right = right; - this.top = top; - this.bottom = bottom; + this.left = left; + this.right = right; + this.top = top; + this.bottom = bottom; - this.near = ( near !== undefined ) ? near : 0.1; - this.far = ( far !== undefined ) ? far : 2000; + this.near = ( near !== undefined ) ? near : 0.1; + this.far = ( far !== undefined ) ? far : 2000; - this.updateProjectionMatrix(); + this.updateProjectionMatrix(); - } + } - OrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), { + OrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), { - constructor: OrthographicCamera, + constructor: OrthographicCamera, - isOrthographicCamera: true, + isOrthographicCamera: true, - copy: function ( source, recursive ) { + copy: function ( source, recursive ) { - Camera.prototype.copy.call( this, source, recursive ); + Camera.prototype.copy.call( this, source, recursive ); - this.left = source.left; - this.right = source.right; - this.top = source.top; - this.bottom = source.bottom; - this.near = source.near; - this.far = source.far; + this.left = source.left; + this.right = source.right; + this.top = source.top; + this.bottom = source.bottom; + this.near = source.near; + this.far = source.far; - this.zoom = source.zoom; - this.view = source.view === null ? null : Object.assign( {}, source.view ); + this.zoom = source.zoom; + this.view = source.view === null ? null : Object.assign( {}, source.view ); - return this; + return this; - }, + }, - setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) { + setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) { - if ( this.view === null ) { + if ( this.view === null ) { - this.view = { - enabled: true, - fullWidth: 1, - fullHeight: 1, - offsetX: 0, - offsetY: 0, - width: 1, - height: 1 - }; + this.view = { + enabled: true, + fullWidth: 1, + fullHeight: 1, + offsetX: 0, + offsetY: 0, + width: 1, + height: 1 + }; - } + } - this.view.enabled = true; - this.view.fullWidth = fullWidth; - this.view.fullHeight = fullHeight; - this.view.offsetX = x; - this.view.offsetY = y; - this.view.width = width; - this.view.height = height; + this.view.enabled = true; + this.view.fullWidth = fullWidth; + this.view.fullHeight = fullHeight; + this.view.offsetX = x; + this.view.offsetY = y; + this.view.width = width; + this.view.height = height; - this.updateProjectionMatrix(); + this.updateProjectionMatrix(); - }, + }, - clearViewOffset: function () { + clearViewOffset: function () { - if ( this.view !== null ) { + if ( this.view !== null ) { - this.view.enabled = false; + this.view.enabled = false; - } + } - this.updateProjectionMatrix(); + this.updateProjectionMatrix(); - }, + }, - updateProjectionMatrix: function () { + updateProjectionMatrix: function () { - var dx = ( this.right - this.left ) / ( 2 * this.zoom ); - var dy = ( this.top - this.bottom ) / ( 2 * this.zoom ); - var cx = ( this.right + this.left ) / 2; - var cy = ( this.top + this.bottom ) / 2; + var dx = ( this.right - this.left ) / ( 2 * this.zoom ); + var dy = ( this.top - this.bottom ) / ( 2 * this.zoom ); + var cx = ( this.right + this.left ) / 2; + var cy = ( this.top + this.bottom ) / 2; - var left = cx - dx; - var right = cx + dx; - var top = cy + dy; - var bottom = cy - dy; + var left = cx - dx; + var right = cx + dx; + var top = cy + dy; + var bottom = cy - dy; - if ( this.view !== null && this.view.enabled ) { + if ( this.view !== null && this.view.enabled ) { - var zoomW = this.zoom / ( this.view.width / this.view.fullWidth ); - var zoomH = this.zoom / ( this.view.height / this.view.fullHeight ); - var scaleW = ( this.right - this.left ) / this.view.width; - var scaleH = ( this.top - this.bottom ) / this.view.height; + var zoomW = this.zoom / ( this.view.width / this.view.fullWidth ); + var zoomH = this.zoom / ( this.view.height / this.view.fullHeight ); + var scaleW = ( this.right - this.left ) / this.view.width; + var scaleH = ( this.top - this.bottom ) / this.view.height; - left += scaleW * ( this.view.offsetX / zoomW ); - right = left + scaleW * ( this.view.width / zoomW ); - top -= scaleH * ( this.view.offsetY / zoomH ); - bottom = top - scaleH * ( this.view.height / zoomH ); + left += scaleW * ( this.view.offsetX / zoomW ); + right = left + scaleW * ( this.view.width / zoomW ); + top -= scaleH * ( this.view.offsetY / zoomH ); + bottom = top - scaleH * ( this.view.height / zoomH ); - } + } - this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far ); + this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far ); - }, + }, - toJSON: function ( meta ) { + toJSON: function ( meta ) { - var data = Object3D.prototype.toJSON.call( this, meta ); + var data = Object3D.prototype.toJSON.call( this, meta ); - data.object.zoom = this.zoom; - data.object.left = this.left; - data.object.right = this.right; - data.object.top = this.top; - data.object.bottom = this.bottom; - data.object.near = this.near; - data.object.far = this.far; + data.object.zoom = this.zoom; + data.object.left = this.left; + data.object.right = this.right; + data.object.top = this.top; + data.object.bottom = this.bottom; + data.object.near = this.near; + data.object.far = this.far; - if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); + if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); - return data; + return data; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + */ - function Face3( a, b, c, normal, color, materialIndex ) { + function Face3( a, b, c, normal, color, materialIndex ) { - this.a = a; - this.b = b; - this.c = c; + this.a = a; + this.b = b; + this.c = c; - this.normal = ( normal && normal.isVector3 ) ? normal : new Vector3(); - this.vertexNormals = Array.isArray( normal ) ? normal : []; + this.normal = ( normal && normal.isVector3 ) ? normal : new Vector3(); + this.vertexNormals = Array.isArray( normal ) ? normal : []; - this.color = ( color && color.isColor ) ? color : new Color(); - this.vertexColors = Array.isArray( color ) ? color : []; + this.color = ( color && color.isColor ) ? color : new Color(); + this.vertexColors = Array.isArray( color ) ? color : []; - this.materialIndex = materialIndex !== undefined ? materialIndex : 0; + this.materialIndex = materialIndex !== undefined ? materialIndex : 0; - } + } - Object.assign( Face3.prototype, { + Object.assign( Face3.prototype, { - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( source ) { + copy: function ( source ) { - this.a = source.a; - this.b = source.b; - this.c = source.c; + this.a = source.a; + this.b = source.b; + this.c = source.c; - this.normal.copy( source.normal ); - this.color.copy( source.color ); + this.normal.copy( source.normal ); + this.color.copy( source.color ); - this.materialIndex = source.materialIndex; + this.materialIndex = source.materialIndex; - for ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) { + for ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) { - this.vertexNormals[ i ] = source.vertexNormals[ i ].clone(); + this.vertexNormals[ i ] = source.vertexNormals[ i ].clone(); - } + } - for ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) { + for ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) { - this.vertexColors[ i ] = source.vertexColors[ i ].clone(); + this.vertexColors[ i ] = source.vertexColors[ i ].clone(); - } + } - return this; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author kile / http://kile.stravaganza.org/ - * @author alteredq / http://alteredqualia.com/ - * @author mikael emtinger / http://gomo.se/ - * @author zz85 / http://www.lab4games.net/zz85/blog - * @author bhouston / http://clara.io - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author kile / http://kile.stravaganza.org/ + * @author alteredq / http://alteredqualia.com/ + * @author mikael emtinger / http://gomo.se/ + * @author zz85 / http://www.lab4games.net/zz85/blog + * @author bhouston / http://clara.io + */ - var geometryId = 0; // Geometry uses even numbers as Id + var geometryId = 0; // Geometry uses even numbers as Id - function Geometry() { + function Geometry() { - Object.defineProperty( this, 'id', { value: geometryId += 2 } ); + Object.defineProperty( this, 'id', { value: geometryId += 2 } ); - this.uuid = _Math.generateUUID(); + this.uuid = _Math.generateUUID(); - this.name = ''; - this.type = 'Geometry'; + this.name = ''; + this.type = 'Geometry'; - this.vertices = []; - this.colors = []; - this.faces = []; - this.faceVertexUvs = [[]]; + this.vertices = []; + this.colors = []; + this.faces = []; + this.faceVertexUvs = [[]]; - this.morphTargets = []; - this.morphNormals = []; + this.morphTargets = []; + this.morphNormals = []; - this.skinWeights = []; - this.skinIndices = []; + this.skinWeights = []; + this.skinIndices = []; - this.lineDistances = []; + this.lineDistances = []; - this.boundingBox = null; - this.boundingSphere = null; + this.boundingBox = null; + this.boundingSphere = null; - // update flags + // update flags - this.elementsNeedUpdate = false; - this.verticesNeedUpdate = false; - this.uvsNeedUpdate = false; - this.normalsNeedUpdate = false; - this.colorsNeedUpdate = false; - this.lineDistancesNeedUpdate = false; - this.groupsNeedUpdate = false; + this.elementsNeedUpdate = false; + this.verticesNeedUpdate = false; + this.uvsNeedUpdate = false; + this.normalsNeedUpdate = false; + this.colorsNeedUpdate = false; + this.lineDistancesNeedUpdate = false; + this.groupsNeedUpdate = false; - } + } - Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { + Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - constructor: Geometry, + constructor: Geometry, - isGeometry: true, + isGeometry: true, - applyMatrix: function ( matrix ) { + applyMatrix: function ( matrix ) { - var normalMatrix = new Matrix3().getNormalMatrix( matrix ); + var normalMatrix = new Matrix3().getNormalMatrix( matrix ); - for ( var i = 0, il = this.vertices.length; i < il; i ++ ) { + for ( var i = 0, il = this.vertices.length; i < il; i ++ ) { - var vertex = this.vertices[ i ]; - vertex.applyMatrix4( matrix ); + var vertex = this.vertices[ i ]; + vertex.applyMatrix4( matrix ); - } + } - for ( var i = 0, il = this.faces.length; i < il; i ++ ) { + for ( var i = 0, il = this.faces.length; i < il; i ++ ) { - var face = this.faces[ i ]; - face.normal.applyMatrix3( normalMatrix ).normalize(); + var face = this.faces[ i ]; + face.normal.applyMatrix3( normalMatrix ).normalize(); - for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { + for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { - face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize(); + face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize(); - } + } - } + } - if ( this.boundingBox !== null ) { + if ( this.boundingBox !== null ) { - this.computeBoundingBox(); + this.computeBoundingBox(); - } + } - if ( this.boundingSphere !== null ) { + if ( this.boundingSphere !== null ) { - this.computeBoundingSphere(); + this.computeBoundingSphere(); - } + } - this.verticesNeedUpdate = true; - this.normalsNeedUpdate = true; + this.verticesNeedUpdate = true; + this.normalsNeedUpdate = true; - return this; + return this; - }, + }, - rotateX: function () { + rotateX: function () { - // rotate geometry around world x-axis + // rotate geometry around world x-axis - var m1 = new Matrix4(); + var m1 = new Matrix4(); - return function rotateX( angle ) { + return function rotateX( angle ) { - m1.makeRotationX( angle ); + m1.makeRotationX( angle ); - this.applyMatrix( m1 ); + this.applyMatrix( m1 ); - return this; + return this; - }; + }; - }(), + }(), - rotateY: function () { + rotateY: function () { - // rotate geometry around world y-axis + // rotate geometry around world y-axis - var m1 = new Matrix4(); + var m1 = new Matrix4(); - return function rotateY( angle ) { + return function rotateY( angle ) { - m1.makeRotationY( angle ); + m1.makeRotationY( angle ); - this.applyMatrix( m1 ); + this.applyMatrix( m1 ); - return this; + return this; - }; + }; - }(), + }(), - rotateZ: function () { + rotateZ: function () { - // rotate geometry around world z-axis + // rotate geometry around world z-axis - var m1 = new Matrix4(); + var m1 = new Matrix4(); - return function rotateZ( angle ) { + return function rotateZ( angle ) { - m1.makeRotationZ( angle ); + m1.makeRotationZ( angle ); - this.applyMatrix( m1 ); + this.applyMatrix( m1 ); - return this; + return this; - }; + }; - }(), + }(), - translate: function () { + translate: function () { - // translate geometry + // translate geometry - var m1 = new Matrix4(); + var m1 = new Matrix4(); - return function translate( x, y, z ) { + return function translate( x, y, z ) { - m1.makeTranslation( x, y, z ); + m1.makeTranslation( x, y, z ); - this.applyMatrix( m1 ); + this.applyMatrix( m1 ); - return this; + return this; - }; + }; - }(), + }(), - scale: function () { + scale: function () { - // scale geometry + // scale geometry - var m1 = new Matrix4(); + var m1 = new Matrix4(); - return function scale( x, y, z ) { + return function scale( x, y, z ) { - m1.makeScale( x, y, z ); + m1.makeScale( x, y, z ); - this.applyMatrix( m1 ); + this.applyMatrix( m1 ); - return this; + return this; - }; + }; - }(), + }(), - lookAt: function () { + lookAt: function () { - var obj = new Object3D(); + var obj = new Object3D(); - return function lookAt( vector ) { + return function lookAt( vector ) { - obj.lookAt( vector ); + obj.lookAt( vector ); - obj.updateMatrix(); + obj.updateMatrix(); - this.applyMatrix( obj.matrix ); + this.applyMatrix( obj.matrix ); - }; + }; - }(), + }(), - fromBufferGeometry: function ( geometry ) { + fromBufferGeometry: function ( geometry ) { - var scope = this; + var scope = this; - var indices = geometry.index !== null ? geometry.index.array : undefined; - var attributes = geometry.attributes; + var indices = geometry.index !== null ? geometry.index.array : undefined; + var attributes = geometry.attributes; - var positions = attributes.position.array; - var normals = attributes.normal !== undefined ? attributes.normal.array : undefined; - var colors = attributes.color !== undefined ? attributes.color.array : undefined; - var uvs = attributes.uv !== undefined ? attributes.uv.array : undefined; - var uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined; + var positions = attributes.position.array; + var normals = attributes.normal !== undefined ? attributes.normal.array : undefined; + var colors = attributes.color !== undefined ? attributes.color.array : undefined; + var uvs = attributes.uv !== undefined ? attributes.uv.array : undefined; + var uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined; - if ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = []; + if ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = []; - var tempNormals = []; - var tempUVs = []; - var tempUVs2 = []; + var tempNormals = []; + var tempUVs = []; + var tempUVs2 = []; - for ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) { + for ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) { - scope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) ); + scope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) ); - if ( normals !== undefined ) { + if ( normals !== undefined ) { - tempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) ); + tempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) ); - } + } - if ( colors !== undefined ) { + if ( colors !== undefined ) { - scope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) ); + scope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) ); - } + } - if ( uvs !== undefined ) { + if ( uvs !== undefined ) { - tempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) ); + tempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) ); - } + } - if ( uvs2 !== undefined ) { + if ( uvs2 !== undefined ) { - tempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) ); + tempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) ); - } + } - } + } - function addFace( a, b, c, materialIndex ) { + function addFace( a, b, c, materialIndex ) { - var vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : []; - var vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : []; + var vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : []; + var vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : []; - var face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex ); + var face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex ); - scope.faces.push( face ); + scope.faces.push( face ); - if ( uvs !== undefined ) { + if ( uvs !== undefined ) { - scope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] ); + scope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] ); - } + } - if ( uvs2 !== undefined ) { + if ( uvs2 !== undefined ) { - scope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] ); + scope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] ); - } + } - } + } - var groups = geometry.groups; + var groups = geometry.groups; - if ( groups.length > 0 ) { + if ( groups.length > 0 ) { - for ( var i = 0; i < groups.length; i ++ ) { + for ( var i = 0; i < groups.length; i ++ ) { - var group = groups[ i ]; + var group = groups[ i ]; - var start = group.start; - var count = group.count; + var start = group.start; + var count = group.count; - for ( var j = start, jl = start + count; j < jl; j += 3 ) { + for ( var j = start, jl = start + count; j < jl; j += 3 ) { - if ( indices !== undefined ) { + if ( indices !== undefined ) { - addFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex ); + addFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex ); - } else { + } else { - addFace( j, j + 1, j + 2, group.materialIndex ); + addFace( j, j + 1, j + 2, group.materialIndex ); - } + } - } + } - } + } - } else { + } else { - if ( indices !== undefined ) { + if ( indices !== undefined ) { - for ( var i = 0; i < indices.length; i += 3 ) { + for ( var i = 0; i < indices.length; i += 3 ) { - addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] ); + addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] ); - } + } - } else { + } else { - for ( var i = 0; i < positions.length / 3; i += 3 ) { + for ( var i = 0; i < positions.length / 3; i += 3 ) { - addFace( i, i + 1, i + 2 ); + addFace( i, i + 1, i + 2 ); - } + } - } + } - } + } - this.computeFaceNormals(); + this.computeFaceNormals(); - if ( geometry.boundingBox !== null ) { + if ( geometry.boundingBox !== null ) { - this.boundingBox = geometry.boundingBox.clone(); + this.boundingBox = geometry.boundingBox.clone(); - } + } - if ( geometry.boundingSphere !== null ) { + if ( geometry.boundingSphere !== null ) { - this.boundingSphere = geometry.boundingSphere.clone(); + this.boundingSphere = geometry.boundingSphere.clone(); - } + } - return this; + return this; - }, + }, - center: function () { + center: function () { - var offset = new Vector3(); + var offset = new Vector3(); - return function center() { + return function center() { - this.computeBoundingBox(); + this.computeBoundingBox(); - this.boundingBox.getCenter( offset ).negate(); + this.boundingBox.getCenter( offset ).negate(); - this.translate( offset.x, offset.y, offset.z ); + this.translate( offset.x, offset.y, offset.z ); - return this; + return this; - }; + }; - }(), + }(), - normalize: function () { + normalize: function () { - this.computeBoundingSphere(); + this.computeBoundingSphere(); - var center = this.boundingSphere.center; - var radius = this.boundingSphere.radius; + var center = this.boundingSphere.center; + var radius = this.boundingSphere.radius; - var s = radius === 0 ? 1 : 1.0 / radius; + var s = radius === 0 ? 1 : 1.0 / radius; - var matrix = new Matrix4(); - matrix.set( - s, 0, 0, - s * center.x, - 0, s, 0, - s * center.y, - 0, 0, s, - s * center.z, - 0, 0, 0, 1 - ); + var matrix = new Matrix4(); + matrix.set( + s, 0, 0, - s * center.x, + 0, s, 0, - s * center.y, + 0, 0, s, - s * center.z, + 0, 0, 0, 1 + ); - this.applyMatrix( matrix ); + this.applyMatrix( matrix ); - return this; + return this; - }, + }, - computeFaceNormals: function () { + computeFaceNormals: function () { - var cb = new Vector3(), ab = new Vector3(); + var cb = new Vector3(), ab = new Vector3(); - for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) { + for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) { - var face = this.faces[ f ]; + var face = this.faces[ f ]; - var vA = this.vertices[ face.a ]; - var vB = this.vertices[ face.b ]; - var vC = this.vertices[ face.c ]; + var vA = this.vertices[ face.a ]; + var vB = this.vertices[ face.b ]; + var vC = this.vertices[ face.c ]; - cb.subVectors( vC, vB ); - ab.subVectors( vA, vB ); - cb.cross( ab ); + cb.subVectors( vC, vB ); + ab.subVectors( vA, vB ); + cb.cross( ab ); - cb.normalize(); + cb.normalize(); - face.normal.copy( cb ); + face.normal.copy( cb ); - } + } - }, + }, - computeVertexNormals: function ( areaWeighted ) { + computeVertexNormals: function ( areaWeighted ) { - if ( areaWeighted === undefined ) areaWeighted = true; + if ( areaWeighted === undefined ) areaWeighted = true; - var v, vl, f, fl, face, vertices; + var v, vl, f, fl, face, vertices; - vertices = new Array( this.vertices.length ); + vertices = new Array( this.vertices.length ); - for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { + for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { - vertices[ v ] = new Vector3(); + vertices[ v ] = new Vector3(); - } + } - if ( areaWeighted ) { + if ( areaWeighted ) { - // vertex normals weighted by triangle areas - // http://www.iquilezles.org/www/articles/normals/normals.htm + // vertex normals weighted by triangle areas + // http://www.iquilezles.org/www/articles/normals/normals.htm - var vA, vB, vC; - var cb = new Vector3(), ab = new Vector3(); + var vA, vB, vC; + var cb = new Vector3(), ab = new Vector3(); - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - face = this.faces[ f ]; + face = this.faces[ f ]; - vA = this.vertices[ face.a ]; - vB = this.vertices[ face.b ]; - vC = this.vertices[ face.c ]; + vA = this.vertices[ face.a ]; + vB = this.vertices[ face.b ]; + vC = this.vertices[ face.c ]; - cb.subVectors( vC, vB ); - ab.subVectors( vA, vB ); - cb.cross( ab ); + cb.subVectors( vC, vB ); + ab.subVectors( vA, vB ); + cb.cross( ab ); - vertices[ face.a ].add( cb ); - vertices[ face.b ].add( cb ); - vertices[ face.c ].add( cb ); + vertices[ face.a ].add( cb ); + vertices[ face.b ].add( cb ); + vertices[ face.c ].add( cb ); - } + } - } else { + } else { - this.computeFaceNormals(); + this.computeFaceNormals(); - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - face = this.faces[ f ]; + face = this.faces[ f ]; - vertices[ face.a ].add( face.normal ); - vertices[ face.b ].add( face.normal ); - vertices[ face.c ].add( face.normal ); + vertices[ face.a ].add( face.normal ); + vertices[ face.b ].add( face.normal ); + vertices[ face.c ].add( face.normal ); - } + } - } + } - for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { + for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { - vertices[ v ].normalize(); + vertices[ v ].normalize(); - } + } - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - face = this.faces[ f ]; + face = this.faces[ f ]; - var vertexNormals = face.vertexNormals; + var vertexNormals = face.vertexNormals; - if ( vertexNormals.length === 3 ) { + if ( vertexNormals.length === 3 ) { - vertexNormals[ 0 ].copy( vertices[ face.a ] ); - vertexNormals[ 1 ].copy( vertices[ face.b ] ); - vertexNormals[ 2 ].copy( vertices[ face.c ] ); + vertexNormals[ 0 ].copy( vertices[ face.a ] ); + vertexNormals[ 1 ].copy( vertices[ face.b ] ); + vertexNormals[ 2 ].copy( vertices[ face.c ] ); - } else { + } else { - vertexNormals[ 0 ] = vertices[ face.a ].clone(); - vertexNormals[ 1 ] = vertices[ face.b ].clone(); - vertexNormals[ 2 ] = vertices[ face.c ].clone(); + vertexNormals[ 0 ] = vertices[ face.a ].clone(); + vertexNormals[ 1 ] = vertices[ face.b ].clone(); + vertexNormals[ 2 ] = vertices[ face.c ].clone(); - } + } - } + } - if ( this.faces.length > 0 ) { + if ( this.faces.length > 0 ) { - this.normalsNeedUpdate = true; + this.normalsNeedUpdate = true; - } + } - }, + }, - computeFlatVertexNormals: function () { + computeFlatVertexNormals: function () { - var f, fl, face; + var f, fl, face; - this.computeFaceNormals(); + this.computeFaceNormals(); - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - face = this.faces[ f ]; + face = this.faces[ f ]; - var vertexNormals = face.vertexNormals; + var vertexNormals = face.vertexNormals; - if ( vertexNormals.length === 3 ) { + if ( vertexNormals.length === 3 ) { - vertexNormals[ 0 ].copy( face.normal ); - vertexNormals[ 1 ].copy( face.normal ); - vertexNormals[ 2 ].copy( face.normal ); + vertexNormals[ 0 ].copy( face.normal ); + vertexNormals[ 1 ].copy( face.normal ); + vertexNormals[ 2 ].copy( face.normal ); - } else { + } else { - vertexNormals[ 0 ] = face.normal.clone(); - vertexNormals[ 1 ] = face.normal.clone(); - vertexNormals[ 2 ] = face.normal.clone(); + vertexNormals[ 0 ] = face.normal.clone(); + vertexNormals[ 1 ] = face.normal.clone(); + vertexNormals[ 2 ] = face.normal.clone(); - } + } - } + } - if ( this.faces.length > 0 ) { + if ( this.faces.length > 0 ) { - this.normalsNeedUpdate = true; + this.normalsNeedUpdate = true; - } + } - }, + }, - computeMorphNormals: function () { + computeMorphNormals: function () { - var i, il, f, fl, face; + var i, il, f, fl, face; - // save original normals - // - create temp variables on first access - // otherwise just copy (for faster repeated calls) + // save original normals + // - create temp variables on first access + // otherwise just copy (for faster repeated calls) - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - face = this.faces[ f ]; + face = this.faces[ f ]; - if ( ! face.__originalFaceNormal ) { + if ( ! face.__originalFaceNormal ) { - face.__originalFaceNormal = face.normal.clone(); + face.__originalFaceNormal = face.normal.clone(); - } else { + } else { - face.__originalFaceNormal.copy( face.normal ); + face.__originalFaceNormal.copy( face.normal ); - } + } - if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = []; + if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = []; - for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) { + for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) { - if ( ! face.__originalVertexNormals[ i ] ) { + if ( ! face.__originalVertexNormals[ i ] ) { - face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone(); + face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone(); - } else { + } else { - face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] ); + face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] ); - } + } - } + } - } + } - // use temp geometry to compute face and vertex normals for each morph + // use temp geometry to compute face and vertex normals for each morph - var tmpGeo = new Geometry(); - tmpGeo.faces = this.faces; + var tmpGeo = new Geometry(); + tmpGeo.faces = this.faces; - for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) { + for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) { - // create on first access + // create on first access - if ( ! this.morphNormals[ i ] ) { + if ( ! this.morphNormals[ i ] ) { - this.morphNormals[ i ] = {}; - this.morphNormals[ i ].faceNormals = []; - this.morphNormals[ i ].vertexNormals = []; + this.morphNormals[ i ] = {}; + this.morphNormals[ i ].faceNormals = []; + this.morphNormals[ i ].vertexNormals = []; - var dstNormalsFace = this.morphNormals[ i ].faceNormals; - var dstNormalsVertex = this.morphNormals[ i ].vertexNormals; + var dstNormalsFace = this.morphNormals[ i ].faceNormals; + var dstNormalsVertex = this.morphNormals[ i ].vertexNormals; - var faceNormal, vertexNormals; + var faceNormal, vertexNormals; - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - faceNormal = new Vector3(); - vertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() }; + faceNormal = new Vector3(); + vertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() }; - dstNormalsFace.push( faceNormal ); - dstNormalsVertex.push( vertexNormals ); + dstNormalsFace.push( faceNormal ); + dstNormalsVertex.push( vertexNormals ); - } + } - } + } - var morphNormals = this.morphNormals[ i ]; + var morphNormals = this.morphNormals[ i ]; - // set vertices to morph target + // set vertices to morph target - tmpGeo.vertices = this.morphTargets[ i ].vertices; + tmpGeo.vertices = this.morphTargets[ i ].vertices; - // compute morph normals + // compute morph normals - tmpGeo.computeFaceNormals(); - tmpGeo.computeVertexNormals(); + tmpGeo.computeFaceNormals(); + tmpGeo.computeVertexNormals(); - // store morph normals + // store morph normals - var faceNormal, vertexNormals; + var faceNormal, vertexNormals; - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - face = this.faces[ f ]; + face = this.faces[ f ]; - faceNormal = morphNormals.faceNormals[ f ]; - vertexNormals = morphNormals.vertexNormals[ f ]; + faceNormal = morphNormals.faceNormals[ f ]; + vertexNormals = morphNormals.vertexNormals[ f ]; - faceNormal.copy( face.normal ); + faceNormal.copy( face.normal ); - vertexNormals.a.copy( face.vertexNormals[ 0 ] ); - vertexNormals.b.copy( face.vertexNormals[ 1 ] ); - vertexNormals.c.copy( face.vertexNormals[ 2 ] ); + vertexNormals.a.copy( face.vertexNormals[ 0 ] ); + vertexNormals.b.copy( face.vertexNormals[ 1 ] ); + vertexNormals.c.copy( face.vertexNormals[ 2 ] ); - } + } - } + } - // restore original normals + // restore original normals - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - face = this.faces[ f ]; + face = this.faces[ f ]; - face.normal = face.__originalFaceNormal; - face.vertexNormals = face.__originalVertexNormals; + face.normal = face.__originalFaceNormal; + face.vertexNormals = face.__originalVertexNormals; - } + } - }, + }, - computeBoundingBox: function () { + computeBoundingBox: function () { - if ( this.boundingBox === null ) { + if ( this.boundingBox === null ) { - this.boundingBox = new Box3(); + this.boundingBox = new Box3(); - } + } - this.boundingBox.setFromPoints( this.vertices ); + this.boundingBox.setFromPoints( this.vertices ); - }, + }, - computeBoundingSphere: function () { + computeBoundingSphere: function () { - if ( this.boundingSphere === null ) { + if ( this.boundingSphere === null ) { - this.boundingSphere = new Sphere(); + this.boundingSphere = new Sphere(); - } + } - this.boundingSphere.setFromPoints( this.vertices ); + this.boundingSphere.setFromPoints( this.vertices ); - }, + }, - merge: function ( geometry, matrix, materialIndexOffset ) { + merge: function ( geometry, matrix, materialIndexOffset ) { - if ( ! ( geometry && geometry.isGeometry ) ) { + if ( ! ( geometry && geometry.isGeometry ) ) { - console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry ); - return; + console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry ); + return; - } + } - var normalMatrix, - vertexOffset = this.vertices.length, - vertices1 = this.vertices, - vertices2 = geometry.vertices, - faces1 = this.faces, - faces2 = geometry.faces, - uvs1 = this.faceVertexUvs[ 0 ], - uvs2 = geometry.faceVertexUvs[ 0 ], - colors1 = this.colors, - colors2 = geometry.colors; + var normalMatrix, + vertexOffset = this.vertices.length, + vertices1 = this.vertices, + vertices2 = geometry.vertices, + faces1 = this.faces, + faces2 = geometry.faces, + uvs1 = this.faceVertexUvs[ 0 ], + uvs2 = geometry.faceVertexUvs[ 0 ], + colors1 = this.colors, + colors2 = geometry.colors; - if ( materialIndexOffset === undefined ) materialIndexOffset = 0; + if ( materialIndexOffset === undefined ) materialIndexOffset = 0; - if ( matrix !== undefined ) { + if ( matrix !== undefined ) { - normalMatrix = new Matrix3().getNormalMatrix( matrix ); + normalMatrix = new Matrix3().getNormalMatrix( matrix ); - } + } - // vertices + // vertices - for ( var i = 0, il = vertices2.length; i < il; i ++ ) { + for ( var i = 0, il = vertices2.length; i < il; i ++ ) { - var vertex = vertices2[ i ]; + var vertex = vertices2[ i ]; - var vertexCopy = vertex.clone(); + var vertexCopy = vertex.clone(); - if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix ); + if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix ); - vertices1.push( vertexCopy ); + vertices1.push( vertexCopy ); - } + } - // colors + // colors - for ( var i = 0, il = colors2.length; i < il; i ++ ) { + for ( var i = 0, il = colors2.length; i < il; i ++ ) { - colors1.push( colors2[ i ].clone() ); + colors1.push( colors2[ i ].clone() ); - } + } - // faces + // faces - for ( i = 0, il = faces2.length; i < il; i ++ ) { + for ( i = 0, il = faces2.length; i < il; i ++ ) { - var face = faces2[ i ], faceCopy, normal, color, - faceVertexNormals = face.vertexNormals, - faceVertexColors = face.vertexColors; + var face = faces2[ i ], faceCopy, normal, color, + faceVertexNormals = face.vertexNormals, + faceVertexColors = face.vertexColors; - faceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset ); - faceCopy.normal.copy( face.normal ); + faceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset ); + faceCopy.normal.copy( face.normal ); - if ( normalMatrix !== undefined ) { + if ( normalMatrix !== undefined ) { - faceCopy.normal.applyMatrix3( normalMatrix ).normalize(); + faceCopy.normal.applyMatrix3( normalMatrix ).normalize(); - } + } - for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) { + for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) { - normal = faceVertexNormals[ j ].clone(); + normal = faceVertexNormals[ j ].clone(); - if ( normalMatrix !== undefined ) { + if ( normalMatrix !== undefined ) { - normal.applyMatrix3( normalMatrix ).normalize(); + normal.applyMatrix3( normalMatrix ).normalize(); - } + } - faceCopy.vertexNormals.push( normal ); + faceCopy.vertexNormals.push( normal ); - } + } - faceCopy.color.copy( face.color ); + faceCopy.color.copy( face.color ); - for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) { + for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) { - color = faceVertexColors[ j ]; - faceCopy.vertexColors.push( color.clone() ); + color = faceVertexColors[ j ]; + faceCopy.vertexColors.push( color.clone() ); - } + } - faceCopy.materialIndex = face.materialIndex + materialIndexOffset; + faceCopy.materialIndex = face.materialIndex + materialIndexOffset; - faces1.push( faceCopy ); + faces1.push( faceCopy ); - } + } - // uvs + // uvs - for ( i = 0, il = uvs2.length; i < il; i ++ ) { + for ( i = 0, il = uvs2.length; i < il; i ++ ) { - var uv = uvs2[ i ], uvCopy = []; + var uv = uvs2[ i ], uvCopy = []; - if ( uv === undefined ) { + if ( uv === undefined ) { - continue; + continue; - } + } - for ( var j = 0, jl = uv.length; j < jl; j ++ ) { + for ( var j = 0, jl = uv.length; j < jl; j ++ ) { - uvCopy.push( uv[ j ].clone() ); + uvCopy.push( uv[ j ].clone() ); - } + } - uvs1.push( uvCopy ); + uvs1.push( uvCopy ); - } + } - }, + }, - mergeMesh: function ( mesh ) { + mergeMesh: function ( mesh ) { - if ( ! ( mesh && mesh.isMesh ) ) { + if ( ! ( mesh && mesh.isMesh ) ) { - console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh ); - return; + console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh ); + return; - } + } - if ( mesh.matrixAutoUpdate ) mesh.updateMatrix(); + if ( mesh.matrixAutoUpdate ) mesh.updateMatrix(); - this.merge( mesh.geometry, mesh.matrix ); + this.merge( mesh.geometry, mesh.matrix ); - }, + }, - /* - * Checks for duplicate vertices with hashmap. - * Duplicated vertices are removed - * and faces' vertices are updated. - */ + /* + * Checks for duplicate vertices with hashmap. + * Duplicated vertices are removed + * and faces' vertices are updated. + */ - mergeVertices: function () { + mergeVertices: function () { - var verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique) - var unique = [], changes = []; + var verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique) + var unique = [], changes = []; - var v, key; - var precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001 - var precision = Math.pow( 10, precisionPoints ); - var i, il, face; - var indices, j, jl; + var v, key; + var precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001 + var precision = Math.pow( 10, precisionPoints ); + var i, il, face; + var indices, j, jl; - for ( i = 0, il = this.vertices.length; i < il; i ++ ) { + for ( i = 0, il = this.vertices.length; i < il; i ++ ) { - v = this.vertices[ i ]; - key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision ); + v = this.vertices[ i ]; + key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision ); - if ( verticesMap[ key ] === undefined ) { + if ( verticesMap[ key ] === undefined ) { - verticesMap[ key ] = i; - unique.push( this.vertices[ i ] ); - changes[ i ] = unique.length - 1; + verticesMap[ key ] = i; + unique.push( this.vertices[ i ] ); + changes[ i ] = unique.length - 1; - } else { + } else { - //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]); - changes[ i ] = changes[ verticesMap[ key ] ]; + //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]); + changes[ i ] = changes[ verticesMap[ key ] ]; - } + } - } + } - // if faces are completely degenerate after merging vertices, we - // have to remove them from the geometry. - var faceIndicesToRemove = []; + // if faces are completely degenerate after merging vertices, we + // have to remove them from the geometry. + var faceIndicesToRemove = []; - for ( i = 0, il = this.faces.length; i < il; i ++ ) { + for ( i = 0, il = this.faces.length; i < il; i ++ ) { - face = this.faces[ i ]; + face = this.faces[ i ]; - face.a = changes[ face.a ]; - face.b = changes[ face.b ]; - face.c = changes[ face.c ]; + face.a = changes[ face.a ]; + face.b = changes[ face.b ]; + face.c = changes[ face.c ]; - indices = [ face.a, face.b, face.c ]; + indices = [ face.a, face.b, face.c ]; - // if any duplicate vertices are found in a Face3 - // we have to remove the face as nothing can be saved - for ( var n = 0; n < 3; n ++ ) { + // if any duplicate vertices are found in a Face3 + // we have to remove the face as nothing can be saved + for ( var n = 0; n < 3; n ++ ) { - if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) { + if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) { - faceIndicesToRemove.push( i ); - break; + faceIndicesToRemove.push( i ); + break; - } + } - } + } - } + } - for ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) { + for ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) { - var idx = faceIndicesToRemove[ i ]; + var idx = faceIndicesToRemove[ i ]; - this.faces.splice( idx, 1 ); + this.faces.splice( idx, 1 ); - for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) { + for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) { - this.faceVertexUvs[ j ].splice( idx, 1 ); + this.faceVertexUvs[ j ].splice( idx, 1 ); - } + } - } + } - // Use unique set of vertices + // Use unique set of vertices - var diff = this.vertices.length - unique.length; - this.vertices = unique; - return diff; + var diff = this.vertices.length - unique.length; + this.vertices = unique; + return diff; - }, + }, - setFromPoints: function ( points ) { + setFromPoints: function ( points ) { - this.vertices = []; + this.vertices = []; - for ( var i = 0, l = points.length; i < l; i ++ ) { + for ( var i = 0, l = points.length; i < l; i ++ ) { - var point = points[ i ]; - this.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) ); + var point = points[ i ]; + this.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) ); - } + } - return this; + return this; - }, + }, - sortFacesByMaterialIndex: function () { + sortFacesByMaterialIndex: function () { - var faces = this.faces; - var length = faces.length; + var faces = this.faces; + var length = faces.length; - // tag faces + // tag faces - for ( var i = 0; i < length; i ++ ) { + for ( var i = 0; i < length; i ++ ) { - faces[ i ]._id = i; + faces[ i ]._id = i; - } + } - // sort faces + // sort faces - function materialIndexSort( a, b ) { + function materialIndexSort( a, b ) { - return a.materialIndex - b.materialIndex; + return a.materialIndex - b.materialIndex; - } + } - faces.sort( materialIndexSort ); + faces.sort( materialIndexSort ); - // sort uvs + // sort uvs - var uvs1 = this.faceVertexUvs[ 0 ]; - var uvs2 = this.faceVertexUvs[ 1 ]; + var uvs1 = this.faceVertexUvs[ 0 ]; + var uvs2 = this.faceVertexUvs[ 1 ]; - var newUvs1, newUvs2; + var newUvs1, newUvs2; - if ( uvs1 && uvs1.length === length ) newUvs1 = []; - if ( uvs2 && uvs2.length === length ) newUvs2 = []; + if ( uvs1 && uvs1.length === length ) newUvs1 = []; + if ( uvs2 && uvs2.length === length ) newUvs2 = []; - for ( var i = 0; i < length; i ++ ) { + for ( var i = 0; i < length; i ++ ) { - var id = faces[ i ]._id; + var id = faces[ i ]._id; - if ( newUvs1 ) newUvs1.push( uvs1[ id ] ); - if ( newUvs2 ) newUvs2.push( uvs2[ id ] ); + if ( newUvs1 ) newUvs1.push( uvs1[ id ] ); + if ( newUvs2 ) newUvs2.push( uvs2[ id ] ); - } + } - if ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1; - if ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2; + if ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1; + if ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2; - }, + }, - toJSON: function () { + toJSON: function () { - var data = { - metadata: { - version: 4.5, - type: 'Geometry', - generator: 'Geometry.toJSON' - } - }; + var data = { + metadata: { + version: 4.5, + type: 'Geometry', + generator: 'Geometry.toJSON' + } + }; - // standard Geometry serialization + // standard Geometry serialization - data.uuid = this.uuid; - data.type = this.type; - if ( this.name !== '' ) data.name = this.name; + data.uuid = this.uuid; + data.type = this.type; + if ( this.name !== '' ) data.name = this.name; - if ( this.parameters !== undefined ) { + if ( this.parameters !== undefined ) { - var parameters = this.parameters; + var parameters = this.parameters; - for ( var key in parameters ) { + for ( var key in parameters ) { - if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; + if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; - } + } - return data; + return data; - } + } - var vertices = []; + var vertices = []; - for ( var i = 0; i < this.vertices.length; i ++ ) { + for ( var i = 0; i < this.vertices.length; i ++ ) { - var vertex = this.vertices[ i ]; - vertices.push( vertex.x, vertex.y, vertex.z ); + var vertex = this.vertices[ i ]; + vertices.push( vertex.x, vertex.y, vertex.z ); - } + } - var faces = []; - var normals = []; - var normalsHash = {}; - var colors = []; - var colorsHash = {}; - var uvs = []; - var uvsHash = {}; + var faces = []; + var normals = []; + var normalsHash = {}; + var colors = []; + var colorsHash = {}; + var uvs = []; + var uvsHash = {}; - for ( var i = 0; i < this.faces.length; i ++ ) { + for ( var i = 0; i < this.faces.length; i ++ ) { - var face = this.faces[ i ]; + var face = this.faces[ i ]; - var hasMaterial = true; - var hasFaceUv = false; // deprecated - var hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined; - var hasFaceNormal = face.normal.length() > 0; - var hasFaceVertexNormal = face.vertexNormals.length > 0; - var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1; - var hasFaceVertexColor = face.vertexColors.length > 0; + var hasMaterial = true; + var hasFaceUv = false; // deprecated + var hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined; + var hasFaceNormal = face.normal.length() > 0; + var hasFaceVertexNormal = face.vertexNormals.length > 0; + var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1; + var hasFaceVertexColor = face.vertexColors.length > 0; - var faceType = 0; + var faceType = 0; - faceType = setBit( faceType, 0, 0 ); // isQuad - faceType = setBit( faceType, 1, hasMaterial ); - faceType = setBit( faceType, 2, hasFaceUv ); - faceType = setBit( faceType, 3, hasFaceVertexUv ); - faceType = setBit( faceType, 4, hasFaceNormal ); - faceType = setBit( faceType, 5, hasFaceVertexNormal ); - faceType = setBit( faceType, 6, hasFaceColor ); - faceType = setBit( faceType, 7, hasFaceVertexColor ); + faceType = setBit( faceType, 0, 0 ); // isQuad + faceType = setBit( faceType, 1, hasMaterial ); + faceType = setBit( faceType, 2, hasFaceUv ); + faceType = setBit( faceType, 3, hasFaceVertexUv ); + faceType = setBit( faceType, 4, hasFaceNormal ); + faceType = setBit( faceType, 5, hasFaceVertexNormal ); + faceType = setBit( faceType, 6, hasFaceColor ); + faceType = setBit( faceType, 7, hasFaceVertexColor ); - faces.push( faceType ); - faces.push( face.a, face.b, face.c ); - faces.push( face.materialIndex ); + faces.push( faceType ); + faces.push( face.a, face.b, face.c ); + faces.push( face.materialIndex ); - if ( hasFaceVertexUv ) { + if ( hasFaceVertexUv ) { - var faceVertexUvs = this.faceVertexUvs[ 0 ][ i ]; + var faceVertexUvs = this.faceVertexUvs[ 0 ][ i ]; - faces.push( - getUvIndex( faceVertexUvs[ 0 ] ), - getUvIndex( faceVertexUvs[ 1 ] ), - getUvIndex( faceVertexUvs[ 2 ] ) - ); + faces.push( + getUvIndex( faceVertexUvs[ 0 ] ), + getUvIndex( faceVertexUvs[ 1 ] ), + getUvIndex( faceVertexUvs[ 2 ] ) + ); - } + } - if ( hasFaceNormal ) { + if ( hasFaceNormal ) { - faces.push( getNormalIndex( face.normal ) ); + faces.push( getNormalIndex( face.normal ) ); - } + } - if ( hasFaceVertexNormal ) { + if ( hasFaceVertexNormal ) { - var vertexNormals = face.vertexNormals; + var vertexNormals = face.vertexNormals; - faces.push( - getNormalIndex( vertexNormals[ 0 ] ), - getNormalIndex( vertexNormals[ 1 ] ), - getNormalIndex( vertexNormals[ 2 ] ) - ); + faces.push( + getNormalIndex( vertexNormals[ 0 ] ), + getNormalIndex( vertexNormals[ 1 ] ), + getNormalIndex( vertexNormals[ 2 ] ) + ); - } + } - if ( hasFaceColor ) { + if ( hasFaceColor ) { - faces.push( getColorIndex( face.color ) ); + faces.push( getColorIndex( face.color ) ); - } + } - if ( hasFaceVertexColor ) { + if ( hasFaceVertexColor ) { - var vertexColors = face.vertexColors; + var vertexColors = face.vertexColors; - faces.push( - getColorIndex( vertexColors[ 0 ] ), - getColorIndex( vertexColors[ 1 ] ), - getColorIndex( vertexColors[ 2 ] ) - ); + faces.push( + getColorIndex( vertexColors[ 0 ] ), + getColorIndex( vertexColors[ 1 ] ), + getColorIndex( vertexColors[ 2 ] ) + ); - } + } - } + } - function setBit( value, position, enabled ) { + function setBit( value, position, enabled ) { - return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) ); + return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) ); - } + } - function getNormalIndex( normal ) { + function getNormalIndex( normal ) { - var hash = normal.x.toString() + normal.y.toString() + normal.z.toString(); + var hash = normal.x.toString() + normal.y.toString() + normal.z.toString(); - if ( normalsHash[ hash ] !== undefined ) { + if ( normalsHash[ hash ] !== undefined ) { - return normalsHash[ hash ]; + return normalsHash[ hash ]; - } + } - normalsHash[ hash ] = normals.length / 3; - normals.push( normal.x, normal.y, normal.z ); + normalsHash[ hash ] = normals.length / 3; + normals.push( normal.x, normal.y, normal.z ); - return normalsHash[ hash ]; + return normalsHash[ hash ]; - } + } - function getColorIndex( color ) { + function getColorIndex( color ) { - var hash = color.r.toString() + color.g.toString() + color.b.toString(); + var hash = color.r.toString() + color.g.toString() + color.b.toString(); - if ( colorsHash[ hash ] !== undefined ) { + if ( colorsHash[ hash ] !== undefined ) { - return colorsHash[ hash ]; + return colorsHash[ hash ]; - } + } - colorsHash[ hash ] = colors.length; - colors.push( color.getHex() ); + colorsHash[ hash ] = colors.length; + colors.push( color.getHex() ); - return colorsHash[ hash ]; + return colorsHash[ hash ]; - } + } - function getUvIndex( uv ) { + function getUvIndex( uv ) { - var hash = uv.x.toString() + uv.y.toString(); + var hash = uv.x.toString() + uv.y.toString(); - if ( uvsHash[ hash ] !== undefined ) { + if ( uvsHash[ hash ] !== undefined ) { - return uvsHash[ hash ]; + return uvsHash[ hash ]; - } + } - uvsHash[ hash ] = uvs.length / 2; - uvs.push( uv.x, uv.y ); + uvsHash[ hash ] = uvs.length / 2; + uvs.push( uv.x, uv.y ); - return uvsHash[ hash ]; + return uvsHash[ hash ]; - } + } - data.data = {}; + data.data = {}; - data.data.vertices = vertices; - data.data.normals = normals; - if ( colors.length > 0 ) data.data.colors = colors; - if ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility - data.data.faces = faces; + data.data.vertices = vertices; + data.data.normals = normals; + if ( colors.length > 0 ) data.data.colors = colors; + if ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility + data.data.faces = faces; - return data; + return data; - }, + }, - clone: function () { + clone: function () { - /* - // Handle primitives + /* + // Handle primitives - var parameters = this.parameters; + var parameters = this.parameters; - if ( parameters !== undefined ) { + if ( parameters !== undefined ) { - var values = []; + var values = []; - for ( var key in parameters ) { + for ( var key in parameters ) { - values.push( parameters[ key ] ); + values.push( parameters[ key ] ); - } + } - var geometry = Object.create( this.constructor.prototype ); - this.constructor.apply( geometry, values ); - return geometry; + var geometry = Object.create( this.constructor.prototype ); + this.constructor.apply( geometry, values ); + return geometry; - } + } - return new this.constructor().copy( this ); - */ + return new this.constructor().copy( this ); + */ - return new Geometry().copy( this ); + return new Geometry().copy( this ); - }, + }, - copy: function ( source ) { + copy: function ( source ) { - var i, il, j, jl, k, kl; + var i, il, j, jl, k, kl; - // reset + // reset - this.vertices = []; - this.colors = []; - this.faces = []; - this.faceVertexUvs = [[]]; - this.morphTargets = []; - this.morphNormals = []; - this.skinWeights = []; - this.skinIndices = []; - this.lineDistances = []; - this.boundingBox = null; - this.boundingSphere = null; + this.vertices = []; + this.colors = []; + this.faces = []; + this.faceVertexUvs = [[]]; + this.morphTargets = []; + this.morphNormals = []; + this.skinWeights = []; + this.skinIndices = []; + this.lineDistances = []; + this.boundingBox = null; + this.boundingSphere = null; - // name + // name - this.name = source.name; + this.name = source.name; - // vertices + // vertices - var vertices = source.vertices; + var vertices = source.vertices; - for ( i = 0, il = vertices.length; i < il; i ++ ) { + for ( i = 0, il = vertices.length; i < il; i ++ ) { - this.vertices.push( vertices[ i ].clone() ); + this.vertices.push( vertices[ i ].clone() ); - } + } - // colors + // colors - var colors = source.colors; + var colors = source.colors; - for ( i = 0, il = colors.length; i < il; i ++ ) { + for ( i = 0, il = colors.length; i < il; i ++ ) { - this.colors.push( colors[ i ].clone() ); + this.colors.push( colors[ i ].clone() ); - } + } - // faces + // faces - var faces = source.faces; + var faces = source.faces; - for ( i = 0, il = faces.length; i < il; i ++ ) { + for ( i = 0, il = faces.length; i < il; i ++ ) { - this.faces.push( faces[ i ].clone() ); + this.faces.push( faces[ i ].clone() ); - } + } - // face vertex uvs + // face vertex uvs - for ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) { + for ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) { - var faceVertexUvs = source.faceVertexUvs[ i ]; + var faceVertexUvs = source.faceVertexUvs[ i ]; - if ( this.faceVertexUvs[ i ] === undefined ) { + if ( this.faceVertexUvs[ i ] === undefined ) { - this.faceVertexUvs[ i ] = []; + this.faceVertexUvs[ i ] = []; - } + } - for ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) { + for ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) { - var uvs = faceVertexUvs[ j ], uvsCopy = []; + var uvs = faceVertexUvs[ j ], uvsCopy = []; - for ( k = 0, kl = uvs.length; k < kl; k ++ ) { + for ( k = 0, kl = uvs.length; k < kl; k ++ ) { - var uv = uvs[ k ]; + var uv = uvs[ k ]; - uvsCopy.push( uv.clone() ); + uvsCopy.push( uv.clone() ); - } + } - this.faceVertexUvs[ i ].push( uvsCopy ); + this.faceVertexUvs[ i ].push( uvsCopy ); - } + } - } + } - // morph targets + // morph targets - var morphTargets = source.morphTargets; + var morphTargets = source.morphTargets; - for ( i = 0, il = morphTargets.length; i < il; i ++ ) { + for ( i = 0, il = morphTargets.length; i < il; i ++ ) { - var morphTarget = {}; - morphTarget.name = morphTargets[ i ].name; + var morphTarget = {}; + morphTarget.name = morphTargets[ i ].name; - // vertices + // vertices - if ( morphTargets[ i ].vertices !== undefined ) { + if ( morphTargets[ i ].vertices !== undefined ) { - morphTarget.vertices = []; + morphTarget.vertices = []; - for ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) { + for ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) { - morphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() ); + morphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() ); - } + } - } + } - // normals + // normals - if ( morphTargets[ i ].normals !== undefined ) { + if ( morphTargets[ i ].normals !== undefined ) { - morphTarget.normals = []; + morphTarget.normals = []; - for ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) { + for ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) { - morphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() ); + morphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() ); - } + } - } + } - this.morphTargets.push( morphTarget ); + this.morphTargets.push( morphTarget ); - } + } - // morph normals + // morph normals - var morphNormals = source.morphNormals; + var morphNormals = source.morphNormals; - for ( i = 0, il = morphNormals.length; i < il; i ++ ) { + for ( i = 0, il = morphNormals.length; i < il; i ++ ) { - var morphNormal = {}; + var morphNormal = {}; - // vertex normals + // vertex normals - if ( morphNormals[ i ].vertexNormals !== undefined ) { + if ( morphNormals[ i ].vertexNormals !== undefined ) { - morphNormal.vertexNormals = []; + morphNormal.vertexNormals = []; - for ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) { + for ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) { - var srcVertexNormal = morphNormals[ i ].vertexNormals[ j ]; - var destVertexNormal = {}; + var srcVertexNormal = morphNormals[ i ].vertexNormals[ j ]; + var destVertexNormal = {}; - destVertexNormal.a = srcVertexNormal.a.clone(); - destVertexNormal.b = srcVertexNormal.b.clone(); - destVertexNormal.c = srcVertexNormal.c.clone(); + destVertexNormal.a = srcVertexNormal.a.clone(); + destVertexNormal.b = srcVertexNormal.b.clone(); + destVertexNormal.c = srcVertexNormal.c.clone(); - morphNormal.vertexNormals.push( destVertexNormal ); + morphNormal.vertexNormals.push( destVertexNormal ); - } + } - } + } - // face normals + // face normals - if ( morphNormals[ i ].faceNormals !== undefined ) { + if ( morphNormals[ i ].faceNormals !== undefined ) { - morphNormal.faceNormals = []; + morphNormal.faceNormals = []; - for ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) { + for ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) { - morphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() ); + morphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() ); - } + } - } + } - this.morphNormals.push( morphNormal ); + this.morphNormals.push( morphNormal ); - } + } - // skin weights + // skin weights - var skinWeights = source.skinWeights; + var skinWeights = source.skinWeights; - for ( i = 0, il = skinWeights.length; i < il; i ++ ) { + for ( i = 0, il = skinWeights.length; i < il; i ++ ) { - this.skinWeights.push( skinWeights[ i ].clone() ); + this.skinWeights.push( skinWeights[ i ].clone() ); - } + } - // skin indices + // skin indices - var skinIndices = source.skinIndices; + var skinIndices = source.skinIndices; - for ( i = 0, il = skinIndices.length; i < il; i ++ ) { + for ( i = 0, il = skinIndices.length; i < il; i ++ ) { - this.skinIndices.push( skinIndices[ i ].clone() ); + this.skinIndices.push( skinIndices[ i ].clone() ); - } + } - // line distances + // line distances - var lineDistances = source.lineDistances; + var lineDistances = source.lineDistances; - for ( i = 0, il = lineDistances.length; i < il; i ++ ) { + for ( i = 0, il = lineDistances.length; i < il; i ++ ) { - this.lineDistances.push( lineDistances[ i ] ); + this.lineDistances.push( lineDistances[ i ] ); - } + } - // bounding box + // bounding box - var boundingBox = source.boundingBox; + var boundingBox = source.boundingBox; - if ( boundingBox !== null ) { + if ( boundingBox !== null ) { - this.boundingBox = boundingBox.clone(); + this.boundingBox = boundingBox.clone(); - } + } - // bounding sphere + // bounding sphere - var boundingSphere = source.boundingSphere; + var boundingSphere = source.boundingSphere; - if ( boundingSphere !== null ) { + if ( boundingSphere !== null ) { - this.boundingSphere = boundingSphere.clone(); + this.boundingSphere = boundingSphere.clone(); - } + } - // update flags + // update flags - this.elementsNeedUpdate = source.elementsNeedUpdate; - this.verticesNeedUpdate = source.verticesNeedUpdate; - this.uvsNeedUpdate = source.uvsNeedUpdate; - this.normalsNeedUpdate = source.normalsNeedUpdate; - this.colorsNeedUpdate = source.colorsNeedUpdate; - this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate; - this.groupsNeedUpdate = source.groupsNeedUpdate; + this.elementsNeedUpdate = source.elementsNeedUpdate; + this.verticesNeedUpdate = source.verticesNeedUpdate; + this.uvsNeedUpdate = source.uvsNeedUpdate; + this.normalsNeedUpdate = source.normalsNeedUpdate; + this.colorsNeedUpdate = source.colorsNeedUpdate; + this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate; + this.groupsNeedUpdate = source.groupsNeedUpdate; - return this; + return this; - }, + }, - dispose: function () { + dispose: function () { - this.dispatchEvent( { type: 'dispose' } ); + this.dispatchEvent( { type: 'dispose' } ); - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function BufferAttribute( array, itemSize, normalized ) { + function BufferAttribute( array, itemSize, normalized ) { - if ( Array.isArray( array ) ) { + if ( Array.isArray( array ) ) { - throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); + throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); - } + } - this.name = ''; + this.name = ''; - this.array = array; - this.itemSize = itemSize; - this.count = array !== undefined ? array.length / itemSize : 0; - this.normalized = normalized === true; + this.array = array; + this.itemSize = itemSize; + this.count = array !== undefined ? array.length / itemSize : 0; + this.normalized = normalized === true; - this.dynamic = false; - this.updateRange = { offset: 0, count: - 1 }; + this.dynamic = false; + this.updateRange = { offset: 0, count: - 1 }; - this.version = 0; + this.version = 0; - } + } - Object.defineProperty( BufferAttribute.prototype, 'needsUpdate', { + Object.defineProperty( BufferAttribute.prototype, 'needsUpdate', { - set: function ( value ) { + set: function ( value ) { - if ( value === true ) this.version ++; + if ( value === true ) this.version ++; - } + } - } ); + } ); - Object.assign( BufferAttribute.prototype, { + Object.assign( BufferAttribute.prototype, { - isBufferAttribute: true, + isBufferAttribute: true, - onUploadCallback: function () {}, + onUploadCallback: function () {}, - setArray: function ( array ) { + setArray: function ( array ) { - if ( Array.isArray( array ) ) { + if ( Array.isArray( array ) ) { - throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); + throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); - } + } - this.count = array !== undefined ? array.length / this.itemSize : 0; - this.array = array; + this.count = array !== undefined ? array.length / this.itemSize : 0; + this.array = array; - return this; + return this; - }, + }, - setDynamic: function ( value ) { + setDynamic: function ( value ) { - this.dynamic = value; + this.dynamic = value; - return this; + return this; - }, + }, - copy: function ( source ) { + copy: function ( source ) { - this.name = source.name; - this.array = new source.array.constructor( source.array ); - this.itemSize = source.itemSize; - this.count = source.count; - this.normalized = source.normalized; + this.name = source.name; + this.array = new source.array.constructor( source.array ); + this.itemSize = source.itemSize; + this.count = source.count; + this.normalized = source.normalized; - this.dynamic = source.dynamic; + this.dynamic = source.dynamic; - return this; + return this; - }, + }, - copyAt: function ( index1, attribute, index2 ) { + copyAt: function ( index1, attribute, index2 ) { - index1 *= this.itemSize; - index2 *= attribute.itemSize; + index1 *= this.itemSize; + index2 *= attribute.itemSize; - for ( var i = 0, l = this.itemSize; i < l; i ++ ) { + for ( var i = 0, l = this.itemSize; i < l; i ++ ) { - this.array[ index1 + i ] = attribute.array[ index2 + i ]; + this.array[ index1 + i ] = attribute.array[ index2 + i ]; - } + } - return this; + return this; - }, + }, - copyArray: function ( array ) { + copyArray: function ( array ) { - this.array.set( array ); + this.array.set( array ); - return this; + return this; - }, + }, - copyColorsArray: function ( colors ) { + copyColorsArray: function ( colors ) { - var array = this.array, offset = 0; + var array = this.array, offset = 0; - for ( var i = 0, l = colors.length; i < l; i ++ ) { + for ( var i = 0, l = colors.length; i < l; i ++ ) { - var color = colors[ i ]; + var color = colors[ i ]; - if ( color === undefined ) { + if ( color === undefined ) { - console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i ); - color = new Color(); + console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i ); + color = new Color(); - } + } - array[ offset ++ ] = color.r; - array[ offset ++ ] = color.g; - array[ offset ++ ] = color.b; + array[ offset ++ ] = color.r; + array[ offset ++ ] = color.g; + array[ offset ++ ] = color.b; - } + } - return this; + return this; - }, + }, - copyVector2sArray: function ( vectors ) { + copyVector2sArray: function ( vectors ) { - var array = this.array, offset = 0; + var array = this.array, offset = 0; - for ( var i = 0, l = vectors.length; i < l; i ++ ) { + for ( var i = 0, l = vectors.length; i < l; i ++ ) { - var vector = vectors[ i ]; + var vector = vectors[ i ]; - if ( vector === undefined ) { + if ( vector === undefined ) { - console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i ); - vector = new Vector2(); + console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i ); + vector = new Vector2(); - } + } - array[ offset ++ ] = vector.x; - array[ offset ++ ] = vector.y; + array[ offset ++ ] = vector.x; + array[ offset ++ ] = vector.y; - } + } - return this; + return this; - }, + }, - copyVector3sArray: function ( vectors ) { + copyVector3sArray: function ( vectors ) { - var array = this.array, offset = 0; + var array = this.array, offset = 0; - for ( var i = 0, l = vectors.length; i < l; i ++ ) { + for ( var i = 0, l = vectors.length; i < l; i ++ ) { - var vector = vectors[ i ]; + var vector = vectors[ i ]; - if ( vector === undefined ) { + if ( vector === undefined ) { - console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i ); - vector = new Vector3(); + console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i ); + vector = new Vector3(); - } + } - array[ offset ++ ] = vector.x; - array[ offset ++ ] = vector.y; - array[ offset ++ ] = vector.z; + array[ offset ++ ] = vector.x; + array[ offset ++ ] = vector.y; + array[ offset ++ ] = vector.z; - } + } - return this; + return this; - }, + }, - copyVector4sArray: function ( vectors ) { + copyVector4sArray: function ( vectors ) { - var array = this.array, offset = 0; + var array = this.array, offset = 0; - for ( var i = 0, l = vectors.length; i < l; i ++ ) { + for ( var i = 0, l = vectors.length; i < l; i ++ ) { - var vector = vectors[ i ]; + var vector = vectors[ i ]; - if ( vector === undefined ) { + if ( vector === undefined ) { - console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i ); - vector = new Vector4(); + console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i ); + vector = new Vector4(); - } + } - array[ offset ++ ] = vector.x; - array[ offset ++ ] = vector.y; - array[ offset ++ ] = vector.z; - array[ offset ++ ] = vector.w; + array[ offset ++ ] = vector.x; + array[ offset ++ ] = vector.y; + array[ offset ++ ] = vector.z; + array[ offset ++ ] = vector.w; - } + } - return this; + return this; - }, + }, - set: function ( value, offset ) { + set: function ( value, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - this.array.set( value, offset ); + this.array.set( value, offset ); - return this; + return this; - }, + }, - getX: function ( index ) { + getX: function ( index ) { - return this.array[ index * this.itemSize ]; + return this.array[ index * this.itemSize ]; - }, + }, - setX: function ( index, x ) { + setX: function ( index, x ) { - this.array[ index * this.itemSize ] = x; + this.array[ index * this.itemSize ] = x; - return this; + return this; - }, + }, - getY: function ( index ) { + getY: function ( index ) { - return this.array[ index * this.itemSize + 1 ]; + return this.array[ index * this.itemSize + 1 ]; - }, + }, - setY: function ( index, y ) { + setY: function ( index, y ) { - this.array[ index * this.itemSize + 1 ] = y; + this.array[ index * this.itemSize + 1 ] = y; - return this; + return this; - }, + }, - getZ: function ( index ) { + getZ: function ( index ) { - return this.array[ index * this.itemSize + 2 ]; + return this.array[ index * this.itemSize + 2 ]; - }, + }, - setZ: function ( index, z ) { + setZ: function ( index, z ) { - this.array[ index * this.itemSize + 2 ] = z; + this.array[ index * this.itemSize + 2 ] = z; - return this; + return this; - }, + }, - getW: function ( index ) { + getW: function ( index ) { - return this.array[ index * this.itemSize + 3 ]; + return this.array[ index * this.itemSize + 3 ]; - }, + }, - setW: function ( index, w ) { + setW: function ( index, w ) { - this.array[ index * this.itemSize + 3 ] = w; + this.array[ index * this.itemSize + 3 ] = w; - return this; + return this; - }, + }, - setXY: function ( index, x, y ) { + setXY: function ( index, x, y ) { - index *= this.itemSize; + index *= this.itemSize; - this.array[ index + 0 ] = x; - this.array[ index + 1 ] = y; + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; - return this; + return this; - }, + }, - setXYZ: function ( index, x, y, z ) { + setXYZ: function ( index, x, y, z ) { - index *= this.itemSize; + index *= this.itemSize; - this.array[ index + 0 ] = x; - this.array[ index + 1 ] = y; - this.array[ index + 2 ] = z; + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; + this.array[ index + 2 ] = z; - return this; + return this; - }, + }, - setXYZW: function ( index, x, y, z, w ) { + setXYZW: function ( index, x, y, z, w ) { - index *= this.itemSize; + index *= this.itemSize; - this.array[ index + 0 ] = x; - this.array[ index + 1 ] = y; - this.array[ index + 2 ] = z; - this.array[ index + 3 ] = w; + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; + this.array[ index + 2 ] = z; + this.array[ index + 3 ] = w; - return this; + return this; - }, + }, - onUpload: function ( callback ) { + onUpload: function ( callback ) { - this.onUploadCallback = callback; + this.onUploadCallback = callback; - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new this.constructor( this.array, this.itemSize ).copy( this ); + return new this.constructor( this.array, this.itemSize ).copy( this ); - } + } - } ); + } ); - // + // - function Int8BufferAttribute( array, itemSize, normalized ) { + function Int8BufferAttribute( array, itemSize, normalized ) { - BufferAttribute.call( this, new Int8Array( array ), itemSize, normalized ); + BufferAttribute.call( this, new Int8Array( array ), itemSize, normalized ); - } + } - Int8BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Int8BufferAttribute.prototype.constructor = Int8BufferAttribute; + Int8BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Int8BufferAttribute.prototype.constructor = Int8BufferAttribute; - function Uint8BufferAttribute( array, itemSize, normalized ) { + function Uint8BufferAttribute( array, itemSize, normalized ) { - BufferAttribute.call( this, new Uint8Array( array ), itemSize, normalized ); + BufferAttribute.call( this, new Uint8Array( array ), itemSize, normalized ); - } + } - Uint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute; + Uint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute; - function Uint8ClampedBufferAttribute( array, itemSize, normalized ) { + function Uint8ClampedBufferAttribute( array, itemSize, normalized ) { - BufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize, normalized ); + BufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize, normalized ); - } + } - Uint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute; + Uint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute; - function Int16BufferAttribute( array, itemSize, normalized ) { + function Int16BufferAttribute( array, itemSize, normalized ) { - BufferAttribute.call( this, new Int16Array( array ), itemSize, normalized ); + BufferAttribute.call( this, new Int16Array( array ), itemSize, normalized ); - } + } - Int16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Int16BufferAttribute.prototype.constructor = Int16BufferAttribute; + Int16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Int16BufferAttribute.prototype.constructor = Int16BufferAttribute; - function Uint16BufferAttribute( array, itemSize, normalized ) { + function Uint16BufferAttribute( array, itemSize, normalized ) { - BufferAttribute.call( this, new Uint16Array( array ), itemSize, normalized ); + BufferAttribute.call( this, new Uint16Array( array ), itemSize, normalized ); - } + } - Uint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute; + Uint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute; - function Int32BufferAttribute( array, itemSize, normalized ) { + function Int32BufferAttribute( array, itemSize, normalized ) { - BufferAttribute.call( this, new Int32Array( array ), itemSize, normalized ); + BufferAttribute.call( this, new Int32Array( array ), itemSize, normalized ); - } + } - Int32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Int32BufferAttribute.prototype.constructor = Int32BufferAttribute; + Int32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Int32BufferAttribute.prototype.constructor = Int32BufferAttribute; - function Uint32BufferAttribute( array, itemSize, normalized ) { + function Uint32BufferAttribute( array, itemSize, normalized ) { - BufferAttribute.call( this, new Uint32Array( array ), itemSize, normalized ); + BufferAttribute.call( this, new Uint32Array( array ), itemSize, normalized ); - } + } - Uint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute; + Uint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute; - function Float32BufferAttribute( array, itemSize, normalized ) { + function Float32BufferAttribute( array, itemSize, normalized ) { - BufferAttribute.call( this, new Float32Array( array ), itemSize, normalized ); + BufferAttribute.call( this, new Float32Array( array ), itemSize, normalized ); - } + } - Float32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Float32BufferAttribute.prototype.constructor = Float32BufferAttribute; + Float32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Float32BufferAttribute.prototype.constructor = Float32BufferAttribute; - function Float64BufferAttribute( array, itemSize, normalized ) { + function Float64BufferAttribute( array, itemSize, normalized ) { - BufferAttribute.call( this, new Float64Array( array ), itemSize, normalized ); + BufferAttribute.call( this, new Float64Array( array ), itemSize, normalized ); - } + } - Float64BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Float64BufferAttribute.prototype.constructor = Float64BufferAttribute; + Float64BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Float64BufferAttribute.prototype.constructor = Float64BufferAttribute; - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function DirectGeometry() { + function DirectGeometry() { - this.vertices = []; - this.normals = []; - this.colors = []; - this.uvs = []; - this.uvs2 = []; + this.vertices = []; + this.normals = []; + this.colors = []; + this.uvs = []; + this.uvs2 = []; - this.groups = []; + this.groups = []; - this.morphTargets = {}; + this.morphTargets = {}; - this.skinWeights = []; - this.skinIndices = []; + this.skinWeights = []; + this.skinIndices = []; - // this.lineDistances = []; + // this.lineDistances = []; - this.boundingBox = null; - this.boundingSphere = null; + this.boundingBox = null; + this.boundingSphere = null; - // update flags + // update flags - this.verticesNeedUpdate = false; - this.normalsNeedUpdate = false; - this.colorsNeedUpdate = false; - this.uvsNeedUpdate = false; - this.groupsNeedUpdate = false; + this.verticesNeedUpdate = false; + this.normalsNeedUpdate = false; + this.colorsNeedUpdate = false; + this.uvsNeedUpdate = false; + this.groupsNeedUpdate = false; - } + } - Object.assign( DirectGeometry.prototype, { + Object.assign( DirectGeometry.prototype, { - computeGroups: function ( geometry ) { + computeGroups: function ( geometry ) { - var group; - var groups = []; - var materialIndex = undefined; + var group; + var groups = []; + var materialIndex = undefined; - var faces = geometry.faces; + var faces = geometry.faces; - for ( var i = 0; i < faces.length; i ++ ) { + for ( var i = 0; i < faces.length; i ++ ) { - var face = faces[ i ]; + var face = faces[ i ]; - // materials + // materials - if ( face.materialIndex !== materialIndex ) { + if ( face.materialIndex !== materialIndex ) { - materialIndex = face.materialIndex; + materialIndex = face.materialIndex; - if ( group !== undefined ) { + if ( group !== undefined ) { - group.count = ( i * 3 ) - group.start; - groups.push( group ); + group.count = ( i * 3 ) - group.start; + groups.push( group ); - } + } - group = { - start: i * 3, - materialIndex: materialIndex - }; + group = { + start: i * 3, + materialIndex: materialIndex + }; - } + } - } + } - if ( group !== undefined ) { + if ( group !== undefined ) { - group.count = ( i * 3 ) - group.start; - groups.push( group ); + group.count = ( i * 3 ) - group.start; + groups.push( group ); - } + } - this.groups = groups; + this.groups = groups; - }, + }, - fromGeometry: function ( geometry ) { + fromGeometry: function ( geometry ) { - var faces = geometry.faces; - var vertices = geometry.vertices; - var faceVertexUvs = geometry.faceVertexUvs; + var faces = geometry.faces; + var vertices = geometry.vertices; + var faceVertexUvs = geometry.faceVertexUvs; - var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0; - var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0; + var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0; + var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0; - // morphs + // morphs - var morphTargets = geometry.morphTargets; - var morphTargetsLength = morphTargets.length; + var morphTargets = geometry.morphTargets; + var morphTargetsLength = morphTargets.length; - var morphTargetsPosition; + var morphTargetsPosition; - if ( morphTargetsLength > 0 ) { + if ( morphTargetsLength > 0 ) { - morphTargetsPosition = []; + morphTargetsPosition = []; - for ( var i = 0; i < morphTargetsLength; i ++ ) { + for ( var i = 0; i < morphTargetsLength; i ++ ) { - morphTargetsPosition[ i ] = []; + morphTargetsPosition[ i ] = []; - } + } - this.morphTargets.position = morphTargetsPosition; + this.morphTargets.position = morphTargetsPosition; - } + } - var morphNormals = geometry.morphNormals; - var morphNormalsLength = morphNormals.length; + var morphNormals = geometry.morphNormals; + var morphNormalsLength = morphNormals.length; - var morphTargetsNormal; + var morphTargetsNormal; - if ( morphNormalsLength > 0 ) { + if ( morphNormalsLength > 0 ) { - morphTargetsNormal = []; + morphTargetsNormal = []; - for ( var i = 0; i < morphNormalsLength; i ++ ) { + for ( var i = 0; i < morphNormalsLength; i ++ ) { - morphTargetsNormal[ i ] = []; + morphTargetsNormal[ i ] = []; - } + } - this.morphTargets.normal = morphTargetsNormal; + this.morphTargets.normal = morphTargetsNormal; - } + } - // skins + // skins - var skinIndices = geometry.skinIndices; - var skinWeights = geometry.skinWeights; + var skinIndices = geometry.skinIndices; + var skinWeights = geometry.skinWeights; - var hasSkinIndices = skinIndices.length === vertices.length; - var hasSkinWeights = skinWeights.length === vertices.length; + var hasSkinIndices = skinIndices.length === vertices.length; + var hasSkinWeights = skinWeights.length === vertices.length; - // + // - if ( vertices.length > 0 && faces.length === 0 ) { + if ( vertices.length > 0 && faces.length === 0 ) { - console.error( 'THREE.DirectGeometry: Faceless geometries are not supported.' ); + console.error( 'THREE.DirectGeometry: Faceless geometries are not supported.' ); - } + } - for ( var i = 0; i < faces.length; i ++ ) { + for ( var i = 0; i < faces.length; i ++ ) { - var face = faces[ i ]; + var face = faces[ i ]; - this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] ); + this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] ); - var vertexNormals = face.vertexNormals; + var vertexNormals = face.vertexNormals; - if ( vertexNormals.length === 3 ) { + if ( vertexNormals.length === 3 ) { - this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] ); + this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] ); - } else { + } else { - var normal = face.normal; + var normal = face.normal; - this.normals.push( normal, normal, normal ); + this.normals.push( normal, normal, normal ); - } + } - var vertexColors = face.vertexColors; + var vertexColors = face.vertexColors; - if ( vertexColors.length === 3 ) { + if ( vertexColors.length === 3 ) { - this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] ); + this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] ); - } else { + } else { - var color = face.color; + var color = face.color; - this.colors.push( color, color, color ); + this.colors.push( color, color, color ); - } + } - if ( hasFaceVertexUv === true ) { + if ( hasFaceVertexUv === true ) { - var vertexUvs = faceVertexUvs[ 0 ][ i ]; + var vertexUvs = faceVertexUvs[ 0 ][ i ]; - if ( vertexUvs !== undefined ) { + if ( vertexUvs !== undefined ) { - this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] ); + this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] ); - } else { + } else { - console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i ); + console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i ); - this.uvs.push( new Vector2(), new Vector2(), new Vector2() ); + this.uvs.push( new Vector2(), new Vector2(), new Vector2() ); - } + } - } + } - if ( hasFaceVertexUv2 === true ) { + if ( hasFaceVertexUv2 === true ) { - var vertexUvs = faceVertexUvs[ 1 ][ i ]; + var vertexUvs = faceVertexUvs[ 1 ][ i ]; - if ( vertexUvs !== undefined ) { + if ( vertexUvs !== undefined ) { - this.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] ); + this.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] ); - } else { + } else { - console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i ); + console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i ); - this.uvs2.push( new Vector2(), new Vector2(), new Vector2() ); + this.uvs2.push( new Vector2(), new Vector2(), new Vector2() ); - } + } - } + } - // morphs + // morphs - for ( var j = 0; j < morphTargetsLength; j ++ ) { + for ( var j = 0; j < morphTargetsLength; j ++ ) { - var morphTarget = morphTargets[ j ].vertices; + var morphTarget = morphTargets[ j ].vertices; - morphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] ); + morphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] ); - } + } - for ( var j = 0; j < morphNormalsLength; j ++ ) { + for ( var j = 0; j < morphNormalsLength; j ++ ) { - var morphNormal = morphNormals[ j ].vertexNormals[ i ]; + var morphNormal = morphNormals[ j ].vertexNormals[ i ]; - morphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c ); + morphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c ); - } + } - // skins + // skins - if ( hasSkinIndices ) { + if ( hasSkinIndices ) { - this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] ); + this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] ); - } + } - if ( hasSkinWeights ) { + if ( hasSkinWeights ) { - this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] ); + this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] ); - } + } - } + } - this.computeGroups( geometry ); + this.computeGroups( geometry ); - this.verticesNeedUpdate = geometry.verticesNeedUpdate; - this.normalsNeedUpdate = geometry.normalsNeedUpdate; - this.colorsNeedUpdate = geometry.colorsNeedUpdate; - this.uvsNeedUpdate = geometry.uvsNeedUpdate; - this.groupsNeedUpdate = geometry.groupsNeedUpdate; + this.verticesNeedUpdate = geometry.verticesNeedUpdate; + this.normalsNeedUpdate = geometry.normalsNeedUpdate; + this.colorsNeedUpdate = geometry.colorsNeedUpdate; + this.uvsNeedUpdate = geometry.uvsNeedUpdate; + this.groupsNeedUpdate = geometry.groupsNeedUpdate; - return this; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function arrayMax( array ) { + function arrayMax( array ) { - if ( array.length === 0 ) return - Infinity; + if ( array.length === 0 ) return - Infinity; - var max = array[ 0 ]; + var max = array[ 0 ]; - for ( var i = 1, l = array.length; i < l; ++ i ) { + for ( var i = 1, l = array.length; i < l; ++ i ) { - if ( array[ i ] > max ) max = array[ i ]; + if ( array[ i ] > max ) max = array[ i ]; - } + } - return max; + return max; - } + } - /** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author alteredq / http://alteredqualia.com/ + * @author mrdoob / http://mrdoob.com/ + */ - var bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id + var bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id - function BufferGeometry() { + function BufferGeometry() { - Object.defineProperty( this, 'id', { value: bufferGeometryId += 2 } ); + Object.defineProperty( this, 'id', { value: bufferGeometryId += 2 } ); - this.uuid = _Math.generateUUID(); + this.uuid = _Math.generateUUID(); - this.name = ''; - this.type = 'BufferGeometry'; + this.name = ''; + this.type = 'BufferGeometry'; - this.index = null; - this.attributes = {}; + this.index = null; + this.attributes = {}; - this.morphAttributes = {}; + this.morphAttributes = {}; - this.groups = []; + this.groups = []; - this.boundingBox = null; - this.boundingSphere = null; + this.boundingBox = null; + this.boundingSphere = null; - this.drawRange = { start: 0, count: Infinity }; + this.drawRange = { start: 0, count: Infinity }; - this.userData = {}; + this.userData = {}; - } + } - BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { + BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - constructor: BufferGeometry, + constructor: BufferGeometry, - isBufferGeometry: true, + isBufferGeometry: true, - getIndex: function () { + getIndex: function () { - return this.index; + return this.index; - }, + }, - setIndex: function ( index ) { + setIndex: function ( index ) { - if ( Array.isArray( index ) ) { + if ( Array.isArray( index ) ) { - this.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 ); + this.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 ); - } else { + } else { - this.index = index; + this.index = index; - } + } - }, + }, - addAttribute: function ( name, attribute ) { + addAttribute: function ( name, attribute ) { - if ( ! ( attribute && attribute.isBufferAttribute ) && ! ( attribute && attribute.isInterleavedBufferAttribute ) ) { + if ( ! ( attribute && attribute.isBufferAttribute ) && ! ( attribute && attribute.isInterleavedBufferAttribute ) ) { - console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); + console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); - return this.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) ); + return this.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) ); - } + } - if ( name === 'index' ) { + if ( name === 'index' ) { - console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' ); - this.setIndex( attribute ); + console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' ); + this.setIndex( attribute ); - return this; + return this; - } + } - this.attributes[ name ] = attribute; + this.attributes[ name ] = attribute; - return this; + return this; - }, + }, - getAttribute: function ( name ) { + getAttribute: function ( name ) { - return this.attributes[ name ]; + return this.attributes[ name ]; - }, + }, - removeAttribute: function ( name ) { + removeAttribute: function ( name ) { - delete this.attributes[ name ]; + delete this.attributes[ name ]; - return this; + return this; - }, + }, - addGroup: function ( start, count, materialIndex ) { + addGroup: function ( start, count, materialIndex ) { - this.groups.push( { + this.groups.push( { - start: start, - count: count, - materialIndex: materialIndex !== undefined ? materialIndex : 0 + start: start, + count: count, + materialIndex: materialIndex !== undefined ? materialIndex : 0 - } ); + } ); - }, + }, - clearGroups: function () { + clearGroups: function () { - this.groups = []; + this.groups = []; - }, + }, - setDrawRange: function ( start, count ) { + setDrawRange: function ( start, count ) { - this.drawRange.start = start; - this.drawRange.count = count; + this.drawRange.start = start; + this.drawRange.count = count; - }, + }, - applyMatrix: function ( matrix ) { + applyMatrix: function ( matrix ) { - var position = this.attributes.position; + var position = this.attributes.position; - if ( position !== undefined ) { + if ( position !== undefined ) { - matrix.applyToBufferAttribute( position ); - position.needsUpdate = true; + matrix.applyToBufferAttribute( position ); + position.needsUpdate = true; - } + } - var normal = this.attributes.normal; + var normal = this.attributes.normal; - if ( normal !== undefined ) { + if ( normal !== undefined ) { - var normalMatrix = new Matrix3().getNormalMatrix( matrix ); + var normalMatrix = new Matrix3().getNormalMatrix( matrix ); - normalMatrix.applyToBufferAttribute( normal ); - normal.needsUpdate = true; + normalMatrix.applyToBufferAttribute( normal ); + normal.needsUpdate = true; - } + } - if ( this.boundingBox !== null ) { + if ( this.boundingBox !== null ) { - this.computeBoundingBox(); + this.computeBoundingBox(); - } + } - if ( this.boundingSphere !== null ) { + if ( this.boundingSphere !== null ) { - this.computeBoundingSphere(); + this.computeBoundingSphere(); - } + } - return this; + return this; - }, + }, - rotateX: function () { + rotateX: function () { - // rotate geometry around world x-axis + // rotate geometry around world x-axis - var m1 = new Matrix4(); + var m1 = new Matrix4(); - return function rotateX( angle ) { + return function rotateX( angle ) { - m1.makeRotationX( angle ); + m1.makeRotationX( angle ); - this.applyMatrix( m1 ); + this.applyMatrix( m1 ); - return this; + return this; - }; + }; - }(), + }(), - rotateY: function () { + rotateY: function () { - // rotate geometry around world y-axis + // rotate geometry around world y-axis - var m1 = new Matrix4(); + var m1 = new Matrix4(); - return function rotateY( angle ) { + return function rotateY( angle ) { - m1.makeRotationY( angle ); + m1.makeRotationY( angle ); - this.applyMatrix( m1 ); + this.applyMatrix( m1 ); - return this; + return this; - }; + }; - }(), + }(), - rotateZ: function () { + rotateZ: function () { - // rotate geometry around world z-axis + // rotate geometry around world z-axis - var m1 = new Matrix4(); + var m1 = new Matrix4(); - return function rotateZ( angle ) { + return function rotateZ( angle ) { - m1.makeRotationZ( angle ); + m1.makeRotationZ( angle ); - this.applyMatrix( m1 ); + this.applyMatrix( m1 ); - return this; + return this; - }; + }; - }(), + }(), - translate: function () { + translate: function () { - // translate geometry + // translate geometry - var m1 = new Matrix4(); + var m1 = new Matrix4(); - return function translate( x, y, z ) { + return function translate( x, y, z ) { - m1.makeTranslation( x, y, z ); + m1.makeTranslation( x, y, z ); - this.applyMatrix( m1 ); + this.applyMatrix( m1 ); - return this; + return this; - }; + }; - }(), + }(), - scale: function () { + scale: function () { - // scale geometry + // scale geometry - var m1 = new Matrix4(); + var m1 = new Matrix4(); - return function scale( x, y, z ) { + return function scale( x, y, z ) { - m1.makeScale( x, y, z ); + m1.makeScale( x, y, z ); - this.applyMatrix( m1 ); + this.applyMatrix( m1 ); - return this; + return this; - }; + }; - }(), + }(), - lookAt: function () { + lookAt: function () { - var obj = new Object3D(); + var obj = new Object3D(); - return function lookAt( vector ) { + return function lookAt( vector ) { - obj.lookAt( vector ); + obj.lookAt( vector ); - obj.updateMatrix(); + obj.updateMatrix(); - this.applyMatrix( obj.matrix ); + this.applyMatrix( obj.matrix ); - }; + }; - }(), + }(), - center: function () { + center: function () { - var offset = new Vector3(); + var offset = new Vector3(); - return function center() { + return function center() { - this.computeBoundingBox(); + this.computeBoundingBox(); - this.boundingBox.getCenter( offset ).negate(); + this.boundingBox.getCenter( offset ).negate(); - this.translate( offset.x, offset.y, offset.z ); + this.translate( offset.x, offset.y, offset.z ); - return this; + return this; - }; + }; - }(), + }(), - setFromObject: function ( object ) { + setFromObject: function ( object ) { - // console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this ); + // console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this ); - var geometry = object.geometry; + var geometry = object.geometry; - if ( object.isPoints || object.isLine ) { + if ( object.isPoints || object.isLine ) { - var positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 ); - var colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 ); + var positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 ); + var colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 ); - this.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) ); - this.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) ); + this.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) ); + this.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) ); - if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) { + if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) { - var lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 ); + var lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 ); - this.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) ); + this.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) ); - } + } - if ( geometry.boundingSphere !== null ) { + if ( geometry.boundingSphere !== null ) { - this.boundingSphere = geometry.boundingSphere.clone(); + this.boundingSphere = geometry.boundingSphere.clone(); - } + } - if ( geometry.boundingBox !== null ) { + if ( geometry.boundingBox !== null ) { - this.boundingBox = geometry.boundingBox.clone(); + this.boundingBox = geometry.boundingBox.clone(); - } + } - } else if ( object.isMesh ) { + } else if ( object.isMesh ) { - if ( geometry && geometry.isGeometry ) { + if ( geometry && geometry.isGeometry ) { - this.fromGeometry( geometry ); + this.fromGeometry( geometry ); - } + } - } + } - return this; + return this; - }, + }, - setFromPoints: function ( points ) { + setFromPoints: function ( points ) { - var position = []; + var position = []; - for ( var i = 0, l = points.length; i < l; i ++ ) { + for ( var i = 0, l = points.length; i < l; i ++ ) { - var point = points[ i ]; - position.push( point.x, point.y, point.z || 0 ); + var point = points[ i ]; + position.push( point.x, point.y, point.z || 0 ); - } + } - this.addAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); + this.addAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); - return this; + return this; - }, + }, - updateFromObject: function ( object ) { + updateFromObject: function ( object ) { - var geometry = object.geometry; + var geometry = object.geometry; - if ( object.isMesh ) { + if ( object.isMesh ) { - var direct = geometry.__directGeometry; + var direct = geometry.__directGeometry; - if ( geometry.elementsNeedUpdate === true ) { + if ( geometry.elementsNeedUpdate === true ) { - direct = undefined; - geometry.elementsNeedUpdate = false; + direct = undefined; + geometry.elementsNeedUpdate = false; - } + } - if ( direct === undefined ) { + if ( direct === undefined ) { - return this.fromGeometry( geometry ); + return this.fromGeometry( geometry ); - } + } - direct.verticesNeedUpdate = geometry.verticesNeedUpdate; - direct.normalsNeedUpdate = geometry.normalsNeedUpdate; - direct.colorsNeedUpdate = geometry.colorsNeedUpdate; - direct.uvsNeedUpdate = geometry.uvsNeedUpdate; - direct.groupsNeedUpdate = geometry.groupsNeedUpdate; + direct.verticesNeedUpdate = geometry.verticesNeedUpdate; + direct.normalsNeedUpdate = geometry.normalsNeedUpdate; + direct.colorsNeedUpdate = geometry.colorsNeedUpdate; + direct.uvsNeedUpdate = geometry.uvsNeedUpdate; + direct.groupsNeedUpdate = geometry.groupsNeedUpdate; - geometry.verticesNeedUpdate = false; - geometry.normalsNeedUpdate = false; - geometry.colorsNeedUpdate = false; - geometry.uvsNeedUpdate = false; - geometry.groupsNeedUpdate = false; + geometry.verticesNeedUpdate = false; + geometry.normalsNeedUpdate = false; + geometry.colorsNeedUpdate = false; + geometry.uvsNeedUpdate = false; + geometry.groupsNeedUpdate = false; - geometry = direct; + geometry = direct; - } + } - var attribute; + var attribute; - if ( geometry.verticesNeedUpdate === true ) { + if ( geometry.verticesNeedUpdate === true ) { - attribute = this.attributes.position; + attribute = this.attributes.position; - if ( attribute !== undefined ) { + if ( attribute !== undefined ) { - attribute.copyVector3sArray( geometry.vertices ); - attribute.needsUpdate = true; + attribute.copyVector3sArray( geometry.vertices ); + attribute.needsUpdate = true; - } + } - geometry.verticesNeedUpdate = false; + geometry.verticesNeedUpdate = false; - } + } - if ( geometry.normalsNeedUpdate === true ) { + if ( geometry.normalsNeedUpdate === true ) { - attribute = this.attributes.normal; + attribute = this.attributes.normal; - if ( attribute !== undefined ) { + if ( attribute !== undefined ) { - attribute.copyVector3sArray( geometry.normals ); - attribute.needsUpdate = true; + attribute.copyVector3sArray( geometry.normals ); + attribute.needsUpdate = true; - } + } - geometry.normalsNeedUpdate = false; + geometry.normalsNeedUpdate = false; - } + } - if ( geometry.colorsNeedUpdate === true ) { + if ( geometry.colorsNeedUpdate === true ) { - attribute = this.attributes.color; + attribute = this.attributes.color; - if ( attribute !== undefined ) { + if ( attribute !== undefined ) { - attribute.copyColorsArray( geometry.colors ); - attribute.needsUpdate = true; + attribute.copyColorsArray( geometry.colors ); + attribute.needsUpdate = true; - } + } - geometry.colorsNeedUpdate = false; + geometry.colorsNeedUpdate = false; - } + } - if ( geometry.uvsNeedUpdate ) { + if ( geometry.uvsNeedUpdate ) { - attribute = this.attributes.uv; + attribute = this.attributes.uv; - if ( attribute !== undefined ) { + if ( attribute !== undefined ) { - attribute.copyVector2sArray( geometry.uvs ); - attribute.needsUpdate = true; + attribute.copyVector2sArray( geometry.uvs ); + attribute.needsUpdate = true; - } + } - geometry.uvsNeedUpdate = false; + geometry.uvsNeedUpdate = false; - } + } - if ( geometry.lineDistancesNeedUpdate ) { + if ( geometry.lineDistancesNeedUpdate ) { - attribute = this.attributes.lineDistance; + attribute = this.attributes.lineDistance; - if ( attribute !== undefined ) { + if ( attribute !== undefined ) { - attribute.copyArray( geometry.lineDistances ); - attribute.needsUpdate = true; + attribute.copyArray( geometry.lineDistances ); + attribute.needsUpdate = true; - } + } - geometry.lineDistancesNeedUpdate = false; + geometry.lineDistancesNeedUpdate = false; - } + } - if ( geometry.groupsNeedUpdate ) { + if ( geometry.groupsNeedUpdate ) { - geometry.computeGroups( object.geometry ); - this.groups = geometry.groups; + geometry.computeGroups( object.geometry ); + this.groups = geometry.groups; - geometry.groupsNeedUpdate = false; + geometry.groupsNeedUpdate = false; - } + } - return this; + return this; - }, + }, - fromGeometry: function ( geometry ) { + fromGeometry: function ( geometry ) { - geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry ); + geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry ); - return this.fromDirectGeometry( geometry.__directGeometry ); + return this.fromDirectGeometry( geometry.__directGeometry ); - }, + }, - fromDirectGeometry: function ( geometry ) { + fromDirectGeometry: function ( geometry ) { - var positions = new Float32Array( geometry.vertices.length * 3 ); - this.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) ); + var positions = new Float32Array( geometry.vertices.length * 3 ); + this.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) ); - if ( geometry.normals.length > 0 ) { + if ( geometry.normals.length > 0 ) { - var normals = new Float32Array( geometry.normals.length * 3 ); - this.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) ); + var normals = new Float32Array( geometry.normals.length * 3 ); + this.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) ); - } + } - if ( geometry.colors.length > 0 ) { + if ( geometry.colors.length > 0 ) { - var colors = new Float32Array( geometry.colors.length * 3 ); - this.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) ); + var colors = new Float32Array( geometry.colors.length * 3 ); + this.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) ); - } + } - if ( geometry.uvs.length > 0 ) { + if ( geometry.uvs.length > 0 ) { - var uvs = new Float32Array( geometry.uvs.length * 2 ); - this.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) ); + var uvs = new Float32Array( geometry.uvs.length * 2 ); + this.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) ); - } + } - if ( geometry.uvs2.length > 0 ) { + if ( geometry.uvs2.length > 0 ) { - var uvs2 = new Float32Array( geometry.uvs2.length * 2 ); - this.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) ); + var uvs2 = new Float32Array( geometry.uvs2.length * 2 ); + this.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) ); - } + } - // groups + // groups - this.groups = geometry.groups; + this.groups = geometry.groups; - // morphs + // morphs - for ( var name in geometry.morphTargets ) { + for ( var name in geometry.morphTargets ) { - var array = []; - var morphTargets = geometry.morphTargets[ name ]; + var array = []; + var morphTargets = geometry.morphTargets[ name ]; - for ( var i = 0, l = morphTargets.length; i < l; i ++ ) { + for ( var i = 0, l = morphTargets.length; i < l; i ++ ) { - var morphTarget = morphTargets[ i ]; + var morphTarget = morphTargets[ i ]; - var attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 ); + var attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 ); - array.push( attribute.copyVector3sArray( morphTarget ) ); + array.push( attribute.copyVector3sArray( morphTarget ) ); - } + } - this.morphAttributes[ name ] = array; + this.morphAttributes[ name ] = array; - } + } - // skinning + // skinning - if ( geometry.skinIndices.length > 0 ) { + if ( geometry.skinIndices.length > 0 ) { - var skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 ); - this.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) ); + var skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 ); + this.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) ); - } + } - if ( geometry.skinWeights.length > 0 ) { + if ( geometry.skinWeights.length > 0 ) { - var skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 ); - this.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) ); + var skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 ); + this.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) ); - } + } - // + // - if ( geometry.boundingSphere !== null ) { + if ( geometry.boundingSphere !== null ) { - this.boundingSphere = geometry.boundingSphere.clone(); + this.boundingSphere = geometry.boundingSphere.clone(); - } + } - if ( geometry.boundingBox !== null ) { + if ( geometry.boundingBox !== null ) { - this.boundingBox = geometry.boundingBox.clone(); + this.boundingBox = geometry.boundingBox.clone(); - } + } - return this; + return this; - }, + }, - computeBoundingBox: function () { + computeBoundingBox: function () { - if ( this.boundingBox === null ) { + if ( this.boundingBox === null ) { - this.boundingBox = new Box3(); + this.boundingBox = new Box3(); - } + } - var position = this.attributes.position; + var position = this.attributes.position; - if ( position !== undefined ) { + if ( position !== undefined ) { - this.boundingBox.setFromBufferAttribute( position ); + this.boundingBox.setFromBufferAttribute( position ); - } else { + } else { - this.boundingBox.makeEmpty(); + this.boundingBox.makeEmpty(); - } + } - if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { + if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { - console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this ); + console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this ); - } + } - }, + }, - computeBoundingSphere: function () { + computeBoundingSphere: function () { - var box = new Box3(); - var vector = new Vector3(); + var box = new Box3(); + var vector = new Vector3(); - return function computeBoundingSphere() { + return function computeBoundingSphere() { - if ( this.boundingSphere === null ) { + if ( this.boundingSphere === null ) { - this.boundingSphere = new Sphere(); + this.boundingSphere = new Sphere(); - } + } - var position = this.attributes.position; + var position = this.attributes.position; - if ( position ) { + if ( position ) { - var center = this.boundingSphere.center; + var center = this.boundingSphere.center; - box.setFromBufferAttribute( position ); - box.getCenter( center ); + box.setFromBufferAttribute( position ); + box.getCenter( center ); - // hoping to find a boundingSphere with a radius smaller than the - // boundingSphere of the boundingBox: sqrt(3) smaller in the best case + // hoping to find a boundingSphere with a radius smaller than the + // boundingSphere of the boundingBox: sqrt(3) smaller in the best case - var maxRadiusSq = 0; + var maxRadiusSq = 0; - for ( var i = 0, il = position.count; i < il; i ++ ) { + for ( var i = 0, il = position.count; i < il; i ++ ) { - vector.x = position.getX( i ); - vector.y = position.getY( i ); - vector.z = position.getZ( i ); - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) ); + vector.x = position.getX( i ); + vector.y = position.getY( i ); + vector.z = position.getZ( i ); + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) ); - } + } - this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); + this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); - if ( isNaN( this.boundingSphere.radius ) ) { + if ( isNaN( this.boundingSphere.radius ) ) { - console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this ); + console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this ); - } + } - } + } - }; + }; - }(), + }(), - computeFaceNormals: function () { + computeFaceNormals: function () { - // backwards compatibility + // backwards compatibility - }, + }, - computeVertexNormals: function () { + computeVertexNormals: function () { - var index = this.index; - var attributes = this.attributes; - var groups = this.groups; + var index = this.index; + var attributes = this.attributes; + var groups = this.groups; - if ( attributes.position ) { + if ( attributes.position ) { - var positions = attributes.position.array; + var positions = attributes.position.array; - if ( attributes.normal === undefined ) { + if ( attributes.normal === undefined ) { - this.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) ); + this.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) ); - } else { + } else { - // reset existing normals to zero + // reset existing normals to zero - var array = attributes.normal.array; + var array = attributes.normal.array; - for ( var i = 0, il = array.length; i < il; i ++ ) { + for ( var i = 0, il = array.length; i < il; i ++ ) { - array[ i ] = 0; + array[ i ] = 0; - } + } - } + } - var normals = attributes.normal.array; + var normals = attributes.normal.array; - var vA, vB, vC; - var pA = new Vector3(), pB = new Vector3(), pC = new Vector3(); - var cb = new Vector3(), ab = new Vector3(); + var vA, vB, vC; + var pA = new Vector3(), pB = new Vector3(), pC = new Vector3(); + var cb = new Vector3(), ab = new Vector3(); - // indexed elements + // indexed elements - if ( index ) { + if ( index ) { - var indices = index.array; + var indices = index.array; - if ( groups.length === 0 ) { + if ( groups.length === 0 ) { - this.addGroup( 0, indices.length ); + this.addGroup( 0, indices.length ); - } + } - for ( var j = 0, jl = groups.length; j < jl; ++ j ) { + for ( var j = 0, jl = groups.length; j < jl; ++ j ) { - var group = groups[ j ]; + var group = groups[ j ]; - var start = group.start; - var count = group.count; + var start = group.start; + var count = group.count; - for ( var i = start, il = start + count; i < il; i += 3 ) { + for ( var i = start, il = start + count; i < il; i += 3 ) { - vA = indices[ i + 0 ] * 3; - vB = indices[ i + 1 ] * 3; - vC = indices[ i + 2 ] * 3; + vA = indices[ i + 0 ] * 3; + vB = indices[ i + 1 ] * 3; + vC = indices[ i + 2 ] * 3; - pA.fromArray( positions, vA ); - pB.fromArray( positions, vB ); - pC.fromArray( positions, vC ); + pA.fromArray( positions, vA ); + pB.fromArray( positions, vB ); + pC.fromArray( positions, vC ); - cb.subVectors( pC, pB ); - ab.subVectors( pA, pB ); - cb.cross( ab ); + cb.subVectors( pC, pB ); + ab.subVectors( pA, pB ); + cb.cross( ab ); - normals[ vA ] += cb.x; - normals[ vA + 1 ] += cb.y; - normals[ vA + 2 ] += cb.z; + normals[ vA ] += cb.x; + normals[ vA + 1 ] += cb.y; + normals[ vA + 2 ] += cb.z; - normals[ vB ] += cb.x; - normals[ vB + 1 ] += cb.y; - normals[ vB + 2 ] += cb.z; + normals[ vB ] += cb.x; + normals[ vB + 1 ] += cb.y; + normals[ vB + 2 ] += cb.z; - normals[ vC ] += cb.x; - normals[ vC + 1 ] += cb.y; - normals[ vC + 2 ] += cb.z; + normals[ vC ] += cb.x; + normals[ vC + 1 ] += cb.y; + normals[ vC + 2 ] += cb.z; - } + } - } + } - } else { + } else { - // non-indexed elements (unconnected triangle soup) + // non-indexed elements (unconnected triangle soup) - for ( var i = 0, il = positions.length; i < il; i += 9 ) { + for ( var i = 0, il = positions.length; i < il; i += 9 ) { - pA.fromArray( positions, i ); - pB.fromArray( positions, i + 3 ); - pC.fromArray( positions, i + 6 ); + pA.fromArray( positions, i ); + pB.fromArray( positions, i + 3 ); + pC.fromArray( positions, i + 6 ); - cb.subVectors( pC, pB ); - ab.subVectors( pA, pB ); - cb.cross( ab ); + cb.subVectors( pC, pB ); + ab.subVectors( pA, pB ); + cb.cross( ab ); - normals[ i ] = cb.x; - normals[ i + 1 ] = cb.y; - normals[ i + 2 ] = cb.z; + normals[ i ] = cb.x; + normals[ i + 1 ] = cb.y; + normals[ i + 2 ] = cb.z; - normals[ i + 3 ] = cb.x; - normals[ i + 4 ] = cb.y; - normals[ i + 5 ] = cb.z; + normals[ i + 3 ] = cb.x; + normals[ i + 4 ] = cb.y; + normals[ i + 5 ] = cb.z; - normals[ i + 6 ] = cb.x; - normals[ i + 7 ] = cb.y; - normals[ i + 8 ] = cb.z; + normals[ i + 6 ] = cb.x; + normals[ i + 7 ] = cb.y; + normals[ i + 8 ] = cb.z; - } + } - } + } - this.normalizeNormals(); + this.normalizeNormals(); - attributes.normal.needsUpdate = true; + attributes.normal.needsUpdate = true; - } + } - }, + }, - merge: function ( geometry, offset ) { + merge: function ( geometry, offset ) { - if ( ! ( geometry && geometry.isBufferGeometry ) ) { + if ( ! ( geometry && geometry.isBufferGeometry ) ) { - console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry ); - return; + console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry ); + return; - } + } - if ( offset === undefined ) { + if ( offset === undefined ) { - offset = 0; + offset = 0; - console.warn( - 'THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' - + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.' - ); + console.warn( + 'THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' + + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.' + ); - } + } - var attributes = this.attributes; + var attributes = this.attributes; - for ( var key in attributes ) { + for ( var key in attributes ) { - if ( geometry.attributes[ key ] === undefined ) continue; + if ( geometry.attributes[ key ] === undefined ) continue; - var attribute1 = attributes[ key ]; - var attributeArray1 = attribute1.array; + var attribute1 = attributes[ key ]; + var attributeArray1 = attribute1.array; - var attribute2 = geometry.attributes[ key ]; - var attributeArray2 = attribute2.array; + var attribute2 = geometry.attributes[ key ]; + var attributeArray2 = attribute2.array; - var attributeSize = attribute2.itemSize; + var attributeSize = attribute2.itemSize; - for ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) { + for ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) { - attributeArray1[ j ] = attributeArray2[ i ]; + attributeArray1[ j ] = attributeArray2[ i ]; - } + } - } + } - return this; + return this; - }, + }, - normalizeNormals: function () { + normalizeNormals: function () { - var vector = new Vector3(); + var vector = new Vector3(); - return function normalizeNormals() { + return function normalizeNormals() { - var normals = this.attributes.normal; + var normals = this.attributes.normal; - for ( var i = 0, il = normals.count; i < il; i ++ ) { + for ( var i = 0, il = normals.count; i < il; i ++ ) { - vector.x = normals.getX( i ); - vector.y = normals.getY( i ); - vector.z = normals.getZ( i ); + vector.x = normals.getX( i ); + vector.y = normals.getY( i ); + vector.z = normals.getZ( i ); - vector.normalize(); + vector.normalize(); - normals.setXYZ( i, vector.x, vector.y, vector.z ); + normals.setXYZ( i, vector.x, vector.y, vector.z ); - } + } - }; + }; - }(), + }(), - toNonIndexed: function () { + toNonIndexed: function () { - if ( this.index === null ) { + if ( this.index === null ) { - console.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' ); - return this; + console.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' ); + return this; - } + } - var geometry2 = new BufferGeometry(); + var geometry2 = new BufferGeometry(); - var indices = this.index.array; - var attributes = this.attributes; + var indices = this.index.array; + var attributes = this.attributes; - for ( var name in attributes ) { + for ( var name in attributes ) { - var attribute = attributes[ name ]; + var attribute = attributes[ name ]; - var array = attribute.array; - var itemSize = attribute.itemSize; + var array = attribute.array; + var itemSize = attribute.itemSize; - var array2 = new array.constructor( indices.length * itemSize ); + var array2 = new array.constructor( indices.length * itemSize ); - var index = 0, index2 = 0; + var index = 0, index2 = 0; - for ( var i = 0, l = indices.length; i < l; i ++ ) { + for ( var i = 0, l = indices.length; i < l; i ++ ) { - index = indices[ i ] * itemSize; + index = indices[ i ] * itemSize; - for ( var j = 0; j < itemSize; j ++ ) { + for ( var j = 0; j < itemSize; j ++ ) { - array2[ index2 ++ ] = array[ index ++ ]; + array2[ index2 ++ ] = array[ index ++ ]; - } + } - } + } - geometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) ); + geometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) ); - } + } - var groups = this.groups; + var groups = this.groups; - for ( var i = 0, l = groups.length; i < l; i ++ ) { + for ( var i = 0, l = groups.length; i < l; i ++ ) { - var group = groups[ i ]; - geometry2.addGroup( group.start, group.count, group.materialIndex ); + var group = groups[ i ]; + geometry2.addGroup( group.start, group.count, group.materialIndex ); - } + } - return geometry2; + return geometry2; - }, + }, - toJSON: function () { + toJSON: function () { - var data = { - metadata: { - version: 4.5, - type: 'BufferGeometry', - generator: 'BufferGeometry.toJSON' - } - }; + var data = { + metadata: { + version: 4.5, + type: 'BufferGeometry', + generator: 'BufferGeometry.toJSON' + } + }; - // standard BufferGeometry serialization + // standard BufferGeometry serialization - data.uuid = this.uuid; - data.type = this.type; - if ( this.name !== '' ) data.name = this.name; - if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; + data.uuid = this.uuid; + data.type = this.type; + if ( this.name !== '' ) data.name = this.name; + if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; - if ( this.parameters !== undefined ) { + if ( this.parameters !== undefined ) { - var parameters = this.parameters; + var parameters = this.parameters; - for ( var key in parameters ) { + for ( var key in parameters ) { - if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; + if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; - } + } - return data; + return data; - } + } - data.data = { attributes: {} }; + data.data = { attributes: {} }; - var index = this.index; + var index = this.index; - if ( index !== null ) { + if ( index !== null ) { - var array = Array.prototype.slice.call( index.array ); + var array = Array.prototype.slice.call( index.array ); - data.data.index = { - type: index.array.constructor.name, - array: array - }; + data.data.index = { + type: index.array.constructor.name, + array: array + }; - } + } - var attributes = this.attributes; + var attributes = this.attributes; - for ( var key in attributes ) { + for ( var key in attributes ) { - var attribute = attributes[ key ]; + var attribute = attributes[ key ]; - var array = Array.prototype.slice.call( attribute.array ); + var array = Array.prototype.slice.call( attribute.array ); - data.data.attributes[ key ] = { - itemSize: attribute.itemSize, - type: attribute.array.constructor.name, - array: array, - normalized: attribute.normalized - }; + data.data.attributes[ key ] = { + itemSize: attribute.itemSize, + type: attribute.array.constructor.name, + array: array, + normalized: attribute.normalized + }; - } + } - var groups = this.groups; + var groups = this.groups; - if ( groups.length > 0 ) { + if ( groups.length > 0 ) { - data.data.groups = JSON.parse( JSON.stringify( groups ) ); + data.data.groups = JSON.parse( JSON.stringify( groups ) ); - } + } - var boundingSphere = this.boundingSphere; + var boundingSphere = this.boundingSphere; - if ( boundingSphere !== null ) { + if ( boundingSphere !== null ) { - data.data.boundingSphere = { - center: boundingSphere.center.toArray(), - radius: boundingSphere.radius - }; + data.data.boundingSphere = { + center: boundingSphere.center.toArray(), + radius: boundingSphere.radius + }; - } + } - return data; + return data; - }, + }, - clone: function () { + clone: function () { - /* - // Handle primitives + /* + // Handle primitives - var parameters = this.parameters; + var parameters = this.parameters; - if ( parameters !== undefined ) { + if ( parameters !== undefined ) { - var values = []; + var values = []; - for ( var key in parameters ) { + for ( var key in parameters ) { - values.push( parameters[ key ] ); + values.push( parameters[ key ] ); - } + } - var geometry = Object.create( this.constructor.prototype ); - this.constructor.apply( geometry, values ); - return geometry; + var geometry = Object.create( this.constructor.prototype ); + this.constructor.apply( geometry, values ); + return geometry; - } + } - return new this.constructor().copy( this ); - */ + return new this.constructor().copy( this ); + */ - return new BufferGeometry().copy( this ); + return new BufferGeometry().copy( this ); - }, + }, - copy: function ( source ) { + copy: function ( source ) { - var name, i, l; + var name, i, l; - // reset + // reset - this.index = null; - this.attributes = {}; - this.morphAttributes = {}; - this.groups = []; - this.boundingBox = null; - this.boundingSphere = null; + this.index = null; + this.attributes = {}; + this.morphAttributes = {}; + this.groups = []; + this.boundingBox = null; + this.boundingSphere = null; - // name + // name - this.name = source.name; + this.name = source.name; - // index + // index - var index = source.index; + var index = source.index; - if ( index !== null ) { + if ( index !== null ) { - this.setIndex( index.clone() ); + this.setIndex( index.clone() ); - } + } - // attributes + // attributes - var attributes = source.attributes; + var attributes = source.attributes; - for ( name in attributes ) { + for ( name in attributes ) { - var attribute = attributes[ name ]; - this.addAttribute( name, attribute.clone() ); + var attribute = attributes[ name ]; + this.addAttribute( name, attribute.clone() ); - } + } - // morph attributes + // morph attributes - var morphAttributes = source.morphAttributes; + var morphAttributes = source.morphAttributes; - for ( name in morphAttributes ) { + for ( name in morphAttributes ) { - var array = []; - var morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes + var array = []; + var morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes - for ( i = 0, l = morphAttribute.length; i < l; i ++ ) { + for ( i = 0, l = morphAttribute.length; i < l; i ++ ) { - array.push( morphAttribute[ i ].clone() ); + array.push( morphAttribute[ i ].clone() ); - } + } - this.morphAttributes[ name ] = array; + this.morphAttributes[ name ] = array; - } + } - // groups + // groups - var groups = source.groups; + var groups = source.groups; - for ( i = 0, l = groups.length; i < l; i ++ ) { + for ( i = 0, l = groups.length; i < l; i ++ ) { - var group = groups[ i ]; - this.addGroup( group.start, group.count, group.materialIndex ); + var group = groups[ i ]; + this.addGroup( group.start, group.count, group.materialIndex ); - } + } - // bounding box + // bounding box - var boundingBox = source.boundingBox; + var boundingBox = source.boundingBox; - if ( boundingBox !== null ) { + if ( boundingBox !== null ) { - this.boundingBox = boundingBox.clone(); + this.boundingBox = boundingBox.clone(); - } + } - // bounding sphere + // bounding sphere - var boundingSphere = source.boundingSphere; + var boundingSphere = source.boundingSphere; - if ( boundingSphere !== null ) { + if ( boundingSphere !== null ) { - this.boundingSphere = boundingSphere.clone(); + this.boundingSphere = boundingSphere.clone(); - } + } - // draw range + // draw range - this.drawRange.start = source.drawRange.start; - this.drawRange.count = source.drawRange.count; + this.drawRange.start = source.drawRange.start; + this.drawRange.count = source.drawRange.count; - // user data + // user data - this.userData = source.userData; + this.userData = source.userData; - return this; + return this; - }, + }, - dispose: function () { + dispose: function () { - this.dispatchEvent( { type: 'dispose' } ); + this.dispatchEvent( { type: 'dispose' } ); - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author Mugen87 / https://github.com/Mugen87 + */ - // BoxGeometry + // BoxGeometry - function BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) { + function BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'BoxGeometry'; + this.type = 'BoxGeometry'; - this.parameters = { - width: width, - height: height, - depth: depth, - widthSegments: widthSegments, - heightSegments: heightSegments, - depthSegments: depthSegments - }; + this.parameters = { + width: width, + height: height, + depth: depth, + widthSegments: widthSegments, + heightSegments: heightSegments, + depthSegments: depthSegments + }; - this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) ); - this.mergeVertices(); + this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) ); + this.mergeVertices(); - } + } - BoxGeometry.prototype = Object.create( Geometry.prototype ); - BoxGeometry.prototype.constructor = BoxGeometry; + BoxGeometry.prototype = Object.create( Geometry.prototype ); + BoxGeometry.prototype.constructor = BoxGeometry; - // BoxBufferGeometry + // BoxBufferGeometry - function BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) { + function BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'BoxBufferGeometry'; + this.type = 'BoxBufferGeometry'; - this.parameters = { - width: width, - height: height, - depth: depth, - widthSegments: widthSegments, - heightSegments: heightSegments, - depthSegments: depthSegments - }; + this.parameters = { + width: width, + height: height, + depth: depth, + widthSegments: widthSegments, + heightSegments: heightSegments, + depthSegments: depthSegments + }; - var scope = this; + var scope = this; - width = width || 1; - height = height || 1; - depth = depth || 1; + width = width || 1; + height = height || 1; + depth = depth || 1; - // segments + // segments - widthSegments = Math.floor( widthSegments ) || 1; - heightSegments = Math.floor( heightSegments ) || 1; - depthSegments = Math.floor( depthSegments ) || 1; + widthSegments = Math.floor( widthSegments ) || 1; + heightSegments = Math.floor( heightSegments ) || 1; + depthSegments = Math.floor( depthSegments ) || 1; - // buffers + // buffers - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - // helper variables + // helper variables - var numberOfVertices = 0; - var groupStart = 0; + var numberOfVertices = 0; + var groupStart = 0; - // build each side of the box geometry + // build each side of the box geometry - buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px - buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx - buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py - buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny - buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz - buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz + buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px + buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx + buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py + buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny + buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz + buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz - // build geometry + // build geometry - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setIndex( indices ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { + function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { - var segmentWidth = width / gridX; - var segmentHeight = height / gridY; + var segmentWidth = width / gridX; + var segmentHeight = height / gridY; - var widthHalf = width / 2; - var heightHalf = height / 2; - var depthHalf = depth / 2; + var widthHalf = width / 2; + var heightHalf = height / 2; + var depthHalf = depth / 2; - var gridX1 = gridX + 1; - var gridY1 = gridY + 1; + var gridX1 = gridX + 1; + var gridY1 = gridY + 1; - var vertexCounter = 0; - var groupCount = 0; + var vertexCounter = 0; + var groupCount = 0; - var ix, iy; + var ix, iy; - var vector = new Vector3(); + var vector = new Vector3(); - // generate vertices, normals and uvs + // generate vertices, normals and uvs - for ( iy = 0; iy < gridY1; iy ++ ) { + for ( iy = 0; iy < gridY1; iy ++ ) { - var y = iy * segmentHeight - heightHalf; + var y = iy * segmentHeight - heightHalf; - for ( ix = 0; ix < gridX1; ix ++ ) { + for ( ix = 0; ix < gridX1; ix ++ ) { - var x = ix * segmentWidth - widthHalf; + var x = ix * segmentWidth - widthHalf; - // set values to correct vector component + // set values to correct vector component - vector[ u ] = x * udir; - vector[ v ] = y * vdir; - vector[ w ] = depthHalf; + vector[ u ] = x * udir; + vector[ v ] = y * vdir; + vector[ w ] = depthHalf; - // now apply vector to vertex buffer + // now apply vector to vertex buffer - vertices.push( vector.x, vector.y, vector.z ); + vertices.push( vector.x, vector.y, vector.z ); - // set values to correct vector component + // set values to correct vector component - vector[ u ] = 0; - vector[ v ] = 0; - vector[ w ] = depth > 0 ? 1 : - 1; + vector[ u ] = 0; + vector[ v ] = 0; + vector[ w ] = depth > 0 ? 1 : - 1; - // now apply vector to normal buffer + // now apply vector to normal buffer - normals.push( vector.x, vector.y, vector.z ); + normals.push( vector.x, vector.y, vector.z ); - // uvs + // uvs - uvs.push( ix / gridX ); - uvs.push( 1 - ( iy / gridY ) ); + uvs.push( ix / gridX ); + uvs.push( 1 - ( iy / gridY ) ); - // counters + // counters - vertexCounter += 1; + vertexCounter += 1; - } + } - } + } - // indices + // indices - // 1. you need three indices to draw a single face - // 2. a single segment consists of two faces - // 3. so we need to generate six (2*3) indices per segment + // 1. you need three indices to draw a single face + // 2. a single segment consists of two faces + // 3. so we need to generate six (2*3) indices per segment - for ( iy = 0; iy < gridY; iy ++ ) { + for ( iy = 0; iy < gridY; iy ++ ) { - for ( ix = 0; ix < gridX; ix ++ ) { + for ( ix = 0; ix < gridX; ix ++ ) { - var a = numberOfVertices + ix + gridX1 * iy; - var b = numberOfVertices + ix + gridX1 * ( iy + 1 ); - var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); - var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; + var a = numberOfVertices + ix + gridX1 * iy; + var b = numberOfVertices + ix + gridX1 * ( iy + 1 ); + var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); + var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; - // faces + // faces - indices.push( a, b, d ); - indices.push( b, c, d ); + indices.push( a, b, d ); + indices.push( b, c, d ); - // increase counter + // increase counter - groupCount += 6; + groupCount += 6; - } + } - } + } - // add a group to the geometry. this will ensure multi material support + // add a group to the geometry. this will ensure multi material support - scope.addGroup( groupStart, groupCount, materialIndex ); + scope.addGroup( groupStart, groupCount, materialIndex ); - // calculate new start value for groups + // calculate new start value for groups - groupStart += groupCount; + groupStart += groupCount; - // update total number of vertices + // update total number of vertices - numberOfVertices += vertexCounter; + numberOfVertices += vertexCounter; - } + } - } + } - BoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - BoxBufferGeometry.prototype.constructor = BoxBufferGeometry; + BoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + BoxBufferGeometry.prototype.constructor = BoxBufferGeometry; - /** - * @author mrdoob / http://mrdoob.com/ - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author Mugen87 / https://github.com/Mugen87 + */ - // PlaneGeometry + // PlaneGeometry - function PlaneGeometry( width, height, widthSegments, heightSegments ) { + function PlaneGeometry( width, height, widthSegments, heightSegments ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'PlaneGeometry'; + this.type = 'PlaneGeometry'; - this.parameters = { - width: width, - height: height, - widthSegments: widthSegments, - heightSegments: heightSegments - }; + this.parameters = { + width: width, + height: height, + widthSegments: widthSegments, + heightSegments: heightSegments + }; - this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) ); - this.mergeVertices(); + this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) ); + this.mergeVertices(); - } + } - PlaneGeometry.prototype = Object.create( Geometry.prototype ); - PlaneGeometry.prototype.constructor = PlaneGeometry; + PlaneGeometry.prototype = Object.create( Geometry.prototype ); + PlaneGeometry.prototype.constructor = PlaneGeometry; - // PlaneBufferGeometry + // PlaneBufferGeometry - function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) { + function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'PlaneBufferGeometry'; + this.type = 'PlaneBufferGeometry'; - this.parameters = { - width: width, - height: height, - widthSegments: widthSegments, - heightSegments: heightSegments - }; + this.parameters = { + width: width, + height: height, + widthSegments: widthSegments, + heightSegments: heightSegments + }; - width = width || 1; - height = height || 1; + width = width || 1; + height = height || 1; - var width_half = width / 2; - var height_half = height / 2; + var width_half = width / 2; + var height_half = height / 2; - var gridX = Math.floor( widthSegments ) || 1; - var gridY = Math.floor( heightSegments ) || 1; + var gridX = Math.floor( widthSegments ) || 1; + var gridY = Math.floor( heightSegments ) || 1; - var gridX1 = gridX + 1; - var gridY1 = gridY + 1; + var gridX1 = gridX + 1; + var gridY1 = gridY + 1; - var segment_width = width / gridX; - var segment_height = height / gridY; + var segment_width = width / gridX; + var segment_height = height / gridY; - var ix, iy; + var ix, iy; - // buffers + // buffers - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - // generate vertices, normals and uvs + // generate vertices, normals and uvs - for ( iy = 0; iy < gridY1; iy ++ ) { + for ( iy = 0; iy < gridY1; iy ++ ) { - var y = iy * segment_height - height_half; + var y = iy * segment_height - height_half; - for ( ix = 0; ix < gridX1; ix ++ ) { + for ( ix = 0; ix < gridX1; ix ++ ) { - var x = ix * segment_width - width_half; + var x = ix * segment_width - width_half; - vertices.push( x, - y, 0 ); + vertices.push( x, - y, 0 ); - normals.push( 0, 0, 1 ); + normals.push( 0, 0, 1 ); - uvs.push( ix / gridX ); - uvs.push( 1 - ( iy / gridY ) ); + uvs.push( ix / gridX ); + uvs.push( 1 - ( iy / gridY ) ); - } + } - } + } - // indices + // indices - for ( iy = 0; iy < gridY; iy ++ ) { + for ( iy = 0; iy < gridY; iy ++ ) { - for ( ix = 0; ix < gridX; ix ++ ) { + for ( ix = 0; ix < gridX; ix ++ ) { - var a = ix + gridX1 * iy; - var b = ix + gridX1 * ( iy + 1 ); - var c = ( ix + 1 ) + gridX1 * ( iy + 1 ); - var d = ( ix + 1 ) + gridX1 * iy; + var a = ix + gridX1 * iy; + var b = ix + gridX1 * ( iy + 1 ); + var c = ( ix + 1 ) + gridX1 * ( iy + 1 ); + var d = ( ix + 1 ) + gridX1 * iy; - // faces + // faces - indices.push( a, b, d ); - indices.push( b, c, d ); + indices.push( a, b, d ); + indices.push( b, c, d ); - } + } - } + } - // build geometry + // build geometry - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setIndex( indices ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - } + } - PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry; + PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry; - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + */ - var materialId = 0; + var materialId = 0; - function Material() { + function Material() { - Object.defineProperty( this, 'id', { value: materialId ++ } ); + Object.defineProperty( this, 'id', { value: materialId ++ } ); - this.uuid = _Math.generateUUID(); + this.uuid = _Math.generateUUID(); - this.name = ''; - this.type = 'Material'; + this.name = ''; + this.type = 'Material'; - this.fog = true; - this.lights = true; + this.fog = true; + this.lights = true; - this.blending = NormalBlending; - this.side = FrontSide; - this.flatShading = false; - this.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors + this.blending = NormalBlending; + this.side = FrontSide; + this.flatShading = false; + this.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors - this.opacity = 1; - this.transparent = false; + this.opacity = 1; + this.transparent = false; - this.blendSrc = SrcAlphaFactor; - this.blendDst = OneMinusSrcAlphaFactor; - this.blendEquation = AddEquation; - this.blendSrcAlpha = null; - this.blendDstAlpha = null; - this.blendEquationAlpha = null; + this.blendSrc = SrcAlphaFactor; + this.blendDst = OneMinusSrcAlphaFactor; + this.blendEquation = AddEquation; + this.blendSrcAlpha = null; + this.blendDstAlpha = null; + this.blendEquationAlpha = null; - this.depthFunc = LessEqualDepth; - this.depthTest = true; - this.depthWrite = true; + this.depthFunc = LessEqualDepth; + this.depthTest = true; + this.depthWrite = true; - this.clippingPlanes = null; - this.clipIntersection = false; - this.clipShadows = false; + this.clippingPlanes = null; + this.clipIntersection = false; + this.clipShadows = false; - this.shadowSide = null; + this.shadowSide = null; - this.colorWrite = true; + this.colorWrite = true; - this.precision = null; // override the renderer's default precision for this material + this.precision = null; // override the renderer's default precision for this material - this.polygonOffset = false; - this.polygonOffsetFactor = 0; - this.polygonOffsetUnits = 0; + this.polygonOffset = false; + this.polygonOffsetFactor = 0; + this.polygonOffsetUnits = 0; - this.dithering = false; + this.dithering = false; - this.alphaTest = 0; - this.premultipliedAlpha = false; + this.alphaTest = 0; + this.premultipliedAlpha = false; - this.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer + this.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer - this.visible = true; + this.visible = true; - this.userData = {}; + this.userData = {}; - this.needsUpdate = true; + this.needsUpdate = true; - } + } - Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { + Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - constructor: Material, + constructor: Material, - isMaterial: true, + isMaterial: true, - onBeforeCompile: function () {}, + onBeforeCompile: function () {}, - setValues: function ( values ) { + setValues: function ( values ) { - if ( values === undefined ) return; + if ( values === undefined ) return; - for ( var key in values ) { + for ( var key in values ) { - var newValue = values[ key ]; + var newValue = values[ key ]; - if ( newValue === undefined ) { + if ( newValue === undefined ) { - console.warn( "THREE.Material: '" + key + "' parameter is undefined." ); - continue; + console.warn( "THREE.Material: '" + key + "' parameter is undefined." ); + continue; - } + } - // for backward compatability if shading is set in the constructor - if ( key === 'shading' ) { + // for backward compatability if shading is set in the constructor + if ( key === 'shading' ) { - console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); - this.flatShading = ( newValue === FlatShading ) ? true : false; - continue; + console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); + this.flatShading = ( newValue === FlatShading ) ? true : false; + continue; - } + } - var currentValue = this[ key ]; + var currentValue = this[ key ]; - if ( currentValue === undefined ) { + if ( currentValue === undefined ) { - console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." ); - continue; + console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." ); + continue; - } + } - if ( currentValue && currentValue.isColor ) { + if ( currentValue && currentValue.isColor ) { - currentValue.set( newValue ); + currentValue.set( newValue ); - } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) { + } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) { - currentValue.copy( newValue ); + currentValue.copy( newValue ); - } else if ( key === 'overdraw' ) { + } else if ( key === 'overdraw' ) { - // ensure overdraw is backwards-compatible with legacy boolean type - this[ key ] = Number( newValue ); + // ensure overdraw is backwards-compatible with legacy boolean type + this[ key ] = Number( newValue ); - } else { + } else { - this[ key ] = newValue; + this[ key ] = newValue; - } + } - } + } - }, + }, - toJSON: function ( meta ) { + toJSON: function ( meta ) { - var isRoot = ( meta === undefined || typeof meta === 'string' ); + var isRoot = ( meta === undefined || typeof meta === 'string' ); - if ( isRoot ) { + if ( isRoot ) { - meta = { - textures: {}, - images: {} - }; + meta = { + textures: {}, + images: {} + }; - } + } - var data = { - metadata: { - version: 4.5, - type: 'Material', - generator: 'Material.toJSON' - } - }; + var data = { + metadata: { + version: 4.5, + type: 'Material', + generator: 'Material.toJSON' + } + }; - // standard Material serialization - data.uuid = this.uuid; - data.type = this.type; + // standard Material serialization + data.uuid = this.uuid; + data.type = this.type; - if ( this.name !== '' ) data.name = this.name; + if ( this.name !== '' ) data.name = this.name; - if ( this.color && this.color.isColor ) data.color = this.color.getHex(); + if ( this.color && this.color.isColor ) data.color = this.color.getHex(); - if ( this.roughness !== undefined ) data.roughness = this.roughness; - if ( this.metalness !== undefined ) data.metalness = this.metalness; + if ( this.roughness !== undefined ) data.roughness = this.roughness; + if ( this.metalness !== undefined ) data.metalness = this.metalness; - if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); - if ( this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; + if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); + if ( this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; - if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); - if ( this.shininess !== undefined ) data.shininess = this.shininess; - if ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat; - if ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness; + if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); + if ( this.shininess !== undefined ) data.shininess = this.shininess; + if ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat; + if ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness; - if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid; - if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid; - if ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid; + if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid; + if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid; + if ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid; - if ( this.aoMap && this.aoMap.isTexture ) { + if ( this.aoMap && this.aoMap.isTexture ) { - data.aoMap = this.aoMap.toJSON( meta ).uuid; - data.aoMapIntensity = this.aoMapIntensity; + data.aoMap = this.aoMap.toJSON( meta ).uuid; + data.aoMapIntensity = this.aoMapIntensity; - } + } - if ( this.bumpMap && this.bumpMap.isTexture ) { + if ( this.bumpMap && this.bumpMap.isTexture ) { - data.bumpMap = this.bumpMap.toJSON( meta ).uuid; - data.bumpScale = this.bumpScale; + data.bumpMap = this.bumpMap.toJSON( meta ).uuid; + data.bumpScale = this.bumpScale; - } + } - if ( this.normalMap && this.normalMap.isTexture ) { + if ( this.normalMap && this.normalMap.isTexture ) { - data.normalMap = this.normalMap.toJSON( meta ).uuid; - data.normalMapType = this.normalMapType; - data.normalScale = this.normalScale.toArray(); + data.normalMap = this.normalMap.toJSON( meta ).uuid; + data.normalMapType = this.normalMapType; + data.normalScale = this.normalScale.toArray(); - } + } - if ( this.displacementMap && this.displacementMap.isTexture ) { + if ( this.displacementMap && this.displacementMap.isTexture ) { - data.displacementMap = this.displacementMap.toJSON( meta ).uuid; - data.displacementScale = this.displacementScale; - data.displacementBias = this.displacementBias; + data.displacementMap = this.displacementMap.toJSON( meta ).uuid; + data.displacementScale = this.displacementScale; + data.displacementBias = this.displacementBias; - } + } - if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; - if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; + if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; + if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; - if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; - if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid; + if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; + if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid; - if ( this.envMap && this.envMap.isTexture ) { + if ( this.envMap && this.envMap.isTexture ) { - data.envMap = this.envMap.toJSON( meta ).uuid; - data.reflectivity = this.reflectivity; // Scale behind envMap + data.envMap = this.envMap.toJSON( meta ).uuid; + data.reflectivity = this.reflectivity; // Scale behind envMap - } + } - if ( this.gradientMap && this.gradientMap.isTexture ) { + if ( this.gradientMap && this.gradientMap.isTexture ) { - data.gradientMap = this.gradientMap.toJSON( meta ).uuid; + data.gradientMap = this.gradientMap.toJSON( meta ).uuid; - } + } - if ( this.size !== undefined ) data.size = this.size; - if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation; + if ( this.size !== undefined ) data.size = this.size; + if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation; - if ( this.blending !== NormalBlending ) data.blending = this.blending; - if ( this.flatShading === true ) data.flatShading = this.flatShading; - if ( this.side !== FrontSide ) data.side = this.side; - if ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors; + if ( this.blending !== NormalBlending ) data.blending = this.blending; + if ( this.flatShading === true ) data.flatShading = this.flatShading; + if ( this.side !== FrontSide ) data.side = this.side; + if ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors; - if ( this.opacity < 1 ) data.opacity = this.opacity; - if ( this.transparent === true ) data.transparent = this.transparent; + if ( this.opacity < 1 ) data.opacity = this.opacity; + if ( this.transparent === true ) data.transparent = this.transparent; - data.depthFunc = this.depthFunc; - data.depthTest = this.depthTest; - data.depthWrite = this.depthWrite; + data.depthFunc = this.depthFunc; + data.depthTest = this.depthTest; + data.depthWrite = this.depthWrite; - // rotation (SpriteMaterial) - if ( this.rotation !== 0 ) data.rotation = this.rotation; + // rotation (SpriteMaterial) + if ( this.rotation !== 0 ) data.rotation = this.rotation; - if ( this.linewidth !== 1 ) data.linewidth = this.linewidth; - if ( this.dashSize !== undefined ) data.dashSize = this.dashSize; - if ( this.gapSize !== undefined ) data.gapSize = this.gapSize; - if ( this.scale !== undefined ) data.scale = this.scale; + if ( this.linewidth !== 1 ) data.linewidth = this.linewidth; + if ( this.dashSize !== undefined ) data.dashSize = this.dashSize; + if ( this.gapSize !== undefined ) data.gapSize = this.gapSize; + if ( this.scale !== undefined ) data.scale = this.scale; - if ( this.dithering === true ) data.dithering = true; + if ( this.dithering === true ) data.dithering = true; - if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; - if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha; + if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; + if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha; - if ( this.wireframe === true ) data.wireframe = this.wireframe; - if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; - if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap; - if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin; + if ( this.wireframe === true ) data.wireframe = this.wireframe; + if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; + if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap; + if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin; - if ( this.morphTargets === true ) data.morphTargets = true; - if ( this.skinning === true ) data.skinning = true; + if ( this.morphTargets === true ) data.morphTargets = true; + if ( this.skinning === true ) data.skinning = true; - if ( this.visible === false ) data.visible = false; - if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData; + if ( this.visible === false ) data.visible = false; + if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData; - // TODO: Copied from Object3D.toJSON + // TODO: Copied from Object3D.toJSON - function extractFromCache( cache ) { + function extractFromCache( cache ) { - var values = []; + var values = []; - for ( var key in cache ) { + for ( var key in cache ) { - var data = cache[ key ]; - delete data.metadata; - values.push( data ); + var data = cache[ key ]; + delete data.metadata; + values.push( data ); - } + } - return values; + return values; - } + } - if ( isRoot ) { + if ( isRoot ) { - var textures = extractFromCache( meta.textures ); - var images = extractFromCache( meta.images ); + var textures = extractFromCache( meta.textures ); + var images = extractFromCache( meta.images ); - if ( textures.length > 0 ) data.textures = textures; - if ( images.length > 0 ) data.images = images; + if ( textures.length > 0 ) data.textures = textures; + if ( images.length > 0 ) data.images = images; - } + } - return data; + return data; - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( source ) { + copy: function ( source ) { - this.name = source.name; + this.name = source.name; - this.fog = source.fog; - this.lights = source.lights; + this.fog = source.fog; + this.lights = source.lights; - this.blending = source.blending; - this.side = source.side; - this.flatShading = source.flatShading; - this.vertexColors = source.vertexColors; + this.blending = source.blending; + this.side = source.side; + this.flatShading = source.flatShading; + this.vertexColors = source.vertexColors; - this.opacity = source.opacity; - this.transparent = source.transparent; + this.opacity = source.opacity; + this.transparent = source.transparent; - this.blendSrc = source.blendSrc; - this.blendDst = source.blendDst; - this.blendEquation = source.blendEquation; - this.blendSrcAlpha = source.blendSrcAlpha; - this.blendDstAlpha = source.blendDstAlpha; - this.blendEquationAlpha = source.blendEquationAlpha; + this.blendSrc = source.blendSrc; + this.blendDst = source.blendDst; + this.blendEquation = source.blendEquation; + this.blendSrcAlpha = source.blendSrcAlpha; + this.blendDstAlpha = source.blendDstAlpha; + this.blendEquationAlpha = source.blendEquationAlpha; - this.depthFunc = source.depthFunc; - this.depthTest = source.depthTest; - this.depthWrite = source.depthWrite; + this.depthFunc = source.depthFunc; + this.depthTest = source.depthTest; + this.depthWrite = source.depthWrite; - this.colorWrite = source.colorWrite; + this.colorWrite = source.colorWrite; - this.precision = source.precision; + this.precision = source.precision; - this.polygonOffset = source.polygonOffset; - this.polygonOffsetFactor = source.polygonOffsetFactor; - this.polygonOffsetUnits = source.polygonOffsetUnits; + this.polygonOffset = source.polygonOffset; + this.polygonOffsetFactor = source.polygonOffsetFactor; + this.polygonOffsetUnits = source.polygonOffsetUnits; - this.dithering = source.dithering; + this.dithering = source.dithering; - this.alphaTest = source.alphaTest; - this.premultipliedAlpha = source.premultipliedAlpha; + this.alphaTest = source.alphaTest; + this.premultipliedAlpha = source.premultipliedAlpha; - this.overdraw = source.overdraw; + this.overdraw = source.overdraw; - this.visible = source.visible; - this.userData = JSON.parse( JSON.stringify( source.userData ) ); + this.visible = source.visible; + this.userData = JSON.parse( JSON.stringify( source.userData ) ); - this.clipShadows = source.clipShadows; - this.clipIntersection = source.clipIntersection; + this.clipShadows = source.clipShadows; + this.clipIntersection = source.clipIntersection; - var srcPlanes = source.clippingPlanes, - dstPlanes = null; + var srcPlanes = source.clippingPlanes, + dstPlanes = null; - if ( srcPlanes !== null ) { + if ( srcPlanes !== null ) { - var n = srcPlanes.length; - dstPlanes = new Array( n ); + var n = srcPlanes.length; + dstPlanes = new Array( n ); - for ( var i = 0; i !== n; ++ i ) - dstPlanes[ i ] = srcPlanes[ i ].clone(); + for ( var i = 0; i !== n; ++ i ) + dstPlanes[ i ] = srcPlanes[ i ].clone(); - } + } - this.clippingPlanes = dstPlanes; + this.clippingPlanes = dstPlanes; - this.shadowSide = source.shadowSide; + this.shadowSide = source.shadowSide; - return this; + return this; - }, + }, - dispose: function () { + dispose: function () { - this.dispatchEvent( { type: 'dispose' } ); + this.dispatchEvent( { type: 'dispose' } ); - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * opacity: , - * map: new THREE.Texture( ), - * - * lightMap: new THREE.Texture( ), - * lightMapIntensity: - * - * aoMap: new THREE.Texture( ), - * aoMapIntensity: - * - * specularMap: new THREE.Texture( ), - * - * alphaMap: new THREE.Texture( ), - * - * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), - * combine: THREE.Multiply, - * reflectivity: , - * refractionRatio: , - * - * depthTest: , - * depthWrite: , - * - * wireframe: , - * wireframeLinewidth: , - * - * skinning: , - * morphTargets: - * } - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * + * parameters = { + * color: , + * opacity: , + * map: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * specularMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), + * combine: THREE.Multiply, + * reflectivity: , + * refractionRatio: , + * + * depthTest: , + * depthWrite: , + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: + * } + */ - function MeshBasicMaterial( parameters ) { + function MeshBasicMaterial( parameters ) { - Material.call( this ); + Material.call( this ); - this.type = 'MeshBasicMaterial'; + this.type = 'MeshBasicMaterial'; - this.color = new Color( 0xffffff ); // emissive + this.color = new Color( 0xffffff ); // emissive - this.map = null; + this.map = null; - this.lightMap = null; - this.lightMapIntensity = 1.0; + this.lightMap = null; + this.lightMapIntensity = 1.0; - this.aoMap = null; - this.aoMapIntensity = 1.0; + this.aoMap = null; + this.aoMapIntensity = 1.0; - this.specularMap = null; + this.specularMap = null; - this.alphaMap = null; + this.alphaMap = null; - this.envMap = null; - this.combine = MultiplyOperation; - this.reflectivity = 1; - this.refractionRatio = 0.98; + this.envMap = null; + this.combine = MultiplyOperation; + this.reflectivity = 1; + this.refractionRatio = 0.98; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; - this.skinning = false; - this.morphTargets = false; + this.skinning = false; + this.morphTargets = false; - this.lights = false; + this.lights = false; - this.setValues( parameters ); + this.setValues( parameters ); - } + } - MeshBasicMaterial.prototype = Object.create( Material.prototype ); - MeshBasicMaterial.prototype.constructor = MeshBasicMaterial; + MeshBasicMaterial.prototype = Object.create( Material.prototype ); + MeshBasicMaterial.prototype.constructor = MeshBasicMaterial; - MeshBasicMaterial.prototype.isMeshBasicMaterial = true; + MeshBasicMaterial.prototype.isMeshBasicMaterial = true; - MeshBasicMaterial.prototype.copy = function ( source ) { + MeshBasicMaterial.prototype.copy = function ( source ) { - Material.prototype.copy.call( this, source ); + Material.prototype.copy.call( this, source ); - this.color.copy( source.color ); + this.color.copy( source.color ); - this.map = source.map; + this.map = source.map; - this.lightMap = source.lightMap; - this.lightMapIntensity = source.lightMapIntensity; + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; - this.aoMap = source.aoMap; - this.aoMapIntensity = source.aoMapIntensity; + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; - this.specularMap = source.specularMap; + this.specularMap = source.specularMap; - this.alphaMap = source.alphaMap; + this.alphaMap = source.alphaMap; - this.envMap = source.envMap; - this.combine = source.combine; - this.reflectivity = source.reflectivity; - this.refractionRatio = source.refractionRatio; + this.envMap = source.envMap; + this.combine = source.combine; + this.reflectivity = source.reflectivity; + this.refractionRatio = source.refractionRatio; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.wireframeLinecap = source.wireframeLinecap; - this.wireframeLinejoin = source.wireframeLinejoin; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; - this.skinning = source.skinning; - this.morphTargets = source.morphTargets; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; - return this; + return this; - }; + }; - /** - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * defines: { "label" : "value" }, - * uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } }, - * - * fragmentShader: , - * vertexShader: , - * - * wireframe: , - * wireframeLinewidth: , - * - * lights: , - * - * skinning: , - * morphTargets: , - * morphNormals: - * } - */ + /** + * @author alteredq / http://alteredqualia.com/ + * + * parameters = { + * defines: { "label" : "value" }, + * uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } }, + * + * fragmentShader: , + * vertexShader: , + * + * wireframe: , + * wireframeLinewidth: , + * + * lights: , + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ - function ShaderMaterial( parameters ) { + function ShaderMaterial( parameters ) { - Material.call( this ); + Material.call( this ); - this.type = 'ShaderMaterial'; + this.type = 'ShaderMaterial'; - this.defines = {}; - this.uniforms = {}; + this.defines = {}; + this.uniforms = {}; - this.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}'; - this.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}'; + this.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}'; + this.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}'; - this.linewidth = 1; + this.linewidth = 1; - this.wireframe = false; - this.wireframeLinewidth = 1; + this.wireframe = false; + this.wireframeLinewidth = 1; - this.fog = false; // set to use scene fog - this.lights = false; // set to use scene lights - this.clipping = false; // set to use user-defined clipping planes + this.fog = false; // set to use scene fog + this.lights = false; // set to use scene lights + this.clipping = false; // set to use user-defined clipping planes - this.skinning = false; // set to use skinning attribute streams - this.morphTargets = false; // set to use morph targets - this.morphNormals = false; // set to use morph normals + this.skinning = false; // set to use skinning attribute streams + this.morphTargets = false; // set to use morph targets + this.morphNormals = false; // set to use morph normals - this.extensions = { - derivatives: false, // set to use derivatives - fragDepth: false, // set to use fragment depth values - drawBuffers: false, // set to use draw buffers - shaderTextureLOD: false // set to use shader texture LOD - }; + this.extensions = { + derivatives: false, // set to use derivatives + fragDepth: false, // set to use fragment depth values + drawBuffers: false, // set to use draw buffers + shaderTextureLOD: false // set to use shader texture LOD + }; - // When rendered geometry doesn't include these attributes but the material does, - // use these default values in WebGL. This avoids errors when buffer data is missing. - this.defaultAttributeValues = { - 'color': [ 1, 1, 1 ], - 'uv': [ 0, 0 ], - 'uv2': [ 0, 0 ] - }; + // When rendered geometry doesn't include these attributes but the material does, + // use these default values in WebGL. This avoids errors when buffer data is missing. + this.defaultAttributeValues = { + 'color': [ 1, 1, 1 ], + 'uv': [ 0, 0 ], + 'uv2': [ 0, 0 ] + }; - this.index0AttributeName = undefined; - this.uniformsNeedUpdate = false; + this.index0AttributeName = undefined; + this.uniformsNeedUpdate = false; - if ( parameters !== undefined ) { + if ( parameters !== undefined ) { - if ( parameters.attributes !== undefined ) { + if ( parameters.attributes !== undefined ) { - console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' ); + console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' ); - } + } - this.setValues( parameters ); + this.setValues( parameters ); - } + } - } + } - ShaderMaterial.prototype = Object.create( Material.prototype ); - ShaderMaterial.prototype.constructor = ShaderMaterial; + ShaderMaterial.prototype = Object.create( Material.prototype ); + ShaderMaterial.prototype.constructor = ShaderMaterial; - ShaderMaterial.prototype.isShaderMaterial = true; + ShaderMaterial.prototype.isShaderMaterial = true; - ShaderMaterial.prototype.copy = function ( source ) { + ShaderMaterial.prototype.copy = function ( source ) { - Material.prototype.copy.call( this, source ); + Material.prototype.copy.call( this, source ); - this.fragmentShader = source.fragmentShader; - this.vertexShader = source.vertexShader; + this.fragmentShader = source.fragmentShader; + this.vertexShader = source.vertexShader; - this.uniforms = UniformsUtils.clone( source.uniforms ); + this.uniforms = UniformsUtils.clone( source.uniforms ); - this.defines = Object.assign( {}, source.defines ); + this.defines = Object.assign( {}, source.defines ); - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; - this.lights = source.lights; - this.clipping = source.clipping; + this.lights = source.lights; + this.clipping = source.clipping; - this.skinning = source.skinning; + this.skinning = source.skinning; - this.morphTargets = source.morphTargets; - this.morphNormals = source.morphNormals; + this.morphTargets = source.morphTargets; + this.morphNormals = source.morphNormals; - this.extensions = source.extensions; + this.extensions = source.extensions; - return this; + return this; - }; + }; - ShaderMaterial.prototype.toJSON = function ( meta ) { + ShaderMaterial.prototype.toJSON = function ( meta ) { - var data = Material.prototype.toJSON.call( this, meta ); + var data = Material.prototype.toJSON.call( this, meta ); - data.uniforms = this.uniforms; - data.vertexShader = this.vertexShader; - data.fragmentShader = this.fragmentShader; + data.uniforms = this.uniforms; + data.vertexShader = this.vertexShader; + data.fragmentShader = this.fragmentShader; - return data; + return data; - }; + }; - /** - * @author bhouston / http://clara.io - */ + /** + * @author bhouston / http://clara.io + */ - function Ray( origin, direction ) { + function Ray( origin, direction ) { - this.origin = ( origin !== undefined ) ? origin : new Vector3(); - this.direction = ( direction !== undefined ) ? direction : new Vector3(); + this.origin = ( origin !== undefined ) ? origin : new Vector3(); + this.direction = ( direction !== undefined ) ? direction : new Vector3(); - } + } - Object.assign( Ray.prototype, { + Object.assign( Ray.prototype, { - set: function ( origin, direction ) { + set: function ( origin, direction ) { - this.origin.copy( origin ); - this.direction.copy( direction ); + this.origin.copy( origin ); + this.direction.copy( direction ); - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( ray ) { + copy: function ( ray ) { - this.origin.copy( ray.origin ); - this.direction.copy( ray.direction ); + this.origin.copy( ray.origin ); + this.direction.copy( ray.direction ); - return this; + return this; - }, + }, - at: function ( t, target ) { + at: function ( t, target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Ray: .at() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Ray: .at() target is now required' ); + target = new Vector3(); - } + } - return target.copy( this.direction ).multiplyScalar( t ).add( this.origin ); + return target.copy( this.direction ).multiplyScalar( t ).add( this.origin ); - }, + }, - lookAt: function ( v ) { + lookAt: function ( v ) { - this.direction.copy( v ).sub( this.origin ).normalize(); + this.direction.copy( v ).sub( this.origin ).normalize(); - return this; + return this; - }, + }, - recast: function () { + recast: function () { - var v1 = new Vector3(); + var v1 = new Vector3(); - return function recast( t ) { + return function recast( t ) { - this.origin.copy( this.at( t, v1 ) ); + this.origin.copy( this.at( t, v1 ) ); - return this; + return this; - }; + }; - }(), + }(), - closestPointToPoint: function ( point, target ) { + closestPointToPoint: function ( point, target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Ray: .closestPointToPoint() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Ray: .closestPointToPoint() target is now required' ); + target = new Vector3(); - } + } - target.subVectors( point, this.origin ); + target.subVectors( point, this.origin ); - var directionDistance = target.dot( this.direction ); + var directionDistance = target.dot( this.direction ); - if ( directionDistance < 0 ) { + if ( directionDistance < 0 ) { - return target.copy( this.origin ); + return target.copy( this.origin ); - } + } - return target.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); + return target.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); - }, + }, - distanceToPoint: function ( point ) { + distanceToPoint: function ( point ) { - return Math.sqrt( this.distanceSqToPoint( point ) ); + return Math.sqrt( this.distanceSqToPoint( point ) ); - }, + }, - distanceSqToPoint: function () { + distanceSqToPoint: function () { - var v1 = new Vector3(); + var v1 = new Vector3(); - return function distanceSqToPoint( point ) { + return function distanceSqToPoint( point ) { - var directionDistance = v1.subVectors( point, this.origin ).dot( this.direction ); + var directionDistance = v1.subVectors( point, this.origin ).dot( this.direction ); - // point behind the ray + // point behind the ray - if ( directionDistance < 0 ) { + if ( directionDistance < 0 ) { - return this.origin.distanceToSquared( point ); + return this.origin.distanceToSquared( point ); - } + } - v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); + v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); - return v1.distanceToSquared( point ); + return v1.distanceToSquared( point ); - }; + }; - }(), + }(), - distanceSqToSegment: function () { + distanceSqToSegment: function () { - var segCenter = new Vector3(); - var segDir = new Vector3(); - var diff = new Vector3(); + var segCenter = new Vector3(); + var segDir = new Vector3(); + var diff = new Vector3(); - return function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { + return function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { - // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h - // It returns the min distance between the ray and the segment - // defined by v0 and v1 - // It can also set two optional targets : - // - The closest point on the ray - // - The closest point on the segment + // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h + // It returns the min distance between the ray and the segment + // defined by v0 and v1 + // It can also set two optional targets : + // - The closest point on the ray + // - The closest point on the segment - segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 ); - segDir.copy( v1 ).sub( v0 ).normalize(); - diff.copy( this.origin ).sub( segCenter ); + segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 ); + segDir.copy( v1 ).sub( v0 ).normalize(); + diff.copy( this.origin ).sub( segCenter ); - var segExtent = v0.distanceTo( v1 ) * 0.5; - var a01 = - this.direction.dot( segDir ); - var b0 = diff.dot( this.direction ); - var b1 = - diff.dot( segDir ); - var c = diff.lengthSq(); - var det = Math.abs( 1 - a01 * a01 ); - var s0, s1, sqrDist, extDet; + var segExtent = v0.distanceTo( v1 ) * 0.5; + var a01 = - this.direction.dot( segDir ); + var b0 = diff.dot( this.direction ); + var b1 = - diff.dot( segDir ); + var c = diff.lengthSq(); + var det = Math.abs( 1 - a01 * a01 ); + var s0, s1, sqrDist, extDet; - if ( det > 0 ) { + if ( det > 0 ) { - // The ray and segment are not parallel. + // The ray and segment are not parallel. - s0 = a01 * b1 - b0; - s1 = a01 * b0 - b1; - extDet = segExtent * det; + s0 = a01 * b1 - b0; + s1 = a01 * b0 - b1; + extDet = segExtent * det; - if ( s0 >= 0 ) { + if ( s0 >= 0 ) { - if ( s1 >= - extDet ) { + if ( s1 >= - extDet ) { - if ( s1 <= extDet ) { + if ( s1 <= extDet ) { - // region 0 - // Minimum at interior points of ray and segment. + // region 0 + // Minimum at interior points of ray and segment. - var invDet = 1 / det; - s0 *= invDet; - s1 *= invDet; - sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c; + var invDet = 1 / det; + s0 *= invDet; + s1 *= invDet; + sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c; - } else { + } else { - // region 1 + // region 1 - s1 = segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + s1 = segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - } + } - } else { + } else { - // region 5 + // region 5 - s1 = - segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + s1 = - segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - } + } - } else { + } else { - if ( s1 <= - extDet ) { + if ( s1 <= - extDet ) { - // region 4 + // region 4 - s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) ); - s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) ); + s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - } else if ( s1 <= extDet ) { + } else if ( s1 <= extDet ) { - // region 3 + // region 3 - s0 = 0; - s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = s1 * ( s1 + 2 * b1 ) + c; + s0 = 0; + s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = s1 * ( s1 + 2 * b1 ) + c; - } else { + } else { - // region 2 + // region 2 - s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); - s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); + s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - } + } - } + } - } else { + } else { - // Ray and segment are parallel. + // Ray and segment are parallel. - s1 = ( a01 > 0 ) ? - segExtent : segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + s1 = ( a01 > 0 ) ? - segExtent : segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - } + } - if ( optionalPointOnRay ) { + if ( optionalPointOnRay ) { - optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin ); + optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin ); - } + } - if ( optionalPointOnSegment ) { + if ( optionalPointOnSegment ) { - optionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter ); + optionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter ); - } + } - return sqrDist; + return sqrDist; - }; + }; - }(), + }(), - intersectSphere: function () { + intersectSphere: function () { - var v1 = new Vector3(); + var v1 = new Vector3(); - return function intersectSphere( sphere, target ) { + return function intersectSphere( sphere, target ) { - v1.subVectors( sphere.center, this.origin ); - var tca = v1.dot( this.direction ); - var d2 = v1.dot( v1 ) - tca * tca; - var radius2 = sphere.radius * sphere.radius; + v1.subVectors( sphere.center, this.origin ); + var tca = v1.dot( this.direction ); + var d2 = v1.dot( v1 ) - tca * tca; + var radius2 = sphere.radius * sphere.radius; - if ( d2 > radius2 ) return null; + if ( d2 > radius2 ) return null; - var thc = Math.sqrt( radius2 - d2 ); + var thc = Math.sqrt( radius2 - d2 ); - // t0 = first intersect point - entrance on front of sphere - var t0 = tca - thc; + // t0 = first intersect point - entrance on front of sphere + var t0 = tca - thc; - // t1 = second intersect point - exit point on back of sphere - var t1 = tca + thc; + // t1 = second intersect point - exit point on back of sphere + var t1 = tca + thc; - // test to see if both t0 and t1 are behind the ray - if so, return null - if ( t0 < 0 && t1 < 0 ) return null; + // test to see if both t0 and t1 are behind the ray - if so, return null + if ( t0 < 0 && t1 < 0 ) return null; - // test to see if t0 is behind the ray: - // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, - // in order to always return an intersect point that is in front of the ray. - if ( t0 < 0 ) return this.at( t1, target ); + // test to see if t0 is behind the ray: + // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, + // in order to always return an intersect point that is in front of the ray. + if ( t0 < 0 ) return this.at( t1, target ); - // else t0 is in front of the ray, so return the first collision point scaled by t0 - return this.at( t0, target ); + // else t0 is in front of the ray, so return the first collision point scaled by t0 + return this.at( t0, target ); - }; + }; - }(), + }(), - intersectsSphere: function ( sphere ) { + intersectsSphere: function ( sphere ) { - return this.distanceToPoint( sphere.center ) <= sphere.radius; + return this.distanceToPoint( sphere.center ) <= sphere.radius; - }, + }, - distanceToPlane: function ( plane ) { + distanceToPlane: function ( plane ) { - var denominator = plane.normal.dot( this.direction ); + var denominator = plane.normal.dot( this.direction ); - if ( denominator === 0 ) { + if ( denominator === 0 ) { - // line is coplanar, return origin - if ( plane.distanceToPoint( this.origin ) === 0 ) { + // line is coplanar, return origin + if ( plane.distanceToPoint( this.origin ) === 0 ) { - return 0; + return 0; - } + } - // Null is preferable to undefined since undefined means.... it is undefined + // Null is preferable to undefined since undefined means.... it is undefined - return null; + return null; - } + } - var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator; + var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator; - // Return if the ray never intersects the plane + // Return if the ray never intersects the plane - return t >= 0 ? t : null; + return t >= 0 ? t : null; - }, + }, - intersectPlane: function ( plane, target ) { + intersectPlane: function ( plane, target ) { - var t = this.distanceToPlane( plane ); + var t = this.distanceToPlane( plane ); - if ( t === null ) { + if ( t === null ) { - return null; + return null; - } + } - return this.at( t, target ); + return this.at( t, target ); - }, + }, - intersectsPlane: function ( plane ) { + intersectsPlane: function ( plane ) { - // check if the ray lies on the plane first + // check if the ray lies on the plane first - var distToPoint = plane.distanceToPoint( this.origin ); + var distToPoint = plane.distanceToPoint( this.origin ); - if ( distToPoint === 0 ) { + if ( distToPoint === 0 ) { - return true; + return true; - } + } - var denominator = plane.normal.dot( this.direction ); + var denominator = plane.normal.dot( this.direction ); - if ( denominator * distToPoint < 0 ) { + if ( denominator * distToPoint < 0 ) { - return true; + return true; - } + } - // ray origin is behind the plane (and is pointing behind it) + // ray origin is behind the plane (and is pointing behind it) - return false; + return false; - }, + }, - intersectBox: function ( box, target ) { + intersectBox: function ( box, target ) { - var tmin, tmax, tymin, tymax, tzmin, tzmax; + var tmin, tmax, tymin, tymax, tzmin, tzmax; - var invdirx = 1 / this.direction.x, - invdiry = 1 / this.direction.y, - invdirz = 1 / this.direction.z; + var invdirx = 1 / this.direction.x, + invdiry = 1 / this.direction.y, + invdirz = 1 / this.direction.z; - var origin = this.origin; + var origin = this.origin; - if ( invdirx >= 0 ) { + if ( invdirx >= 0 ) { - tmin = ( box.min.x - origin.x ) * invdirx; - tmax = ( box.max.x - origin.x ) * invdirx; + tmin = ( box.min.x - origin.x ) * invdirx; + tmax = ( box.max.x - origin.x ) * invdirx; - } else { + } else { - tmin = ( box.max.x - origin.x ) * invdirx; - tmax = ( box.min.x - origin.x ) * invdirx; + tmin = ( box.max.x - origin.x ) * invdirx; + tmax = ( box.min.x - origin.x ) * invdirx; - } + } - if ( invdiry >= 0 ) { + if ( invdiry >= 0 ) { - tymin = ( box.min.y - origin.y ) * invdiry; - tymax = ( box.max.y - origin.y ) * invdiry; + tymin = ( box.min.y - origin.y ) * invdiry; + tymax = ( box.max.y - origin.y ) * invdiry; - } else { + } else { - tymin = ( box.max.y - origin.y ) * invdiry; - tymax = ( box.min.y - origin.y ) * invdiry; + tymin = ( box.max.y - origin.y ) * invdiry; + tymax = ( box.min.y - origin.y ) * invdiry; - } + } - if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null; + if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null; - // These lines also handle the case where tmin or tmax is NaN - // (result of 0 * Infinity). x !== x returns true if x is NaN + // These lines also handle the case where tmin or tmax is NaN + // (result of 0 * Infinity). x !== x returns true if x is NaN - if ( tymin > tmin || tmin !== tmin ) tmin = tymin; + if ( tymin > tmin || tmin !== tmin ) tmin = tymin; - if ( tymax < tmax || tmax !== tmax ) tmax = tymax; + if ( tymax < tmax || tmax !== tmax ) tmax = tymax; - if ( invdirz >= 0 ) { + if ( invdirz >= 0 ) { - tzmin = ( box.min.z - origin.z ) * invdirz; - tzmax = ( box.max.z - origin.z ) * invdirz; + tzmin = ( box.min.z - origin.z ) * invdirz; + tzmax = ( box.max.z - origin.z ) * invdirz; - } else { + } else { - tzmin = ( box.max.z - origin.z ) * invdirz; - tzmax = ( box.min.z - origin.z ) * invdirz; + tzmin = ( box.max.z - origin.z ) * invdirz; + tzmax = ( box.min.z - origin.z ) * invdirz; - } + } - if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null; + if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null; - if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin; + if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin; - if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax; + if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax; - //return point closest to the ray (positive side) + //return point closest to the ray (positive side) - if ( tmax < 0 ) return null; + if ( tmax < 0 ) return null; - return this.at( tmin >= 0 ? tmin : tmax, target ); + return this.at( tmin >= 0 ? tmin : tmax, target ); - }, + }, - intersectsBox: ( function () { + intersectsBox: ( function () { - var v = new Vector3(); + var v = new Vector3(); - return function intersectsBox( box ) { + return function intersectsBox( box ) { - return this.intersectBox( box, v ) !== null; + return this.intersectBox( box, v ) !== null; - }; + }; - } )(), + } )(), - intersectTriangle: function () { + intersectTriangle: function () { - // Compute the offset origin, edges, and normal. - var diff = new Vector3(); - var edge1 = new Vector3(); - var edge2 = new Vector3(); - var normal = new Vector3(); + // Compute the offset origin, edges, and normal. + var diff = new Vector3(); + var edge1 = new Vector3(); + var edge2 = new Vector3(); + var normal = new Vector3(); - return function intersectTriangle( a, b, c, backfaceCulling, target ) { + return function intersectTriangle( a, b, c, backfaceCulling, target ) { - // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h + // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h - edge1.subVectors( b, a ); - edge2.subVectors( c, a ); - normal.crossVectors( edge1, edge2 ); + edge1.subVectors( b, a ); + edge2.subVectors( c, a ); + normal.crossVectors( edge1, edge2 ); - // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, - // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by - // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) - // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) - // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) - var DdN = this.direction.dot( normal ); - var sign; + // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, + // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by + // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) + // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) + // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) + var DdN = this.direction.dot( normal ); + var sign; - if ( DdN > 0 ) { + if ( DdN > 0 ) { - if ( backfaceCulling ) return null; - sign = 1; + if ( backfaceCulling ) return null; + sign = 1; - } else if ( DdN < 0 ) { + } else if ( DdN < 0 ) { - sign = - 1; - DdN = - DdN; + sign = - 1; + DdN = - DdN; - } else { + } else { - return null; + return null; - } + } - diff.subVectors( this.origin, a ); - var DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) ); + diff.subVectors( this.origin, a ); + var DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) ); - // b1 < 0, no intersection - if ( DdQxE2 < 0 ) { + // b1 < 0, no intersection + if ( DdQxE2 < 0 ) { - return null; + return null; - } + } - var DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) ); + var DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) ); - // b2 < 0, no intersection - if ( DdE1xQ < 0 ) { + // b2 < 0, no intersection + if ( DdE1xQ < 0 ) { - return null; + return null; - } + } - // b1+b2 > 1, no intersection - if ( DdQxE2 + DdE1xQ > DdN ) { + // b1+b2 > 1, no intersection + if ( DdQxE2 + DdE1xQ > DdN ) { - return null; + return null; - } + } - // Line intersects triangle, check if ray does. - var QdN = - sign * diff.dot( normal ); + // Line intersects triangle, check if ray does. + var QdN = - sign * diff.dot( normal ); - // t < 0, no intersection - if ( QdN < 0 ) { + // t < 0, no intersection + if ( QdN < 0 ) { - return null; + return null; - } + } - // Ray intersects triangle. - return this.at( QdN / DdN, target ); + // Ray intersects triangle. + return this.at( QdN / DdN, target ); - }; + }; - }(), + }(), - applyMatrix4: function ( matrix4 ) { + applyMatrix4: function ( matrix4 ) { - this.origin.applyMatrix4( matrix4 ); - this.direction.transformDirection( matrix4 ); + this.origin.applyMatrix4( matrix4 ); + this.direction.transformDirection( matrix4 ); - return this; + return this; - }, + }, - equals: function ( ray ) { + equals: function ( ray ) { - return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction ); + return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction ); - } + } - } ); + } ); - /** - * @author bhouston / http://clara.io - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author bhouston / http://clara.io + * @author mrdoob / http://mrdoob.com/ + */ - function Triangle( a, b, c ) { + function Triangle( a, b, c ) { - this.a = ( a !== undefined ) ? a : new Vector3(); - this.b = ( b !== undefined ) ? b : new Vector3(); - this.c = ( c !== undefined ) ? c : new Vector3(); + this.a = ( a !== undefined ) ? a : new Vector3(); + this.b = ( b !== undefined ) ? b : new Vector3(); + this.c = ( c !== undefined ) ? c : new Vector3(); - } + } - Object.assign( Triangle, { + Object.assign( Triangle, { - getNormal: function () { + getNormal: function () { - var v0 = new Vector3(); + var v0 = new Vector3(); - return function getNormal( a, b, c, target ) { + return function getNormal( a, b, c, target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Triangle: .getNormal() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Triangle: .getNormal() target is now required' ); + target = new Vector3(); - } + } - target.subVectors( c, b ); - v0.subVectors( a, b ); - target.cross( v0 ); + target.subVectors( c, b ); + v0.subVectors( a, b ); + target.cross( v0 ); - var targetLengthSq = target.lengthSq(); - if ( targetLengthSq > 0 ) { + var targetLengthSq = target.lengthSq(); + if ( targetLengthSq > 0 ) { - return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); + return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); - } + } - return target.set( 0, 0, 0 ); + return target.set( 0, 0, 0 ); - }; + }; - }(), + }(), - // static/instance method to calculate barycentric coordinates - // based on: http://www.blackpawn.com/texts/pointinpoly/default.html - getBarycoord: function () { + // static/instance method to calculate barycentric coordinates + // based on: http://www.blackpawn.com/texts/pointinpoly/default.html + getBarycoord: function () { - var v0 = new Vector3(); - var v1 = new Vector3(); - var v2 = new Vector3(); + var v0 = new Vector3(); + var v1 = new Vector3(); + var v2 = new Vector3(); - return function getBarycoord( point, a, b, c, target ) { + return function getBarycoord( point, a, b, c, target ) { - v0.subVectors( c, a ); - v1.subVectors( b, a ); - v2.subVectors( point, a ); + v0.subVectors( c, a ); + v1.subVectors( b, a ); + v2.subVectors( point, a ); - var dot00 = v0.dot( v0 ); - var dot01 = v0.dot( v1 ); - var dot02 = v0.dot( v2 ); - var dot11 = v1.dot( v1 ); - var dot12 = v1.dot( v2 ); + var dot00 = v0.dot( v0 ); + var dot01 = v0.dot( v1 ); + var dot02 = v0.dot( v2 ); + var dot11 = v1.dot( v1 ); + var dot12 = v1.dot( v2 ); - var denom = ( dot00 * dot11 - dot01 * dot01 ); + var denom = ( dot00 * dot11 - dot01 * dot01 ); - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Triangle: .getBarycoord() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Triangle: .getBarycoord() target is now required' ); + target = new Vector3(); - } + } - // collinear or singular triangle - if ( denom === 0 ) { + // collinear or singular triangle + if ( denom === 0 ) { - // arbitrary location outside of triangle? - // not sure if this is the best idea, maybe should be returning undefined - return target.set( - 2, - 1, - 1 ); + // arbitrary location outside of triangle? + // not sure if this is the best idea, maybe should be returning undefined + return target.set( - 2, - 1, - 1 ); - } + } - var invDenom = 1 / denom; - var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; - var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; + var invDenom = 1 / denom; + var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; + var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; - // barycentric coordinates must always sum to 1 - return target.set( 1 - u - v, v, u ); + // barycentric coordinates must always sum to 1 + return target.set( 1 - u - v, v, u ); - }; + }; - }(), + }(), - containsPoint: function () { + containsPoint: function () { - var v1 = new Vector3(); + var v1 = new Vector3(); - return function containsPoint( point, a, b, c ) { + return function containsPoint( point, a, b, c ) { - Triangle.getBarycoord( point, a, b, c, v1 ); + Triangle.getBarycoord( point, a, b, c, v1 ); - return ( v1.x >= 0 ) && ( v1.y >= 0 ) && ( ( v1.x + v1.y ) <= 1 ); + return ( v1.x >= 0 ) && ( v1.y >= 0 ) && ( ( v1.x + v1.y ) <= 1 ); - }; + }; - }() + }() - } ); + } ); - Object.assign( Triangle.prototype, { + Object.assign( Triangle.prototype, { - set: function ( a, b, c ) { + set: function ( a, b, c ) { - this.a.copy( a ); - this.b.copy( b ); - this.c.copy( c ); + this.a.copy( a ); + this.b.copy( b ); + this.c.copy( c ); - return this; + return this; - }, + }, - setFromPointsAndIndices: function ( points, i0, i1, i2 ) { + setFromPointsAndIndices: function ( points, i0, i1, i2 ) { - this.a.copy( points[ i0 ] ); - this.b.copy( points[ i1 ] ); - this.c.copy( points[ i2 ] ); + this.a.copy( points[ i0 ] ); + this.b.copy( points[ i1 ] ); + this.c.copy( points[ i2 ] ); - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( triangle ) { + copy: function ( triangle ) { - this.a.copy( triangle.a ); - this.b.copy( triangle.b ); - this.c.copy( triangle.c ); + this.a.copy( triangle.a ); + this.b.copy( triangle.b ); + this.c.copy( triangle.c ); - return this; + return this; - }, + }, - getArea: function () { + getArea: function () { - var v0 = new Vector3(); - var v1 = new Vector3(); + var v0 = new Vector3(); + var v1 = new Vector3(); - return function getArea() { + return function getArea() { - v0.subVectors( this.c, this.b ); - v1.subVectors( this.a, this.b ); + v0.subVectors( this.c, this.b ); + v1.subVectors( this.a, this.b ); - return v0.cross( v1 ).length() * 0.5; + return v0.cross( v1 ).length() * 0.5; - }; + }; - }(), + }(), - getMidpoint: function ( target ) { + getMidpoint: function ( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Triangle: .getMidpoint() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Triangle: .getMidpoint() target is now required' ); + target = new Vector3(); - } + } - return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 ); + return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 ); - }, + }, - getNormal: function ( target ) { + getNormal: function ( target ) { - return Triangle.getNormal( this.a, this.b, this.c, target ); + return Triangle.getNormal( this.a, this.b, this.c, target ); - }, + }, - getPlane: function ( target ) { + getPlane: function ( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Triangle: .getPlane() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Triangle: .getPlane() target is now required' ); + target = new Vector3(); - } + } - return target.setFromCoplanarPoints( this.a, this.b, this.c ); + return target.setFromCoplanarPoints( this.a, this.b, this.c ); - }, + }, - getBarycoord: function ( point, target ) { + getBarycoord: function ( point, target ) { - return Triangle.getBarycoord( point, this.a, this.b, this.c, target ); + return Triangle.getBarycoord( point, this.a, this.b, this.c, target ); - }, + }, - containsPoint: function ( point ) { + containsPoint: function ( point ) { - return Triangle.containsPoint( point, this.a, this.b, this.c ); + return Triangle.containsPoint( point, this.a, this.b, this.c ); - }, + }, - intersectsBox: function ( box ) { + intersectsBox: function ( box ) { - return box.intersectsTriangle( this ); + return box.intersectsTriangle( this ); - }, + }, - closestPointToPoint: function () { + closestPointToPoint: function () { - var vab = new Vector3(); - var vac = new Vector3(); - var vbc = new Vector3(); - var vap = new Vector3(); - var vbp = new Vector3(); - var vcp = new Vector3(); + var vab = new Vector3(); + var vac = new Vector3(); + var vbc = new Vector3(); + var vap = new Vector3(); + var vbp = new Vector3(); + var vcp = new Vector3(); - return function closestPointToPoint( p, target ) { + return function closestPointToPoint( p, target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Triangle: .closestPointToPoint() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Triangle: .closestPointToPoint() target is now required' ); + target = new Vector3(); - } + } - var a = this.a, b = this.b, c = this.c; - var v, w; + var a = this.a, b = this.b, c = this.c; + var v, w; - // algorithm thanks to Real-Time Collision Detection by Christer Ericson, - // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc., - // under the accompanying license; see chapter 5.1.5 for detailed explanation. - // basically, we're distinguishing which of the voronoi regions of the triangle - // the point lies in with the minimum amount of redundant computation. + // algorithm thanks to Real-Time Collision Detection by Christer Ericson, + // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc., + // under the accompanying license; see chapter 5.1.5 for detailed explanation. + // basically, we're distinguishing which of the voronoi regions of the triangle + // the point lies in with the minimum amount of redundant computation. - vab.subVectors( b, a ); - vac.subVectors( c, a ); - vap.subVectors( p, a ); - var d1 = vab.dot( vap ); - var d2 = vac.dot( vap ); - if ( d1 <= 0 && d2 <= 0 ) { + vab.subVectors( b, a ); + vac.subVectors( c, a ); + vap.subVectors( p, a ); + var d1 = vab.dot( vap ); + var d2 = vac.dot( vap ); + if ( d1 <= 0 && d2 <= 0 ) { - // vertex region of A; barycentric coords (1, 0, 0) - return target.copy( a ); + // vertex region of A; barycentric coords (1, 0, 0) + return target.copy( a ); - } + } - vbp.subVectors( p, b ); - var d3 = vab.dot( vbp ); - var d4 = vac.dot( vbp ); - if ( d3 >= 0 && d4 <= d3 ) { + vbp.subVectors( p, b ); + var d3 = vab.dot( vbp ); + var d4 = vac.dot( vbp ); + if ( d3 >= 0 && d4 <= d3 ) { - // vertex region of B; barycentric coords (0, 1, 0) - return target.copy( b ); + // vertex region of B; barycentric coords (0, 1, 0) + return target.copy( b ); - } + } - var vc = d1 * d4 - d3 * d2; - if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) { + var vc = d1 * d4 - d3 * d2; + if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) { - v = d1 / ( d1 - d3 ); - // edge region of AB; barycentric coords (1-v, v, 0) - return target.copy( a ).addScaledVector( vab, v ); + v = d1 / ( d1 - d3 ); + // edge region of AB; barycentric coords (1-v, v, 0) + return target.copy( a ).addScaledVector( vab, v ); - } + } - vcp.subVectors( p, c ); - var d5 = vab.dot( vcp ); - var d6 = vac.dot( vcp ); - if ( d6 >= 0 && d5 <= d6 ) { + vcp.subVectors( p, c ); + var d5 = vab.dot( vcp ); + var d6 = vac.dot( vcp ); + if ( d6 >= 0 && d5 <= d6 ) { - // vertex region of C; barycentric coords (0, 0, 1) - return target.copy( c ); + // vertex region of C; barycentric coords (0, 0, 1) + return target.copy( c ); - } + } - var vb = d5 * d2 - d1 * d6; - if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) { + var vb = d5 * d2 - d1 * d6; + if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) { - w = d2 / ( d2 - d6 ); - // edge region of AC; barycentric coords (1-w, 0, w) - return target.copy( a ).addScaledVector( vac, w ); + w = d2 / ( d2 - d6 ); + // edge region of AC; barycentric coords (1-w, 0, w) + return target.copy( a ).addScaledVector( vac, w ); - } + } - var va = d3 * d6 - d5 * d4; - if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) { + var va = d3 * d6 - d5 * d4; + if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) { - vbc.subVectors( c, b ); - w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) ); - // edge region of BC; barycentric coords (0, 1-w, w) - return target.copy( b ).addScaledVector( vbc, w ); // edge region of BC + vbc.subVectors( c, b ); + w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) ); + // edge region of BC; barycentric coords (0, 1-w, w) + return target.copy( b ).addScaledVector( vbc, w ); // edge region of BC - } + } - // face region - var denom = 1 / ( va + vb + vc ); - // u = va * denom - v = vb * denom; - w = vc * denom; - return target.copy( a ).addScaledVector( vab, v ).addScaledVector( vac, w ); + // face region + var denom = 1 / ( va + vb + vc ); + // u = va * denom + v = vb * denom; + w = vc * denom; + return target.copy( a ).addScaledVector( vab, v ).addScaledVector( vac, w ); - }; + }; - }(), + }(), - equals: function ( triangle ) { + equals: function ( triangle ) { - return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); + return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author mikael emtinger / http://gomo.se/ - * @author jonobr1 / http://jonobr1.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author mikael emtinger / http://gomo.se/ + * @author jonobr1 / http://jonobr1.com/ + */ - function Mesh( geometry, material ) { + function Mesh( geometry, material ) { - Object3D.call( this ); + Object3D.call( this ); - this.type = 'Mesh'; + this.type = 'Mesh'; - this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); - this.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } ); + this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); + this.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } ); - this.drawMode = TrianglesDrawMode; + this.drawMode = TrianglesDrawMode; - this.updateMorphTargets(); + this.updateMorphTargets(); - } + } - Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { + Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { - constructor: Mesh, + constructor: Mesh, - isMesh: true, + isMesh: true, - setDrawMode: function ( value ) { + setDrawMode: function ( value ) { - this.drawMode = value; + this.drawMode = value; - }, + }, - copy: function ( source ) { + copy: function ( source ) { - Object3D.prototype.copy.call( this, source ); + Object3D.prototype.copy.call( this, source ); - this.drawMode = source.drawMode; + this.drawMode = source.drawMode; - if ( source.morphTargetInfluences !== undefined ) { + if ( source.morphTargetInfluences !== undefined ) { - this.morphTargetInfluences = source.morphTargetInfluences.slice(); + this.morphTargetInfluences = source.morphTargetInfluences.slice(); - } + } - if ( source.morphTargetDictionary !== undefined ) { + if ( source.morphTargetDictionary !== undefined ) { - this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary ); + this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary ); - } + } - return this; + return this; - }, + }, - updateMorphTargets: function () { + updateMorphTargets: function () { - var geometry = this.geometry; - var m, ml, name; + var geometry = this.geometry; + var m, ml, name; - if ( geometry.isBufferGeometry ) { + if ( geometry.isBufferGeometry ) { - var morphAttributes = geometry.morphAttributes; - var keys = Object.keys( morphAttributes ); + var morphAttributes = geometry.morphAttributes; + var keys = Object.keys( morphAttributes ); - if ( keys.length > 0 ) { + if ( keys.length > 0 ) { - var morphAttribute = morphAttributes[ keys[ 0 ] ]; + var morphAttribute = morphAttributes[ keys[ 0 ] ]; - if ( morphAttribute !== undefined ) { + if ( morphAttribute !== undefined ) { - this.morphTargetInfluences = []; - this.morphTargetDictionary = {}; + this.morphTargetInfluences = []; + this.morphTargetDictionary = {}; - for ( m = 0, ml = morphAttribute.length; m < ml; m ++ ) { + for ( m = 0, ml = morphAttribute.length; m < ml; m ++ ) { - name = morphAttribute[ m ].name || String( m ); + name = morphAttribute[ m ].name || String( m ); - this.morphTargetInfluences.push( 0 ); - this.morphTargetDictionary[ name ] = m; + this.morphTargetInfluences.push( 0 ); + this.morphTargetDictionary[ name ] = m; - } + } - } + } - } + } - } else { + } else { - var morphTargets = geometry.morphTargets; + var morphTargets = geometry.morphTargets; - if ( morphTargets !== undefined && morphTargets.length > 0 ) { + if ( morphTargets !== undefined && morphTargets.length > 0 ) { - this.morphTargetInfluences = []; - this.morphTargetDictionary = {}; + this.morphTargetInfluences = []; + this.morphTargetDictionary = {}; - for ( m = 0, ml = morphTargets.length; m < ml; m ++ ) { + for ( m = 0, ml = morphTargets.length; m < ml; m ++ ) { - name = morphTargets[ m ].name || String( m ); + name = morphTargets[ m ].name || String( m ); - this.morphTargetInfluences.push( 0 ); - this.morphTargetDictionary[ name ] = m; + this.morphTargetInfluences.push( 0 ); + this.morphTargetDictionary[ name ] = m; - } + } - } + } - } + } - }, + }, - raycast: ( function () { + raycast: ( function () { - var inverseMatrix = new Matrix4(); - var ray = new Ray(); - var sphere = new Sphere(); + var inverseMatrix = new Matrix4(); + var ray = new Ray(); + var sphere = new Sphere(); - var vA = new Vector3(); - var vB = new Vector3(); - var vC = new Vector3(); + var vA = new Vector3(); + var vB = new Vector3(); + var vC = new Vector3(); - var tempA = new Vector3(); - var tempB = new Vector3(); - var tempC = new Vector3(); + var tempA = new Vector3(); + var tempB = new Vector3(); + var tempC = new Vector3(); - var uvA = new Vector2(); - var uvB = new Vector2(); - var uvC = new Vector2(); + var uvA = new Vector2(); + var uvB = new Vector2(); + var uvC = new Vector2(); - var barycoord = new Vector3(); + var barycoord = new Vector3(); - var intersectionPoint = new Vector3(); - var intersectionPointWorld = new Vector3(); + var intersectionPoint = new Vector3(); + var intersectionPointWorld = new Vector3(); - function uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) { + function uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) { - Triangle.getBarycoord( point, p1, p2, p3, barycoord ); + Triangle.getBarycoord( point, p1, p2, p3, barycoord ); - uv1.multiplyScalar( barycoord.x ); - uv2.multiplyScalar( barycoord.y ); - uv3.multiplyScalar( barycoord.z ); + uv1.multiplyScalar( barycoord.x ); + uv2.multiplyScalar( barycoord.y ); + uv3.multiplyScalar( barycoord.z ); - uv1.add( uv2 ).add( uv3 ); + uv1.add( uv2 ).add( uv3 ); - return uv1.clone(); + return uv1.clone(); - } + } - function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) { + function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) { - var intersect; + var intersect; - if ( material.side === BackSide ) { + if ( material.side === BackSide ) { - intersect = ray.intersectTriangle( pC, pB, pA, true, point ); + intersect = ray.intersectTriangle( pC, pB, pA, true, point ); - } else { + } else { - intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point ); + intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point ); - } + } - if ( intersect === null ) return null; + if ( intersect === null ) return null; - intersectionPointWorld.copy( point ); - intersectionPointWorld.applyMatrix4( object.matrixWorld ); + intersectionPointWorld.copy( point ); + intersectionPointWorld.applyMatrix4( object.matrixWorld ); - var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld ); + var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld ); - if ( distance < raycaster.near || distance > raycaster.far ) return null; + if ( distance < raycaster.near || distance > raycaster.far ) return null; - return { - distance: distance, - point: intersectionPointWorld.clone(), - object: object - }; + return { + distance: distance, + point: intersectionPointWorld.clone(), + object: object + }; - } + } - function checkBufferGeometryIntersection( object, material, raycaster, ray, position, uv, a, b, c ) { + function checkBufferGeometryIntersection( object, material, raycaster, ray, position, uv, a, b, c ) { - vA.fromBufferAttribute( position, a ); - vB.fromBufferAttribute( position, b ); - vC.fromBufferAttribute( position, c ); + vA.fromBufferAttribute( position, a ); + vB.fromBufferAttribute( position, b ); + vC.fromBufferAttribute( position, c ); - var intersection = checkIntersection( object, material, raycaster, ray, vA, vB, vC, intersectionPoint ); + var intersection = checkIntersection( object, material, raycaster, ray, vA, vB, vC, intersectionPoint ); - if ( intersection ) { + if ( intersection ) { - if ( uv ) { + if ( uv ) { - uvA.fromBufferAttribute( uv, a ); - uvB.fromBufferAttribute( uv, b ); - uvC.fromBufferAttribute( uv, c ); + uvA.fromBufferAttribute( uv, a ); + uvB.fromBufferAttribute( uv, b ); + uvC.fromBufferAttribute( uv, c ); - intersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC ); + intersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC ); - } + } - var face = new Face3( a, b, c ); - Triangle.getNormal( vA, vB, vC, face.normal ); + var face = new Face3( a, b, c ); + Triangle.getNormal( vA, vB, vC, face.normal ); - intersection.face = face; + intersection.face = face; - } + } - return intersection; + return intersection; - } + } - return function raycast( raycaster, intersects ) { + return function raycast( raycaster, intersects ) { - var geometry = this.geometry; - var material = this.material; - var matrixWorld = this.matrixWorld; + var geometry = this.geometry; + var material = this.material; + var matrixWorld = this.matrixWorld; - if ( material === undefined ) return; + if ( material === undefined ) return; - // Checking boundingSphere distance to ray + // Checking boundingSphere distance to ray - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); - sphere.copy( geometry.boundingSphere ); - sphere.applyMatrix4( matrixWorld ); + sphere.copy( geometry.boundingSphere ); + sphere.applyMatrix4( matrixWorld ); - if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; + if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; - // + // - inverseMatrix.getInverse( matrixWorld ); - ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); + inverseMatrix.getInverse( matrixWorld ); + ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); - // Check boundingBox before continuing + // Check boundingBox before continuing - if ( geometry.boundingBox !== null ) { + if ( geometry.boundingBox !== null ) { - if ( ray.intersectsBox( geometry.boundingBox ) === false ) return; + if ( ray.intersectsBox( geometry.boundingBox ) === false ) return; - } + } - var intersection; + var intersection; - if ( geometry.isBufferGeometry ) { + if ( geometry.isBufferGeometry ) { - var a, b, c; - var index = geometry.index; - var position = geometry.attributes.position; - var uv = geometry.attributes.uv; - var groups = geometry.groups; - var drawRange = geometry.drawRange; - var i, j, il, jl; - var group, groupMaterial; - var start, end; + var a, b, c; + var index = geometry.index; + var position = geometry.attributes.position; + var uv = geometry.attributes.uv; + var groups = geometry.groups; + var drawRange = geometry.drawRange; + var i, j, il, jl; + var group, groupMaterial; + var start, end; - if ( index !== null ) { + if ( index !== null ) { - // indexed buffer geometry + // indexed buffer geometry - if ( Array.isArray( material ) ) { + if ( Array.isArray( material ) ) { - for ( i = 0, il = groups.length; i < il; i ++ ) { + for ( i = 0, il = groups.length; i < il; i ++ ) { - group = groups[ i ]; - groupMaterial = material[ group.materialIndex ]; + group = groups[ i ]; + groupMaterial = material[ group.materialIndex ]; - start = Math.max( group.start, drawRange.start ); - end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); + start = Math.max( group.start, drawRange.start ); + end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); - for ( j = start, jl = end; j < jl; j += 3 ) { + for ( j = start, jl = end; j < jl; j += 3 ) { - a = index.getX( j ); - b = index.getX( j + 1 ); - c = index.getX( j + 2 ); + a = index.getX( j ); + b = index.getX( j + 1 ); + c = index.getX( j + 2 ); - intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, uv, a, b, c ); + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, uv, a, b, c ); - if ( intersection ) { + if ( intersection ) { - intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics - intersects.push( intersection ); + intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics + intersects.push( intersection ); - } + } - } + } - } + } - } else { + } else { - start = Math.max( 0, drawRange.start ); - end = Math.min( index.count, ( drawRange.start + drawRange.count ) ); + start = Math.max( 0, drawRange.start ); + end = Math.min( index.count, ( drawRange.start + drawRange.count ) ); - for ( i = start, il = end; i < il; i += 3 ) { + for ( i = start, il = end; i < il; i += 3 ) { - a = index.getX( i ); - b = index.getX( i + 1 ); - c = index.getX( i + 2 ); + a = index.getX( i ); + b = index.getX( i + 1 ); + c = index.getX( i + 2 ); - intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, uv, a, b, c ); + intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, uv, a, b, c ); - if ( intersection ) { + if ( intersection ) { - intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics - intersects.push( intersection ); + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics + intersects.push( intersection ); - } + } - } + } - } + } - } else if ( position !== undefined ) { + } else if ( position !== undefined ) { - // non-indexed buffer geometry + // non-indexed buffer geometry - if ( Array.isArray( material ) ) { + if ( Array.isArray( material ) ) { - for ( i = 0, il = groups.length; i < il; i ++ ) { + for ( i = 0, il = groups.length; i < il; i ++ ) { - group = groups[ i ]; - groupMaterial = material[ group.materialIndex ]; + group = groups[ i ]; + groupMaterial = material[ group.materialIndex ]; - start = Math.max( group.start, drawRange.start ); - end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); + start = Math.max( group.start, drawRange.start ); + end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); - for ( j = start, jl = end; j < jl; j += 3 ) { + for ( j = start, jl = end; j < jl; j += 3 ) { - a = j; - b = j + 1; - c = j + 2; + a = j; + b = j + 1; + c = j + 2; - intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, uv, a, b, c ); + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, uv, a, b, c ); - if ( intersection ) { + if ( intersection ) { - intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics - intersects.push( intersection ); + intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics + intersects.push( intersection ); - } + } - } + } - } + } - } else { + } else { - start = Math.max( 0, drawRange.start ); - end = Math.min( position.count, ( drawRange.start + drawRange.count ) ); + start = Math.max( 0, drawRange.start ); + end = Math.min( position.count, ( drawRange.start + drawRange.count ) ); - for ( i = start, il = end; i < il; i += 3 ) { + for ( i = start, il = end; i < il; i += 3 ) { - a = i; - b = i + 1; - c = i + 2; + a = i; + b = i + 1; + c = i + 2; - intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, uv, a, b, c ); + intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, uv, a, b, c ); - if ( intersection ) { + if ( intersection ) { - intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics - intersects.push( intersection ); + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics + intersects.push( intersection ); - } + } - } + } - } + } - } + } - } else if ( geometry.isGeometry ) { + } else if ( geometry.isGeometry ) { - var fvA, fvB, fvC; - var isMultiMaterial = Array.isArray( material ); + var fvA, fvB, fvC; + var isMultiMaterial = Array.isArray( material ); - var vertices = geometry.vertices; - var faces = geometry.faces; - var uvs; + var vertices = geometry.vertices; + var faces = geometry.faces; + var uvs; - var faceVertexUvs = geometry.faceVertexUvs[ 0 ]; - if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs; + var faceVertexUvs = geometry.faceVertexUvs[ 0 ]; + if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs; - for ( var f = 0, fl = faces.length; f < fl; f ++ ) { + for ( var f = 0, fl = faces.length; f < fl; f ++ ) { - var face = faces[ f ]; - var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material; + var face = faces[ f ]; + var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material; - if ( faceMaterial === undefined ) continue; + if ( faceMaterial === undefined ) continue; - fvA = vertices[ face.a ]; - fvB = vertices[ face.b ]; - fvC = vertices[ face.c ]; + fvA = vertices[ face.a ]; + fvB = vertices[ face.b ]; + fvC = vertices[ face.c ]; - if ( faceMaterial.morphTargets === true ) { + if ( faceMaterial.morphTargets === true ) { - var morphTargets = geometry.morphTargets; - var morphInfluences = this.morphTargetInfluences; + var morphTargets = geometry.morphTargets; + var morphInfluences = this.morphTargetInfluences; - vA.set( 0, 0, 0 ); - vB.set( 0, 0, 0 ); - vC.set( 0, 0, 0 ); + vA.set( 0, 0, 0 ); + vB.set( 0, 0, 0 ); + vC.set( 0, 0, 0 ); - for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) { + for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) { - var influence = morphInfluences[ t ]; + var influence = morphInfluences[ t ]; - if ( influence === 0 ) continue; + if ( influence === 0 ) continue; - var targets = morphTargets[ t ].vertices; + var targets = morphTargets[ t ].vertices; - vA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence ); - vB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence ); - vC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence ); + vA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence ); + vB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence ); + vC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence ); - } + } - vA.add( fvA ); - vB.add( fvB ); - vC.add( fvC ); + vA.add( fvA ); + vB.add( fvB ); + vC.add( fvC ); - fvA = vA; - fvB = vB; - fvC = vC; + fvA = vA; + fvB = vB; + fvC = vC; - } + } - intersection = checkIntersection( this, faceMaterial, raycaster, ray, fvA, fvB, fvC, intersectionPoint ); + intersection = checkIntersection( this, faceMaterial, raycaster, ray, fvA, fvB, fvC, intersectionPoint ); - if ( intersection ) { + if ( intersection ) { - if ( uvs && uvs[ f ] ) { + if ( uvs && uvs[ f ] ) { - var uvs_f = uvs[ f ]; - uvA.copy( uvs_f[ 0 ] ); - uvB.copy( uvs_f[ 1 ] ); - uvC.copy( uvs_f[ 2 ] ); + var uvs_f = uvs[ f ]; + uvA.copy( uvs_f[ 0 ] ); + uvB.copy( uvs_f[ 1 ] ); + uvC.copy( uvs_f[ 2 ] ); - intersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC ); + intersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC ); - } + } - intersection.face = face; - intersection.faceIndex = f; - intersects.push( intersection ); + intersection.face = face; + intersection.faceIndex = f; + intersects.push( intersection ); - } + } - } + } - } + } - }; + }; - }() ), + }() ), - clone: function () { + clone: function () { - return new this.constructor( this.geometry, this.material ).copy( this ); + return new this.constructor( this.geometry, this.material ).copy( this ); - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { + function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { - var clearColor = new Color( 0x000000 ); - var clearAlpha = 0; + var clearColor = new Color( 0x000000 ); + var clearAlpha = 0; - var planeCamera, planeMesh; - var boxMesh; + var planeCamera, planeMesh; + var boxMesh; - function render( renderList, scene, camera, forceClear ) { + function render( renderList, scene, camera, forceClear ) { - var background = scene.background; + var background = scene.background; - if ( background === null ) { + if ( background === null ) { - setClear( clearColor, clearAlpha ); + setClear( clearColor, clearAlpha ); - } else if ( background && background.isColor ) { + } else if ( background && background.isColor ) { - setClear( background, 1 ); - forceClear = true; + setClear( background, 1 ); + forceClear = true; - } + } - if ( renderer.autoClear || forceClear ) { + if ( renderer.autoClear || forceClear ) { - renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil ); + renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil ); - } + } - if ( background && background.isCubeTexture ) { + if ( background && background.isCubeTexture ) { - if ( boxMesh === undefined ) { + if ( boxMesh === undefined ) { - boxMesh = new Mesh( - new BoxBufferGeometry( 1, 1, 1 ), - new ShaderMaterial( { - uniforms: ShaderLib.cube.uniforms, - vertexShader: ShaderLib.cube.vertexShader, - fragmentShader: ShaderLib.cube.fragmentShader, - side: BackSide, - depthTest: true, - depthWrite: false, - fog: false - } ) - ); + boxMesh = new Mesh( + new BoxBufferGeometry( 1, 1, 1 ), + new ShaderMaterial( { + uniforms: ShaderLib.cube.uniforms, + vertexShader: ShaderLib.cube.vertexShader, + fragmentShader: ShaderLib.cube.fragmentShader, + side: BackSide, + depthTest: true, + depthWrite: false, + fog: false + } ) + ); - boxMesh.geometry.removeAttribute( 'normal' ); - boxMesh.geometry.removeAttribute( 'uv' ); + boxMesh.geometry.removeAttribute( 'normal' ); + boxMesh.geometry.removeAttribute( 'uv' ); - boxMesh.onBeforeRender = function ( renderer, scene, camera ) { + boxMesh.onBeforeRender = function ( renderer, scene, camera ) { - this.matrixWorld.copyPosition( camera.matrixWorld ); + this.matrixWorld.copyPosition( camera.matrixWorld ); - }; + }; - objects.update( boxMesh ); + objects.update( boxMesh ); - } + } - boxMesh.material.uniforms.tCube.value = background; + boxMesh.material.uniforms.tCube.value = background; - renderList.push( boxMesh, boxMesh.geometry, boxMesh.material, 0, null ); + renderList.push( boxMesh, boxMesh.geometry, boxMesh.material, 0, null ); - } else if ( background && background.isTexture ) { + } else if ( background && background.isTexture ) { - if ( planeCamera === undefined ) { + if ( planeCamera === undefined ) { - planeCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); + planeCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); - planeMesh = new Mesh( - new PlaneBufferGeometry( 2, 2 ), - new MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } ) - ); + planeMesh = new Mesh( + new PlaneBufferGeometry( 2, 2 ), + new MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } ) + ); - objects.update( planeMesh ); + objects.update( planeMesh ); - } + } - planeMesh.material.map = background; + planeMesh.material.map = background; - // TODO Push this to renderList + // TODO Push this to renderList - renderer.renderBufferDirect( planeCamera, null, planeMesh.geometry, planeMesh.material, planeMesh, null ); + renderer.renderBufferDirect( planeCamera, null, planeMesh.geometry, planeMesh.material, planeMesh, null ); - } + } - } + } - function setClear( color, alpha ) { + function setClear( color, alpha ) { - state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha ); + state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha ); - } + } - return { + return { - getClearColor: function () { + getClearColor: function () { - return clearColor; + return clearColor; - }, - setClearColor: function ( color, alpha ) { + }, + setClearColor: function ( color, alpha ) { - clearColor.set( color ); - clearAlpha = alpha !== undefined ? alpha : 1; - setClear( clearColor, clearAlpha ); + clearColor.set( color ); + clearAlpha = alpha !== undefined ? alpha : 1; + setClear( clearColor, clearAlpha ); - }, - getClearAlpha: function () { + }, + getClearAlpha: function () { - return clearAlpha; + return clearAlpha; - }, - setClearAlpha: function ( alpha ) { + }, + setClearAlpha: function ( alpha ) { - clearAlpha = alpha; - setClear( clearColor, clearAlpha ); + clearAlpha = alpha; + setClear( clearColor, clearAlpha ); - }, - render: render + }, + render: render - }; + }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function WebGLBufferRenderer( gl, extensions, info, capabilities ) { + function WebGLBufferRenderer( gl, extensions, info, capabilities ) { - var mode; + var mode; - function setMode( value ) { + function setMode( value ) { - mode = value; + mode = value; - } + } - function render( start, count ) { + function render( start, count ) { - gl.drawArrays( mode, start, count ); + gl.drawArrays( mode, start, count ); - info.update( count, mode ); + info.update( count, mode ); - } + } - function renderInstances( geometry, start, count ) { + function renderInstances( geometry, start, count ) { - var extension; + var extension; - if ( capabilities.isWebGL2 ) { + if ( capabilities.isWebGL2 ) { - extension = gl; + extension = gl; - } else { + } else { - extension = extensions.get( 'ANGLE_instanced_arrays' ); + extension = extensions.get( 'ANGLE_instanced_arrays' ); - if ( extension === null ) { + if ( extension === null ) { - console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); - return; + console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); + return; - } + } - } + } - extension[ capabilities.isWebGL2 ? 'drawArraysInstanced' : 'drawArraysInstancedANGLE' ]( mode, start, count, geometry.maxInstancedCount ); + extension[ capabilities.isWebGL2 ? 'drawArraysInstanced' : 'drawArraysInstancedANGLE' ]( mode, start, count, geometry.maxInstancedCount ); - info.update( count, mode, geometry.maxInstancedCount ); + info.update( count, mode, geometry.maxInstancedCount ); - } + } - // + // - this.setMode = setMode; - this.render = render; - this.renderInstances = renderInstances; + this.setMode = setMode; + this.render = render; + this.renderInstances = renderInstances; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function WebGLCapabilities( gl, extensions, parameters ) { + function WebGLCapabilities( gl, extensions, parameters ) { - var maxAnisotropy; + var maxAnisotropy; - function getMaxAnisotropy() { + function getMaxAnisotropy() { - if ( maxAnisotropy !== undefined ) return maxAnisotropy; + if ( maxAnisotropy !== undefined ) return maxAnisotropy; - var extension = extensions.get( 'EXT_texture_filter_anisotropic' ); + var extension = extensions.get( 'EXT_texture_filter_anisotropic' ); - if ( extension !== null ) { + if ( extension !== null ) { - maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT ); + maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT ); - } else { + } else { - maxAnisotropy = 0; + maxAnisotropy = 0; - } + } - return maxAnisotropy; + return maxAnisotropy; - } + } - function getMaxPrecision( precision ) { + function getMaxPrecision( precision ) { - if ( precision === 'highp' ) { + if ( precision === 'highp' ) { - if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 && - gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) { + if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 && + gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) { - return 'highp'; + return 'highp'; - } + } - precision = 'mediump'; + precision = 'mediump'; - } + } - if ( precision === 'mediump' ) { + if ( precision === 'mediump' ) { - if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 && - gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) { + if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 && + gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) { - return 'mediump'; + return 'mediump'; - } + } - } + } - return 'lowp'; + return 'lowp'; - } + } - var isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext; + var isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext; - var precision = parameters.precision !== undefined ? parameters.precision : 'highp'; - var maxPrecision = getMaxPrecision( precision ); + var precision = parameters.precision !== undefined ? parameters.precision : 'highp'; + var maxPrecision = getMaxPrecision( precision ); - if ( maxPrecision !== precision ) { + if ( maxPrecision !== precision ) { - console.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' ); - precision = maxPrecision; + console.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' ); + precision = maxPrecision; - } + } - var logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; + var logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; - var maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS ); - var maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ); - var maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE ); - var maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE ); + var maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS ); + var maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ); + var maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE ); + var maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE ); - var maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); - var maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS ); - var maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS ); - var maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS ); + var maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); + var maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS ); + var maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS ); + var maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS ); - var vertexTextures = maxVertexTextures > 0; - var floatFragmentTextures = isWebGL2 || !! extensions.get( 'OES_texture_float' ); - var floatVertexTextures = vertexTextures && floatFragmentTextures; + var vertexTextures = maxVertexTextures > 0; + var floatFragmentTextures = isWebGL2 || !! extensions.get( 'OES_texture_float' ); + var floatVertexTextures = vertexTextures && floatFragmentTextures; - return { + return { - isWebGL2: isWebGL2, + isWebGL2: isWebGL2, - getMaxAnisotropy: getMaxAnisotropy, - getMaxPrecision: getMaxPrecision, + getMaxAnisotropy: getMaxAnisotropy, + getMaxPrecision: getMaxPrecision, - precision: precision, - logarithmicDepthBuffer: logarithmicDepthBuffer, + precision: precision, + logarithmicDepthBuffer: logarithmicDepthBuffer, - maxTextures: maxTextures, - maxVertexTextures: maxVertexTextures, - maxTextureSize: maxTextureSize, - maxCubemapSize: maxCubemapSize, + maxTextures: maxTextures, + maxVertexTextures: maxVertexTextures, + maxTextureSize: maxTextureSize, + maxCubemapSize: maxCubemapSize, - maxAttributes: maxAttributes, - maxVertexUniforms: maxVertexUniforms, - maxVaryings: maxVaryings, - maxFragmentUniforms: maxFragmentUniforms, + maxAttributes: maxAttributes, + maxVertexUniforms: maxVertexUniforms, + maxVaryings: maxVaryings, + maxFragmentUniforms: maxFragmentUniforms, - vertexTextures: vertexTextures, - floatFragmentTextures: floatFragmentTextures, - floatVertexTextures: floatVertexTextures + vertexTextures: vertexTextures, + floatFragmentTextures: floatFragmentTextures, + floatVertexTextures: floatVertexTextures - }; + }; - } + } - /** - * @author tschw - */ + /** + * @author tschw + */ - function WebGLClipping() { + function WebGLClipping() { - var scope = this, + var scope = this, - globalState = null, - numGlobalPlanes = 0, - localClippingEnabled = false, - renderingShadows = false, + globalState = null, + numGlobalPlanes = 0, + localClippingEnabled = false, + renderingShadows = false, - plane = new Plane(), - viewNormalMatrix = new Matrix3(), + plane = new Plane(), + viewNormalMatrix = new Matrix3(), - uniform = { value: null, needsUpdate: false }; + uniform = { value: null, needsUpdate: false }; - this.uniform = uniform; - this.numPlanes = 0; - this.numIntersection = 0; + this.uniform = uniform; + this.numPlanes = 0; + this.numIntersection = 0; - this.init = function ( planes, enableLocalClipping, camera ) { + this.init = function ( planes, enableLocalClipping, camera ) { - var enabled = - planes.length !== 0 || - enableLocalClipping || - // enable state of previous frame - the clipping code has to - // run another frame in order to reset the state: - numGlobalPlanes !== 0 || - localClippingEnabled; + var enabled = + planes.length !== 0 || + enableLocalClipping || + // enable state of previous frame - the clipping code has to + // run another frame in order to reset the state: + numGlobalPlanes !== 0 || + localClippingEnabled; - localClippingEnabled = enableLocalClipping; + localClippingEnabled = enableLocalClipping; - globalState = projectPlanes( planes, camera, 0 ); - numGlobalPlanes = planes.length; + globalState = projectPlanes( planes, camera, 0 ); + numGlobalPlanes = planes.length; - return enabled; + return enabled; - }; + }; - this.beginShadows = function () { + this.beginShadows = function () { - renderingShadows = true; - projectPlanes( null ); + renderingShadows = true; + projectPlanes( null ); - }; + }; - this.endShadows = function () { + this.endShadows = function () { - renderingShadows = false; - resetGlobalState(); + renderingShadows = false; + resetGlobalState(); - }; + }; - this.setState = function ( planes, clipIntersection, clipShadows, camera, cache, fromCache ) { + this.setState = function ( planes, clipIntersection, clipShadows, camera, cache, fromCache ) { - if ( ! localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && ! clipShadows ) { + if ( ! localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && ! clipShadows ) { - // there's no local clipping + // there's no local clipping - if ( renderingShadows ) { + if ( renderingShadows ) { - // there's no global clipping + // there's no global clipping - projectPlanes( null ); + projectPlanes( null ); - } else { + } else { - resetGlobalState(); + resetGlobalState(); - } + } - } else { + } else { - var nGlobal = renderingShadows ? 0 : numGlobalPlanes, - lGlobal = nGlobal * 4, + var nGlobal = renderingShadows ? 0 : numGlobalPlanes, + lGlobal = nGlobal * 4, - dstArray = cache.clippingState || null; + dstArray = cache.clippingState || null; - uniform.value = dstArray; // ensure unique state + uniform.value = dstArray; // ensure unique state - dstArray = projectPlanes( planes, camera, lGlobal, fromCache ); + dstArray = projectPlanes( planes, camera, lGlobal, fromCache ); - for ( var i = 0; i !== lGlobal; ++ i ) { + for ( var i = 0; i !== lGlobal; ++ i ) { - dstArray[ i ] = globalState[ i ]; + dstArray[ i ] = globalState[ i ]; - } + } - cache.clippingState = dstArray; - this.numIntersection = clipIntersection ? this.numPlanes : 0; - this.numPlanes += nGlobal; + cache.clippingState = dstArray; + this.numIntersection = clipIntersection ? this.numPlanes : 0; + this.numPlanes += nGlobal; - } + } - }; + }; - function resetGlobalState() { + function resetGlobalState() { - if ( uniform.value !== globalState ) { + if ( uniform.value !== globalState ) { - uniform.value = globalState; - uniform.needsUpdate = numGlobalPlanes > 0; + uniform.value = globalState; + uniform.needsUpdate = numGlobalPlanes > 0; - } + } - scope.numPlanes = numGlobalPlanes; - scope.numIntersection = 0; + scope.numPlanes = numGlobalPlanes; + scope.numIntersection = 0; - } + } - function projectPlanes( planes, camera, dstOffset, skipTransform ) { + function projectPlanes( planes, camera, dstOffset, skipTransform ) { - var nPlanes = planes !== null ? planes.length : 0, - dstArray = null; + var nPlanes = planes !== null ? planes.length : 0, + dstArray = null; - if ( nPlanes !== 0 ) { + if ( nPlanes !== 0 ) { - dstArray = uniform.value; + dstArray = uniform.value; - if ( skipTransform !== true || dstArray === null ) { + if ( skipTransform !== true || dstArray === null ) { - var flatSize = dstOffset + nPlanes * 4, - viewMatrix = camera.matrixWorldInverse; + var flatSize = dstOffset + nPlanes * 4, + viewMatrix = camera.matrixWorldInverse; - viewNormalMatrix.getNormalMatrix( viewMatrix ); + viewNormalMatrix.getNormalMatrix( viewMatrix ); - if ( dstArray === null || dstArray.length < flatSize ) { + if ( dstArray === null || dstArray.length < flatSize ) { - dstArray = new Float32Array( flatSize ); + dstArray = new Float32Array( flatSize ); - } + } - for ( var i = 0, i4 = dstOffset; i !== nPlanes; ++ i, i4 += 4 ) { + for ( var i = 0, i4 = dstOffset; i !== nPlanes; ++ i, i4 += 4 ) { - plane.copy( planes[ i ] ).applyMatrix4( viewMatrix, viewNormalMatrix ); + plane.copy( planes[ i ] ).applyMatrix4( viewMatrix, viewNormalMatrix ); - plane.normal.toArray( dstArray, i4 ); - dstArray[ i4 + 3 ] = plane.constant; + plane.normal.toArray( dstArray, i4 ); + dstArray[ i4 + 3 ] = plane.constant; - } + } - } + } - uniform.value = dstArray; - uniform.needsUpdate = true; + uniform.value = dstArray; + uniform.needsUpdate = true; - } + } - scope.numPlanes = nPlanes; + scope.numPlanes = nPlanes; - return dstArray; + return dstArray; - } + } - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function WebGLExtensions( gl ) { + function WebGLExtensions( gl ) { - var extensions = {}; + var extensions = {}; - return { + return { - get: function ( name ) { + get: function ( name ) { - if ( extensions[ name ] !== undefined ) { + if ( extensions[ name ] !== undefined ) { - return extensions[ name ]; + return extensions[ name ]; - } + } - var extension; + var extension; - switch ( name ) { + switch ( name ) { - case 'WEBGL_depth_texture': - extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' ); - break; + case 'WEBGL_depth_texture': + extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' ); + break; - case 'EXT_texture_filter_anisotropic': - extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' ); - break; + case 'EXT_texture_filter_anisotropic': + extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' ); + break; - case 'WEBGL_compressed_texture_s3tc': - extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' ); - break; + case 'WEBGL_compressed_texture_s3tc': + extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' ); + break; - case 'WEBGL_compressed_texture_pvrtc': - extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' ); - break; + case 'WEBGL_compressed_texture_pvrtc': + extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' ); + break; - default: - extension = gl.getExtension( name ); + default: + extension = gl.getExtension( name ); - } + } - if ( extension === null ) { + if ( extension === null ) { - console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' ); + console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' ); - } + } - extensions[ name ] = extension; + extensions[ name ] = extension; - return extension; + return extension; - } + } - }; + }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function WebGLGeometries( gl, attributes, info ) { + function WebGLGeometries( gl, attributes, info ) { - var geometries = {}; - var wireframeAttributes = {}; + var geometries = {}; + var wireframeAttributes = {}; - function onGeometryDispose( event ) { + function onGeometryDispose( event ) { - var geometry = event.target; - var buffergeometry = geometries[ geometry.id ]; + var geometry = event.target; + var buffergeometry = geometries[ geometry.id ]; - if ( buffergeometry.index !== null ) { + if ( buffergeometry.index !== null ) { - attributes.remove( buffergeometry.index ); + attributes.remove( buffergeometry.index ); - } + } - for ( var name in buffergeometry.attributes ) { + for ( var name in buffergeometry.attributes ) { - attributes.remove( buffergeometry.attributes[ name ] ); + attributes.remove( buffergeometry.attributes[ name ] ); - } + } - geometry.removeEventListener( 'dispose', onGeometryDispose ); + geometry.removeEventListener( 'dispose', onGeometryDispose ); - delete geometries[ geometry.id ]; + delete geometries[ geometry.id ]; - var attribute = wireframeAttributes[ buffergeometry.id ]; + var attribute = wireframeAttributes[ buffergeometry.id ]; - if ( attribute ) { + if ( attribute ) { - attributes.remove( attribute ); - delete wireframeAttributes[ buffergeometry.id ]; + attributes.remove( attribute ); + delete wireframeAttributes[ buffergeometry.id ]; - } + } - // + // - info.memory.geometries --; + info.memory.geometries --; - } + } - function get( object, geometry ) { + function get( object, geometry ) { - var buffergeometry = geometries[ geometry.id ]; + var buffergeometry = geometries[ geometry.id ]; - if ( buffergeometry ) return buffergeometry; + if ( buffergeometry ) return buffergeometry; - geometry.addEventListener( 'dispose', onGeometryDispose ); + geometry.addEventListener( 'dispose', onGeometryDispose ); - if ( geometry.isBufferGeometry ) { + if ( geometry.isBufferGeometry ) { - buffergeometry = geometry; + buffergeometry = geometry; - } else if ( geometry.isGeometry ) { + } else if ( geometry.isGeometry ) { - if ( geometry._bufferGeometry === undefined ) { + if ( geometry._bufferGeometry === undefined ) { - geometry._bufferGeometry = new BufferGeometry().setFromObject( object ); + geometry._bufferGeometry = new BufferGeometry().setFromObject( object ); - } + } - buffergeometry = geometry._bufferGeometry; + buffergeometry = geometry._bufferGeometry; - } + } - geometries[ geometry.id ] = buffergeometry; + geometries[ geometry.id ] = buffergeometry; - info.memory.geometries ++; + info.memory.geometries ++; - return buffergeometry; + return buffergeometry; - } + } - function update( geometry ) { + function update( geometry ) { - var index = geometry.index; - var geometryAttributes = geometry.attributes; + var index = geometry.index; + var geometryAttributes = geometry.attributes; - if ( index !== null ) { + if ( index !== null ) { - attributes.update( index, gl.ELEMENT_ARRAY_BUFFER ); + attributes.update( index, gl.ELEMENT_ARRAY_BUFFER ); - } + } - for ( var name in geometryAttributes ) { + for ( var name in geometryAttributes ) { - attributes.update( geometryAttributes[ name ], gl.ARRAY_BUFFER ); + attributes.update( geometryAttributes[ name ], gl.ARRAY_BUFFER ); - } + } - // morph targets + // morph targets - var morphAttributes = geometry.morphAttributes; + var morphAttributes = geometry.morphAttributes; - for ( var name in morphAttributes ) { + for ( var name in morphAttributes ) { - var array = morphAttributes[ name ]; + var array = morphAttributes[ name ]; - for ( var i = 0, l = array.length; i < l; i ++ ) { + for ( var i = 0, l = array.length; i < l; i ++ ) { - attributes.update( array[ i ], gl.ARRAY_BUFFER ); + attributes.update( array[ i ], gl.ARRAY_BUFFER ); - } + } - } + } - } + } - function getWireframeAttribute( geometry ) { + function getWireframeAttribute( geometry ) { - var attribute = wireframeAttributes[ geometry.id ]; + var attribute = wireframeAttributes[ geometry.id ]; - if ( attribute ) return attribute; + if ( attribute ) return attribute; - var indices = []; + var indices = []; - var geometryIndex = geometry.index; - var geometryAttributes = geometry.attributes; + var geometryIndex = geometry.index; + var geometryAttributes = geometry.attributes; - // console.time( 'wireframe' ); + // console.time( 'wireframe' ); - if ( geometryIndex !== null ) { + if ( geometryIndex !== null ) { - var array = geometryIndex.array; + var array = geometryIndex.array; - for ( var i = 0, l = array.length; i < l; i += 3 ) { + for ( var i = 0, l = array.length; i < l; i += 3 ) { - var a = array[ i + 0 ]; - var b = array[ i + 1 ]; - var c = array[ i + 2 ]; + var a = array[ i + 0 ]; + var b = array[ i + 1 ]; + var c = array[ i + 2 ]; - indices.push( a, b, b, c, c, a ); + indices.push( a, b, b, c, c, a ); - } + } - } else { + } else { - var array = geometryAttributes.position.array; + var array = geometryAttributes.position.array; - for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) { + for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) { - var a = i + 0; - var b = i + 1; - var c = i + 2; + var a = i + 0; + var b = i + 1; + var c = i + 2; - indices.push( a, b, b, c, c, a ); + indices.push( a, b, b, c, c, a ); - } + } - } + } - // console.timeEnd( 'wireframe' ); + // console.timeEnd( 'wireframe' ); - attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 ); + attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 ); - attributes.update( attribute, gl.ELEMENT_ARRAY_BUFFER ); + attributes.update( attribute, gl.ELEMENT_ARRAY_BUFFER ); - wireframeAttributes[ geometry.id ] = attribute; + wireframeAttributes[ geometry.id ] = attribute; - return attribute; + return attribute; - } + } - return { + return { - get: get, - update: update, + get: get, + update: update, - getWireframeAttribute: getWireframeAttribute + getWireframeAttribute: getWireframeAttribute - }; + }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) { + function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) { - var mode; + var mode; - function setMode( value ) { + function setMode( value ) { - mode = value; + mode = value; - } + } - var type, bytesPerElement; + var type, bytesPerElement; - function setIndex( value ) { + function setIndex( value ) { - type = value.type; - bytesPerElement = value.bytesPerElement; + type = value.type; + bytesPerElement = value.bytesPerElement; - } + } - function render( start, count ) { + function render( start, count ) { - gl.drawElements( mode, count, type, start * bytesPerElement ); + gl.drawElements( mode, count, type, start * bytesPerElement ); - info.update( count, mode ); + info.update( count, mode ); - } + } - function renderInstances( geometry, start, count ) { + function renderInstances( geometry, start, count ) { - var extension; + var extension; - if ( capabilities.isWebGL2 ) { + if ( capabilities.isWebGL2 ) { - extension = gl; + extension = gl; - } else { + } else { - var extension = extensions.get( 'ANGLE_instanced_arrays' ); + var extension = extensions.get( 'ANGLE_instanced_arrays' ); - if ( extension === null ) { + if ( extension === null ) { - console.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); - return; + console.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); + return; - } + } - } + } - extension[ capabilities.isWebGL2 ? 'drawElementsInstanced' : 'drawElementsInstancedANGLE' ]( mode, count, type, start * bytesPerElement, geometry.maxInstancedCount ); + extension[ capabilities.isWebGL2 ? 'drawElementsInstanced' : 'drawElementsInstancedANGLE' ]( mode, count, type, start * bytesPerElement, geometry.maxInstancedCount ); - info.update( count, mode, geometry.maxInstancedCount ); + info.update( count, mode, geometry.maxInstancedCount ); - } + } - // + // - this.setMode = setMode; - this.setIndex = setIndex; - this.render = render; - this.renderInstances = renderInstances; + this.setMode = setMode; + this.setIndex = setIndex; + this.render = render; + this.renderInstances = renderInstances; - } + } - /** - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author Mugen87 / https://github.com/Mugen87 + */ - function WebGLInfo( gl ) { + function WebGLInfo( gl ) { - var memory = { - geometries: 0, - textures: 0 - }; + var memory = { + geometries: 0, + textures: 0 + }; - var render = { - frame: 0, - calls: 0, - triangles: 0, - points: 0, - lines: 0 - }; + var render = { + frame: 0, + calls: 0, + triangles: 0, + points: 0, + lines: 0 + }; - function update( count, mode, instanceCount ) { + function update( count, mode, instanceCount ) { - instanceCount = instanceCount || 1; + instanceCount = instanceCount || 1; - render.calls ++; + render.calls ++; - switch ( mode ) { + switch ( mode ) { - case gl.TRIANGLES: - render.triangles += instanceCount * ( count / 3 ); - break; + case gl.TRIANGLES: + render.triangles += instanceCount * ( count / 3 ); + break; - case gl.TRIANGLE_STRIP: - case gl.TRIANGLE_FAN: - render.triangles += instanceCount * ( count - 2 ); - break; + case gl.TRIANGLE_STRIP: + case gl.TRIANGLE_FAN: + render.triangles += instanceCount * ( count - 2 ); + break; - case gl.LINES: - render.lines += instanceCount * ( count / 2 ); - break; + case gl.LINES: + render.lines += instanceCount * ( count / 2 ); + break; - case gl.LINE_STRIP: - render.lines += instanceCount * ( count - 1 ); - break; + case gl.LINE_STRIP: + render.lines += instanceCount * ( count - 1 ); + break; - case gl.LINE_LOOP: - render.lines += instanceCount * count; - break; + case gl.LINE_LOOP: + render.lines += instanceCount * count; + break; - case gl.POINTS: - render.points += instanceCount * count; - break; + case gl.POINTS: + render.points += instanceCount * count; + break; - default: - console.error( 'THREE.WebGLInfo: Unknown draw mode:', mode ); - break; + default: + console.error( 'THREE.WebGLInfo: Unknown draw mode:', mode ); + break; - } + } - } + } - function reset() { + function reset() { - render.frame ++; - render.calls = 0; - render.triangles = 0; - render.points = 0; - render.lines = 0; + render.frame ++; + render.calls = 0; + render.triangles = 0; + render.points = 0; + render.lines = 0; - } + } - return { - memory: memory, - render: render, - programs: null, - autoReset: true, - reset: reset, - update: update - }; + return { + memory: memory, + render: render, + programs: null, + autoReset: true, + reset: reset, + update: update + }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function absNumericalSort( a, b ) { + function absNumericalSort( a, b ) { - return Math.abs( b[ 1 ] ) - Math.abs( a[ 1 ] ); + return Math.abs( b[ 1 ] ) - Math.abs( a[ 1 ] ); - } + } - function WebGLMorphtargets( gl ) { + function WebGLMorphtargets( gl ) { - var influencesList = {}; - var morphInfluences = new Float32Array( 8 ); + var influencesList = {}; + var morphInfluences = new Float32Array( 8 ); - function update( object, geometry, material, program ) { + function update( object, geometry, material, program ) { - var objectInfluences = object.morphTargetInfluences; + var objectInfluences = object.morphTargetInfluences; - var length = objectInfluences.length; + var length = objectInfluences.length; - var influences = influencesList[ geometry.id ]; + var influences = influencesList[ geometry.id ]; - if ( influences === undefined ) { + if ( influences === undefined ) { - // initialise list + // initialise list - influences = []; + influences = []; - for ( var i = 0; i < length; i ++ ) { + for ( var i = 0; i < length; i ++ ) { - influences[ i ] = [ i, 0 ]; + influences[ i ] = [ i, 0 ]; - } + } - influencesList[ geometry.id ] = influences; + influencesList[ geometry.id ] = influences; - } + } - var morphTargets = material.morphTargets && geometry.morphAttributes.position; - var morphNormals = material.morphNormals && geometry.morphAttributes.normal; + var morphTargets = material.morphTargets && geometry.morphAttributes.position; + var morphNormals = material.morphNormals && geometry.morphAttributes.normal; - // Remove current morphAttributes + // Remove current morphAttributes - for ( var i = 0; i < length; i ++ ) { + for ( var i = 0; i < length; i ++ ) { - var influence = influences[ i ]; + var influence = influences[ i ]; - if ( influence[ 1 ] !== 0 ) { + if ( influence[ 1 ] !== 0 ) { - if ( morphTargets ) geometry.removeAttribute( 'morphTarget' + i ); - if ( morphNormals ) geometry.removeAttribute( 'morphNormal' + i ); + if ( morphTargets ) geometry.removeAttribute( 'morphTarget' + i ); + if ( morphNormals ) geometry.removeAttribute( 'morphNormal' + i ); - } + } - } + } - // Collect influences + // Collect influences - for ( var i = 0; i < length; i ++ ) { + for ( var i = 0; i < length; i ++ ) { - var influence = influences[ i ]; + var influence = influences[ i ]; - influence[ 0 ] = i; - influence[ 1 ] = objectInfluences[ i ]; + influence[ 0 ] = i; + influence[ 1 ] = objectInfluences[ i ]; - } + } - influences.sort( absNumericalSort ); + influences.sort( absNumericalSort ); - // Add morphAttributes + // Add morphAttributes - for ( var i = 0; i < 8; i ++ ) { + for ( var i = 0; i < 8; i ++ ) { - var influence = influences[ i ]; + var influence = influences[ i ]; - if ( influence ) { + if ( influence ) { - var index = influence[ 0 ]; - var value = influence[ 1 ]; + var index = influence[ 0 ]; + var value = influence[ 1 ]; - if ( value ) { + if ( value ) { - if ( morphTargets ) geometry.addAttribute( 'morphTarget' + i, morphTargets[ index ] ); - if ( morphNormals ) geometry.addAttribute( 'morphNormal' + i, morphNormals[ index ] ); + if ( morphTargets ) geometry.addAttribute( 'morphTarget' + i, morphTargets[ index ] ); + if ( morphNormals ) geometry.addAttribute( 'morphNormal' + i, morphNormals[ index ] ); - morphInfluences[ i ] = value; - continue; + morphInfluences[ i ] = value; + continue; - } + } - } + } - morphInfluences[ i ] = 0; + morphInfluences[ i ] = 0; - } + } - program.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences ); + program.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences ); - } + } - return { + return { - update: update + update: update - }; + }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function WebGLObjects( geometries, info ) { + function WebGLObjects( geometries, info ) { - var updateList = {}; + var updateList = {}; - function update( object ) { + function update( object ) { - var frame = info.render.frame; + var frame = info.render.frame; - var geometry = object.geometry; - var buffergeometry = geometries.get( object, geometry ); + var geometry = object.geometry; + var buffergeometry = geometries.get( object, geometry ); - // Update once per frame + // Update once per frame - if ( updateList[ buffergeometry.id ] !== frame ) { + if ( updateList[ buffergeometry.id ] !== frame ) { - if ( geometry.isGeometry ) { + if ( geometry.isGeometry ) { - buffergeometry.updateFromObject( object ); + buffergeometry.updateFromObject( object ); - } + } - geometries.update( buffergeometry ); + geometries.update( buffergeometry ); - updateList[ buffergeometry.id ] = frame; + updateList[ buffergeometry.id ] = frame; - } + } - return buffergeometry; + return buffergeometry; - } + } - function dispose() { + function dispose() { - updateList = {}; + updateList = {}; - } + } - return { + return { - update: update, - dispose: dispose + update: update, + dispose: dispose - }; + }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { + function CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { - images = images !== undefined ? images : []; - mapping = mapping !== undefined ? mapping : CubeReflectionMapping; + images = images !== undefined ? images : []; + mapping = mapping !== undefined ? mapping : CubeReflectionMapping; - Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); + Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); - this.flipY = false; + this.flipY = false; - } + } - CubeTexture.prototype = Object.create( Texture.prototype ); - CubeTexture.prototype.constructor = CubeTexture; + CubeTexture.prototype = Object.create( Texture.prototype ); + CubeTexture.prototype.constructor = CubeTexture; - CubeTexture.prototype.isCubeTexture = true; + CubeTexture.prototype.isCubeTexture = true; - Object.defineProperty( CubeTexture.prototype, 'images', { + Object.defineProperty( CubeTexture.prototype, 'images', { - get: function () { + get: function () { - return this.image; + return this.image; - }, + }, - set: function ( value ) { + set: function ( value ) { - this.image = value; + this.image = value; - } + } - } ); + } ); - /** - * @author tschw - * @author Mugen87 / https://github.com/Mugen87 - * @author mrdoob / http://mrdoob.com/ - * - * Uniforms of a program. - * Those form a tree structure with a special top-level container for the root, - * which you get by calling 'new WebGLUniforms( gl, program, renderer )'. - * - * - * Properties of inner nodes including the top-level container: - * - * .seq - array of nested uniforms - * .map - nested uniforms by name - * - * - * Methods of all nodes except the top-level container: - * - * .setValue( gl, value, [renderer] ) - * - * uploads a uniform value(s) - * the 'renderer' parameter is needed for sampler uniforms - * - * - * Static methods of the top-level container (renderer factorizations): - * - * .upload( gl, seq, values, renderer ) - * - * sets uniforms in 'seq' to 'values[id].value' - * - * .seqWithValue( seq, values ) : filteredSeq - * - * filters 'seq' entries with corresponding entry in values - * - * - * Methods of the top-level container (renderer factorizations): - * - * .setValue( gl, name, value ) - * - * sets uniform with name 'name' to 'value' - * - * .set( gl, obj, prop ) - * - * sets uniform from object and property with same name than uniform - * - * .setOptional( gl, obj, prop ) - * - * like .set for an optional property of the object - * - */ + /** + * @author tschw + * @author Mugen87 / https://github.com/Mugen87 + * @author mrdoob / http://mrdoob.com/ + * + * Uniforms of a program. + * Those form a tree structure with a special top-level container for the root, + * which you get by calling 'new WebGLUniforms( gl, program, renderer )'. + * + * + * Properties of inner nodes including the top-level container: + * + * .seq - array of nested uniforms + * .map - nested uniforms by name + * + * + * Methods of all nodes except the top-level container: + * + * .setValue( gl, value, [renderer] ) + * + * uploads a uniform value(s) + * the 'renderer' parameter is needed for sampler uniforms + * + * + * Static methods of the top-level container (renderer factorizations): + * + * .upload( gl, seq, values, renderer ) + * + * sets uniforms in 'seq' to 'values[id].value' + * + * .seqWithValue( seq, values ) : filteredSeq + * + * filters 'seq' entries with corresponding entry in values + * + * + * Methods of the top-level container (renderer factorizations): + * + * .setValue( gl, name, value ) + * + * sets uniform with name 'name' to 'value' + * + * .set( gl, obj, prop ) + * + * sets uniform from object and property with same name than uniform + * + * .setOptional( gl, obj, prop ) + * + * like .set for an optional property of the object + * + */ - var emptyTexture = new Texture(); - var emptyCubeTexture = new CubeTexture(); + var emptyTexture = new Texture(); + var emptyCubeTexture = new CubeTexture(); - // --- Base for inner nodes (including the root) --- + // --- Base for inner nodes (including the root) --- - function UniformContainer() { + function UniformContainer() { - this.seq = []; - this.map = {}; + this.seq = []; + this.map = {}; - } + } - // --- Utilities --- + // --- Utilities --- - // Array Caches (provide typed arrays for temporary by size) + // Array Caches (provide typed arrays for temporary by size) - var arrayCacheF32 = []; - var arrayCacheI32 = []; + var arrayCacheF32 = []; + var arrayCacheI32 = []; - // Float32Array caches used for uploading Matrix uniforms + // Float32Array caches used for uploading Matrix uniforms - var mat4array = new Float32Array( 16 ); - var mat3array = new Float32Array( 9 ); - var mat2array = new Float32Array( 4 ); + var mat4array = new Float32Array( 16 ); + var mat3array = new Float32Array( 9 ); + var mat2array = new Float32Array( 4 ); - // Flattening for arrays of vectors and matrices + // Flattening for arrays of vectors and matrices - function flatten( array, nBlocks, blockSize ) { + function flatten( array, nBlocks, blockSize ) { - var firstElem = array[ 0 ]; + var firstElem = array[ 0 ]; - if ( firstElem <= 0 || firstElem > 0 ) return array; - // unoptimized: ! isNaN( firstElem ) - // see http://jacksondunstan.com/articles/983 + if ( firstElem <= 0 || firstElem > 0 ) return array; + // unoptimized: ! isNaN( firstElem ) + // see http://jacksondunstan.com/articles/983 - var n = nBlocks * blockSize, - r = arrayCacheF32[ n ]; + var n = nBlocks * blockSize, + r = arrayCacheF32[ n ]; - if ( r === undefined ) { + if ( r === undefined ) { - r = new Float32Array( n ); - arrayCacheF32[ n ] = r; + r = new Float32Array( n ); + arrayCacheF32[ n ] = r; - } + } - if ( nBlocks !== 0 ) { + if ( nBlocks !== 0 ) { - firstElem.toArray( r, 0 ); + firstElem.toArray( r, 0 ); - for ( var i = 1, offset = 0; i !== nBlocks; ++ i ) { + for ( var i = 1, offset = 0; i !== nBlocks; ++ i ) { - offset += blockSize; - array[ i ].toArray( r, offset ); + offset += blockSize; + array[ i ].toArray( r, offset ); - } + } - } + } - return r; + return r; - } + } - function arraysEqual( a, b ) { + function arraysEqual( a, b ) { - if ( a.length !== b.length ) return false; + if ( a.length !== b.length ) return false; - for ( var i = 0, l = a.length; i < l; i ++ ) { + for ( var i = 0, l = a.length; i < l; i ++ ) { - if ( a[ i ] !== b[ i ] ) return false; + if ( a[ i ] !== b[ i ] ) return false; - } + } - return true; + return true; - } + } - function copyArray( a, b ) { + function copyArray( a, b ) { - for ( var i = 0, l = b.length; i < l; i ++ ) { + for ( var i = 0, l = b.length; i < l; i ++ ) { - a[ i ] = b[ i ]; + a[ i ] = b[ i ]; - } + } - } + } - // Texture unit allocation + // Texture unit allocation - function allocTexUnits( renderer, n ) { + function allocTexUnits( renderer, n ) { - var r = arrayCacheI32[ n ]; + var r = arrayCacheI32[ n ]; - if ( r === undefined ) { + if ( r === undefined ) { - r = new Int32Array( n ); - arrayCacheI32[ n ] = r; + r = new Int32Array( n ); + arrayCacheI32[ n ] = r; - } + } - for ( var i = 0; i !== n; ++ i ) - r[ i ] = renderer.allocTextureUnit(); + for ( var i = 0; i !== n; ++ i ) + r[ i ] = renderer.allocTextureUnit(); - return r; + return r; - } + } - // --- Setters --- + // --- Setters --- - // Note: Defining these methods externally, because they come in a bunch - // and this way their names minify. + // Note: Defining these methods externally, because they come in a bunch + // and this way their names minify. - // Single scalar + // Single scalar - function setValue1f( gl, v ) { + function setValue1f( gl, v ) { - var cache = this.cache; + var cache = this.cache; - if ( cache[ 0 ] === v ) return; + if ( cache[ 0 ] === v ) return; - gl.uniform1f( this.addr, v ); + gl.uniform1f( this.addr, v ); - cache[ 0 ] = v; + cache[ 0 ] = v; - } + } - function setValue1i( gl, v ) { + function setValue1i( gl, v ) { - var cache = this.cache; + var cache = this.cache; - if ( cache[ 0 ] === v ) return; + if ( cache[ 0 ] === v ) return; - gl.uniform1i( this.addr, v ); + gl.uniform1i( this.addr, v ); - cache[ 0 ] = v; + cache[ 0 ] = v; - } + } - // Single float vector (from flat array or THREE.VectorN) + // Single float vector (from flat array or THREE.VectorN) - function setValue2fv( gl, v ) { + function setValue2fv( gl, v ) { - var cache = this.cache; + var cache = this.cache; - if ( v.x !== undefined ) { + if ( v.x !== undefined ) { - if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) { + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) { - gl.uniform2f( this.addr, v.x, v.y ); + gl.uniform2f( this.addr, v.x, v.y ); - cache[ 0 ] = v.x; - cache[ 1 ] = v.y; + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; - } + } - } else { + } else { - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) return; - gl.uniform2fv( this.addr, v ); + gl.uniform2fv( this.addr, v ); - copyArray( cache, v ); + copyArray( cache, v ); - } + } - } + } - function setValue3fv( gl, v ) { + function setValue3fv( gl, v ) { - var cache = this.cache; + var cache = this.cache; - if ( v.x !== undefined ) { + if ( v.x !== undefined ) { - if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) { + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) { - gl.uniform3f( this.addr, v.x, v.y, v.z ); + gl.uniform3f( this.addr, v.x, v.y, v.z ); - cache[ 0 ] = v.x; - cache[ 1 ] = v.y; - cache[ 2 ] = v.z; + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + cache[ 2 ] = v.z; - } + } - } else if ( v.r !== undefined ) { + } else if ( v.r !== undefined ) { - if ( cache[ 0 ] !== v.r || cache[ 1 ] !== v.g || cache[ 2 ] !== v.b ) { + if ( cache[ 0 ] !== v.r || cache[ 1 ] !== v.g || cache[ 2 ] !== v.b ) { - gl.uniform3f( this.addr, v.r, v.g, v.b ); + gl.uniform3f( this.addr, v.r, v.g, v.b ); - cache[ 0 ] = v.r; - cache[ 1 ] = v.g; - cache[ 2 ] = v.b; + cache[ 0 ] = v.r; + cache[ 1 ] = v.g; + cache[ 2 ] = v.b; - } + } - } else { + } else { - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) return; - gl.uniform3fv( this.addr, v ); + gl.uniform3fv( this.addr, v ); - copyArray( cache, v ); + copyArray( cache, v ); - } + } - } + } - function setValue4fv( gl, v ) { + function setValue4fv( gl, v ) { - var cache = this.cache; + var cache = this.cache; - if ( v.x !== undefined ) { + if ( v.x !== undefined ) { - if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) { + if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) { - gl.uniform4f( this.addr, v.x, v.y, v.z, v.w ); + gl.uniform4f( this.addr, v.x, v.y, v.z, v.w ); - cache[ 0 ] = v.x; - cache[ 1 ] = v.y; - cache[ 2 ] = v.z; - cache[ 3 ] = v.w; + cache[ 0 ] = v.x; + cache[ 1 ] = v.y; + cache[ 2 ] = v.z; + cache[ 3 ] = v.w; - } + } - } else { + } else { - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) return; - gl.uniform4fv( this.addr, v ); + gl.uniform4fv( this.addr, v ); - copyArray( cache, v ); + copyArray( cache, v ); - } + } - } + } - // Single matrix (from flat array or MatrixN) + // Single matrix (from flat array or MatrixN) - function setValue2fm( gl, v ) { + function setValue2fm( gl, v ) { - var cache = this.cache; - var elements = v.elements; + var cache = this.cache; + var elements = v.elements; - if ( elements === undefined ) { + if ( elements === undefined ) { - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) return; - gl.uniformMatrix2fv( this.addr, false, v ); + gl.uniformMatrix2fv( this.addr, false, v ); - copyArray( cache, v ); + copyArray( cache, v ); - } else { + } else { - if ( arraysEqual( cache, elements ) ) return; + if ( arraysEqual( cache, elements ) ) return; - mat2array.set( elements ); + mat2array.set( elements ); - gl.uniformMatrix2fv( this.addr, false, mat2array ); + gl.uniformMatrix2fv( this.addr, false, mat2array ); - copyArray( cache, elements ); + copyArray( cache, elements ); - } + } - } + } - function setValue3fm( gl, v ) { + function setValue3fm( gl, v ) { - var cache = this.cache; - var elements = v.elements; + var cache = this.cache; + var elements = v.elements; - if ( elements === undefined ) { + if ( elements === undefined ) { - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) return; - gl.uniformMatrix3fv( this.addr, false, v ); + gl.uniformMatrix3fv( this.addr, false, v ); - copyArray( cache, v ); + copyArray( cache, v ); - } else { + } else { - if ( arraysEqual( cache, elements ) ) return; + if ( arraysEqual( cache, elements ) ) return; - mat3array.set( elements ); + mat3array.set( elements ); - gl.uniformMatrix3fv( this.addr, false, mat3array ); + gl.uniformMatrix3fv( this.addr, false, mat3array ); - copyArray( cache, elements ); + copyArray( cache, elements ); - } + } - } + } - function setValue4fm( gl, v ) { + function setValue4fm( gl, v ) { - var cache = this.cache; - var elements = v.elements; + var cache = this.cache; + var elements = v.elements; - if ( elements === undefined ) { + if ( elements === undefined ) { - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) return; - gl.uniformMatrix4fv( this.addr, false, v ); + gl.uniformMatrix4fv( this.addr, false, v ); - copyArray( cache, v ); + copyArray( cache, v ); - } else { + } else { - if ( arraysEqual( cache, elements ) ) return; + if ( arraysEqual( cache, elements ) ) return; - mat4array.set( elements ); + mat4array.set( elements ); - gl.uniformMatrix4fv( this.addr, false, mat4array ); + gl.uniformMatrix4fv( this.addr, false, mat4array ); - copyArray( cache, elements ); + copyArray( cache, elements ); - } + } - } + } - // Single texture (2D / Cube) + // Single texture (2D / Cube) - function setValueT1( gl, v, renderer ) { + function setValueT1( gl, v, renderer ) { - var cache = this.cache; - var unit = renderer.allocTextureUnit(); + var cache = this.cache; + var unit = renderer.allocTextureUnit(); - if ( cache[ 0 ] !== unit ) { + if ( cache[ 0 ] !== unit ) { - gl.uniform1i( this.addr, unit ); - cache[ 0 ] = unit; + gl.uniform1i( this.addr, unit ); + cache[ 0 ] = unit; - } + } - renderer.setTexture2D( v || emptyTexture, unit ); + renderer.setTexture2D( v || emptyTexture, unit ); - } + } - function setValueT6( gl, v, renderer ) { + function setValueT6( gl, v, renderer ) { - var cache = this.cache; - var unit = renderer.allocTextureUnit(); + var cache = this.cache; + var unit = renderer.allocTextureUnit(); - if ( cache[ 0 ] !== unit ) { + if ( cache[ 0 ] !== unit ) { - gl.uniform1i( this.addr, unit ); - cache[ 0 ] = unit; + gl.uniform1i( this.addr, unit ); + cache[ 0 ] = unit; - } + } - renderer.setTextureCube( v || emptyCubeTexture, unit ); + renderer.setTextureCube( v || emptyCubeTexture, unit ); - } + } - // Integer / Boolean vectors or arrays thereof (always flat arrays) + // Integer / Boolean vectors or arrays thereof (always flat arrays) - function setValue2iv( gl, v ) { + function setValue2iv( gl, v ) { - var cache = this.cache; + var cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) return; - gl.uniform2iv( this.addr, v ); + gl.uniform2iv( this.addr, v ); - copyArray( cache, v ); + copyArray( cache, v ); - } + } - function setValue3iv( gl, v ) { + function setValue3iv( gl, v ) { - var cache = this.cache; + var cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) return; - gl.uniform3iv( this.addr, v ); + gl.uniform3iv( this.addr, v ); - copyArray( cache, v ); + copyArray( cache, v ); - } + } - function setValue4iv( gl, v ) { + function setValue4iv( gl, v ) { - var cache = this.cache; + var cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) return; - gl.uniform4iv( this.addr, v ); + gl.uniform4iv( this.addr, v ); - copyArray( cache, v ); + copyArray( cache, v ); - } + } - // Helper to pick the right setter for the singular case + // Helper to pick the right setter for the singular case - function getSingularSetter( type ) { + function getSingularSetter( type ) { - switch ( type ) { + switch ( type ) { - case 0x1406: return setValue1f; // FLOAT - case 0x8b50: return setValue2fv; // _VEC2 - case 0x8b51: return setValue3fv; // _VEC3 - case 0x8b52: return setValue4fv; // _VEC4 + case 0x1406: return setValue1f; // FLOAT + case 0x8b50: return setValue2fv; // _VEC2 + case 0x8b51: return setValue3fv; // _VEC3 + case 0x8b52: return setValue4fv; // _VEC4 - case 0x8b5a: return setValue2fm; // _MAT2 - case 0x8b5b: return setValue3fm; // _MAT3 - case 0x8b5c: return setValue4fm; // _MAT4 + case 0x8b5a: return setValue2fm; // _MAT2 + case 0x8b5b: return setValue3fm; // _MAT3 + case 0x8b5c: return setValue4fm; // _MAT4 - case 0x8b5e: case 0x8d66: return setValueT1; // SAMPLER_2D, SAMPLER_EXTERNAL_OES - case 0x8b60: return setValueT6; // SAMPLER_CUBE + case 0x8b5e: case 0x8d66: return setValueT1; // SAMPLER_2D, SAMPLER_EXTERNAL_OES + case 0x8b60: return setValueT6; // SAMPLER_CUBE - case 0x1404: case 0x8b56: return setValue1i; // INT, BOOL - case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2 - case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3 - case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4 + case 0x1404: case 0x8b56: return setValue1i; // INT, BOOL + case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2 + case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3 + case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4 - } + } - } + } - // Array of scalars + // Array of scalars - function setValue1fv( gl, v ) { + function setValue1fv( gl, v ) { - var cache = this.cache; + var cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) return; - gl.uniform1fv( this.addr, v ); + gl.uniform1fv( this.addr, v ); - copyArray( cache, v ); + copyArray( cache, v ); - } - function setValue1iv( gl, v ) { + } + function setValue1iv( gl, v ) { - var cache = this.cache; + var cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) return; - gl.uniform1iv( this.addr, v ); + gl.uniform1iv( this.addr, v ); - copyArray( cache, v ); + copyArray( cache, v ); - } + } - // Array of vectors (flat or from THREE classes) + // Array of vectors (flat or from THREE classes) - function setValueV2a( gl, v ) { + function setValueV2a( gl, v ) { - var cache = this.cache; - var data = flatten( v, this.size, 2 ); + var cache = this.cache; + var data = flatten( v, this.size, 2 ); - if ( arraysEqual( cache, data ) ) return; + if ( arraysEqual( cache, data ) ) return; - gl.uniform2fv( this.addr, data ); + gl.uniform2fv( this.addr, data ); - this.updateCache( data ); + this.updateCache( data ); - } + } - function setValueV3a( gl, v ) { + function setValueV3a( gl, v ) { - var cache = this.cache; - var data = flatten( v, this.size, 3 ); + var cache = this.cache; + var data = flatten( v, this.size, 3 ); - if ( arraysEqual( cache, data ) ) return; + if ( arraysEqual( cache, data ) ) return; - gl.uniform3fv( this.addr, data ); + gl.uniform3fv( this.addr, data ); - this.updateCache( data ); + this.updateCache( data ); - } + } - function setValueV4a( gl, v ) { + function setValueV4a( gl, v ) { - var cache = this.cache; - var data = flatten( v, this.size, 4 ); + var cache = this.cache; + var data = flatten( v, this.size, 4 ); - if ( arraysEqual( cache, data ) ) return; + if ( arraysEqual( cache, data ) ) return; - gl.uniform4fv( this.addr, data ); + gl.uniform4fv( this.addr, data ); - this.updateCache( data ); + this.updateCache( data ); - } + } - // Array of matrices (flat or from THREE clases) + // Array of matrices (flat or from THREE clases) - function setValueM2a( gl, v ) { + function setValueM2a( gl, v ) { - var cache = this.cache; - var data = flatten( v, this.size, 4 ); + var cache = this.cache; + var data = flatten( v, this.size, 4 ); - if ( arraysEqual( cache, data ) ) return; + if ( arraysEqual( cache, data ) ) return; - gl.uniformMatrix2fv( this.addr, false, data ); + gl.uniformMatrix2fv( this.addr, false, data ); - this.updateCache( data ); + this.updateCache( data ); - } + } - function setValueM3a( gl, v ) { + function setValueM3a( gl, v ) { - var cache = this.cache; - var data = flatten( v, this.size, 9 ); + var cache = this.cache; + var data = flatten( v, this.size, 9 ); - if ( arraysEqual( cache, data ) ) return; + if ( arraysEqual( cache, data ) ) return; - gl.uniformMatrix3fv( this.addr, false, data ); + gl.uniformMatrix3fv( this.addr, false, data ); - this.updateCache( data ); + this.updateCache( data ); - } + } - function setValueM4a( gl, v ) { + function setValueM4a( gl, v ) { - var cache = this.cache; - var data = flatten( v, this.size, 16 ); + var cache = this.cache; + var data = flatten( v, this.size, 16 ); - if ( arraysEqual( cache, data ) ) return; + if ( arraysEqual( cache, data ) ) return; - gl.uniformMatrix4fv( this.addr, false, data ); + gl.uniformMatrix4fv( this.addr, false, data ); - this.updateCache( data ); + this.updateCache( data ); - } + } - // Array of textures (2D / Cube) + // Array of textures (2D / Cube) - function setValueT1a( gl, v, renderer ) { + function setValueT1a( gl, v, renderer ) { - var cache = this.cache; - var n = v.length; + var cache = this.cache; + var n = v.length; - var units = allocTexUnits( renderer, n ); + var units = allocTexUnits( renderer, n ); - if ( arraysEqual( cache, units ) === false ) { + if ( arraysEqual( cache, units ) === false ) { - gl.uniform1iv( this.addr, units ); - copyArray( cache, units ); + gl.uniform1iv( this.addr, units ); + copyArray( cache, units ); - } + } - for ( var i = 0; i !== n; ++ i ) { + for ( var i = 0; i !== n; ++ i ) { - renderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] ); + renderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] ); - } + } - } + } - function setValueT6a( gl, v, renderer ) { + function setValueT6a( gl, v, renderer ) { - var cache = this.cache; - var n = v.length; + var cache = this.cache; + var n = v.length; - var units = allocTexUnits( renderer, n ); + var units = allocTexUnits( renderer, n ); - if ( arraysEqual( cache, units ) === false ) { + if ( arraysEqual( cache, units ) === false ) { - gl.uniform1iv( this.addr, units ); - copyArray( cache, units ); + gl.uniform1iv( this.addr, units ); + copyArray( cache, units ); - } + } - for ( var i = 0; i !== n; ++ i ) { + for ( var i = 0; i !== n; ++ i ) { - renderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] ); + renderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] ); - } + } - } + } - // Helper to pick the right setter for a pure (bottom-level) array + // Helper to pick the right setter for a pure (bottom-level) array - function getPureArraySetter( type ) { + function getPureArraySetter( type ) { - switch ( type ) { + switch ( type ) { - case 0x1406: return setValue1fv; // FLOAT - case 0x8b50: return setValueV2a; // _VEC2 - case 0x8b51: return setValueV3a; // _VEC3 - case 0x8b52: return setValueV4a; // _VEC4 + case 0x1406: return setValue1fv; // FLOAT + case 0x8b50: return setValueV2a; // _VEC2 + case 0x8b51: return setValueV3a; // _VEC3 + case 0x8b52: return setValueV4a; // _VEC4 - case 0x8b5a: return setValueM2a; // _MAT2 - case 0x8b5b: return setValueM3a; // _MAT3 - case 0x8b5c: return setValueM4a; // _MAT4 + case 0x8b5a: return setValueM2a; // _MAT2 + case 0x8b5b: return setValueM3a; // _MAT3 + case 0x8b5c: return setValueM4a; // _MAT4 - case 0x8b5e: return setValueT1a; // SAMPLER_2D - case 0x8b60: return setValueT6a; // SAMPLER_CUBE + case 0x8b5e: return setValueT1a; // SAMPLER_2D + case 0x8b60: return setValueT6a; // SAMPLER_CUBE - case 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL - case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2 - case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3 - case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4 + case 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL + case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2 + case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3 + case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4 - } + } - } + } - // --- Uniform Classes --- + // --- Uniform Classes --- - function SingleUniform( id, activeInfo, addr ) { + function SingleUniform( id, activeInfo, addr ) { - this.id = id; - this.addr = addr; - this.cache = []; - this.setValue = getSingularSetter( activeInfo.type ); + this.id = id; + this.addr = addr; + this.cache = []; + this.setValue = getSingularSetter( activeInfo.type ); - // this.path = activeInfo.name; // DEBUG + // this.path = activeInfo.name; // DEBUG - } + } - function PureArrayUniform( id, activeInfo, addr ) { + function PureArrayUniform( id, activeInfo, addr ) { - this.id = id; - this.addr = addr; - this.cache = []; - this.size = activeInfo.size; - this.setValue = getPureArraySetter( activeInfo.type ); + this.id = id; + this.addr = addr; + this.cache = []; + this.size = activeInfo.size; + this.setValue = getPureArraySetter( activeInfo.type ); - // this.path = activeInfo.name; // DEBUG + // this.path = activeInfo.name; // DEBUG - } + } - PureArrayUniform.prototype.updateCache = function ( data ) { + PureArrayUniform.prototype.updateCache = function ( data ) { - var cache = this.cache; + var cache = this.cache; - if ( data instanceof Float32Array && cache.length !== data.length ) { + if ( data instanceof Float32Array && cache.length !== data.length ) { - this.cache = new Float32Array( data.length ); + this.cache = new Float32Array( data.length ); - } + } - copyArray( cache, data ); + copyArray( cache, data ); - }; + }; - function StructuredUniform( id ) { + function StructuredUniform( id ) { - this.id = id; + this.id = id; - UniformContainer.call( this ); // mix-in + UniformContainer.call( this ); // mix-in - } + } - StructuredUniform.prototype.setValue = function ( gl, value, renderer ) { + StructuredUniform.prototype.setValue = function ( gl, value, renderer ) { - var seq = this.seq; + var seq = this.seq; - for ( var i = 0, n = seq.length; i !== n; ++ i ) { + for ( var i = 0, n = seq.length; i !== n; ++ i ) { - var u = seq[ i ]; - u.setValue( gl, value[ u.id ], renderer ); + var u = seq[ i ]; + u.setValue( gl, value[ u.id ], renderer ); - } + } - }; + }; - // --- Top-level --- + // --- Top-level --- - // Parser - builds up the property tree from the path strings + // Parser - builds up the property tree from the path strings - var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g; + var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g; - // extracts - // - the identifier (member name or array index) - // - followed by an optional right bracket (found when array index) - // - followed by an optional left bracket or dot (type of subscript) - // - // Note: These portions can be read in a non-overlapping fashion and - // allow straightforward parsing of the hierarchy that WebGL encodes - // in the uniform names. + // extracts + // - the identifier (member name or array index) + // - followed by an optional right bracket (found when array index) + // - followed by an optional left bracket or dot (type of subscript) + // + // Note: These portions can be read in a non-overlapping fashion and + // allow straightforward parsing of the hierarchy that WebGL encodes + // in the uniform names. - function addUniform( container, uniformObject ) { + function addUniform( container, uniformObject ) { - container.seq.push( uniformObject ); - container.map[ uniformObject.id ] = uniformObject; + container.seq.push( uniformObject ); + container.map[ uniformObject.id ] = uniformObject; - } + } - function parseUniform( activeInfo, addr, container ) { + function parseUniform( activeInfo, addr, container ) { - var path = activeInfo.name, - pathLength = path.length; + var path = activeInfo.name, + pathLength = path.length; - // reset RegExp object, because of the early exit of a previous run - RePathPart.lastIndex = 0; + // reset RegExp object, because of the early exit of a previous run + RePathPart.lastIndex = 0; - while ( true ) { + while ( true ) { - var match = RePathPart.exec( path ), - matchEnd = RePathPart.lastIndex, + var match = RePathPart.exec( path ), + matchEnd = RePathPart.lastIndex, - id = match[ 1 ], - idIsIndex = match[ 2 ] === ']', - subscript = match[ 3 ]; + id = match[ 1 ], + idIsIndex = match[ 2 ] === ']', + subscript = match[ 3 ]; - if ( idIsIndex ) id = id | 0; // convert to integer + if ( idIsIndex ) id = id | 0; // convert to integer - if ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) { + if ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) { - // bare name or "pure" bottom-level array "[0]" suffix + // bare name or "pure" bottom-level array "[0]" suffix - addUniform( container, subscript === undefined ? - new SingleUniform( id, activeInfo, addr ) : - new PureArrayUniform( id, activeInfo, addr ) ); + addUniform( container, subscript === undefined ? + new SingleUniform( id, activeInfo, addr ) : + new PureArrayUniform( id, activeInfo, addr ) ); - break; + break; - } else { + } else { - // step into inner node / create it in case it doesn't exist + // step into inner node / create it in case it doesn't exist - var map = container.map, next = map[ id ]; + var map = container.map, next = map[ id ]; - if ( next === undefined ) { + if ( next === undefined ) { - next = new StructuredUniform( id ); - addUniform( container, next ); + next = new StructuredUniform( id ); + addUniform( container, next ); - } + } - container = next; + container = next; - } + } - } + } - } + } - // Root Container + // Root Container - function WebGLUniforms( gl, program, renderer ) { + function WebGLUniforms( gl, program, renderer ) { - UniformContainer.call( this ); + UniformContainer.call( this ); - this.renderer = renderer; + this.renderer = renderer; - var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS ); + var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS ); - for ( var i = 0; i < n; ++ i ) { + for ( var i = 0; i < n; ++ i ) { - var info = gl.getActiveUniform( program, i ), - addr = gl.getUniformLocation( program, info.name ); + var info = gl.getActiveUniform( program, i ), + addr = gl.getUniformLocation( program, info.name ); - parseUniform( info, addr, this ); + parseUniform( info, addr, this ); - } + } - } + } - WebGLUniforms.prototype.setValue = function ( gl, name, value ) { + WebGLUniforms.prototype.setValue = function ( gl, name, value ) { - var u = this.map[ name ]; + var u = this.map[ name ]; - if ( u !== undefined ) u.setValue( gl, value, this.renderer ); + if ( u !== undefined ) u.setValue( gl, value, this.renderer ); - }; + }; - WebGLUniforms.prototype.setOptional = function ( gl, object, name ) { + WebGLUniforms.prototype.setOptional = function ( gl, object, name ) { - var v = object[ name ]; + var v = object[ name ]; - if ( v !== undefined ) this.setValue( gl, name, v ); + if ( v !== undefined ) this.setValue( gl, name, v ); - }; + }; - // Static interface + // Static interface - WebGLUniforms.upload = function ( gl, seq, values, renderer ) { + WebGLUniforms.upload = function ( gl, seq, values, renderer ) { - for ( var i = 0, n = seq.length; i !== n; ++ i ) { + for ( var i = 0, n = seq.length; i !== n; ++ i ) { - var u = seq[ i ], - v = values[ u.id ]; + var u = seq[ i ], + v = values[ u.id ]; - if ( v.needsUpdate !== false ) { + if ( v.needsUpdate !== false ) { - // note: always updating when .needsUpdate is undefined - u.setValue( gl, v.value, renderer ); + // note: always updating when .needsUpdate is undefined + u.setValue( gl, v.value, renderer ); - } + } - } + } - }; + }; - WebGLUniforms.seqWithValue = function ( seq, values ) { + WebGLUniforms.seqWithValue = function ( seq, values ) { - var r = []; + var r = []; - for ( var i = 0, n = seq.length; i !== n; ++ i ) { + for ( var i = 0, n = seq.length; i !== n; ++ i ) { - var u = seq[ i ]; - if ( u.id in values ) r.push( u ); + var u = seq[ i ]; + if ( u.id in values ) r.push( u ); - } + } - return r; + return r; - }; + }; - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function addLineNumbers( string ) { + function addLineNumbers( string ) { - var lines = string.split( '\n' ); + var lines = string.split( '\n' ); - for ( var i = 0; i < lines.length; i ++ ) { + for ( var i = 0; i < lines.length; i ++ ) { - lines[ i ] = ( i + 1 ) + ': ' + lines[ i ]; + lines[ i ] = ( i + 1 ) + ': ' + lines[ i ]; - } + } - return lines.join( '\n' ); + return lines.join( '\n' ); - } + } - function WebGLShader( gl, type, string ) { + function WebGLShader( gl, type, string ) { - var shader = gl.createShader( type ); + var shader = gl.createShader( type ); - gl.shaderSource( shader, string ); - gl.compileShader( shader ); + gl.shaderSource( shader, string ); + gl.compileShader( shader ); - if ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) { + if ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) { - console.error( 'THREE.WebGLShader: Shader couldn\'t compile.' ); + console.error( 'THREE.WebGLShader: Shader couldn\'t compile.' ); - } + } - if ( gl.getShaderInfoLog( shader ) !== '' ) { + if ( gl.getShaderInfoLog( shader ) !== '' ) { - console.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) ); + console.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) ); - } + } - // --enable-privileged-webgl-extension - // console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); + // --enable-privileged-webgl-extension + // console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); - return shader; + return shader; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - var programIdCount = 0; + var programIdCount = 0; - function getEncodingComponents( encoding ) { + function getEncodingComponents( encoding ) { - switch ( encoding ) { + switch ( encoding ) { - case LinearEncoding: - return [ 'Linear', '( value )' ]; - case sRGBEncoding: - return [ 'sRGB', '( value )' ]; - case RGBEEncoding: - return [ 'RGBE', '( value )' ]; - case RGBM7Encoding: - return [ 'RGBM', '( value, 7.0 )' ]; - case RGBM16Encoding: - return [ 'RGBM', '( value, 16.0 )' ]; - case RGBDEncoding: - return [ 'RGBD', '( value, 256.0 )' ]; - case GammaEncoding: - return [ 'Gamma', '( value, float( GAMMA_FACTOR ) )' ]; - default: - throw new Error( 'unsupported encoding: ' + encoding ); + case LinearEncoding: + return [ 'Linear', '( value )' ]; + case sRGBEncoding: + return [ 'sRGB', '( value )' ]; + case RGBEEncoding: + return [ 'RGBE', '( value )' ]; + case RGBM7Encoding: + return [ 'RGBM', '( value, 7.0 )' ]; + case RGBM16Encoding: + return [ 'RGBM', '( value, 16.0 )' ]; + case RGBDEncoding: + return [ 'RGBD', '( value, 256.0 )' ]; + case GammaEncoding: + return [ 'Gamma', '( value, float( GAMMA_FACTOR ) )' ]; + default: + throw new Error( 'unsupported encoding: ' + encoding ); - } + } - } + } - function getTexelDecodingFunction( functionName, encoding ) { + function getTexelDecodingFunction( functionName, encoding ) { - var components = getEncodingComponents( encoding ); - return 'vec4 ' + functionName + '( vec4 value ) { return ' + components[ 0 ] + 'ToLinear' + components[ 1 ] + '; }'; + var components = getEncodingComponents( encoding ); + return 'vec4 ' + functionName + '( vec4 value ) { return ' + components[ 0 ] + 'ToLinear' + components[ 1 ] + '; }'; - } + } - function getTexelEncodingFunction( functionName, encoding ) { + function getTexelEncodingFunction( functionName, encoding ) { - var components = getEncodingComponents( encoding ); - return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[ 0 ] + components[ 1 ] + '; }'; + var components = getEncodingComponents( encoding ); + return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[ 0 ] + components[ 1 ] + '; }'; - } + } - function getToneMappingFunction( functionName, toneMapping ) { + function getToneMappingFunction( functionName, toneMapping ) { - var toneMappingName; + var toneMappingName; - switch ( toneMapping ) { + switch ( toneMapping ) { - case LinearToneMapping: - toneMappingName = 'Linear'; - break; + case LinearToneMapping: + toneMappingName = 'Linear'; + break; - case ReinhardToneMapping: - toneMappingName = 'Reinhard'; - break; + case ReinhardToneMapping: + toneMappingName = 'Reinhard'; + break; - case Uncharted2ToneMapping: - toneMappingName = 'Uncharted2'; - break; + case Uncharted2ToneMapping: + toneMappingName = 'Uncharted2'; + break; - case CineonToneMapping: - toneMappingName = 'OptimizedCineon'; - break; + case CineonToneMapping: + toneMappingName = 'OptimizedCineon'; + break; - default: - throw new Error( 'unsupported toneMapping: ' + toneMapping ); + default: + throw new Error( 'unsupported toneMapping: ' + toneMapping ); - } + } - return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }'; + return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }'; - } + } - function generateExtensions( extensions, parameters, rendererExtensions ) { + function generateExtensions( extensions, parameters, rendererExtensions ) { - extensions = extensions || {}; + extensions = extensions || {}; - var chunks = [ - ( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || ( parameters.normalMap && ! parameters.objectSpaceNormalMap ) || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '', - ( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '', - ( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '', - ( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : '' - ]; + var chunks = [ + ( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || ( parameters.normalMap && ! parameters.objectSpaceNormalMap ) || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '', + ( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '', + ( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '', + ( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : '' + ]; - return chunks.filter( filterEmptyLine ).join( '\n' ); + return chunks.filter( filterEmptyLine ).join( '\n' ); - } + } - function generateDefines( defines ) { + function generateDefines( defines ) { - var chunks = []; + var chunks = []; - for ( var name in defines ) { + for ( var name in defines ) { - var value = defines[ name ]; + var value = defines[ name ]; - if ( value === false ) continue; + if ( value === false ) continue; - chunks.push( '#define ' + name + ' ' + value ); + chunks.push( '#define ' + name + ' ' + value ); - } + } - return chunks.join( '\n' ); + return chunks.join( '\n' ); - } + } - function fetchAttributeLocations( gl, program ) { + function fetchAttributeLocations( gl, program ) { - var attributes = {}; + var attributes = {}; - var n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES ); + var n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES ); - for ( var i = 0; i < n; i ++ ) { + for ( var i = 0; i < n; i ++ ) { - var info = gl.getActiveAttrib( program, i ); - var name = info.name; + var info = gl.getActiveAttrib( program, i ); + var name = info.name; - // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i ); + // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i ); - attributes[ name ] = gl.getAttribLocation( program, name ); + attributes[ name ] = gl.getAttribLocation( program, name ); - } + } - return attributes; + return attributes; - } + } - function filterEmptyLine( string ) { + function filterEmptyLine( string ) { - return string !== ''; + return string !== ''; - } + } - function replaceLightNums( string, parameters ) { + function replaceLightNums( string, parameters ) { - return string - .replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights ) - .replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights ) - .replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights ) - .replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights ) - .replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights ); + return string + .replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights ) + .replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights ) + .replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights ) + .replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights ) + .replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights ); - } + } - function replaceClippingPlaneNums( string, parameters ) { + function replaceClippingPlaneNums( string, parameters ) { - return string - .replace( /NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes ) - .replace( /UNION_CLIPPING_PLANES/g, ( parameters.numClippingPlanes - parameters.numClipIntersection ) ); + return string + .replace( /NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes ) + .replace( /UNION_CLIPPING_PLANES/g, ( parameters.numClippingPlanes - parameters.numClipIntersection ) ); - } + } - function parseIncludes( string ) { + function parseIncludes( string ) { - var pattern = /^[ \t]*#include +<([\w\d./]+)>/gm; + var pattern = /^[ \t]*#include +<([\w\d./]+)>/gm; - function replace( match, include ) { + function replace( match, include ) { - var replace = ShaderChunk[ include ]; + var replace = ShaderChunk[ include ]; - if ( replace === undefined ) { + if ( replace === undefined ) { - throw new Error( 'Can not resolve #include <' + include + '>' ); + throw new Error( 'Can not resolve #include <' + include + '>' ); - } + } - return parseIncludes( replace ); + return parseIncludes( replace ); - } + } - return string.replace( pattern, replace ); + return string.replace( pattern, replace ); - } + } - function unrollLoops( string ) { + function unrollLoops( string ) { - var pattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; + var pattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; - function replace( match, start, end, snippet ) { + function replace( match, start, end, snippet ) { - var unroll = ''; + var unroll = ''; - for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) { + for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) { - unroll += snippet.replace( /\[ i \]/g, '[ ' + i + ' ]' ); + unroll += snippet.replace( /\[ i \]/g, '[ ' + i + ' ]' ); - } + } - return unroll; + return unroll; - } + } - return string.replace( pattern, replace ); + return string.replace( pattern, replace ); - } + } - function WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities ) { + function WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities ) { - var gl = renderer.context; + var gl = renderer.context; - var defines = material.defines; + var defines = material.defines; - var vertexShader = shader.vertexShader; - var fragmentShader = shader.fragmentShader; + var vertexShader = shader.vertexShader; + var fragmentShader = shader.fragmentShader; - var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; + var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; - if ( parameters.shadowMapType === PCFShadowMap ) { + if ( parameters.shadowMapType === PCFShadowMap ) { - shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF'; + shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF'; - } else if ( parameters.shadowMapType === PCFSoftShadowMap ) { + } else if ( parameters.shadowMapType === PCFSoftShadowMap ) { - shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; + shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; - } + } - var envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; - var envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; - var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; + var envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; + var envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; + var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; - if ( parameters.envMap ) { + if ( parameters.envMap ) { - switch ( material.envMap.mapping ) { + switch ( material.envMap.mapping ) { - case CubeReflectionMapping: - case CubeRefractionMapping: - envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; - break; + case CubeReflectionMapping: + case CubeRefractionMapping: + envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; + break; - case CubeUVReflectionMapping: - case CubeUVRefractionMapping: - envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV'; - break; + case CubeUVReflectionMapping: + case CubeUVRefractionMapping: + envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV'; + break; - case EquirectangularReflectionMapping: - case EquirectangularRefractionMapping: - envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC'; - break; + case EquirectangularReflectionMapping: + case EquirectangularRefractionMapping: + envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC'; + break; - case SphericalReflectionMapping: - envMapTypeDefine = 'ENVMAP_TYPE_SPHERE'; - break; + case SphericalReflectionMapping: + envMapTypeDefine = 'ENVMAP_TYPE_SPHERE'; + break; - } + } - switch ( material.envMap.mapping ) { + switch ( material.envMap.mapping ) { - case CubeRefractionMapping: - case EquirectangularRefractionMapping: - envMapModeDefine = 'ENVMAP_MODE_REFRACTION'; - break; + case CubeRefractionMapping: + case EquirectangularRefractionMapping: + envMapModeDefine = 'ENVMAP_MODE_REFRACTION'; + break; - } + } - switch ( material.combine ) { + switch ( material.combine ) { - case MultiplyOperation: - envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; - break; + case MultiplyOperation: + envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; + break; - case MixOperation: - envMapBlendingDefine = 'ENVMAP_BLENDING_MIX'; - break; + case MixOperation: + envMapBlendingDefine = 'ENVMAP_BLENDING_MIX'; + break; - case AddOperation: - envMapBlendingDefine = 'ENVMAP_BLENDING_ADD'; - break; + case AddOperation: + envMapBlendingDefine = 'ENVMAP_BLENDING_ADD'; + break; - } + } - } + } - var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0; + var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0; - // console.log( 'building new program ' ); + // console.log( 'building new program ' ); - // + // - var customExtensions = capabilities.isWebGL2 ? '' : generateExtensions( material.extensions, parameters, extensions ); + var customExtensions = capabilities.isWebGL2 ? '' : generateExtensions( material.extensions, parameters, extensions ); - var customDefines = generateDefines( defines ); + var customDefines = generateDefines( defines ); - // + // - var program = gl.createProgram(); + var program = gl.createProgram(); - var prefixVertex, prefixFragment; + var prefixVertex, prefixFragment; - if ( material.isRawShaderMaterial ) { + if ( material.isRawShaderMaterial ) { - prefixVertex = [ + prefixVertex = [ - customDefines + customDefines - ].filter( filterEmptyLine ).join( '\n' ); + ].filter( filterEmptyLine ).join( '\n' ); - if ( prefixVertex.length > 0 ) { + if ( prefixVertex.length > 0 ) { - prefixVertex += '\n'; + prefixVertex += '\n'; - } + } - prefixFragment = [ + prefixFragment = [ - customExtensions, - customDefines + customExtensions, + customDefines - ].filter( filterEmptyLine ).join( '\n' ); + ].filter( filterEmptyLine ).join( '\n' ); - if ( prefixFragment.length > 0 ) { + if ( prefixFragment.length > 0 ) { - prefixFragment += '\n'; + prefixFragment += '\n'; - } + } - } else { + } else { - prefixVertex = [ + prefixVertex = [ - 'precision ' + parameters.precision + ' float;', - 'precision ' + parameters.precision + ' int;', + 'precision ' + parameters.precision + ' float;', + 'precision ' + parameters.precision + ' int;', - '#define SHADER_NAME ' + shader.name, + '#define SHADER_NAME ' + shader.name, - customDefines, + customDefines, - parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '', + parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '', - '#define GAMMA_FACTOR ' + gammaFactorDefine, + '#define GAMMA_FACTOR ' + gammaFactorDefine, - '#define MAX_BONES ' + parameters.maxBones, - ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', - ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '', + '#define MAX_BONES ' + parameters.maxBones, + ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', + ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '', - parameters.map ? '#define USE_MAP' : '', - parameters.envMap ? '#define USE_ENVMAP' : '', - parameters.envMap ? '#define ' + envMapModeDefine : '', - parameters.lightMap ? '#define USE_LIGHTMAP' : '', - parameters.aoMap ? '#define USE_AOMAP' : '', - parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', - parameters.bumpMap ? '#define USE_BUMPMAP' : '', - parameters.normalMap ? '#define USE_NORMALMAP' : '', - ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '', - parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', - parameters.specularMap ? '#define USE_SPECULARMAP' : '', - parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', - parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', - parameters.alphaMap ? '#define USE_ALPHAMAP' : '', - parameters.vertexColors ? '#define USE_COLOR' : '', + parameters.map ? '#define USE_MAP' : '', + parameters.envMap ? '#define USE_ENVMAP' : '', + parameters.envMap ? '#define ' + envMapModeDefine : '', + parameters.lightMap ? '#define USE_LIGHTMAP' : '', + parameters.aoMap ? '#define USE_AOMAP' : '', + parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', + parameters.bumpMap ? '#define USE_BUMPMAP' : '', + parameters.normalMap ? '#define USE_NORMALMAP' : '', + ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '', + parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', + parameters.specularMap ? '#define USE_SPECULARMAP' : '', + parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', + parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', + parameters.alphaMap ? '#define USE_ALPHAMAP' : '', + parameters.vertexColors ? '#define USE_COLOR' : '', - parameters.flatShading ? '#define FLAT_SHADED' : '', + parameters.flatShading ? '#define FLAT_SHADED' : '', - parameters.skinning ? '#define USE_SKINNING' : '', - parameters.useVertexTexture ? '#define BONE_TEXTURE' : '', + parameters.skinning ? '#define USE_SKINNING' : '', + parameters.useVertexTexture ? '#define BONE_TEXTURE' : '', - parameters.morphTargets ? '#define USE_MORPHTARGETS' : '', - parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '', - parameters.doubleSided ? '#define DOUBLE_SIDED' : '', - parameters.flipSided ? '#define FLIP_SIDED' : '', + parameters.morphTargets ? '#define USE_MORPHTARGETS' : '', + parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '', + parameters.doubleSided ? '#define DOUBLE_SIDED' : '', + parameters.flipSided ? '#define FLIP_SIDED' : '', - parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', - parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', + parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', + parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', - parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '', + parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '', - parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', - parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '', + parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', + parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '', - 'uniform mat4 modelMatrix;', - 'uniform mat4 modelViewMatrix;', - 'uniform mat4 projectionMatrix;', - 'uniform mat4 viewMatrix;', - 'uniform mat3 normalMatrix;', - 'uniform vec3 cameraPosition;', + 'uniform mat4 modelMatrix;', + 'uniform mat4 modelViewMatrix;', + 'uniform mat4 projectionMatrix;', + 'uniform mat4 viewMatrix;', + 'uniform mat3 normalMatrix;', + 'uniform vec3 cameraPosition;', - 'attribute vec3 position;', - 'attribute vec3 normal;', - 'attribute vec2 uv;', + 'attribute vec3 position;', + 'attribute vec3 normal;', + 'attribute vec2 uv;', - '#ifdef USE_COLOR', + '#ifdef USE_COLOR', - ' attribute vec3 color;', + ' attribute vec3 color;', - '#endif', + '#endif', - '#ifdef USE_MORPHTARGETS', + '#ifdef USE_MORPHTARGETS', - ' attribute vec3 morphTarget0;', - ' attribute vec3 morphTarget1;', - ' attribute vec3 morphTarget2;', - ' attribute vec3 morphTarget3;', + ' attribute vec3 morphTarget0;', + ' attribute vec3 morphTarget1;', + ' attribute vec3 morphTarget2;', + ' attribute vec3 morphTarget3;', - ' #ifdef USE_MORPHNORMALS', + ' #ifdef USE_MORPHNORMALS', - ' attribute vec3 morphNormal0;', - ' attribute vec3 morphNormal1;', - ' attribute vec3 morphNormal2;', - ' attribute vec3 morphNormal3;', + ' attribute vec3 morphNormal0;', + ' attribute vec3 morphNormal1;', + ' attribute vec3 morphNormal2;', + ' attribute vec3 morphNormal3;', - ' #else', + ' #else', - ' attribute vec3 morphTarget4;', - ' attribute vec3 morphTarget5;', - ' attribute vec3 morphTarget6;', - ' attribute vec3 morphTarget7;', + ' attribute vec3 morphTarget4;', + ' attribute vec3 morphTarget5;', + ' attribute vec3 morphTarget6;', + ' attribute vec3 morphTarget7;', - ' #endif', + ' #endif', - '#endif', + '#endif', - '#ifdef USE_SKINNING', + '#ifdef USE_SKINNING', - ' attribute vec4 skinIndex;', - ' attribute vec4 skinWeight;', + ' attribute vec4 skinIndex;', + ' attribute vec4 skinWeight;', - '#endif', + '#endif', - '\n' + '\n' - ].filter( filterEmptyLine ).join( '\n' ); + ].filter( filterEmptyLine ).join( '\n' ); - prefixFragment = [ + prefixFragment = [ - customExtensions, + customExtensions, - 'precision ' + parameters.precision + ' float;', - 'precision ' + parameters.precision + ' int;', + 'precision ' + parameters.precision + ' float;', + 'precision ' + parameters.precision + ' int;', - '#define SHADER_NAME ' + shader.name, + '#define SHADER_NAME ' + shader.name, - customDefines, + customDefines, - parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest + ( parameters.alphaTest % 1 ? '' : '.0' ) : '', // add '.0' if integer + parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest + ( parameters.alphaTest % 1 ? '' : '.0' ) : '', // add '.0' if integer - '#define GAMMA_FACTOR ' + gammaFactorDefine, + '#define GAMMA_FACTOR ' + gammaFactorDefine, - ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', - ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '', + ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', + ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '', - parameters.map ? '#define USE_MAP' : '', - parameters.envMap ? '#define USE_ENVMAP' : '', - parameters.envMap ? '#define ' + envMapTypeDefine : '', - parameters.envMap ? '#define ' + envMapModeDefine : '', - parameters.envMap ? '#define ' + envMapBlendingDefine : '', - parameters.lightMap ? '#define USE_LIGHTMAP' : '', - parameters.aoMap ? '#define USE_AOMAP' : '', - parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', - parameters.bumpMap ? '#define USE_BUMPMAP' : '', - parameters.normalMap ? '#define USE_NORMALMAP' : '', - ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '', - parameters.specularMap ? '#define USE_SPECULARMAP' : '', - parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', - parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', - parameters.alphaMap ? '#define USE_ALPHAMAP' : '', - parameters.vertexColors ? '#define USE_COLOR' : '', + parameters.map ? '#define USE_MAP' : '', + parameters.envMap ? '#define USE_ENVMAP' : '', + parameters.envMap ? '#define ' + envMapTypeDefine : '', + parameters.envMap ? '#define ' + envMapModeDefine : '', + parameters.envMap ? '#define ' + envMapBlendingDefine : '', + parameters.lightMap ? '#define USE_LIGHTMAP' : '', + parameters.aoMap ? '#define USE_AOMAP' : '', + parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', + parameters.bumpMap ? '#define USE_BUMPMAP' : '', + parameters.normalMap ? '#define USE_NORMALMAP' : '', + ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '', + parameters.specularMap ? '#define USE_SPECULARMAP' : '', + parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', + parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', + parameters.alphaMap ? '#define USE_ALPHAMAP' : '', + parameters.vertexColors ? '#define USE_COLOR' : '', - parameters.gradientMap ? '#define USE_GRADIENTMAP' : '', + parameters.gradientMap ? '#define USE_GRADIENTMAP' : '', - parameters.flatShading ? '#define FLAT_SHADED' : '', + parameters.flatShading ? '#define FLAT_SHADED' : '', - parameters.doubleSided ? '#define DOUBLE_SIDED' : '', - parameters.flipSided ? '#define FLIP_SIDED' : '', + parameters.doubleSided ? '#define DOUBLE_SIDED' : '', + parameters.flipSided ? '#define FLIP_SIDED' : '', - parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', - parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', + parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', + parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', - parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '', + parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '', - parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '', + parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '', - parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', - parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '', + parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', + parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '', - parameters.envMap && ( capabilities.isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) ) ? '#define TEXTURE_LOD_EXT' : '', + parameters.envMap && ( capabilities.isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) ) ? '#define TEXTURE_LOD_EXT' : '', - 'uniform mat4 viewMatrix;', - 'uniform vec3 cameraPosition;', + 'uniform mat4 viewMatrix;', + 'uniform vec3 cameraPosition;', - ( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '', - ( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below - ( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '', + ( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '', + ( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below + ( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '', - parameters.dithering ? '#define DITHERING' : '', + parameters.dithering ? '#define DITHERING' : '', - ( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below - parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '', - parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '', - parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '', - parameters.outputEncoding ? getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ) : '', + ( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below + parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '', + parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '', + parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '', + parameters.outputEncoding ? getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ) : '', - parameters.depthPacking ? '#define DEPTH_PACKING ' + material.depthPacking : '', + parameters.depthPacking ? '#define DEPTH_PACKING ' + material.depthPacking : '', - '\n' + '\n' - ].filter( filterEmptyLine ).join( '\n' ); + ].filter( filterEmptyLine ).join( '\n' ); - } + } - vertexShader = parseIncludes( vertexShader ); - vertexShader = replaceLightNums( vertexShader, parameters ); - vertexShader = replaceClippingPlaneNums( vertexShader, parameters ); + vertexShader = parseIncludes( vertexShader ); + vertexShader = replaceLightNums( vertexShader, parameters ); + vertexShader = replaceClippingPlaneNums( vertexShader, parameters ); - fragmentShader = parseIncludes( fragmentShader ); - fragmentShader = replaceLightNums( fragmentShader, parameters ); - fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters ); + fragmentShader = parseIncludes( fragmentShader ); + fragmentShader = replaceLightNums( fragmentShader, parameters ); + fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters ); - vertexShader = unrollLoops( vertexShader ); - fragmentShader = unrollLoops( fragmentShader ); + vertexShader = unrollLoops( vertexShader ); + fragmentShader = unrollLoops( fragmentShader ); - if ( capabilities.isWebGL2 && ! material.isRawShaderMaterial ) { + if ( capabilities.isWebGL2 && ! material.isRawShaderMaterial ) { - var isGLSL3ShaderMaterial = false; + var isGLSL3ShaderMaterial = false; - var versionRegex = /^\s*#version\s+300\s+es\s*\n/; + var versionRegex = /^\s*#version\s+300\s+es\s*\n/; - if ( material.isShaderMaterial && - vertexShader.match( versionRegex ) !== null && - fragmentShader.match( versionRegex ) !== null ) { + if ( material.isShaderMaterial && + vertexShader.match( versionRegex ) !== null && + fragmentShader.match( versionRegex ) !== null ) { - isGLSL3ShaderMaterial = true; + isGLSL3ShaderMaterial = true; - vertexShader = vertexShader.replace( versionRegex, '' ); - fragmentShader = fragmentShader.replace( versionRegex, '' ); + vertexShader = vertexShader.replace( versionRegex, '' ); + fragmentShader = fragmentShader.replace( versionRegex, '' ); - } + } - // GLSL 3.0 conversion - prefixVertex = [ - '#version 300 es\n', - '#define attribute in', - '#define varying out', - '#define texture2D texture' - ].join( '\n' ) + '\n' + prefixVertex; + // GLSL 3.0 conversion + prefixVertex = [ + '#version 300 es\n', + '#define attribute in', + '#define varying out', + '#define texture2D texture' + ].join( '\n' ) + '\n' + prefixVertex; - prefixFragment = [ - '#version 300 es\n', - '#define varying in', - isGLSL3ShaderMaterial ? '' : 'out highp vec4 pc_fragColor;', - isGLSL3ShaderMaterial ? '' : '#define gl_FragColor pc_fragColor', - '#define gl_FragDepthEXT gl_FragDepth', - '#define texture2D texture', - '#define textureCube texture', - '#define texture2DProj textureProj', - '#define texture2DLodEXT textureLod', - '#define texture2DProjLodEXT textureProjLod', - '#define textureCubeLodEXT textureLod', - '#define texture2DGradEXT textureGrad', - '#define texture2DProjGradEXT textureProjGrad', - '#define textureCubeGradEXT textureGrad' - ].join( '\n' ) + '\n' + prefixFragment; + prefixFragment = [ + '#version 300 es\n', + '#define varying in', + isGLSL3ShaderMaterial ? '' : 'out highp vec4 pc_fragColor;', + isGLSL3ShaderMaterial ? '' : '#define gl_FragColor pc_fragColor', + '#define gl_FragDepthEXT gl_FragDepth', + '#define texture2D texture', + '#define textureCube texture', + '#define texture2DProj textureProj', + '#define texture2DLodEXT textureLod', + '#define texture2DProjLodEXT textureProjLod', + '#define textureCubeLodEXT textureLod', + '#define texture2DGradEXT textureGrad', + '#define texture2DProjGradEXT textureProjGrad', + '#define textureCubeGradEXT textureGrad' + ].join( '\n' ) + '\n' + prefixFragment; - } + } - var vertexGlsl = prefixVertex + vertexShader; - var fragmentGlsl = prefixFragment + fragmentShader; + var vertexGlsl = prefixVertex + vertexShader; + var fragmentGlsl = prefixFragment + fragmentShader; - // console.log( '*VERTEX*', vertexGlsl ); - // console.log( '*FRAGMENT*', fragmentGlsl ); + // console.log( '*VERTEX*', vertexGlsl ); + // console.log( '*FRAGMENT*', fragmentGlsl ); - var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl ); - var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl ); + var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl ); + var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl ); - gl.attachShader( program, glVertexShader ); - gl.attachShader( program, glFragmentShader ); + gl.attachShader( program, glVertexShader ); + gl.attachShader( program, glFragmentShader ); - // Force a particular attribute to index 0. + // Force a particular attribute to index 0. - if ( material.index0AttributeName !== undefined ) { + if ( material.index0AttributeName !== undefined ) { - gl.bindAttribLocation( program, 0, material.index0AttributeName ); + gl.bindAttribLocation( program, 0, material.index0AttributeName ); - } else if ( parameters.morphTargets === true ) { + } else if ( parameters.morphTargets === true ) { - // programs with morphTargets displace position out of attribute 0 - gl.bindAttribLocation( program, 0, 'position' ); + // programs with morphTargets displace position out of attribute 0 + gl.bindAttribLocation( program, 0, 'position' ); - } + } - gl.linkProgram( program ); + gl.linkProgram( program ); - var programLog = gl.getProgramInfoLog( program ).trim(); - var vertexLog = gl.getShaderInfoLog( glVertexShader ).trim(); - var fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim(); + var programLog = gl.getProgramInfoLog( program ).trim(); + var vertexLog = gl.getShaderInfoLog( glVertexShader ).trim(); + var fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim(); - var runnable = true; - var haveDiagnostics = true; + var runnable = true; + var haveDiagnostics = true; - // console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) ); - // console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) ); + // console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) ); + // console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) ); - if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) { + if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) { - runnable = false; + runnable = false; - console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog ); + console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog ); - } else if ( programLog !== '' ) { + } else if ( programLog !== '' ) { - console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog ); + console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog ); - } else if ( vertexLog === '' || fragmentLog === '' ) { + } else if ( vertexLog === '' || fragmentLog === '' ) { - haveDiagnostics = false; + haveDiagnostics = false; - } + } - if ( haveDiagnostics ) { + if ( haveDiagnostics ) { - this.diagnostics = { + this.diagnostics = { - runnable: runnable, - material: material, + runnable: runnable, + material: material, - programLog: programLog, + programLog: programLog, - vertexShader: { + vertexShader: { - log: vertexLog, - prefix: prefixVertex + log: vertexLog, + prefix: prefixVertex - }, + }, - fragmentShader: { + fragmentShader: { - log: fragmentLog, - prefix: prefixFragment + log: fragmentLog, + prefix: prefixFragment - } + } - }; + }; - } + } - // clean up + // clean up - gl.deleteShader( glVertexShader ); - gl.deleteShader( glFragmentShader ); + gl.deleteShader( glVertexShader ); + gl.deleteShader( glFragmentShader ); - // set up caching for uniform locations + // set up caching for uniform locations - var cachedUniforms; + var cachedUniforms; - this.getUniforms = function () { + this.getUniforms = function () { - if ( cachedUniforms === undefined ) { + if ( cachedUniforms === undefined ) { - cachedUniforms = new WebGLUniforms( gl, program, renderer ); + cachedUniforms = new WebGLUniforms( gl, program, renderer ); - } + } - return cachedUniforms; + return cachedUniforms; - }; + }; - // set up caching for attribute locations + // set up caching for attribute locations - var cachedAttributes; + var cachedAttributes; - this.getAttributes = function () { + this.getAttributes = function () { - if ( cachedAttributes === undefined ) { + if ( cachedAttributes === undefined ) { - cachedAttributes = fetchAttributeLocations( gl, program ); + cachedAttributes = fetchAttributeLocations( gl, program ); - } + } - return cachedAttributes; + return cachedAttributes; - }; + }; - // free resource + // free resource - this.destroy = function () { + this.destroy = function () { - gl.deleteProgram( program ); - this.program = undefined; + gl.deleteProgram( program ); + this.program = undefined; - }; + }; - // DEPRECATED + // DEPRECATED - Object.defineProperties( this, { + Object.defineProperties( this, { - uniforms: { - get: function () { + uniforms: { + get: function () { - console.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' ); - return this.getUniforms(); + console.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' ); + return this.getUniforms(); - } - }, + } + }, - attributes: { - get: function () { + attributes: { + get: function () { - console.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' ); - return this.getAttributes(); + console.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' ); + return this.getAttributes(); - } - } + } + } - } ); + } ); - // + // - this.name = shader.name; - this.id = programIdCount ++; - this.code = code; - this.usedTimes = 1; - this.program = program; - this.vertexShader = glVertexShader; - this.fragmentShader = glFragmentShader; + this.name = shader.name; + this.id = programIdCount ++; + this.code = code; + this.usedTimes = 1; + this.program = program; + this.vertexShader = glVertexShader; + this.fragmentShader = glFragmentShader; - return this; + return this; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function WebGLPrograms( renderer, extensions, capabilities ) { + function WebGLPrograms( renderer, extensions, capabilities ) { - var programs = []; + var programs = []; - var shaderIDs = { - MeshDepthMaterial: 'depth', - MeshDistanceMaterial: 'distanceRGBA', - MeshNormalMaterial: 'normal', - MeshBasicMaterial: 'basic', - MeshLambertMaterial: 'lambert', - MeshPhongMaterial: 'phong', - MeshToonMaterial: 'phong', - MeshStandardMaterial: 'physical', - MeshPhysicalMaterial: 'physical', - LineBasicMaterial: 'basic', - LineDashedMaterial: 'dashed', - PointsMaterial: 'points', - ShadowMaterial: 'shadow', - SpriteMaterial: 'sprite' - }; + var shaderIDs = { + MeshDepthMaterial: 'depth', + MeshDistanceMaterial: 'distanceRGBA', + MeshNormalMaterial: 'normal', + MeshBasicMaterial: 'basic', + MeshLambertMaterial: 'lambert', + MeshPhongMaterial: 'phong', + MeshToonMaterial: 'phong', + MeshStandardMaterial: 'physical', + MeshPhysicalMaterial: 'physical', + LineBasicMaterial: 'basic', + LineDashedMaterial: 'dashed', + PointsMaterial: 'points', + ShadowMaterial: 'shadow', + SpriteMaterial: 'sprite' + }; - var parameterNames = [ - "precision", "supportsVertexTextures", "map", "mapEncoding", "envMap", "envMapMode", "envMapEncoding", - "lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "displacementMap", "specularMap", - "roughnessMap", "metalnessMap", "gradientMap", - "alphaMap", "combine", "vertexColors", "fog", "useFog", "fogExp", - "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning", - "maxBones", "useVertexTexture", "morphTargets", "morphNormals", - "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha", - "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights", - "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights', - "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering" - ]; + var parameterNames = [ + "precision", "supportsVertexTextures", "map", "mapEncoding", "envMap", "envMapMode", "envMapEncoding", + "lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "displacementMap", "specularMap", + "roughnessMap", "metalnessMap", "gradientMap", + "alphaMap", "combine", "vertexColors", "fog", "useFog", "fogExp", + "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning", + "maxBones", "useVertexTexture", "morphTargets", "morphNormals", + "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha", + "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights", + "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights', + "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering" + ]; - function allocateBones( object ) { + function allocateBones( object ) { - var skeleton = object.skeleton; - var bones = skeleton.bones; + var skeleton = object.skeleton; + var bones = skeleton.bones; - if ( capabilities.floatVertexTextures ) { + if ( capabilities.floatVertexTextures ) { - return 1024; + return 1024; - } else { + } else { - // default for when object is not specified - // ( for example when prebuilding shader to be used with multiple objects ) - // - // - leave some extra space for other uniforms - // - limit here is ANGLE's 254 max uniform vectors - // (up to 54 should be safe) + // default for when object is not specified + // ( for example when prebuilding shader to be used with multiple objects ) + // + // - leave some extra space for other uniforms + // - limit here is ANGLE's 254 max uniform vectors + // (up to 54 should be safe) - var nVertexUniforms = capabilities.maxVertexUniforms; - var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 ); + var nVertexUniforms = capabilities.maxVertexUniforms; + var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 ); - var maxBones = Math.min( nVertexMatrices, bones.length ); + var maxBones = Math.min( nVertexMatrices, bones.length ); - if ( maxBones < bones.length ) { + if ( maxBones < bones.length ) { - console.warn( 'THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.' ); - return 0; + console.warn( 'THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.' ); + return 0; - } + } - return maxBones; + return maxBones; - } + } - } + } - function getTextureEncodingFromMap( map, gammaOverrideLinear ) { + function getTextureEncodingFromMap( map, gammaOverrideLinear ) { - var encoding; + var encoding; - if ( ! map ) { + if ( ! map ) { - encoding = LinearEncoding; + encoding = LinearEncoding; - } else if ( map.isTexture ) { + } else if ( map.isTexture ) { - encoding = map.encoding; + encoding = map.encoding; - } else if ( map.isWebGLRenderTarget ) { + } else if ( map.isWebGLRenderTarget ) { - console.warn( "THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead." ); - encoding = map.texture.encoding; + console.warn( "THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead." ); + encoding = map.texture.encoding; - } + } - // add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point. - if ( encoding === LinearEncoding && gammaOverrideLinear ) { + // add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point. + if ( encoding === LinearEncoding && gammaOverrideLinear ) { - encoding = GammaEncoding; + encoding = GammaEncoding; - } + } - return encoding; + return encoding; - } + } - this.getParameters = function ( material, lights, shadows, fog, nClipPlanes, nClipIntersection, object ) { + this.getParameters = function ( material, lights, shadows, fog, nClipPlanes, nClipIntersection, object ) { - var shaderID = shaderIDs[ material.type ]; + var shaderID = shaderIDs[ material.type ]; - // heuristics to create shader parameters according to lights in the scene - // (not to blow over maxLights budget) + // heuristics to create shader parameters according to lights in the scene + // (not to blow over maxLights budget) - var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0; - var precision = capabilities.precision; + var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0; + var precision = capabilities.precision; - if ( material.precision !== null ) { + if ( material.precision !== null ) { - precision = capabilities.getMaxPrecision( material.precision ); + precision = capabilities.getMaxPrecision( material.precision ); - if ( precision !== material.precision ) { + if ( precision !== material.precision ) { - console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' ); + console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' ); - } + } - } + } - var currentRenderTarget = renderer.getRenderTarget(); + var currentRenderTarget = renderer.getRenderTarget(); - var parameters = { + var parameters = { - shaderID: shaderID, + shaderID: shaderID, - precision: precision, - supportsVertexTextures: capabilities.vertexTextures, - outputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ), - map: !! material.map, - mapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ), - envMap: !! material.envMap, - envMapMode: material.envMap && material.envMap.mapping, - envMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ), - envMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ), - lightMap: !! material.lightMap, - aoMap: !! material.aoMap, - emissiveMap: !! material.emissiveMap, - emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ), - bumpMap: !! material.bumpMap, - normalMap: !! material.normalMap, - objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap, - displacementMap: !! material.displacementMap, - roughnessMap: !! material.roughnessMap, - metalnessMap: !! material.metalnessMap, - specularMap: !! material.specularMap, - alphaMap: !! material.alphaMap, + precision: precision, + supportsVertexTextures: capabilities.vertexTextures, + outputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ), + map: !! material.map, + mapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ), + envMap: !! material.envMap, + envMapMode: material.envMap && material.envMap.mapping, + envMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ), + envMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ), + lightMap: !! material.lightMap, + aoMap: !! material.aoMap, + emissiveMap: !! material.emissiveMap, + emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ), + bumpMap: !! material.bumpMap, + normalMap: !! material.normalMap, + objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap, + displacementMap: !! material.displacementMap, + roughnessMap: !! material.roughnessMap, + metalnessMap: !! material.metalnessMap, + specularMap: !! material.specularMap, + alphaMap: !! material.alphaMap, - gradientMap: !! material.gradientMap, + gradientMap: !! material.gradientMap, - combine: material.combine, + combine: material.combine, - vertexColors: material.vertexColors, + vertexColors: material.vertexColors, - fog: !! fog, - useFog: material.fog, - fogExp: ( fog && fog.isFogExp2 ), + fog: !! fog, + useFog: material.fog, + fogExp: ( fog && fog.isFogExp2 ), - flatShading: material.flatShading, + flatShading: material.flatShading, - sizeAttenuation: material.sizeAttenuation, - logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer, + sizeAttenuation: material.sizeAttenuation, + logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer, - skinning: material.skinning && maxBones > 0, - maxBones: maxBones, - useVertexTexture: capabilities.floatVertexTextures, + skinning: material.skinning && maxBones > 0, + maxBones: maxBones, + useVertexTexture: capabilities.floatVertexTextures, - morphTargets: material.morphTargets, - morphNormals: material.morphNormals, - maxMorphTargets: renderer.maxMorphTargets, - maxMorphNormals: renderer.maxMorphNormals, + morphTargets: material.morphTargets, + morphNormals: material.morphNormals, + maxMorphTargets: renderer.maxMorphTargets, + maxMorphNormals: renderer.maxMorphNormals, - numDirLights: lights.directional.length, - numPointLights: lights.point.length, - numSpotLights: lights.spot.length, - numRectAreaLights: lights.rectArea.length, - numHemiLights: lights.hemi.length, + numDirLights: lights.directional.length, + numPointLights: lights.point.length, + numSpotLights: lights.spot.length, + numRectAreaLights: lights.rectArea.length, + numHemiLights: lights.hemi.length, - numClippingPlanes: nClipPlanes, - numClipIntersection: nClipIntersection, + numClippingPlanes: nClipPlanes, + numClipIntersection: nClipIntersection, - dithering: material.dithering, + dithering: material.dithering, - shadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && shadows.length > 0, - shadowMapType: renderer.shadowMap.type, + shadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && shadows.length > 0, + shadowMapType: renderer.shadowMap.type, - toneMapping: renderer.toneMapping, - physicallyCorrectLights: renderer.physicallyCorrectLights, + toneMapping: renderer.toneMapping, + physicallyCorrectLights: renderer.physicallyCorrectLights, - premultipliedAlpha: material.premultipliedAlpha, + premultipliedAlpha: material.premultipliedAlpha, - alphaTest: material.alphaTest, - doubleSided: material.side === DoubleSide, - flipSided: material.side === BackSide, + alphaTest: material.alphaTest, + doubleSided: material.side === DoubleSide, + flipSided: material.side === BackSide, - depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false + depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false - }; + }; - return parameters; + return parameters; - }; + }; - this.getProgramCode = function ( material, parameters ) { + this.getProgramCode = function ( material, parameters ) { - var array = []; + var array = []; - if ( parameters.shaderID ) { + if ( parameters.shaderID ) { - array.push( parameters.shaderID ); + array.push( parameters.shaderID ); - } else { + } else { - array.push( material.fragmentShader ); - array.push( material.vertexShader ); + array.push( material.fragmentShader ); + array.push( material.vertexShader ); - } + } - if ( material.defines !== undefined ) { + if ( material.defines !== undefined ) { - for ( var name in material.defines ) { + for ( var name in material.defines ) { - array.push( name ); - array.push( material.defines[ name ] ); + array.push( name ); + array.push( material.defines[ name ] ); - } + } - } + } - for ( var i = 0; i < parameterNames.length; i ++ ) { + for ( var i = 0; i < parameterNames.length; i ++ ) { - array.push( parameters[ parameterNames[ i ] ] ); + array.push( parameters[ parameterNames[ i ] ] ); - } + } - array.push( material.onBeforeCompile.toString() ); + array.push( material.onBeforeCompile.toString() ); - array.push( renderer.gammaOutput ); + array.push( renderer.gammaOutput ); - return array.join(); + return array.join(); - }; + }; - this.acquireProgram = function ( material, shader, parameters, code ) { + this.acquireProgram = function ( material, shader, parameters, code ) { - var program; + var program; - // Check if code has been already compiled - for ( var p = 0, pl = programs.length; p < pl; p ++ ) { + // Check if code has been already compiled + for ( var p = 0, pl = programs.length; p < pl; p ++ ) { - var programInfo = programs[ p ]; + var programInfo = programs[ p ]; - if ( programInfo.code === code ) { + if ( programInfo.code === code ) { - program = programInfo; - ++ program.usedTimes; + program = programInfo; + ++ program.usedTimes; - break; + break; - } + } - } + } - if ( program === undefined ) { + if ( program === undefined ) { - program = new WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities ); - programs.push( program ); + program = new WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities ); + programs.push( program ); - } + } - return program; + return program; - }; + }; - this.releaseProgram = function ( program ) { + this.releaseProgram = function ( program ) { - if ( -- program.usedTimes === 0 ) { + if ( -- program.usedTimes === 0 ) { - // Remove from unordered set - var i = programs.indexOf( program ); - programs[ i ] = programs[ programs.length - 1 ]; - programs.pop(); + // Remove from unordered set + var i = programs.indexOf( program ); + programs[ i ] = programs[ programs.length - 1 ]; + programs.pop(); - // Free WebGL resources - program.destroy(); + // Free WebGL resources + program.destroy(); - } + } - }; + }; - // Exposed for resource monitoring & error feedback via renderer.info: - this.programs = programs; + // Exposed for resource monitoring & error feedback via renderer.info: + this.programs = programs; - } + } - /** - * @author fordacious / fordacious.github.io - */ + /** + * @author fordacious / fordacious.github.io + */ - function WebGLProperties() { + function WebGLProperties() { - var properties = new WeakMap(); + var properties = new WeakMap(); - function get( object ) { + function get( object ) { - var map = properties.get( object ); + var map = properties.get( object ); - if ( map === undefined ) { + if ( map === undefined ) { - map = {}; - properties.set( object, map ); + map = {}; + properties.set( object, map ); - } + } - return map; + return map; - } + } - function remove( object ) { + function remove( object ) { - properties.delete( object ); + properties.delete( object ); - } + } - function update( object, key, value ) { + function update( object, key, value ) { - properties.get( object )[ key ] = value; + properties.get( object )[ key ] = value; - } + } - function dispose() { + function dispose() { - properties = new WeakMap(); + properties = new WeakMap(); - } + } - return { - get: get, - remove: remove, - update: update, - dispose: dispose - }; + return { + get: get, + remove: remove, + update: update, + dispose: dispose + }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function painterSortStable( a, b ) { + function painterSortStable( a, b ) { - if ( a.renderOrder !== b.renderOrder ) { + if ( a.renderOrder !== b.renderOrder ) { - return a.renderOrder - b.renderOrder; + return a.renderOrder - b.renderOrder; - } else if ( a.program && b.program && a.program !== b.program ) { + } else if ( a.program && b.program && a.program !== b.program ) { - return a.program.id - b.program.id; + return a.program.id - b.program.id; - } else if ( a.material.id !== b.material.id ) { + } else if ( a.material.id !== b.material.id ) { - return a.material.id - b.material.id; + return a.material.id - b.material.id; - } else if ( a.z !== b.z ) { + } else if ( a.z !== b.z ) { - return a.z - b.z; + return a.z - b.z; - } else { + } else { - return a.id - b.id; + return a.id - b.id; - } + } - } + } - function reversePainterSortStable( a, b ) { + function reversePainterSortStable( a, b ) { - if ( a.renderOrder !== b.renderOrder ) { + if ( a.renderOrder !== b.renderOrder ) { - return a.renderOrder - b.renderOrder; + return a.renderOrder - b.renderOrder; - } if ( a.z !== b.z ) { + } if ( a.z !== b.z ) { - return b.z - a.z; + return b.z - a.z; - } else { + } else { - return a.id - b.id; + return a.id - b.id; - } + } - } + } - function WebGLRenderList() { + function WebGLRenderList() { - var renderItems = []; - var renderItemsIndex = 0; + var renderItems = []; + var renderItemsIndex = 0; - var opaque = []; - var transparent = []; + var opaque = []; + var transparent = []; - function init() { + function init() { - renderItemsIndex = 0; + renderItemsIndex = 0; - opaque.length = 0; - transparent.length = 0; + opaque.length = 0; + transparent.length = 0; - } + } - function push( object, geometry, material, z, group ) { + function push( object, geometry, material, z, group ) { - var renderItem = renderItems[ renderItemsIndex ]; + var renderItem = renderItems[ renderItemsIndex ]; - if ( renderItem === undefined ) { + if ( renderItem === undefined ) { - renderItem = { - id: object.id, - object: object, - geometry: geometry, - material: material, - program: material.program, - renderOrder: object.renderOrder, - z: z, - group: group - }; + renderItem = { + id: object.id, + object: object, + geometry: geometry, + material: material, + program: material.program, + renderOrder: object.renderOrder, + z: z, + group: group + }; - renderItems[ renderItemsIndex ] = renderItem; + renderItems[ renderItemsIndex ] = renderItem; - } else { + } else { - renderItem.id = object.id; - renderItem.object = object; - renderItem.geometry = geometry; - renderItem.material = material; - renderItem.program = material.program; - renderItem.renderOrder = object.renderOrder; - renderItem.z = z; - renderItem.group = group; + renderItem.id = object.id; + renderItem.object = object; + renderItem.geometry = geometry; + renderItem.material = material; + renderItem.program = material.program; + renderItem.renderOrder = object.renderOrder; + renderItem.z = z; + renderItem.group = group; - } + } - ( material.transparent === true ? transparent : opaque ).push( renderItem ); + ( material.transparent === true ? transparent : opaque ).push( renderItem ); - renderItemsIndex ++; + renderItemsIndex ++; - } + } - function sort() { + function sort() { - if ( opaque.length > 1 ) opaque.sort( painterSortStable ); - if ( transparent.length > 1 ) transparent.sort( reversePainterSortStable ); + if ( opaque.length > 1 ) opaque.sort( painterSortStable ); + if ( transparent.length > 1 ) transparent.sort( reversePainterSortStable ); - } + } - return { - opaque: opaque, - transparent: transparent, + return { + opaque: opaque, + transparent: transparent, - init: init, - push: push, + init: init, + push: push, - sort: sort - }; + sort: sort + }; - } + } - function WebGLRenderLists() { + function WebGLRenderLists() { - var lists = {}; + var lists = {}; - function get( scene, camera ) { + function get( scene, camera ) { - var hash = scene.id + ',' + camera.id; - var list = lists[ hash ]; + var hash = scene.id + ',' + camera.id; + var list = lists[ hash ]; - if ( list === undefined ) { + if ( list === undefined ) { - // console.log( 'THREE.WebGLRenderLists:', hash ); + // console.log( 'THREE.WebGLRenderLists:', hash ); - list = new WebGLRenderList(); - lists[ hash ] = list; + list = new WebGLRenderList(); + lists[ hash ] = list; - } + } - return list; + return list; - } + } - function dispose() { + function dispose() { - lists = {}; + lists = {}; - } + } - return { - get: get, - dispose: dispose - }; + return { + get: get, + dispose: dispose + }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function UniformsCache() { + function UniformsCache() { - var lights = {}; + var lights = {}; - return { + return { - get: function ( light ) { + get: function ( light ) { - if ( lights[ light.id ] !== undefined ) { + if ( lights[ light.id ] !== undefined ) { - return lights[ light.id ]; + return lights[ light.id ]; - } + } - var uniforms; + var uniforms; - switch ( light.type ) { + switch ( light.type ) { - case 'DirectionalLight': - uniforms = { - direction: new Vector3(), - color: new Color(), + case 'DirectionalLight': + uniforms = { + direction: new Vector3(), + color: new Color(), - shadow: false, - shadowBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2() - }; - break; + shadow: false, + shadowBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2() + }; + break; - case 'SpotLight': - uniforms = { - position: new Vector3(), - direction: new Vector3(), - color: new Color(), - distance: 0, - coneCos: 0, - penumbraCos: 0, - decay: 0, + case 'SpotLight': + uniforms = { + position: new Vector3(), + direction: new Vector3(), + color: new Color(), + distance: 0, + coneCos: 0, + penumbraCos: 0, + decay: 0, - shadow: false, - shadowBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2() - }; - break; + shadow: false, + shadowBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2() + }; + break; - case 'PointLight': - uniforms = { - position: new Vector3(), - color: new Color(), - distance: 0, - decay: 0, + case 'PointLight': + uniforms = { + position: new Vector3(), + color: new Color(), + distance: 0, + decay: 0, - shadow: false, - shadowBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2(), - shadowCameraNear: 1, - shadowCameraFar: 1000 - }; - break; + shadow: false, + shadowBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2(), + shadowCameraNear: 1, + shadowCameraFar: 1000 + }; + break; - case 'HemisphereLight': - uniforms = { - direction: new Vector3(), - skyColor: new Color(), - groundColor: new Color() - }; - break; + case 'HemisphereLight': + uniforms = { + direction: new Vector3(), + skyColor: new Color(), + groundColor: new Color() + }; + break; - case 'RectAreaLight': - uniforms = { - color: new Color(), - position: new Vector3(), - halfWidth: new Vector3(), - halfHeight: new Vector3() - // TODO (abelnation): set RectAreaLight shadow uniforms - }; - break; + case 'RectAreaLight': + uniforms = { + color: new Color(), + position: new Vector3(), + halfWidth: new Vector3(), + halfHeight: new Vector3() + // TODO (abelnation): set RectAreaLight shadow uniforms + }; + break; - } + } - lights[ light.id ] = uniforms; + lights[ light.id ] = uniforms; - return uniforms; + return uniforms; - } + } - }; + }; - } + } - var count = 0; + var count = 0; - function WebGLLights() { + function WebGLLights() { - var cache = new UniformsCache(); + var cache = new UniformsCache(); - var state = { + var state = { - id: count ++, + id: count ++, - hash: { - stateID: - 1, - directionalLength: - 1, - pointLength: - 1, - spotLength: - 1, - rectAreaLength: - 1, - hemiLength: - 1, - shadowsLength: - 1 - }, + hash: { + stateID: - 1, + directionalLength: - 1, + pointLength: - 1, + spotLength: - 1, + rectAreaLength: - 1, + hemiLength: - 1, + shadowsLength: - 1 + }, - ambient: [ 0, 0, 0 ], - directional: [], - directionalShadowMap: [], - directionalShadowMatrix: [], - spot: [], - spotShadowMap: [], - spotShadowMatrix: [], - rectArea: [], - point: [], - pointShadowMap: [], - pointShadowMatrix: [], - hemi: [] + ambient: [ 0, 0, 0 ], + directional: [], + directionalShadowMap: [], + directionalShadowMatrix: [], + spot: [], + spotShadowMap: [], + spotShadowMatrix: [], + rectArea: [], + point: [], + pointShadowMap: [], + pointShadowMatrix: [], + hemi: [] - }; + }; - var vector3 = new Vector3(); - var matrix4 = new Matrix4(); - var matrix42 = new Matrix4(); + var vector3 = new Vector3(); + var matrix4 = new Matrix4(); + var matrix42 = new Matrix4(); - function setup( lights, shadows, camera ) { + function setup( lights, shadows, camera ) { - var r = 0, g = 0, b = 0; + var r = 0, g = 0, b = 0; - var directionalLength = 0; - var pointLength = 0; - var spotLength = 0; - var rectAreaLength = 0; - var hemiLength = 0; + var directionalLength = 0; + var pointLength = 0; + var spotLength = 0; + var rectAreaLength = 0; + var hemiLength = 0; - var viewMatrix = camera.matrixWorldInverse; + var viewMatrix = camera.matrixWorldInverse; - for ( var i = 0, l = lights.length; i < l; i ++ ) { + for ( var i = 0, l = lights.length; i < l; i ++ ) { - var light = lights[ i ]; + var light = lights[ i ]; - var color = light.color; - var intensity = light.intensity; - var distance = light.distance; + var color = light.color; + var intensity = light.intensity; + var distance = light.distance; - var shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null; + var shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null; - if ( light.isAmbientLight ) { + if ( light.isAmbientLight ) { - r += color.r * intensity; - g += color.g * intensity; - b += color.b * intensity; + r += color.r * intensity; + g += color.g * intensity; + b += color.b * intensity; - } else if ( light.isDirectionalLight ) { + } else if ( light.isDirectionalLight ) { - var uniforms = cache.get( light ); + var uniforms = cache.get( light ); - uniforms.color.copy( light.color ).multiplyScalar( light.intensity ); - uniforms.direction.setFromMatrixPosition( light.matrixWorld ); - vector3.setFromMatrixPosition( light.target.matrixWorld ); - uniforms.direction.sub( vector3 ); - uniforms.direction.transformDirection( viewMatrix ); + uniforms.color.copy( light.color ).multiplyScalar( light.intensity ); + uniforms.direction.setFromMatrixPosition( light.matrixWorld ); + vector3.setFromMatrixPosition( light.target.matrixWorld ); + uniforms.direction.sub( vector3 ); + uniforms.direction.transformDirection( viewMatrix ); - uniforms.shadow = light.castShadow; + uniforms.shadow = light.castShadow; - if ( light.castShadow ) { + if ( light.castShadow ) { - var shadow = light.shadow; + var shadow = light.shadow; - uniforms.shadowBias = shadow.bias; - uniforms.shadowRadius = shadow.radius; - uniforms.shadowMapSize = shadow.mapSize; + uniforms.shadowBias = shadow.bias; + uniforms.shadowRadius = shadow.radius; + uniforms.shadowMapSize = shadow.mapSize; - } + } - state.directionalShadowMap[ directionalLength ] = shadowMap; - state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix; - state.directional[ directionalLength ] = uniforms; + state.directionalShadowMap[ directionalLength ] = shadowMap; + state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix; + state.directional[ directionalLength ] = uniforms; - directionalLength ++; + directionalLength ++; - } else if ( light.isSpotLight ) { + } else if ( light.isSpotLight ) { - var uniforms = cache.get( light ); + var uniforms = cache.get( light ); - uniforms.position.setFromMatrixPosition( light.matrixWorld ); - uniforms.position.applyMatrix4( viewMatrix ); + uniforms.position.setFromMatrixPosition( light.matrixWorld ); + uniforms.position.applyMatrix4( viewMatrix ); - uniforms.color.copy( color ).multiplyScalar( intensity ); - uniforms.distance = distance; + uniforms.color.copy( color ).multiplyScalar( intensity ); + uniforms.distance = distance; - uniforms.direction.setFromMatrixPosition( light.matrixWorld ); - vector3.setFromMatrixPosition( light.target.matrixWorld ); - uniforms.direction.sub( vector3 ); - uniforms.direction.transformDirection( viewMatrix ); + uniforms.direction.setFromMatrixPosition( light.matrixWorld ); + vector3.setFromMatrixPosition( light.target.matrixWorld ); + uniforms.direction.sub( vector3 ); + uniforms.direction.transformDirection( viewMatrix ); - uniforms.coneCos = Math.cos( light.angle ); - uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) ); - uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay; + uniforms.coneCos = Math.cos( light.angle ); + uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) ); + uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay; - uniforms.shadow = light.castShadow; + uniforms.shadow = light.castShadow; - if ( light.castShadow ) { + if ( light.castShadow ) { - var shadow = light.shadow; + var shadow = light.shadow; - uniforms.shadowBias = shadow.bias; - uniforms.shadowRadius = shadow.radius; - uniforms.shadowMapSize = shadow.mapSize; + uniforms.shadowBias = shadow.bias; + uniforms.shadowRadius = shadow.radius; + uniforms.shadowMapSize = shadow.mapSize; - } + } - state.spotShadowMap[ spotLength ] = shadowMap; - state.spotShadowMatrix[ spotLength ] = light.shadow.matrix; - state.spot[ spotLength ] = uniforms; + state.spotShadowMap[ spotLength ] = shadowMap; + state.spotShadowMatrix[ spotLength ] = light.shadow.matrix; + state.spot[ spotLength ] = uniforms; - spotLength ++; + spotLength ++; - } else if ( light.isRectAreaLight ) { + } else if ( light.isRectAreaLight ) { - var uniforms = cache.get( light ); + var uniforms = cache.get( light ); - // (a) intensity is the total visible light emitted - //uniforms.color.copy( color ).multiplyScalar( intensity / ( light.width * light.height * Math.PI ) ); + // (a) intensity is the total visible light emitted + //uniforms.color.copy( color ).multiplyScalar( intensity / ( light.width * light.height * Math.PI ) ); - // (b) intensity is the brightness of the light - uniforms.color.copy( color ).multiplyScalar( intensity ); + // (b) intensity is the brightness of the light + uniforms.color.copy( color ).multiplyScalar( intensity ); - uniforms.position.setFromMatrixPosition( light.matrixWorld ); - uniforms.position.applyMatrix4( viewMatrix ); + uniforms.position.setFromMatrixPosition( light.matrixWorld ); + uniforms.position.applyMatrix4( viewMatrix ); - // extract local rotation of light to derive width/height half vectors - matrix42.identity(); - matrix4.copy( light.matrixWorld ); - matrix4.premultiply( viewMatrix ); - matrix42.extractRotation( matrix4 ); + // extract local rotation of light to derive width/height half vectors + matrix42.identity(); + matrix4.copy( light.matrixWorld ); + matrix4.premultiply( viewMatrix ); + matrix42.extractRotation( matrix4 ); - uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 ); - uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 ); + uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 ); + uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 ); - uniforms.halfWidth.applyMatrix4( matrix42 ); - uniforms.halfHeight.applyMatrix4( matrix42 ); + uniforms.halfWidth.applyMatrix4( matrix42 ); + uniforms.halfHeight.applyMatrix4( matrix42 ); - // TODO (abelnation): RectAreaLight distance? - // uniforms.distance = distance; + // TODO (abelnation): RectAreaLight distance? + // uniforms.distance = distance; - state.rectArea[ rectAreaLength ] = uniforms; + state.rectArea[ rectAreaLength ] = uniforms; - rectAreaLength ++; + rectAreaLength ++; - } else if ( light.isPointLight ) { + } else if ( light.isPointLight ) { - var uniforms = cache.get( light ); + var uniforms = cache.get( light ); - uniforms.position.setFromMatrixPosition( light.matrixWorld ); - uniforms.position.applyMatrix4( viewMatrix ); + uniforms.position.setFromMatrixPosition( light.matrixWorld ); + uniforms.position.applyMatrix4( viewMatrix ); - uniforms.color.copy( light.color ).multiplyScalar( light.intensity ); - uniforms.distance = light.distance; - uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay; + uniforms.color.copy( light.color ).multiplyScalar( light.intensity ); + uniforms.distance = light.distance; + uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay; - uniforms.shadow = light.castShadow; + uniforms.shadow = light.castShadow; - if ( light.castShadow ) { + if ( light.castShadow ) { - var shadow = light.shadow; + var shadow = light.shadow; - uniforms.shadowBias = shadow.bias; - uniforms.shadowRadius = shadow.radius; - uniforms.shadowMapSize = shadow.mapSize; - uniforms.shadowCameraNear = shadow.camera.near; - uniforms.shadowCameraFar = shadow.camera.far; + uniforms.shadowBias = shadow.bias; + uniforms.shadowRadius = shadow.radius; + uniforms.shadowMapSize = shadow.mapSize; + uniforms.shadowCameraNear = shadow.camera.near; + uniforms.shadowCameraFar = shadow.camera.far; - } + } - state.pointShadowMap[ pointLength ] = shadowMap; - state.pointShadowMatrix[ pointLength ] = light.shadow.matrix; - state.point[ pointLength ] = uniforms; + state.pointShadowMap[ pointLength ] = shadowMap; + state.pointShadowMatrix[ pointLength ] = light.shadow.matrix; + state.point[ pointLength ] = uniforms; - pointLength ++; + pointLength ++; - } else if ( light.isHemisphereLight ) { + } else if ( light.isHemisphereLight ) { - var uniforms = cache.get( light ); + var uniforms = cache.get( light ); - uniforms.direction.setFromMatrixPosition( light.matrixWorld ); - uniforms.direction.transformDirection( viewMatrix ); - uniforms.direction.normalize(); + uniforms.direction.setFromMatrixPosition( light.matrixWorld ); + uniforms.direction.transformDirection( viewMatrix ); + uniforms.direction.normalize(); - uniforms.skyColor.copy( light.color ).multiplyScalar( intensity ); - uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity ); + uniforms.skyColor.copy( light.color ).multiplyScalar( intensity ); + uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity ); - state.hemi[ hemiLength ] = uniforms; + state.hemi[ hemiLength ] = uniforms; - hemiLength ++; + hemiLength ++; - } + } - } + } - state.ambient[ 0 ] = r; - state.ambient[ 1 ] = g; - state.ambient[ 2 ] = b; + state.ambient[ 0 ] = r; + state.ambient[ 1 ] = g; + state.ambient[ 2 ] = b; - state.directional.length = directionalLength; - state.spot.length = spotLength; - state.rectArea.length = rectAreaLength; - state.point.length = pointLength; - state.hemi.length = hemiLength; + state.directional.length = directionalLength; + state.spot.length = spotLength; + state.rectArea.length = rectAreaLength; + state.point.length = pointLength; + state.hemi.length = hemiLength; - state.hash.stateID = state.id; - state.hash.directionalLength = directionalLength; - state.hash.pointLength = pointLength; - state.hash.spotLength = spotLength; - state.hash.rectAreaLength = rectAreaLength; - state.hash.hemiLength = hemiLength; - state.hash.shadowsLength = shadows.length; + state.hash.stateID = state.id; + state.hash.directionalLength = directionalLength; + state.hash.pointLength = pointLength; + state.hash.spotLength = spotLength; + state.hash.rectAreaLength = rectAreaLength; + state.hash.hemiLength = hemiLength; + state.hash.shadowsLength = shadows.length; - } + } - return { - setup: setup, - state: state - }; + return { + setup: setup, + state: state + }; - } + } - /** - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author Mugen87 / https://github.com/Mugen87 + */ - function WebGLRenderState() { + function WebGLRenderState() { - var lights = new WebGLLights(); + var lights = new WebGLLights(); - var lightsArray = []; - var shadowsArray = []; + var lightsArray = []; + var shadowsArray = []; - function init() { + function init() { - lightsArray.length = 0; - shadowsArray.length = 0; + lightsArray.length = 0; + shadowsArray.length = 0; - } + } - function pushLight( light ) { + function pushLight( light ) { - lightsArray.push( light ); + lightsArray.push( light ); - } + } - function pushShadow( shadowLight ) { + function pushShadow( shadowLight ) { - shadowsArray.push( shadowLight ); + shadowsArray.push( shadowLight ); - } + } - function setupLights( camera ) { + function setupLights( camera ) { - lights.setup( lightsArray, shadowsArray, camera ); + lights.setup( lightsArray, shadowsArray, camera ); - } + } - var state = { - lightsArray: lightsArray, - shadowsArray: shadowsArray, + var state = { + lightsArray: lightsArray, + shadowsArray: shadowsArray, - lights: lights - }; + lights: lights + }; - return { - init: init, - state: state, - setupLights: setupLights, + return { + init: init, + state: state, + setupLights: setupLights, - pushLight: pushLight, - pushShadow: pushShadow - }; + pushLight: pushLight, + pushShadow: pushShadow + }; - } + } - function WebGLRenderStates() { + function WebGLRenderStates() { - var renderStates = {}; + var renderStates = {}; - function get( scene, camera ) { + function get( scene, camera ) { - var renderState; + var renderState; - if ( renderStates[ scene.id ] === undefined ) { + if ( renderStates[ scene.id ] === undefined ) { - renderState = new WebGLRenderState(); - renderStates[ scene.id ] = {}; - renderStates[ scene.id ][ camera.id ] = renderState; + renderState = new WebGLRenderState(); + renderStates[ scene.id ] = {}; + renderStates[ scene.id ][ camera.id ] = renderState; - } else { + } else { - if ( renderStates[ scene.id ][ camera.id ] === undefined ) { + if ( renderStates[ scene.id ][ camera.id ] === undefined ) { - renderState = new WebGLRenderState(); - renderStates[ scene.id ][ camera.id ] = renderState; + renderState = new WebGLRenderState(); + renderStates[ scene.id ][ camera.id ] = renderState; - } else { + } else { - renderState = renderStates[ scene.id ][ camera.id ]; + renderState = renderStates[ scene.id ][ camera.id ]; - } + } - } + } - return renderState; + return renderState; - } + } - function dispose() { + function dispose() { - renderStates = {}; + renderStates = {}; - } + } - return { - get: get, - dispose: dispose - }; + return { + get: get, + dispose: dispose + }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author bhouston / https://clara.io - * @author WestLangley / http://github.com/WestLangley - * - * parameters = { - * - * opacity: , - * - * map: new THREE.Texture( ), - * - * alphaMap: new THREE.Texture( ), - * - * displacementMap: new THREE.Texture( ), - * displacementScale: , - * displacementBias: , - * - * wireframe: , - * wireframeLinewidth: - * } - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author bhouston / https://clara.io + * @author WestLangley / http://github.com/WestLangley + * + * parameters = { + * + * opacity: , + * + * map: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * wireframe: , + * wireframeLinewidth: + * } + */ - function MeshDepthMaterial( parameters ) { + function MeshDepthMaterial( parameters ) { - Material.call( this ); + Material.call( this ); - this.type = 'MeshDepthMaterial'; + this.type = 'MeshDepthMaterial'; - this.depthPacking = BasicDepthPacking; + this.depthPacking = BasicDepthPacking; - this.skinning = false; - this.morphTargets = false; + this.skinning = false; + this.morphTargets = false; - this.map = null; + this.map = null; - this.alphaMap = null; + this.alphaMap = null; - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; - this.wireframe = false; - this.wireframeLinewidth = 1; + this.wireframe = false; + this.wireframeLinewidth = 1; - this.fog = false; - this.lights = false; + this.fog = false; + this.lights = false; - this.setValues( parameters ); + this.setValues( parameters ); - } + } - MeshDepthMaterial.prototype = Object.create( Material.prototype ); - MeshDepthMaterial.prototype.constructor = MeshDepthMaterial; + MeshDepthMaterial.prototype = Object.create( Material.prototype ); + MeshDepthMaterial.prototype.constructor = MeshDepthMaterial; - MeshDepthMaterial.prototype.isMeshDepthMaterial = true; + MeshDepthMaterial.prototype.isMeshDepthMaterial = true; - MeshDepthMaterial.prototype.copy = function ( source ) { + MeshDepthMaterial.prototype.copy = function ( source ) { - Material.prototype.copy.call( this, source ); + Material.prototype.copy.call( this, source ); - this.depthPacking = source.depthPacking; + this.depthPacking = source.depthPacking; - this.skinning = source.skinning; - this.morphTargets = source.morphTargets; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; - this.map = source.map; + this.map = source.map; - this.alphaMap = source.alphaMap; + this.alphaMap = source.alphaMap; - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; - return this; + return this; - }; + }; - /** - * @author WestLangley / http://github.com/WestLangley - * - * parameters = { - * - * referencePosition: , - * nearDistance: , - * farDistance: , - * - * skinning: , - * morphTargets: , - * - * map: new THREE.Texture( ), - * - * alphaMap: new THREE.Texture( ), - * - * displacementMap: new THREE.Texture( ), - * displacementScale: , - * displacementBias: - * - * } - */ + /** + * @author WestLangley / http://github.com/WestLangley + * + * parameters = { + * + * referencePosition: , + * nearDistance: , + * farDistance: , + * + * skinning: , + * morphTargets: , + * + * map: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: + * + * } + */ - function MeshDistanceMaterial( parameters ) { + function MeshDistanceMaterial( parameters ) { - Material.call( this ); + Material.call( this ); - this.type = 'MeshDistanceMaterial'; + this.type = 'MeshDistanceMaterial'; - this.referencePosition = new Vector3(); - this.nearDistance = 1; - this.farDistance = 1000; + this.referencePosition = new Vector3(); + this.nearDistance = 1; + this.farDistance = 1000; - this.skinning = false; - this.morphTargets = false; + this.skinning = false; + this.morphTargets = false; - this.map = null; + this.map = null; - this.alphaMap = null; + this.alphaMap = null; - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; - this.fog = false; - this.lights = false; + this.fog = false; + this.lights = false; - this.setValues( parameters ); + this.setValues( parameters ); - } + } - MeshDistanceMaterial.prototype = Object.create( Material.prototype ); - MeshDistanceMaterial.prototype.constructor = MeshDistanceMaterial; + MeshDistanceMaterial.prototype = Object.create( Material.prototype ); + MeshDistanceMaterial.prototype.constructor = MeshDistanceMaterial; - MeshDistanceMaterial.prototype.isMeshDistanceMaterial = true; + MeshDistanceMaterial.prototype.isMeshDistanceMaterial = true; - MeshDistanceMaterial.prototype.copy = function ( source ) { + MeshDistanceMaterial.prototype.copy = function ( source ) { - Material.prototype.copy.call( this, source ); + Material.prototype.copy.call( this, source ); - this.referencePosition.copy( source.referencePosition ); - this.nearDistance = source.nearDistance; - this.farDistance = source.farDistance; + this.referencePosition.copy( source.referencePosition ); + this.nearDistance = source.nearDistance; + this.farDistance = source.farDistance; - this.skinning = source.skinning; - this.morphTargets = source.morphTargets; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; - this.map = source.map; + this.map = source.map; - this.alphaMap = source.alphaMap; + this.alphaMap = source.alphaMap; - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; - return this; + return this; - }; + }; - /** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author alteredq / http://alteredqualia.com/ + * @author mrdoob / http://mrdoob.com/ + */ - function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { + function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { - var _frustum = new Frustum(), - _projScreenMatrix = new Matrix4(), + var _frustum = new Frustum(), + _projScreenMatrix = new Matrix4(), - _shadowMapSize = new Vector2(), - _maxShadowMapSize = new Vector2( maxTextureSize, maxTextureSize ), + _shadowMapSize = new Vector2(), + _maxShadowMapSize = new Vector2( maxTextureSize, maxTextureSize ), - _lookTarget = new Vector3(), - _lightPositionWorld = new Vector3(), + _lookTarget = new Vector3(), + _lightPositionWorld = new Vector3(), - _MorphingFlag = 1, - _SkinningFlag = 2, + _MorphingFlag = 1, + _SkinningFlag = 2, - _NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1, + _NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1, - _depthMaterials = new Array( _NumberOfMaterialVariants ), - _distanceMaterials = new Array( _NumberOfMaterialVariants ), + _depthMaterials = new Array( _NumberOfMaterialVariants ), + _distanceMaterials = new Array( _NumberOfMaterialVariants ), - _materialCache = {}; + _materialCache = {}; - var shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide }; + var shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide }; - var cubeDirections = [ - new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ), - new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 ) - ]; + var cubeDirections = [ + new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ), + new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 ) + ]; - var cubeUps = [ - new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), - new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 ) - ]; + var cubeUps = [ + new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), + new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 ) + ]; - var cube2DViewPorts = [ - new Vector4(), new Vector4(), new Vector4(), - new Vector4(), new Vector4(), new Vector4() - ]; + var cube2DViewPorts = [ + new Vector4(), new Vector4(), new Vector4(), + new Vector4(), new Vector4(), new Vector4() + ]; - // init + // init - for ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) { + for ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) { - var useMorphing = ( i & _MorphingFlag ) !== 0; - var useSkinning = ( i & _SkinningFlag ) !== 0; + var useMorphing = ( i & _MorphingFlag ) !== 0; + var useSkinning = ( i & _SkinningFlag ) !== 0; - var depthMaterial = new MeshDepthMaterial( { + var depthMaterial = new MeshDepthMaterial( { - depthPacking: RGBADepthPacking, + depthPacking: RGBADepthPacking, - morphTargets: useMorphing, - skinning: useSkinning + morphTargets: useMorphing, + skinning: useSkinning - } ); + } ); - _depthMaterials[ i ] = depthMaterial; + _depthMaterials[ i ] = depthMaterial; - // + // - var distanceMaterial = new MeshDistanceMaterial( { + var distanceMaterial = new MeshDistanceMaterial( { - morphTargets: useMorphing, - skinning: useSkinning + morphTargets: useMorphing, + skinning: useSkinning - } ); + } ); - _distanceMaterials[ i ] = distanceMaterial; + _distanceMaterials[ i ] = distanceMaterial; - } + } - // + // - var scope = this; + var scope = this; - this.enabled = false; + this.enabled = false; - this.autoUpdate = true; - this.needsUpdate = false; + this.autoUpdate = true; + this.needsUpdate = false; - this.type = PCFShadowMap; + this.type = PCFShadowMap; - this.render = function ( lights, scene, camera ) { + this.render = function ( lights, scene, camera ) { - if ( scope.enabled === false ) return; - if ( scope.autoUpdate === false && scope.needsUpdate === false ) return; + if ( scope.enabled === false ) return; + if ( scope.autoUpdate === false && scope.needsUpdate === false ) return; - if ( lights.length === 0 ) return; + if ( lights.length === 0 ) return; - // TODO Clean up (needed in case of contextlost) - var _gl = _renderer.context; - var _state = _renderer.state; + // TODO Clean up (needed in case of contextlost) + var _gl = _renderer.context; + var _state = _renderer.state; - // Set GL state for depth map. - _state.disable( _gl.BLEND ); - _state.buffers.color.setClear( 1, 1, 1, 1 ); - _state.buffers.depth.setTest( true ); - _state.setScissorTest( false ); + // Set GL state for depth map. + _state.disable( _gl.BLEND ); + _state.buffers.color.setClear( 1, 1, 1, 1 ); + _state.buffers.depth.setTest( true ); + _state.setScissorTest( false ); - // render depth map + // render depth map - var faceCount; + var faceCount; - for ( var i = 0, il = lights.length; i < il; i ++ ) { + for ( var i = 0, il = lights.length; i < il; i ++ ) { - var light = lights[ i ]; - var shadow = light.shadow; - var isPointLight = light && light.isPointLight; + var light = lights[ i ]; + var shadow = light.shadow; + var isPointLight = light && light.isPointLight; - if ( shadow === undefined ) { + if ( shadow === undefined ) { - console.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' ); - continue; + console.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' ); + continue; - } + } - var shadowCamera = shadow.camera; + var shadowCamera = shadow.camera; - _shadowMapSize.copy( shadow.mapSize ); - _shadowMapSize.min( _maxShadowMapSize ); + _shadowMapSize.copy( shadow.mapSize ); + _shadowMapSize.min( _maxShadowMapSize ); - if ( isPointLight ) { + if ( isPointLight ) { - var vpWidth = _shadowMapSize.x; - var vpHeight = _shadowMapSize.y; + var vpWidth = _shadowMapSize.x; + var vpHeight = _shadowMapSize.y; - // These viewports map a cube-map onto a 2D texture with the - // following orientation: - // - // xzXZ - // y Y - // - // X - Positive x direction - // x - Negative x direction - // Y - Positive y direction - // y - Negative y direction - // Z - Positive z direction - // z - Negative z direction + // These viewports map a cube-map onto a 2D texture with the + // following orientation: + // + // xzXZ + // y Y + // + // X - Positive x direction + // x - Negative x direction + // Y - Positive y direction + // y - Negative y direction + // Z - Positive z direction + // z - Negative z direction - // positive X - cube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight ); - // negative X - cube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight ); - // positive Z - cube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight ); - // negative Z - cube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight ); - // positive Y - cube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight ); - // negative Y - cube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight ); + // positive X + cube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight ); + // negative X + cube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight ); + // positive Z + cube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight ); + // negative Z + cube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight ); + // positive Y + cube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight ); + // negative Y + cube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight ); - _shadowMapSize.x *= 4.0; - _shadowMapSize.y *= 2.0; + _shadowMapSize.x *= 4.0; + _shadowMapSize.y *= 2.0; - } + } - if ( shadow.map === null ) { + if ( shadow.map === null ) { - var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat }; + var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat }; - shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); - shadow.map.texture.name = light.name + ".shadowMap"; + shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); + shadow.map.texture.name = light.name + ".shadowMap"; - shadowCamera.updateProjectionMatrix(); + shadowCamera.updateProjectionMatrix(); - } + } - if ( shadow.isSpotLightShadow ) { + if ( shadow.isSpotLightShadow ) { - shadow.update( light ); + shadow.update( light ); - } + } - var shadowMap = shadow.map; - var shadowMatrix = shadow.matrix; + var shadowMap = shadow.map; + var shadowMatrix = shadow.matrix; - _lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); - shadowCamera.position.copy( _lightPositionWorld ); + _lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); + shadowCamera.position.copy( _lightPositionWorld ); - if ( isPointLight ) { + if ( isPointLight ) { - faceCount = 6; + faceCount = 6; - // for point lights we set the shadow matrix to be a translation-only matrix - // equal to inverse of the light's position + // for point lights we set the shadow matrix to be a translation-only matrix + // equal to inverse of the light's position - shadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z ); + shadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z ); - } else { + } else { - faceCount = 1; + faceCount = 1; - _lookTarget.setFromMatrixPosition( light.target.matrixWorld ); - shadowCamera.lookAt( _lookTarget ); - shadowCamera.updateMatrixWorld(); + _lookTarget.setFromMatrixPosition( light.target.matrixWorld ); + shadowCamera.lookAt( _lookTarget ); + shadowCamera.updateMatrixWorld(); - // compute shadow matrix + // compute shadow matrix - shadowMatrix.set( - 0.5, 0.0, 0.0, 0.5, - 0.0, 0.5, 0.0, 0.5, - 0.0, 0.0, 0.5, 0.5, - 0.0, 0.0, 0.0, 1.0 - ); + shadowMatrix.set( + 0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 0.5, 0.5, + 0.0, 0.0, 0.0, 1.0 + ); - shadowMatrix.multiply( shadowCamera.projectionMatrix ); - shadowMatrix.multiply( shadowCamera.matrixWorldInverse ); + shadowMatrix.multiply( shadowCamera.projectionMatrix ); + shadowMatrix.multiply( shadowCamera.matrixWorldInverse ); - } + } - _renderer.setRenderTarget( shadowMap ); - _renderer.clear(); + _renderer.setRenderTarget( shadowMap ); + _renderer.clear(); - // render shadow map for each cube face (if omni-directional) or - // run a single pass if not + // render shadow map for each cube face (if omni-directional) or + // run a single pass if not - for ( var face = 0; face < faceCount; face ++ ) { + for ( var face = 0; face < faceCount; face ++ ) { - if ( isPointLight ) { + if ( isPointLight ) { - _lookTarget.copy( shadowCamera.position ); - _lookTarget.add( cubeDirections[ face ] ); - shadowCamera.up.copy( cubeUps[ face ] ); - shadowCamera.lookAt( _lookTarget ); - shadowCamera.updateMatrixWorld(); + _lookTarget.copy( shadowCamera.position ); + _lookTarget.add( cubeDirections[ face ] ); + shadowCamera.up.copy( cubeUps[ face ] ); + shadowCamera.lookAt( _lookTarget ); + shadowCamera.updateMatrixWorld(); - var vpDimensions = cube2DViewPorts[ face ]; - _state.viewport( vpDimensions ); + var vpDimensions = cube2DViewPorts[ face ]; + _state.viewport( vpDimensions ); - } + } - // update camera matrices and frustum + // update camera matrices and frustum - _projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); - _frustum.setFromMatrix( _projScreenMatrix ); + _projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); + _frustum.setFromMatrix( _projScreenMatrix ); - // set object matrices & frustum culling + // set object matrices & frustum culling - renderObject( scene, camera, shadowCamera, isPointLight ); + renderObject( scene, camera, shadowCamera, isPointLight ); - } + } - } + } - scope.needsUpdate = false; + scope.needsUpdate = false; - }; + }; - function getDepthMaterial( object, material, isPointLight, lightPositionWorld, shadowCameraNear, shadowCameraFar ) { + function getDepthMaterial( object, material, isPointLight, lightPositionWorld, shadowCameraNear, shadowCameraFar ) { - var geometry = object.geometry; + var geometry = object.geometry; - var result = null; + var result = null; - var materialVariants = _depthMaterials; - var customMaterial = object.customDepthMaterial; + var materialVariants = _depthMaterials; + var customMaterial = object.customDepthMaterial; - if ( isPointLight ) { + if ( isPointLight ) { - materialVariants = _distanceMaterials; - customMaterial = object.customDistanceMaterial; + materialVariants = _distanceMaterials; + customMaterial = object.customDistanceMaterial; - } + } - if ( ! customMaterial ) { + if ( ! customMaterial ) { - var useMorphing = false; + var useMorphing = false; - if ( material.morphTargets ) { + if ( material.morphTargets ) { - if ( geometry && geometry.isBufferGeometry ) { + if ( geometry && geometry.isBufferGeometry ) { - useMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0; + useMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0; - } else if ( geometry && geometry.isGeometry ) { + } else if ( geometry && geometry.isGeometry ) { - useMorphing = geometry.morphTargets && geometry.morphTargets.length > 0; + useMorphing = geometry.morphTargets && geometry.morphTargets.length > 0; - } + } - } + } - if ( object.isSkinnedMesh && material.skinning === false ) { + if ( object.isSkinnedMesh && material.skinning === false ) { - console.warn( 'THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object ); + console.warn( 'THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object ); - } + } - var useSkinning = object.isSkinnedMesh && material.skinning; + var useSkinning = object.isSkinnedMesh && material.skinning; - var variantIndex = 0; + var variantIndex = 0; - if ( useMorphing ) variantIndex |= _MorphingFlag; - if ( useSkinning ) variantIndex |= _SkinningFlag; + if ( useMorphing ) variantIndex |= _MorphingFlag; + if ( useSkinning ) variantIndex |= _SkinningFlag; - result = materialVariants[ variantIndex ]; + result = materialVariants[ variantIndex ]; - } else { + } else { - result = customMaterial; + result = customMaterial; - } + } - if ( _renderer.localClippingEnabled && - material.clipShadows === true && - material.clippingPlanes.length !== 0 ) { + if ( _renderer.localClippingEnabled && + material.clipShadows === true && + material.clippingPlanes.length !== 0 ) { - // in this case we need a unique material instance reflecting the - // appropriate state + // in this case we need a unique material instance reflecting the + // appropriate state - var keyA = result.uuid, keyB = material.uuid; + var keyA = result.uuid, keyB = material.uuid; - var materialsForVariant = _materialCache[ keyA ]; + var materialsForVariant = _materialCache[ keyA ]; - if ( materialsForVariant === undefined ) { + if ( materialsForVariant === undefined ) { - materialsForVariant = {}; - _materialCache[ keyA ] = materialsForVariant; + materialsForVariant = {}; + _materialCache[ keyA ] = materialsForVariant; - } + } - var cachedMaterial = materialsForVariant[ keyB ]; + var cachedMaterial = materialsForVariant[ keyB ]; - if ( cachedMaterial === undefined ) { + if ( cachedMaterial === undefined ) { - cachedMaterial = result.clone(); - materialsForVariant[ keyB ] = cachedMaterial; + cachedMaterial = result.clone(); + materialsForVariant[ keyB ] = cachedMaterial; - } + } - result = cachedMaterial; + result = cachedMaterial; - } + } - result.visible = material.visible; - result.wireframe = material.wireframe; + result.visible = material.visible; + result.wireframe = material.wireframe; - result.side = ( material.shadowSide != null ) ? material.shadowSide : shadowSide[ material.side ]; + result.side = ( material.shadowSide != null ) ? material.shadowSide : shadowSide[ material.side ]; - result.clipShadows = material.clipShadows; - result.clippingPlanes = material.clippingPlanes; - result.clipIntersection = material.clipIntersection; + result.clipShadows = material.clipShadows; + result.clippingPlanes = material.clippingPlanes; + result.clipIntersection = material.clipIntersection; - result.wireframeLinewidth = material.wireframeLinewidth; - result.linewidth = material.linewidth; + result.wireframeLinewidth = material.wireframeLinewidth; + result.linewidth = material.linewidth; - if ( isPointLight && result.isMeshDistanceMaterial ) { + if ( isPointLight && result.isMeshDistanceMaterial ) { - result.referencePosition.copy( lightPositionWorld ); - result.nearDistance = shadowCameraNear; - result.farDistance = shadowCameraFar; + result.referencePosition.copy( lightPositionWorld ); + result.nearDistance = shadowCameraNear; + result.farDistance = shadowCameraFar; - } + } - return result; + return result; - } + } - function renderObject( object, camera, shadowCamera, isPointLight ) { + function renderObject( object, camera, shadowCamera, isPointLight ) { - if ( object.visible === false ) return; + if ( object.visible === false ) return; - var visible = object.layers.test( camera.layers ); + var visible = object.layers.test( camera.layers ); - if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) { + if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) { - if ( object.castShadow && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) { + if ( object.castShadow && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) { - object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld ); + object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld ); - var geometry = _objects.update( object ); - var material = object.material; + var geometry = _objects.update( object ); + var material = object.material; - if ( Array.isArray( material ) ) { + if ( Array.isArray( material ) ) { - var groups = geometry.groups; + var groups = geometry.groups; - for ( var k = 0, kl = groups.length; k < kl; k ++ ) { + for ( var k = 0, kl = groups.length; k < kl; k ++ ) { - var group = groups[ k ]; - var groupMaterial = material[ group.materialIndex ]; + var group = groups[ k ]; + var groupMaterial = material[ group.materialIndex ]; - if ( groupMaterial && groupMaterial.visible ) { + if ( groupMaterial && groupMaterial.visible ) { - var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far ); - _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group ); + var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far ); + _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group ); - } + } - } + } - } else if ( material.visible ) { + } else if ( material.visible ) { - var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far ); - _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null ); + var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far ); + _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null ); - } + } - } + } - } + } - var children = object.children; + var children = object.children; - for ( var i = 0, l = children.length; i < l; i ++ ) { + for ( var i = 0, l = children.length; i < l; i ++ ) { - renderObject( children[ i ], camera, shadowCamera, isPointLight ); + renderObject( children[ i ], camera, shadowCamera, isPointLight ); - } + } - } + } - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function WebGLState( gl, extensions, utils, capabilities ) { + function WebGLState( gl, extensions, utils, capabilities ) { - function ColorBuffer() { + function ColorBuffer() { - var locked = false; + var locked = false; - var color = new Vector4(); - var currentColorMask = null; - var currentColorClear = new Vector4( 0, 0, 0, 0 ); + var color = new Vector4(); + var currentColorMask = null; + var currentColorClear = new Vector4( 0, 0, 0, 0 ); - return { + return { - setMask: function ( colorMask ) { + setMask: function ( colorMask ) { - if ( currentColorMask !== colorMask && ! locked ) { + if ( currentColorMask !== colorMask && ! locked ) { - gl.colorMask( colorMask, colorMask, colorMask, colorMask ); - currentColorMask = colorMask; + gl.colorMask( colorMask, colorMask, colorMask, colorMask ); + currentColorMask = colorMask; - } + } - }, + }, - setLocked: function ( lock ) { + setLocked: function ( lock ) { - locked = lock; + locked = lock; - }, + }, - setClear: function ( r, g, b, a, premultipliedAlpha ) { + setClear: function ( r, g, b, a, premultipliedAlpha ) { - if ( premultipliedAlpha === true ) { + if ( premultipliedAlpha === true ) { - r *= a; g *= a; b *= a; + r *= a; g *= a; b *= a; - } + } - color.set( r, g, b, a ); + color.set( r, g, b, a ); - if ( currentColorClear.equals( color ) === false ) { + if ( currentColorClear.equals( color ) === false ) { - gl.clearColor( r, g, b, a ); - currentColorClear.copy( color ); + gl.clearColor( r, g, b, a ); + currentColorClear.copy( color ); - } + } - }, + }, - reset: function () { + reset: function () { - locked = false; + locked = false; - currentColorMask = null; - currentColorClear.set( - 1, 0, 0, 0 ); // set to invalid state + currentColorMask = null; + currentColorClear.set( - 1, 0, 0, 0 ); // set to invalid state - } + } - }; + }; - } + } - function DepthBuffer() { + function DepthBuffer() { - var locked = false; + var locked = false; - var currentDepthMask = null; - var currentDepthFunc = null; - var currentDepthClear = null; + var currentDepthMask = null; + var currentDepthFunc = null; + var currentDepthClear = null; - return { + return { - setTest: function ( depthTest ) { + setTest: function ( depthTest ) { - if ( depthTest ) { + if ( depthTest ) { - enable( gl.DEPTH_TEST ); + enable( gl.DEPTH_TEST ); - } else { + } else { - disable( gl.DEPTH_TEST ); + disable( gl.DEPTH_TEST ); - } + } - }, + }, - setMask: function ( depthMask ) { + setMask: function ( depthMask ) { - if ( currentDepthMask !== depthMask && ! locked ) { + if ( currentDepthMask !== depthMask && ! locked ) { - gl.depthMask( depthMask ); - currentDepthMask = depthMask; + gl.depthMask( depthMask ); + currentDepthMask = depthMask; - } + } - }, + }, - setFunc: function ( depthFunc ) { + setFunc: function ( depthFunc ) { - if ( currentDepthFunc !== depthFunc ) { + if ( currentDepthFunc !== depthFunc ) { - if ( depthFunc ) { + if ( depthFunc ) { - switch ( depthFunc ) { + switch ( depthFunc ) { - case NeverDepth: + case NeverDepth: - gl.depthFunc( gl.NEVER ); - break; + gl.depthFunc( gl.NEVER ); + break; - case AlwaysDepth: + case AlwaysDepth: - gl.depthFunc( gl.ALWAYS ); - break; + gl.depthFunc( gl.ALWAYS ); + break; - case LessDepth: + case LessDepth: - gl.depthFunc( gl.LESS ); - break; + gl.depthFunc( gl.LESS ); + break; - case LessEqualDepth: + case LessEqualDepth: - gl.depthFunc( gl.LEQUAL ); - break; + gl.depthFunc( gl.LEQUAL ); + break; - case EqualDepth: + case EqualDepth: - gl.depthFunc( gl.EQUAL ); - break; + gl.depthFunc( gl.EQUAL ); + break; - case GreaterEqualDepth: + case GreaterEqualDepth: - gl.depthFunc( gl.GEQUAL ); - break; + gl.depthFunc( gl.GEQUAL ); + break; - case GreaterDepth: + case GreaterDepth: - gl.depthFunc( gl.GREATER ); - break; + gl.depthFunc( gl.GREATER ); + break; - case NotEqualDepth: + case NotEqualDepth: - gl.depthFunc( gl.NOTEQUAL ); - break; + gl.depthFunc( gl.NOTEQUAL ); + break; - default: + default: - gl.depthFunc( gl.LEQUAL ); + gl.depthFunc( gl.LEQUAL ); - } + } - } else { + } else { - gl.depthFunc( gl.LEQUAL ); + gl.depthFunc( gl.LEQUAL ); - } + } - currentDepthFunc = depthFunc; + currentDepthFunc = depthFunc; - } + } - }, + }, - setLocked: function ( lock ) { + setLocked: function ( lock ) { - locked = lock; + locked = lock; - }, + }, - setClear: function ( depth ) { + setClear: function ( depth ) { - if ( currentDepthClear !== depth ) { + if ( currentDepthClear !== depth ) { - gl.clearDepth( depth ); - currentDepthClear = depth; + gl.clearDepth( depth ); + currentDepthClear = depth; - } + } - }, + }, - reset: function () { + reset: function () { - locked = false; + locked = false; - currentDepthMask = null; - currentDepthFunc = null; - currentDepthClear = null; + currentDepthMask = null; + currentDepthFunc = null; + currentDepthClear = null; - } + } - }; + }; - } + } - function StencilBuffer() { + function StencilBuffer() { - var locked = false; + var locked = false; - var currentStencilMask = null; - var currentStencilFunc = null; - var currentStencilRef = null; - var currentStencilFuncMask = null; - var currentStencilFail = null; - var currentStencilZFail = null; - var currentStencilZPass = null; - var currentStencilClear = null; + var currentStencilMask = null; + var currentStencilFunc = null; + var currentStencilRef = null; + var currentStencilFuncMask = null; + var currentStencilFail = null; + var currentStencilZFail = null; + var currentStencilZPass = null; + var currentStencilClear = null; - return { + return { - setTest: function ( stencilTest ) { + setTest: function ( stencilTest ) { - if ( stencilTest ) { + if ( stencilTest ) { - enable( gl.STENCIL_TEST ); + enable( gl.STENCIL_TEST ); - } else { + } else { - disable( gl.STENCIL_TEST ); + disable( gl.STENCIL_TEST ); - } + } - }, + }, - setMask: function ( stencilMask ) { + setMask: function ( stencilMask ) { - if ( currentStencilMask !== stencilMask && ! locked ) { + if ( currentStencilMask !== stencilMask && ! locked ) { - gl.stencilMask( stencilMask ); - currentStencilMask = stencilMask; + gl.stencilMask( stencilMask ); + currentStencilMask = stencilMask; - } + } - }, + }, - setFunc: function ( stencilFunc, stencilRef, stencilMask ) { + setFunc: function ( stencilFunc, stencilRef, stencilMask ) { - if ( currentStencilFunc !== stencilFunc || - currentStencilRef !== stencilRef || - currentStencilFuncMask !== stencilMask ) { + if ( currentStencilFunc !== stencilFunc || + currentStencilRef !== stencilRef || + currentStencilFuncMask !== stencilMask ) { - gl.stencilFunc( stencilFunc, stencilRef, stencilMask ); + gl.stencilFunc( stencilFunc, stencilRef, stencilMask ); - currentStencilFunc = stencilFunc; - currentStencilRef = stencilRef; - currentStencilFuncMask = stencilMask; + currentStencilFunc = stencilFunc; + currentStencilRef = stencilRef; + currentStencilFuncMask = stencilMask; - } + } - }, + }, - setOp: function ( stencilFail, stencilZFail, stencilZPass ) { + setOp: function ( stencilFail, stencilZFail, stencilZPass ) { - if ( currentStencilFail !== stencilFail || - currentStencilZFail !== stencilZFail || - currentStencilZPass !== stencilZPass ) { + if ( currentStencilFail !== stencilFail || + currentStencilZFail !== stencilZFail || + currentStencilZPass !== stencilZPass ) { - gl.stencilOp( stencilFail, stencilZFail, stencilZPass ); + gl.stencilOp( stencilFail, stencilZFail, stencilZPass ); - currentStencilFail = stencilFail; - currentStencilZFail = stencilZFail; - currentStencilZPass = stencilZPass; + currentStencilFail = stencilFail; + currentStencilZFail = stencilZFail; + currentStencilZPass = stencilZPass; - } + } - }, + }, - setLocked: function ( lock ) { + setLocked: function ( lock ) { - locked = lock; + locked = lock; - }, + }, - setClear: function ( stencil ) { + setClear: function ( stencil ) { - if ( currentStencilClear !== stencil ) { + if ( currentStencilClear !== stencil ) { - gl.clearStencil( stencil ); - currentStencilClear = stencil; + gl.clearStencil( stencil ); + currentStencilClear = stencil; - } + } - }, + }, - reset: function () { + reset: function () { - locked = false; + locked = false; - currentStencilMask = null; - currentStencilFunc = null; - currentStencilRef = null; - currentStencilFuncMask = null; - currentStencilFail = null; - currentStencilZFail = null; - currentStencilZPass = null; - currentStencilClear = null; + currentStencilMask = null; + currentStencilFunc = null; + currentStencilRef = null; + currentStencilFuncMask = null; + currentStencilFail = null; + currentStencilZFail = null; + currentStencilZPass = null; + currentStencilClear = null; - } + } - }; + }; - } + } - // + // - var colorBuffer = new ColorBuffer(); - var depthBuffer = new DepthBuffer(); - var stencilBuffer = new StencilBuffer(); + var colorBuffer = new ColorBuffer(); + var depthBuffer = new DepthBuffer(); + var stencilBuffer = new StencilBuffer(); - var maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); - var newAttributes = new Uint8Array( maxVertexAttributes ); - var enabledAttributes = new Uint8Array( maxVertexAttributes ); - var attributeDivisors = new Uint8Array( maxVertexAttributes ); + var maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); + var newAttributes = new Uint8Array( maxVertexAttributes ); + var enabledAttributes = new Uint8Array( maxVertexAttributes ); + var attributeDivisors = new Uint8Array( maxVertexAttributes ); - var enabledCapabilities = {}; + var enabledCapabilities = {}; - var compressedTextureFormats = null; + var compressedTextureFormats = null; - var currentProgram = null; + var currentProgram = null; - var currentBlending = null; - var currentBlendEquation = null; - var currentBlendSrc = null; - var currentBlendDst = null; - var currentBlendEquationAlpha = null; - var currentBlendSrcAlpha = null; - var currentBlendDstAlpha = null; - var currentPremultipledAlpha = false; + var currentBlending = null; + var currentBlendEquation = null; + var currentBlendSrc = null; + var currentBlendDst = null; + var currentBlendEquationAlpha = null; + var currentBlendSrcAlpha = null; + var currentBlendDstAlpha = null; + var currentPremultipledAlpha = false; - var currentFlipSided = null; - var currentCullFace = null; + var currentFlipSided = null; + var currentCullFace = null; - var currentLineWidth = null; + var currentLineWidth = null; - var currentPolygonOffsetFactor = null; - var currentPolygonOffsetUnits = null; + var currentPolygonOffsetFactor = null; + var currentPolygonOffsetUnits = null; - var maxTextures = gl.getParameter( gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS ); + var maxTextures = gl.getParameter( gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS ); - var lineWidthAvailable = false; - var version = 0; - var glVersion = gl.getParameter( gl.VERSION ); + var lineWidthAvailable = false; + var version = 0; + var glVersion = gl.getParameter( gl.VERSION ); - if ( glVersion.indexOf( 'WebGL' ) !== - 1 ) { + if ( glVersion.indexOf( 'WebGL' ) !== - 1 ) { - version = parseFloat( /^WebGL\ ([0-9])/.exec( glVersion )[ 1 ] ); - lineWidthAvailable = ( version >= 1.0 ); + version = parseFloat( /^WebGL\ ([0-9])/.exec( glVersion )[ 1 ] ); + lineWidthAvailable = ( version >= 1.0 ); - } else if ( glVersion.indexOf( 'OpenGL ES' ) !== - 1 ) { + } else if ( glVersion.indexOf( 'OpenGL ES' ) !== - 1 ) { - version = parseFloat( /^OpenGL\ ES\ ([0-9])/.exec( glVersion )[ 1 ] ); - lineWidthAvailable = ( version >= 2.0 ); + version = parseFloat( /^OpenGL\ ES\ ([0-9])/.exec( glVersion )[ 1 ] ); + lineWidthAvailable = ( version >= 2.0 ); - } + } - var currentTextureSlot = null; - var currentBoundTextures = {}; + var currentTextureSlot = null; + var currentBoundTextures = {}; - var currentScissor = new Vector4(); - var currentViewport = new Vector4(); + var currentScissor = new Vector4(); + var currentViewport = new Vector4(); - function createTexture( type, target, count ) { + function createTexture( type, target, count ) { - var data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4. - var texture = gl.createTexture(); + var data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4. + var texture = gl.createTexture(); - gl.bindTexture( type, texture ); - gl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST ); - gl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST ); + gl.bindTexture( type, texture ); + gl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST ); + gl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST ); - for ( var i = 0; i < count; i ++ ) { + for ( var i = 0; i < count; i ++ ) { - gl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data ); + gl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data ); - } + } - return texture; + return texture; - } + } - var emptyTextures = {}; - emptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 ); - emptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 ); + var emptyTextures = {}; + emptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 ); + emptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 ); - // init + // init - colorBuffer.setClear( 0, 0, 0, 1 ); - depthBuffer.setClear( 1 ); - stencilBuffer.setClear( 0 ); + colorBuffer.setClear( 0, 0, 0, 1 ); + depthBuffer.setClear( 1 ); + stencilBuffer.setClear( 0 ); - enable( gl.DEPTH_TEST ); - depthBuffer.setFunc( LessEqualDepth ); + enable( gl.DEPTH_TEST ); + depthBuffer.setFunc( LessEqualDepth ); - setFlipSided( false ); - setCullFace( CullFaceBack ); - enable( gl.CULL_FACE ); + setFlipSided( false ); + setCullFace( CullFaceBack ); + enable( gl.CULL_FACE ); - enable( gl.BLEND ); - setBlending( NormalBlending ); + enable( gl.BLEND ); + setBlending( NormalBlending ); - // + // - function initAttributes() { + function initAttributes() { - for ( var i = 0, l = newAttributes.length; i < l; i ++ ) { + for ( var i = 0, l = newAttributes.length; i < l; i ++ ) { - newAttributes[ i ] = 0; + newAttributes[ i ] = 0; - } + } - } + } - function enableAttribute( attribute ) { + function enableAttribute( attribute ) { - enableAttributeAndDivisor( attribute, 0 ); + enableAttributeAndDivisor( attribute, 0 ); - } + } - function enableAttributeAndDivisor( attribute, meshPerAttribute ) { + function enableAttributeAndDivisor( attribute, meshPerAttribute ) { - newAttributes[ attribute ] = 1; + newAttributes[ attribute ] = 1; - if ( enabledAttributes[ attribute ] === 0 ) { + if ( enabledAttributes[ attribute ] === 0 ) { - gl.enableVertexAttribArray( attribute ); - enabledAttributes[ attribute ] = 1; + gl.enableVertexAttribArray( attribute ); + enabledAttributes[ attribute ] = 1; - } + } - if ( attributeDivisors[ attribute ] !== meshPerAttribute ) { + if ( attributeDivisors[ attribute ] !== meshPerAttribute ) { - var extension = capabilities.isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' ); + var extension = capabilities.isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' ); - extension[ capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute ); - attributeDivisors[ attribute ] = meshPerAttribute; + extension[ capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute ); + attributeDivisors[ attribute ] = meshPerAttribute; - } + } - } + } - function disableUnusedAttributes() { + function disableUnusedAttributes() { - for ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) { + for ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) { - if ( enabledAttributes[ i ] !== newAttributes[ i ] ) { + if ( enabledAttributes[ i ] !== newAttributes[ i ] ) { - gl.disableVertexAttribArray( i ); - enabledAttributes[ i ] = 0; + gl.disableVertexAttribArray( i ); + enabledAttributes[ i ] = 0; - } + } - } + } - } + } - function enable( id ) { + function enable( id ) { - if ( enabledCapabilities[ id ] !== true ) { + if ( enabledCapabilities[ id ] !== true ) { - gl.enable( id ); - enabledCapabilities[ id ] = true; + gl.enable( id ); + enabledCapabilities[ id ] = true; - } + } - } + } - function disable( id ) { + function disable( id ) { - if ( enabledCapabilities[ id ] !== false ) { + if ( enabledCapabilities[ id ] !== false ) { - gl.disable( id ); - enabledCapabilities[ id ] = false; + gl.disable( id ); + enabledCapabilities[ id ] = false; - } + } - } + } - function getCompressedTextureFormats() { + function getCompressedTextureFormats() { - if ( compressedTextureFormats === null ) { + if ( compressedTextureFormats === null ) { - compressedTextureFormats = []; + compressedTextureFormats = []; - if ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) || - extensions.get( 'WEBGL_compressed_texture_s3tc' ) || - extensions.get( 'WEBGL_compressed_texture_etc1' ) || - extensions.get( 'WEBGL_compressed_texture_astc' ) ) { + if ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) || + extensions.get( 'WEBGL_compressed_texture_s3tc' ) || + extensions.get( 'WEBGL_compressed_texture_etc1' ) || + extensions.get( 'WEBGL_compressed_texture_astc' ) ) { - var formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS ); + var formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS ); - for ( var i = 0; i < formats.length; i ++ ) { + for ( var i = 0; i < formats.length; i ++ ) { - compressedTextureFormats.push( formats[ i ] ); + compressedTextureFormats.push( formats[ i ] ); - } + } - } + } - } + } - return compressedTextureFormats; + return compressedTextureFormats; - } + } - function useProgram( program ) { + function useProgram( program ) { - if ( currentProgram !== program ) { + if ( currentProgram !== program ) { - gl.useProgram( program ); + gl.useProgram( program ); - currentProgram = program; + currentProgram = program; - return true; + return true; - } + } - return false; + return false; - } + } - function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) { + function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) { - if ( blending !== NoBlending ) { + if ( blending !== NoBlending ) { - enable( gl.BLEND ); + enable( gl.BLEND ); - } else { + } else { - disable( gl.BLEND ); + disable( gl.BLEND ); - } + } - if ( blending !== CustomBlending ) { + if ( blending !== CustomBlending ) { - if ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) { + if ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) { - switch ( blending ) { + switch ( blending ) { - case AdditiveBlending: + case AdditiveBlending: - if ( premultipliedAlpha ) { + if ( premultipliedAlpha ) { - gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); - gl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE ); + gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); + gl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE ); - } else { + } else { - gl.blendEquation( gl.FUNC_ADD ); - gl.blendFunc( gl.SRC_ALPHA, gl.ONE ); + gl.blendEquation( gl.FUNC_ADD ); + gl.blendFunc( gl.SRC_ALPHA, gl.ONE ); - } - break; + } + break; - case SubtractiveBlending: + case SubtractiveBlending: - if ( premultipliedAlpha ) { + if ( premultipliedAlpha ) { - gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); - gl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA ); + gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); + gl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA ); - } else { + } else { - gl.blendEquation( gl.FUNC_ADD ); - gl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR ); + gl.blendEquation( gl.FUNC_ADD ); + gl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR ); - } - break; + } + break; - case MultiplyBlending: + case MultiplyBlending: - if ( premultipliedAlpha ) { + if ( premultipliedAlpha ) { - gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); - gl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA ); + gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); + gl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA ); - } else { + } else { - gl.blendEquation( gl.FUNC_ADD ); - gl.blendFunc( gl.ZERO, gl.SRC_COLOR ); + gl.blendEquation( gl.FUNC_ADD ); + gl.blendFunc( gl.ZERO, gl.SRC_COLOR ); - } - break; + } + break; - default: + default: - if ( premultipliedAlpha ) { + if ( premultipliedAlpha ) { - gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); - gl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); + gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); + gl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); - } else { + } else { - gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); - gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); + gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); + gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); - } + } - } + } - } + } - currentBlendEquation = null; - currentBlendSrc = null; - currentBlendDst = null; - currentBlendEquationAlpha = null; - currentBlendSrcAlpha = null; - currentBlendDstAlpha = null; + currentBlendEquation = null; + currentBlendSrc = null; + currentBlendDst = null; + currentBlendEquationAlpha = null; + currentBlendSrcAlpha = null; + currentBlendDstAlpha = null; - } else { + } else { - blendEquationAlpha = blendEquationAlpha || blendEquation; - blendSrcAlpha = blendSrcAlpha || blendSrc; - blendDstAlpha = blendDstAlpha || blendDst; + blendEquationAlpha = blendEquationAlpha || blendEquation; + blendSrcAlpha = blendSrcAlpha || blendSrc; + blendDstAlpha = blendDstAlpha || blendDst; - if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) { + if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) { - gl.blendEquationSeparate( utils.convert( blendEquation ), utils.convert( blendEquationAlpha ) ); + gl.blendEquationSeparate( utils.convert( blendEquation ), utils.convert( blendEquationAlpha ) ); - currentBlendEquation = blendEquation; - currentBlendEquationAlpha = blendEquationAlpha; + currentBlendEquation = blendEquation; + currentBlendEquationAlpha = blendEquationAlpha; - } + } - if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) { + if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) { - gl.blendFuncSeparate( utils.convert( blendSrc ), utils.convert( blendDst ), utils.convert( blendSrcAlpha ), utils.convert( blendDstAlpha ) ); + gl.blendFuncSeparate( utils.convert( blendSrc ), utils.convert( blendDst ), utils.convert( blendSrcAlpha ), utils.convert( blendDstAlpha ) ); - currentBlendSrc = blendSrc; - currentBlendDst = blendDst; - currentBlendSrcAlpha = blendSrcAlpha; - currentBlendDstAlpha = blendDstAlpha; + currentBlendSrc = blendSrc; + currentBlendDst = blendDst; + currentBlendSrcAlpha = blendSrcAlpha; + currentBlendDstAlpha = blendDstAlpha; - } + } - } + } - currentBlending = blending; - currentPremultipledAlpha = premultipliedAlpha; + currentBlending = blending; + currentPremultipledAlpha = premultipliedAlpha; - } + } - function setMaterial( material, frontFaceCW ) { + function setMaterial( material, frontFaceCW ) { - material.side === DoubleSide - ? disable( gl.CULL_FACE ) - : enable( gl.CULL_FACE ); + material.side === DoubleSide + ? disable( gl.CULL_FACE ) + : enable( gl.CULL_FACE ); - var flipSided = ( material.side === BackSide ); - if ( frontFaceCW ) flipSided = ! flipSided; + var flipSided = ( material.side === BackSide ); + if ( frontFaceCW ) flipSided = ! flipSided; - setFlipSided( flipSided ); + setFlipSided( flipSided ); - ( material.blending === NormalBlending && material.transparent === false ) - ? setBlending( NoBlending ) - : setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha ); + ( material.blending === NormalBlending && material.transparent === false ) + ? setBlending( NoBlending ) + : setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha ); - depthBuffer.setFunc( material.depthFunc ); - depthBuffer.setTest( material.depthTest ); - depthBuffer.setMask( material.depthWrite ); - colorBuffer.setMask( material.colorWrite ); + depthBuffer.setFunc( material.depthFunc ); + depthBuffer.setTest( material.depthTest ); + depthBuffer.setMask( material.depthWrite ); + colorBuffer.setMask( material.colorWrite ); - setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); + setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); - } + } - // + // - function setFlipSided( flipSided ) { + function setFlipSided( flipSided ) { - if ( currentFlipSided !== flipSided ) { + if ( currentFlipSided !== flipSided ) { - if ( flipSided ) { + if ( flipSided ) { - gl.frontFace( gl.CW ); + gl.frontFace( gl.CW ); - } else { + } else { - gl.frontFace( gl.CCW ); + gl.frontFace( gl.CCW ); - } + } - currentFlipSided = flipSided; + currentFlipSided = flipSided; - } + } - } + } - function setCullFace( cullFace ) { + function setCullFace( cullFace ) { - if ( cullFace !== CullFaceNone ) { + if ( cullFace !== CullFaceNone ) { - enable( gl.CULL_FACE ); + enable( gl.CULL_FACE ); - if ( cullFace !== currentCullFace ) { + if ( cullFace !== currentCullFace ) { - if ( cullFace === CullFaceBack ) { + if ( cullFace === CullFaceBack ) { - gl.cullFace( gl.BACK ); + gl.cullFace( gl.BACK ); - } else if ( cullFace === CullFaceFront ) { + } else if ( cullFace === CullFaceFront ) { - gl.cullFace( gl.FRONT ); + gl.cullFace( gl.FRONT ); - } else { + } else { - gl.cullFace( gl.FRONT_AND_BACK ); + gl.cullFace( gl.FRONT_AND_BACK ); - } + } - } + } - } else { + } else { - disable( gl.CULL_FACE ); + disable( gl.CULL_FACE ); - } + } - currentCullFace = cullFace; + currentCullFace = cullFace; - } + } - function setLineWidth( width ) { + function setLineWidth( width ) { - if ( width !== currentLineWidth ) { + if ( width !== currentLineWidth ) { - if ( lineWidthAvailable ) gl.lineWidth( width ); + if ( lineWidthAvailable ) gl.lineWidth( width ); - currentLineWidth = width; + currentLineWidth = width; - } + } - } + } - function setPolygonOffset( polygonOffset, factor, units ) { + function setPolygonOffset( polygonOffset, factor, units ) { - if ( polygonOffset ) { + if ( polygonOffset ) { - enable( gl.POLYGON_OFFSET_FILL ); + enable( gl.POLYGON_OFFSET_FILL ); - if ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) { + if ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) { - gl.polygonOffset( factor, units ); + gl.polygonOffset( factor, units ); - currentPolygonOffsetFactor = factor; - currentPolygonOffsetUnits = units; + currentPolygonOffsetFactor = factor; + currentPolygonOffsetUnits = units; - } + } - } else { + } else { - disable( gl.POLYGON_OFFSET_FILL ); + disable( gl.POLYGON_OFFSET_FILL ); - } + } - } + } - function setScissorTest( scissorTest ) { + function setScissorTest( scissorTest ) { - if ( scissorTest ) { + if ( scissorTest ) { - enable( gl.SCISSOR_TEST ); + enable( gl.SCISSOR_TEST ); - } else { + } else { - disable( gl.SCISSOR_TEST ); + disable( gl.SCISSOR_TEST ); - } + } - } + } - // texture + // texture - function activeTexture( webglSlot ) { + function activeTexture( webglSlot ) { - if ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1; + if ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1; - if ( currentTextureSlot !== webglSlot ) { + if ( currentTextureSlot !== webglSlot ) { - gl.activeTexture( webglSlot ); - currentTextureSlot = webglSlot; + gl.activeTexture( webglSlot ); + currentTextureSlot = webglSlot; - } + } - } + } - function bindTexture( webglType, webglTexture ) { + function bindTexture( webglType, webglTexture ) { - if ( currentTextureSlot === null ) { + if ( currentTextureSlot === null ) { - activeTexture(); + activeTexture(); - } + } - var boundTexture = currentBoundTextures[ currentTextureSlot ]; + var boundTexture = currentBoundTextures[ currentTextureSlot ]; - if ( boundTexture === undefined ) { + if ( boundTexture === undefined ) { - boundTexture = { type: undefined, texture: undefined }; - currentBoundTextures[ currentTextureSlot ] = boundTexture; + boundTexture = { type: undefined, texture: undefined }; + currentBoundTextures[ currentTextureSlot ] = boundTexture; - } + } - if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) { + if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) { - gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] ); + gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] ); - boundTexture.type = webglType; - boundTexture.texture = webglTexture; + boundTexture.type = webglType; + boundTexture.texture = webglTexture; - } + } - } + } - function compressedTexImage2D() { + function compressedTexImage2D() { - try { + try { - gl.compressedTexImage2D.apply( gl, arguments ); + gl.compressedTexImage2D.apply( gl, arguments ); - } catch ( error ) { + } catch ( error ) { - console.error( 'THREE.WebGLState:', error ); + console.error( 'THREE.WebGLState:', error ); - } + } - } + } - function texImage2D() { + function texImage2D() { - try { + try { - gl.texImage2D.apply( gl, arguments ); + gl.texImage2D.apply( gl, arguments ); - } catch ( error ) { + } catch ( error ) { - console.error( 'THREE.WebGLState:', error ); + console.error( 'THREE.WebGLState:', error ); - } + } - } + } - // + // - function scissor( scissor ) { + function scissor( scissor ) { - if ( currentScissor.equals( scissor ) === false ) { + if ( currentScissor.equals( scissor ) === false ) { - gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w ); - currentScissor.copy( scissor ); + gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w ); + currentScissor.copy( scissor ); - } + } - } + } - function viewport( viewport ) { + function viewport( viewport ) { - if ( currentViewport.equals( viewport ) === false ) { + if ( currentViewport.equals( viewport ) === false ) { - gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w ); - currentViewport.copy( viewport ); + gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w ); + currentViewport.copy( viewport ); - } + } - } + } - // + // - function reset() { + function reset() { - for ( var i = 0; i < enabledAttributes.length; i ++ ) { + for ( var i = 0; i < enabledAttributes.length; i ++ ) { - if ( enabledAttributes[ i ] === 1 ) { + if ( enabledAttributes[ i ] === 1 ) { - gl.disableVertexAttribArray( i ); - enabledAttributes[ i ] = 0; + gl.disableVertexAttribArray( i ); + enabledAttributes[ i ] = 0; - } + } - } + } - enabledCapabilities = {}; + enabledCapabilities = {}; - compressedTextureFormats = null; + compressedTextureFormats = null; - currentTextureSlot = null; - currentBoundTextures = {}; + currentTextureSlot = null; + currentBoundTextures = {}; - currentProgram = null; + currentProgram = null; - currentBlending = null; + currentBlending = null; - currentFlipSided = null; - currentCullFace = null; + currentFlipSided = null; + currentCullFace = null; - colorBuffer.reset(); - depthBuffer.reset(); - stencilBuffer.reset(); + colorBuffer.reset(); + depthBuffer.reset(); + stencilBuffer.reset(); - } + } - return { + return { - buffers: { - color: colorBuffer, - depth: depthBuffer, - stencil: stencilBuffer - }, + buffers: { + color: colorBuffer, + depth: depthBuffer, + stencil: stencilBuffer + }, - initAttributes: initAttributes, - enableAttribute: enableAttribute, - enableAttributeAndDivisor: enableAttributeAndDivisor, - disableUnusedAttributes: disableUnusedAttributes, - enable: enable, - disable: disable, - getCompressedTextureFormats: getCompressedTextureFormats, + initAttributes: initAttributes, + enableAttribute: enableAttribute, + enableAttributeAndDivisor: enableAttributeAndDivisor, + disableUnusedAttributes: disableUnusedAttributes, + enable: enable, + disable: disable, + getCompressedTextureFormats: getCompressedTextureFormats, - useProgram: useProgram, + useProgram: useProgram, - setBlending: setBlending, - setMaterial: setMaterial, + setBlending: setBlending, + setMaterial: setMaterial, - setFlipSided: setFlipSided, - setCullFace: setCullFace, + setFlipSided: setFlipSided, + setCullFace: setCullFace, - setLineWidth: setLineWidth, - setPolygonOffset: setPolygonOffset, + setLineWidth: setLineWidth, + setPolygonOffset: setPolygonOffset, - setScissorTest: setScissorTest, + setScissorTest: setScissorTest, - activeTexture: activeTexture, - bindTexture: bindTexture, - compressedTexImage2D: compressedTexImage2D, - texImage2D: texImage2D, + activeTexture: activeTexture, + bindTexture: bindTexture, + compressedTexImage2D: compressedTexImage2D, + texImage2D: texImage2D, - scissor: scissor, - viewport: viewport, + scissor: scissor, + viewport: viewport, - reset: reset + reset: reset - }; + }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) { + function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) { - var _videoTextures = {}; - var _canvas; + var _videoTextures = {}; + var _canvas; - // + // - function clampToMaxSize( image, maxSize ) { + function clampToMaxSize( image, maxSize ) { - if ( image.width > maxSize || image.height > maxSize ) { + if ( image.width > maxSize || image.height > maxSize ) { - if ( 'data' in image ) { + if ( 'data' in image ) { - console.warn( 'THREE.WebGLRenderer: image in DataTexture is too big (' + image.width + 'x' + image.height + ').' ); - return; + console.warn( 'THREE.WebGLRenderer: image in DataTexture is too big (' + image.width + 'x' + image.height + ').' ); + return; - } + } - // Warning: Scaling through the canvas will only work with images that use - // premultiplied alpha. + // Warning: Scaling through the canvas will only work with images that use + // premultiplied alpha. - var scale = maxSize / Math.max( image.width, image.height ); + var scale = maxSize / Math.max( image.width, image.height ); - var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); - canvas.width = Math.floor( image.width * scale ); - canvas.height = Math.floor( image.height * scale ); + var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); + canvas.width = Math.floor( image.width * scale ); + canvas.height = Math.floor( image.height * scale ); - var context = canvas.getContext( '2d' ); - context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height ); + var context = canvas.getContext( '2d' ); + context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height ); - console.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height ); + console.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height ); - return canvas; + return canvas; - } + } - return image; + return image; - } + } - function isPowerOfTwo( image ) { + function isPowerOfTwo( image ) { - return _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height ); + return _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height ); - } + } - function makePowerOfTwo( image ) { + function makePowerOfTwo( image ) { - if ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement || image instanceof ImageBitmap ) { + if ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement || image instanceof ImageBitmap ) { - if ( _canvas === undefined ) _canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); + if ( _canvas === undefined ) _canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); - _canvas.width = _Math.floorPowerOfTwo( image.width ); - _canvas.height = _Math.floorPowerOfTwo( image.height ); + _canvas.width = _Math.floorPowerOfTwo( image.width ); + _canvas.height = _Math.floorPowerOfTwo( image.height ); - var context = _canvas.getContext( '2d' ); - context.drawImage( image, 0, 0, _canvas.width, _canvas.height ); + var context = _canvas.getContext( '2d' ); + context.drawImage( image, 0, 0, _canvas.width, _canvas.height ); - console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + _canvas.width + 'x' + _canvas.height ); + console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + _canvas.width + 'x' + _canvas.height, image ); - return _canvas; + return _canvas; - } + } - return image; + return image; - } + } - function textureNeedsPowerOfTwo( texture ) { + function textureNeedsPowerOfTwo( texture ) { - if ( capabilities.isWebGL2 ) return false; + if ( capabilities.isWebGL2 ) return false; - return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) || - ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ); + return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) || + ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ); - } + } - function textureNeedsGenerateMipmaps( texture, isPowerOfTwo ) { + function textureNeedsGenerateMipmaps( texture, isPowerOfTwo ) { - return texture.generateMipmaps && isPowerOfTwo && - texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; + return texture.generateMipmaps && isPowerOfTwo && + texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; - } + } - function generateMipmap( target, texture, width, height ) { + function generateMipmap( target, texture, width, height ) { - _gl.generateMipmap( target ); + _gl.generateMipmap( target ); - var textureProperties = properties.get( texture ); + var textureProperties = properties.get( texture ); - // Note: Math.log( x ) * Math.LOG2E used instead of Math.log2( x ) which is not supported by IE11 - textureProperties.__maxMipLevel = Math.log( Math.max( width, height ) ) * Math.LOG2E; + // Note: Math.log( x ) * Math.LOG2E used instead of Math.log2( x ) which is not supported by IE11 + textureProperties.__maxMipLevel = Math.log( Math.max( width, height ) ) * Math.LOG2E; - } + } - function getInternalFormat( glFormat, glType ) { + function getInternalFormat( glFormat, glType ) { - if ( ! capabilities.isWebGL2 ) return glFormat; + if ( ! capabilities.isWebGL2 ) return glFormat; - if ( glFormat === _gl.RGB ) { + if ( glFormat === _gl.RGB ) { - if ( glType === _gl.FLOAT ) return _gl.RGB32F; - if ( glType === _gl.HALF_FLOAT ) return _gl.RGB16F; - if ( glType === _gl.UNSIGNED_BYTE ) return _gl.RGB8; + if ( glType === _gl.FLOAT ) return _gl.RGB32F; + if ( glType === _gl.HALF_FLOAT ) return _gl.RGB16F; + if ( glType === _gl.UNSIGNED_BYTE ) return _gl.RGB8; - } + } - if ( glFormat === _gl.RGBA ) { + if ( glFormat === _gl.RGBA ) { - if ( glType === _gl.FLOAT ) return _gl.RGBA32F; - if ( glType === _gl.HALF_FLOAT ) return _gl.RGBA16F; - if ( glType === _gl.UNSIGNED_BYTE ) return _gl.RGBA8; + if ( glType === _gl.FLOAT ) return _gl.RGBA32F; + if ( glType === _gl.HALF_FLOAT ) return _gl.RGBA16F; + if ( glType === _gl.UNSIGNED_BYTE ) return _gl.RGBA8; - } + } - return glFormat; + return glFormat; - } + } - // Fallback filters for non-power-of-2 textures + // Fallback filters for non-power-of-2 textures - function filterFallback( f ) { + function filterFallback( f ) { - if ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) { + if ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) { - return _gl.NEAREST; + return _gl.NEAREST; - } + } - return _gl.LINEAR; + return _gl.LINEAR; - } + } - // + // - function onTextureDispose( event ) { + function onTextureDispose( event ) { - var texture = event.target; + var texture = event.target; - texture.removeEventListener( 'dispose', onTextureDispose ); + texture.removeEventListener( 'dispose', onTextureDispose ); - deallocateTexture( texture ); + deallocateTexture( texture ); - if ( texture.isVideoTexture ) { + if ( texture.isVideoTexture ) { - delete _videoTextures[ texture.id ]; + delete _videoTextures[ texture.id ]; - } + } - info.memory.textures --; + info.memory.textures --; - } + } - function onRenderTargetDispose( event ) { + function onRenderTargetDispose( event ) { - var renderTarget = event.target; + var renderTarget = event.target; - renderTarget.removeEventListener( 'dispose', onRenderTargetDispose ); + renderTarget.removeEventListener( 'dispose', onRenderTargetDispose ); - deallocateRenderTarget( renderTarget ); + deallocateRenderTarget( renderTarget ); - info.memory.textures --; + info.memory.textures --; - } + } - // + // - function deallocateTexture( texture ) { + function deallocateTexture( texture ) { - var textureProperties = properties.get( texture ); + var textureProperties = properties.get( texture ); - if ( texture.image && textureProperties.__image__webglTextureCube ) { + if ( texture.image && textureProperties.__image__webglTextureCube ) { - // cube texture + // cube texture - _gl.deleteTexture( textureProperties.__image__webglTextureCube ); + _gl.deleteTexture( textureProperties.__image__webglTextureCube ); - } else { + } else { - // 2D texture + // 2D texture - if ( textureProperties.__webglInit === undefined ) return; + if ( textureProperties.__webglInit === undefined ) return; - _gl.deleteTexture( textureProperties.__webglTexture ); + _gl.deleteTexture( textureProperties.__webglTexture ); - } + } - // remove all webgl properties - properties.remove( texture ); + // remove all webgl properties + properties.remove( texture ); - } + } - function deallocateRenderTarget( renderTarget ) { + function deallocateRenderTarget( renderTarget ) { - var renderTargetProperties = properties.get( renderTarget ); - var textureProperties = properties.get( renderTarget.texture ); + var renderTargetProperties = properties.get( renderTarget ); + var textureProperties = properties.get( renderTarget.texture ); - if ( ! renderTarget ) return; + if ( ! renderTarget ) return; - if ( textureProperties.__webglTexture !== undefined ) { + if ( textureProperties.__webglTexture !== undefined ) { - _gl.deleteTexture( textureProperties.__webglTexture ); + _gl.deleteTexture( textureProperties.__webglTexture ); - } + } - if ( renderTarget.depthTexture ) { + if ( renderTarget.depthTexture ) { - renderTarget.depthTexture.dispose(); + renderTarget.depthTexture.dispose(); - } + } - if ( renderTarget.isWebGLRenderTargetCube ) { + if ( renderTarget.isWebGLRenderTargetCube ) { - for ( var i = 0; i < 6; i ++ ) { + for ( var i = 0; i < 6; i ++ ) { - _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] ); - if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] ); + _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] ); + if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] ); - } + } - } else { + } else { - _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer ); - if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer ); + _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer ); + if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer ); - } + } - properties.remove( renderTarget.texture ); - properties.remove( renderTarget ); + properties.remove( renderTarget.texture ); + properties.remove( renderTarget ); - } + } - // + // - function setTexture2D( texture, slot ) { + function setTexture2D( texture, slot ) { - var textureProperties = properties.get( texture ); + var textureProperties = properties.get( texture ); - if ( texture.isVideoTexture ) updateVideoTexture( texture ); + if ( texture.isVideoTexture ) updateVideoTexture( texture ); - if ( texture.version > 0 && textureProperties.__version !== texture.version ) { + if ( texture.version > 0 && textureProperties.__version !== texture.version ) { - var image = texture.image; + var image = texture.image; - if ( image === undefined ) { + if ( image === undefined ) { - console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined' ); + console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined' ); - } else if ( image.complete === false ) { + } else if ( image.complete === false ) { - console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete' ); + console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete' ); - } else { + } else { - uploadTexture( textureProperties, texture, slot ); - return; + uploadTexture( textureProperties, texture, slot ); + return; - } + } - } + } - state.activeTexture( _gl.TEXTURE0 + slot ); - state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture ); + state.activeTexture( _gl.TEXTURE0 + slot ); + state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture ); - } + } - function setTextureCube( texture, slot ) { + function setTextureCube( texture, slot ) { - var textureProperties = properties.get( texture ); + var textureProperties = properties.get( texture ); - if ( texture.image.length === 6 ) { + if ( texture.image.length === 6 ) { - if ( texture.version > 0 && textureProperties.__version !== texture.version ) { + if ( texture.version > 0 && textureProperties.__version !== texture.version ) { - if ( ! textureProperties.__image__webglTextureCube ) { + if ( ! textureProperties.__image__webglTextureCube ) { - texture.addEventListener( 'dispose', onTextureDispose ); + texture.addEventListener( 'dispose', onTextureDispose ); - textureProperties.__image__webglTextureCube = _gl.createTexture(); + textureProperties.__image__webglTextureCube = _gl.createTexture(); - info.memory.textures ++; + info.memory.textures ++; - } + } - state.activeTexture( _gl.TEXTURE0 + slot ); - state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube ); + state.activeTexture( _gl.TEXTURE0 + slot ); + state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube ); - _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY ); + _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY ); - var isCompressed = ( texture && texture.isCompressedTexture ); - var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture ); + var isCompressed = ( texture && texture.isCompressedTexture ); + var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture ); - var cubeImage = []; + var cubeImage = []; - for ( var i = 0; i < 6; i ++ ) { + for ( var i = 0; i < 6; i ++ ) { - if ( ! isCompressed && ! isDataTexture ) { + if ( ! isCompressed && ! isDataTexture ) { - cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize ); + cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize ); - } else { + } else { - cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ]; + cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ]; - } + } - } + } - var image = cubeImage[ 0 ], - isPowerOfTwoImage = isPowerOfTwo( image ), - glFormat = utils.convert( texture.format ), - glType = utils.convert( texture.type ), - glInternalFormat = getInternalFormat( glFormat, glType ); + var image = cubeImage[ 0 ], + isPowerOfTwoImage = isPowerOfTwo( image ), + glFormat = utils.convert( texture.format ), + glType = utils.convert( texture.type ), + glInternalFormat = getInternalFormat( glFormat, glType ); - setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage ); + setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage ); - for ( var i = 0; i < 6; i ++ ) { + for ( var i = 0; i < 6; i ++ ) { - if ( ! isCompressed ) { + if ( ! isCompressed ) { - if ( isDataTexture ) { + if ( isDataTexture ) { - state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data ); + state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data ); - } else { + } else { - state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] ); + state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] ); - } + } - } else { + } else { - var mipmap, mipmaps = cubeImage[ i ].mipmaps; + var mipmap, mipmaps = cubeImage[ i ].mipmaps; - for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) { + for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) { - mipmap = mipmaps[ j ]; + mipmap = mipmaps[ j ]; - if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { + if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { - if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) { + if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) { - state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); + state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); - } else { + } else { - console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' ); + console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' ); - } + } - } else { + } else { - state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); + state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); - } + } - } + } - } + } - } + } - if ( ! isCompressed ) { + if ( ! isCompressed ) { - textureProperties.__maxMipLevel = 0; + textureProperties.__maxMipLevel = 0; - } else { + } else { - textureProperties.__maxMipLevel = mipmaps.length - 1; + textureProperties.__maxMipLevel = mipmaps.length - 1; - } + } - if ( textureNeedsGenerateMipmaps( texture, isPowerOfTwoImage ) ) { + if ( textureNeedsGenerateMipmaps( texture, isPowerOfTwoImage ) ) { - // We assume images for cube map have the same size. - generateMipmap( _gl.TEXTURE_CUBE_MAP, texture, image.width, image.height ); + // We assume images for cube map have the same size. + generateMipmap( _gl.TEXTURE_CUBE_MAP, texture, image.width, image.height ); - } + } - textureProperties.__version = texture.version; + textureProperties.__version = texture.version; - if ( texture.onUpdate ) texture.onUpdate( texture ); + if ( texture.onUpdate ) texture.onUpdate( texture ); - } else { + } else { - state.activeTexture( _gl.TEXTURE0 + slot ); - state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube ); + state.activeTexture( _gl.TEXTURE0 + slot ); + state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube ); - } + } - } + } - } + } - function setTextureCubeDynamic( texture, slot ) { + function setTextureCubeDynamic( texture, slot ) { - state.activeTexture( _gl.TEXTURE0 + slot ); - state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture ); + state.activeTexture( _gl.TEXTURE0 + slot ); + state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture ); - } + } - function setTextureParameters( textureType, texture, isPowerOfTwoImage ) { + function setTextureParameters( textureType, texture, isPowerOfTwoImage ) { - var extension; + var extension; - if ( isPowerOfTwoImage ) { + if ( isPowerOfTwoImage ) { - _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, utils.convert( texture.wrapS ) ); - _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, utils.convert( texture.wrapT ) ); + _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, utils.convert( texture.wrapS ) ); + _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, utils.convert( texture.wrapT ) ); - _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, utils.convert( texture.magFilter ) ); - _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, utils.convert( texture.minFilter ) ); + _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, utils.convert( texture.magFilter ) ); + _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, utils.convert( texture.minFilter ) ); - } else { + } else { - _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE ); - _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE ); + _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE ); + _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE ); - if ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) { + if ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) { - console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.' ); + console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.' ); - } + } - _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) ); - _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) ); + _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) ); + _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) ); - if ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) { + if ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) { - console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.' ); + console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.' ); - } + } - } + } - extension = extensions.get( 'EXT_texture_filter_anisotropic' ); + extension = extensions.get( 'EXT_texture_filter_anisotropic' ); - if ( extension ) { + if ( extension ) { - if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return; - if ( texture.type === HalfFloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_half_float_linear' ) ) === null ) return; + if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return; + if ( texture.type === HalfFloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_half_float_linear' ) ) === null ) return; - if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) { + if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) { - _gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) ); - properties.get( texture ).__currentAnisotropy = texture.anisotropy; + _gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) ); + properties.get( texture ).__currentAnisotropy = texture.anisotropy; - } + } - } + } - } + } - function uploadTexture( textureProperties, texture, slot ) { + function uploadTexture( textureProperties, texture, slot ) { - if ( textureProperties.__webglInit === undefined ) { + if ( textureProperties.__webglInit === undefined ) { - textureProperties.__webglInit = true; + textureProperties.__webglInit = true; - texture.addEventListener( 'dispose', onTextureDispose ); + texture.addEventListener( 'dispose', onTextureDispose ); - textureProperties.__webglTexture = _gl.createTexture(); + textureProperties.__webglTexture = _gl.createTexture(); - info.memory.textures ++; + info.memory.textures ++; - } + } - state.activeTexture( _gl.TEXTURE0 + slot ); - state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture ); + state.activeTexture( _gl.TEXTURE0 + slot ); + state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture ); - _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY ); - _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ); - _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment ); + _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY ); + _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ); + _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment ); - var image = clampToMaxSize( texture.image, capabilities.maxTextureSize ); + var image = clampToMaxSize( texture.image, capabilities.maxTextureSize ); - if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) { + if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) { - image = makePowerOfTwo( image ); + image = makePowerOfTwo( image ); - } + } - var isPowerOfTwoImage = isPowerOfTwo( image ), - glFormat = utils.convert( texture.format ), - glType = utils.convert( texture.type ), - glInternalFormat = getInternalFormat( glFormat, glType ); + var isPowerOfTwoImage = isPowerOfTwo( image ), + glFormat = utils.convert( texture.format ), + glType = utils.convert( texture.type ), + glInternalFormat = getInternalFormat( glFormat, glType ); - setTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage ); + setTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage ); - var mipmap, mipmaps = texture.mipmaps; + var mipmap, mipmaps = texture.mipmaps; - if ( texture.isDepthTexture ) { + if ( texture.isDepthTexture ) { - // populate depth texture with dummy data + // populate depth texture with dummy data - glInternalFormat = _gl.DEPTH_COMPONENT; + glInternalFormat = _gl.DEPTH_COMPONENT; - if ( texture.type === FloatType ) { + if ( texture.type === FloatType ) { - if ( ! capabilities.isWebGL2 ) throw new Error( 'Float Depth Texture only supported in WebGL2.0' ); - glInternalFormat = _gl.DEPTH_COMPONENT32F; + if ( ! capabilities.isWebGL2 ) throw new Error( 'Float Depth Texture only supported in WebGL2.0' ); + glInternalFormat = _gl.DEPTH_COMPONENT32F; - } else if ( capabilities.isWebGL2 ) { + } else if ( capabilities.isWebGL2 ) { - // WebGL 2.0 requires signed internalformat for glTexImage2D - glInternalFormat = _gl.DEPTH_COMPONENT16; + // WebGL 2.0 requires signed internalformat for glTexImage2D + glInternalFormat = _gl.DEPTH_COMPONENT16; - } + } - if ( texture.format === DepthFormat && glInternalFormat === _gl.DEPTH_COMPONENT ) { + if ( texture.format === DepthFormat && glInternalFormat === _gl.DEPTH_COMPONENT ) { - // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are - // DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT - // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) - if ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) { + // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are + // DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT + // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) + if ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) { - console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' ); + console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' ); - texture.type = UnsignedShortType; - glType = utils.convert( texture.type ); + texture.type = UnsignedShortType; + glType = utils.convert( texture.type ); - } + } - } + } - // Depth stencil textures need the DEPTH_STENCIL internal format - // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) - if ( texture.format === DepthStencilFormat ) { + // Depth stencil textures need the DEPTH_STENCIL internal format + // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) + if ( texture.format === DepthStencilFormat ) { - glInternalFormat = _gl.DEPTH_STENCIL; + glInternalFormat = _gl.DEPTH_STENCIL; - // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are - // DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL. - // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) - if ( texture.type !== UnsignedInt248Type ) { + // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are + // DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL. + // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/) + if ( texture.type !== UnsignedInt248Type ) { - console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' ); + console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' ); - texture.type = UnsignedInt248Type; - glType = utils.convert( texture.type ); + texture.type = UnsignedInt248Type; + glType = utils.convert( texture.type ); - } + } - } + } - state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null ); + state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null ); - } else if ( texture.isDataTexture ) { + } else if ( texture.isDataTexture ) { - // use manually created mipmaps if available - // if there are no manual mipmaps - // set 0 level mipmap and then use GL to generate other mipmap levels + // use manually created mipmaps if available + // if there are no manual mipmaps + // set 0 level mipmap and then use GL to generate other mipmap levels - if ( mipmaps.length > 0 && isPowerOfTwoImage ) { + if ( mipmaps.length > 0 && isPowerOfTwoImage ) { - for ( var i = 0, il = mipmaps.length; i < il; i ++ ) { + for ( var i = 0, il = mipmaps.length; i < il; i ++ ) { - mipmap = mipmaps[ i ]; - state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); + mipmap = mipmaps[ i ]; + state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); - } + } - texture.generateMipmaps = false; - textureProperties.__maxMipLevel = mipmaps.length - 1; + texture.generateMipmaps = false; + textureProperties.__maxMipLevel = mipmaps.length - 1; - } else { + } else { - state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data ); - textureProperties.__maxMipLevel = 0; + state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data ); + textureProperties.__maxMipLevel = 0; - } + } - } else if ( texture.isCompressedTexture ) { + } else if ( texture.isCompressedTexture ) { - for ( var i = 0, il = mipmaps.length; i < il; i ++ ) { + for ( var i = 0, il = mipmaps.length; i < il; i ++ ) { - mipmap = mipmaps[ i ]; + mipmap = mipmaps[ i ]; - if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { + if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { - if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) { + if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) { - state.compressedTexImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); + state.compressedTexImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); - } else { + } else { - console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); + console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); - } + } - } else { + } else { - state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); + state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); - } + } - } + } - textureProperties.__maxMipLevel = mipmaps.length - 1; + textureProperties.__maxMipLevel = mipmaps.length - 1; - } else { + } else { - // regular Texture (image, video, canvas) + // regular Texture (image, video, canvas) - // use manually created mipmaps if available - // if there are no manual mipmaps - // set 0 level mipmap and then use GL to generate other mipmap levels + // use manually created mipmaps if available + // if there are no manual mipmaps + // set 0 level mipmap and then use GL to generate other mipmap levels - if ( mipmaps.length > 0 && isPowerOfTwoImage ) { + if ( mipmaps.length > 0 && isPowerOfTwoImage ) { - for ( var i = 0, il = mipmaps.length; i < il; i ++ ) { + for ( var i = 0, il = mipmaps.length; i < il; i ++ ) { - mipmap = mipmaps[ i ]; - state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap ); + mipmap = mipmaps[ i ]; + state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap ); - } + } - texture.generateMipmaps = false; - textureProperties.__maxMipLevel = mipmaps.length - 1; + texture.generateMipmaps = false; + textureProperties.__maxMipLevel = mipmaps.length - 1; - } else { + } else { - state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image ); - textureProperties.__maxMipLevel = 0; + state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image ); + textureProperties.__maxMipLevel = 0; - } + } - } + } - if ( textureNeedsGenerateMipmaps( texture, isPowerOfTwoImage ) ) { + if ( textureNeedsGenerateMipmaps( texture, isPowerOfTwoImage ) ) { - generateMipmap( _gl.TEXTURE_2D, texture, image.width, image.height ); + generateMipmap( _gl.TEXTURE_2D, texture, image.width, image.height ); - } + } - textureProperties.__version = texture.version; + textureProperties.__version = texture.version; - if ( texture.onUpdate ) texture.onUpdate( texture ); + if ( texture.onUpdate ) texture.onUpdate( texture ); - } + } - // Render targets + // Render targets - // Setup storage for target texture and bind it to correct framebuffer - function setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) { + // Setup storage for target texture and bind it to correct framebuffer + function setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) { - var glFormat = utils.convert( renderTarget.texture.format ); - var glType = utils.convert( renderTarget.texture.type ); - var glInternalFormat = getInternalFormat( glFormat, glType ); - state.texImage2D( textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null ); - _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); - _gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 ); - _gl.bindFramebuffer( _gl.FRAMEBUFFER, null ); + var glFormat = utils.convert( renderTarget.texture.format ); + var glType = utils.convert( renderTarget.texture.type ); + var glInternalFormat = getInternalFormat( glFormat, glType ); + state.texImage2D( textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); + _gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, null ); - } + } - // Setup storage for internal depth/stencil buffers and bind to correct framebuffer - function setupRenderBufferStorage( renderbuffer, renderTarget ) { + // Setup storage for internal depth/stencil buffers and bind to correct framebuffer + function setupRenderBufferStorage( renderbuffer, renderTarget ) { - _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer ); + _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer ); - if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) { + if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) { - _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height ); - _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer ); + _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height ); + _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer ); - } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) { + } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) { - _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height ); - _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer ); + _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height ); + _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer ); - } else { + } else { - // FIXME: We don't support !depth !stencil - _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height ); + // FIXME: We don't support !depth !stencil + _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height ); - } + } - _gl.bindRenderbuffer( _gl.RENDERBUFFER, null ); + _gl.bindRenderbuffer( _gl.RENDERBUFFER, null ); - } + } - // Setup resources for a Depth Texture for a FBO (needs an extension) - function setupDepthTexture( framebuffer, renderTarget ) { + // Setup resources for a Depth Texture for a FBO (needs an extension) + function setupDepthTexture( framebuffer, renderTarget ) { - var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube ); - if ( isCube ) throw new Error( 'Depth Texture with cube render targets is not supported' ); + var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube ); + if ( isCube ) throw new Error( 'Depth Texture with cube render targets is not supported' ); - _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); - if ( ! ( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) { + if ( ! ( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) { - throw new Error( 'renderTarget.depthTexture must be an instance of THREE.DepthTexture' ); + throw new Error( 'renderTarget.depthTexture must be an instance of THREE.DepthTexture' ); - } + } - // upload an empty depth texture with framebuffer size - if ( ! properties.get( renderTarget.depthTexture ).__webglTexture || - renderTarget.depthTexture.image.width !== renderTarget.width || - renderTarget.depthTexture.image.height !== renderTarget.height ) { + // upload an empty depth texture with framebuffer size + if ( ! properties.get( renderTarget.depthTexture ).__webglTexture || + renderTarget.depthTexture.image.width !== renderTarget.width || + renderTarget.depthTexture.image.height !== renderTarget.height ) { - renderTarget.depthTexture.image.width = renderTarget.width; - renderTarget.depthTexture.image.height = renderTarget.height; - renderTarget.depthTexture.needsUpdate = true; + renderTarget.depthTexture.image.width = renderTarget.width; + renderTarget.depthTexture.image.height = renderTarget.height; + renderTarget.depthTexture.needsUpdate = true; - } + } - setTexture2D( renderTarget.depthTexture, 0 ); + setTexture2D( renderTarget.depthTexture, 0 ); - var webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture; + var webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture; - if ( renderTarget.depthTexture.format === DepthFormat ) { + if ( renderTarget.depthTexture.format === DepthFormat ) { - _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 ); + _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 ); - } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) { + } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) { - _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 ); + _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 ); - } else { + } else { - throw new Error( 'Unknown depthTexture format' ); + throw new Error( 'Unknown depthTexture format' ); - } + } - } + } - // Setup GL resources for a non-texture depth buffer - function setupDepthRenderbuffer( renderTarget ) { + // Setup GL resources for a non-texture depth buffer + function setupDepthRenderbuffer( renderTarget ) { - var renderTargetProperties = properties.get( renderTarget ); + var renderTargetProperties = properties.get( renderTarget ); - var isCube = ( renderTarget.isWebGLRenderTargetCube === true ); + var isCube = ( renderTarget.isWebGLRenderTargetCube === true ); - if ( renderTarget.depthTexture ) { + if ( renderTarget.depthTexture ) { - if ( isCube ) throw new Error( 'target.depthTexture not supported in Cube render targets' ); + if ( isCube ) throw new Error( 'target.depthTexture not supported in Cube render targets' ); - setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget ); + setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget ); - } else { + } else { - if ( isCube ) { + if ( isCube ) { - renderTargetProperties.__webglDepthbuffer = []; + renderTargetProperties.__webglDepthbuffer = []; - for ( var i = 0; i < 6; i ++ ) { + for ( var i = 0; i < 6; i ++ ) { - _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] ); - renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer(); - setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] ); + renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer(); + setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget ); - } + } - } else { + } else { - _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer ); - renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); - setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer ); + renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); + setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget ); - } + } - } + } - _gl.bindFramebuffer( _gl.FRAMEBUFFER, null ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, null ); - } + } - // Set up GL resources for the render target - function setupRenderTarget( renderTarget ) { + // Set up GL resources for the render target + function setupRenderTarget( renderTarget ) { - var renderTargetProperties = properties.get( renderTarget ); - var textureProperties = properties.get( renderTarget.texture ); + var renderTargetProperties = properties.get( renderTarget ); + var textureProperties = properties.get( renderTarget.texture ); - renderTarget.addEventListener( 'dispose', onRenderTargetDispose ); + renderTarget.addEventListener( 'dispose', onRenderTargetDispose ); - textureProperties.__webglTexture = _gl.createTexture(); + textureProperties.__webglTexture = _gl.createTexture(); - info.memory.textures ++; + info.memory.textures ++; - var isCube = ( renderTarget.isWebGLRenderTargetCube === true ); - var isTargetPowerOfTwo = isPowerOfTwo( renderTarget ); + var isCube = ( renderTarget.isWebGLRenderTargetCube === true ); + var isTargetPowerOfTwo = isPowerOfTwo( renderTarget ); - // Setup framebuffer + // Setup framebuffer - if ( isCube ) { + if ( isCube ) { - renderTargetProperties.__webglFramebuffer = []; + renderTargetProperties.__webglFramebuffer = []; - for ( var i = 0; i < 6; i ++ ) { + for ( var i = 0; i < 6; i ++ ) { - renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer(); + renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer(); - } + } - } else { + } else { - renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); + renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); - } + } - // Setup color buffer + // Setup color buffer - if ( isCube ) { + if ( isCube ) { - state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture ); - setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo ); + state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture ); + setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo ); - for ( var i = 0; i < 6; i ++ ) { + for ( var i = 0; i < 6; i ++ ) { - setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i ); + setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i ); - } + } - if ( textureNeedsGenerateMipmaps( renderTarget.texture, isTargetPowerOfTwo ) ) { + if ( textureNeedsGenerateMipmaps( renderTarget.texture, isTargetPowerOfTwo ) ) { - generateMipmap( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, renderTarget.width, renderTarget.height ); + generateMipmap( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, renderTarget.width, renderTarget.height ); - } + } - state.bindTexture( _gl.TEXTURE_CUBE_MAP, null ); + state.bindTexture( _gl.TEXTURE_CUBE_MAP, null ); - } else { + } else { - state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture ); - setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo ); - setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D ); + state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture ); + setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo ); + setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D ); - if ( textureNeedsGenerateMipmaps( renderTarget.texture, isTargetPowerOfTwo ) ) { + if ( textureNeedsGenerateMipmaps( renderTarget.texture, isTargetPowerOfTwo ) ) { - generateMipmap( _gl.TEXTURE_2D, renderTarget.texture, renderTarget.width, renderTarget.height ); + generateMipmap( _gl.TEXTURE_2D, renderTarget.texture, renderTarget.width, renderTarget.height ); - } + } - state.bindTexture( _gl.TEXTURE_2D, null ); + state.bindTexture( _gl.TEXTURE_2D, null ); - } + } - // Setup depth and stencil buffers + // Setup depth and stencil buffers - if ( renderTarget.depthBuffer ) { + if ( renderTarget.depthBuffer ) { - setupDepthRenderbuffer( renderTarget ); + setupDepthRenderbuffer( renderTarget ); - } + } - } + } - function updateRenderTargetMipmap( renderTarget ) { + function updateRenderTargetMipmap( renderTarget ) { - var texture = renderTarget.texture; - var isTargetPowerOfTwo = isPowerOfTwo( renderTarget ); + var texture = renderTarget.texture; + var isTargetPowerOfTwo = isPowerOfTwo( renderTarget ); - if ( textureNeedsGenerateMipmaps( texture, isTargetPowerOfTwo ) ) { + if ( textureNeedsGenerateMipmaps( texture, isTargetPowerOfTwo ) ) { - var target = renderTarget.isWebGLRenderTargetCube ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D; - var webglTexture = properties.get( texture ).__webglTexture; + var target = renderTarget.isWebGLRenderTargetCube ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D; + var webglTexture = properties.get( texture ).__webglTexture; - state.bindTexture( target, webglTexture ); - generateMipmap( target, texture, renderTarget.width, renderTarget.height ); - state.bindTexture( target, null ); + state.bindTexture( target, webglTexture ); + generateMipmap( target, texture, renderTarget.width, renderTarget.height ); + state.bindTexture( target, null ); - } + } - } + } - function updateVideoTexture( texture ) { + function updateVideoTexture( texture ) { - var id = texture.id; - var frame = info.render.frame; + var id = texture.id; + var frame = info.render.frame; - // Check the last frame we updated the VideoTexture + // Check the last frame we updated the VideoTexture - if ( _videoTextures[ id ] !== frame ) { + if ( _videoTextures[ id ] !== frame ) { - _videoTextures[ id ] = frame; - texture.update(); + _videoTextures[ id ] = frame; + texture.update(); - } + } - } + } - this.setTexture2D = setTexture2D; - this.setTextureCube = setTextureCube; - this.setTextureCubeDynamic = setTextureCubeDynamic; - this.setupRenderTarget = setupRenderTarget; - this.updateRenderTargetMipmap = updateRenderTargetMipmap; + this.setTexture2D = setTexture2D; + this.setTextureCube = setTextureCube; + this.setTextureCubeDynamic = setTextureCubeDynamic; + this.setupRenderTarget = setupRenderTarget; + this.updateRenderTargetMipmap = updateRenderTargetMipmap; - } + } - /** - * @author thespite / http://www.twitter.com/thespite - */ + /** + * @author thespite / http://www.twitter.com/thespite + */ - function WebGLUtils( gl, extensions, capabilities ) { + function WebGLUtils( gl, extensions, capabilities ) { - function convert( p ) { + function convert( p ) { - var extension; + var extension; - if ( p === RepeatWrapping ) return gl.REPEAT; - if ( p === ClampToEdgeWrapping ) return gl.CLAMP_TO_EDGE; - if ( p === MirroredRepeatWrapping ) return gl.MIRRORED_REPEAT; + if ( p === RepeatWrapping ) return gl.REPEAT; + if ( p === ClampToEdgeWrapping ) return gl.CLAMP_TO_EDGE; + if ( p === MirroredRepeatWrapping ) return gl.MIRRORED_REPEAT; - if ( p === NearestFilter ) return gl.NEAREST; - if ( p === NearestMipMapNearestFilter ) return gl.NEAREST_MIPMAP_NEAREST; - if ( p === NearestMipMapLinearFilter ) return gl.NEAREST_MIPMAP_LINEAR; + if ( p === NearestFilter ) return gl.NEAREST; + if ( p === NearestMipMapNearestFilter ) return gl.NEAREST_MIPMAP_NEAREST; + if ( p === NearestMipMapLinearFilter ) return gl.NEAREST_MIPMAP_LINEAR; - if ( p === LinearFilter ) return gl.LINEAR; - if ( p === LinearMipMapNearestFilter ) return gl.LINEAR_MIPMAP_NEAREST; - if ( p === LinearMipMapLinearFilter ) return gl.LINEAR_MIPMAP_LINEAR; + if ( p === LinearFilter ) return gl.LINEAR; + if ( p === LinearMipMapNearestFilter ) return gl.LINEAR_MIPMAP_NEAREST; + if ( p === LinearMipMapLinearFilter ) return gl.LINEAR_MIPMAP_LINEAR; - if ( p === UnsignedByteType ) return gl.UNSIGNED_BYTE; - if ( p === UnsignedShort4444Type ) return gl.UNSIGNED_SHORT_4_4_4_4; - if ( p === UnsignedShort5551Type ) return gl.UNSIGNED_SHORT_5_5_5_1; - if ( p === UnsignedShort565Type ) return gl.UNSIGNED_SHORT_5_6_5; + if ( p === UnsignedByteType ) return gl.UNSIGNED_BYTE; + if ( p === UnsignedShort4444Type ) return gl.UNSIGNED_SHORT_4_4_4_4; + if ( p === UnsignedShort5551Type ) return gl.UNSIGNED_SHORT_5_5_5_1; + if ( p === UnsignedShort565Type ) return gl.UNSIGNED_SHORT_5_6_5; - if ( p === ByteType ) return gl.BYTE; - if ( p === ShortType ) return gl.SHORT; - if ( p === UnsignedShortType ) return gl.UNSIGNED_SHORT; - if ( p === IntType ) return gl.INT; - if ( p === UnsignedIntType ) return gl.UNSIGNED_INT; - if ( p === FloatType ) return gl.FLOAT; + if ( p === ByteType ) return gl.BYTE; + if ( p === ShortType ) return gl.SHORT; + if ( p === UnsignedShortType ) return gl.UNSIGNED_SHORT; + if ( p === IntType ) return gl.INT; + if ( p === UnsignedIntType ) return gl.UNSIGNED_INT; + if ( p === FloatType ) return gl.FLOAT; - if ( p === HalfFloatType ) { + if ( p === HalfFloatType ) { - if ( capabilities.isWebGL2 ) return gl.HALF_FLOAT; + if ( capabilities.isWebGL2 ) return gl.HALF_FLOAT; - extension = extensions.get( 'OES_texture_half_float' ); + extension = extensions.get( 'OES_texture_half_float' ); - if ( extension !== null ) return extension.HALF_FLOAT_OES; + if ( extension !== null ) return extension.HALF_FLOAT_OES; - } + } - if ( p === AlphaFormat ) return gl.ALPHA; - if ( p === RGBFormat ) return gl.RGB; - if ( p === RGBAFormat ) return gl.RGBA; - if ( p === LuminanceFormat ) return gl.LUMINANCE; - if ( p === LuminanceAlphaFormat ) return gl.LUMINANCE_ALPHA; - if ( p === DepthFormat ) return gl.DEPTH_COMPONENT; - if ( p === DepthStencilFormat ) return gl.DEPTH_STENCIL; + if ( p === AlphaFormat ) return gl.ALPHA; + if ( p === RGBFormat ) return gl.RGB; + if ( p === RGBAFormat ) return gl.RGBA; + if ( p === LuminanceFormat ) return gl.LUMINANCE; + if ( p === LuminanceAlphaFormat ) return gl.LUMINANCE_ALPHA; + if ( p === DepthFormat ) return gl.DEPTH_COMPONENT; + if ( p === DepthStencilFormat ) return gl.DEPTH_STENCIL; - if ( p === AddEquation ) return gl.FUNC_ADD; - if ( p === SubtractEquation ) return gl.FUNC_SUBTRACT; - if ( p === ReverseSubtractEquation ) return gl.FUNC_REVERSE_SUBTRACT; + if ( p === AddEquation ) return gl.FUNC_ADD; + if ( p === SubtractEquation ) return gl.FUNC_SUBTRACT; + if ( p === ReverseSubtractEquation ) return gl.FUNC_REVERSE_SUBTRACT; - if ( p === ZeroFactor ) return gl.ZERO; - if ( p === OneFactor ) return gl.ONE; - if ( p === SrcColorFactor ) return gl.SRC_COLOR; - if ( p === OneMinusSrcColorFactor ) return gl.ONE_MINUS_SRC_COLOR; - if ( p === SrcAlphaFactor ) return gl.SRC_ALPHA; - if ( p === OneMinusSrcAlphaFactor ) return gl.ONE_MINUS_SRC_ALPHA; - if ( p === DstAlphaFactor ) return gl.DST_ALPHA; - if ( p === OneMinusDstAlphaFactor ) return gl.ONE_MINUS_DST_ALPHA; + if ( p === ZeroFactor ) return gl.ZERO; + if ( p === OneFactor ) return gl.ONE; + if ( p === SrcColorFactor ) return gl.SRC_COLOR; + if ( p === OneMinusSrcColorFactor ) return gl.ONE_MINUS_SRC_COLOR; + if ( p === SrcAlphaFactor ) return gl.SRC_ALPHA; + if ( p === OneMinusSrcAlphaFactor ) return gl.ONE_MINUS_SRC_ALPHA; + if ( p === DstAlphaFactor ) return gl.DST_ALPHA; + if ( p === OneMinusDstAlphaFactor ) return gl.ONE_MINUS_DST_ALPHA; - if ( p === DstColorFactor ) return gl.DST_COLOR; - if ( p === OneMinusDstColorFactor ) return gl.ONE_MINUS_DST_COLOR; - if ( p === SrcAlphaSaturateFactor ) return gl.SRC_ALPHA_SATURATE; + if ( p === DstColorFactor ) return gl.DST_COLOR; + if ( p === OneMinusDstColorFactor ) return gl.ONE_MINUS_DST_COLOR; + if ( p === SrcAlphaSaturateFactor ) return gl.SRC_ALPHA_SATURATE; - if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || - p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) { + if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || + p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) { - extension = extensions.get( 'WEBGL_compressed_texture_s3tc' ); + extension = extensions.get( 'WEBGL_compressed_texture_s3tc' ); - if ( extension !== null ) { + if ( extension !== null ) { - if ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; - if ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; - if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; - if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; + if ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; + if ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; + if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; + if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; - } + } - } + } - if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || - p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) { + if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || + p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) { - extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' ); + extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' ); - if ( extension !== null ) { + if ( extension !== null ) { - if ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; - if ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; - if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; - if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + if ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; + if ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; + if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; - } + } - } + } - if ( p === RGB_ETC1_Format ) { + if ( p === RGB_ETC1_Format ) { - extension = extensions.get( 'WEBGL_compressed_texture_etc1' ); + extension = extensions.get( 'WEBGL_compressed_texture_etc1' ); - if ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL; + if ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL; - } + } - if ( p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format || - p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format || - p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format || - p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format || - p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format ) { + if ( p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format || + p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format || + p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format || + p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format || + p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format ) { - extension = extensions.get( 'WEBGL_compressed_texture_astc' ); + extension = extensions.get( 'WEBGL_compressed_texture_astc' ); - if ( extension !== null ) { + if ( extension !== null ) { - return p; + return p; - } + } - } + } - if ( p === MinEquation || p === MaxEquation ) { + if ( p === MinEquation || p === MaxEquation ) { - if ( capabilities.isWebGL2 ) { + if ( capabilities.isWebGL2 ) { - if ( p === MinEquation ) return gl.MIN; - if ( p === MaxEquation ) return gl.MAX; + if ( p === MinEquation ) return gl.MIN; + if ( p === MaxEquation ) return gl.MAX; - } + } - extension = extensions.get( 'EXT_blend_minmax' ); + extension = extensions.get( 'EXT_blend_minmax' ); - if ( extension !== null ) { + if ( extension !== null ) { - if ( p === MinEquation ) return extension.MIN_EXT; - if ( p === MaxEquation ) return extension.MAX_EXT; + if ( p === MinEquation ) return extension.MIN_EXT; + if ( p === MaxEquation ) return extension.MAX_EXT; - } + } - } + } - if ( p === UnsignedInt248Type ) { + if ( p === UnsignedInt248Type ) { - if ( capabilities.isWebGL2 ) return gl.UNSIGNED_INT_24_8; + if ( capabilities.isWebGL2 ) return gl.UNSIGNED_INT_24_8; - extension = extensions.get( 'WEBGL_depth_texture' ); + extension = extensions.get( 'WEBGL_depth_texture' ); - if ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL; + if ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL; - } + } - return 0; + return 0; - } + } - return { convert: convert }; + return { convert: convert }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function Group() { + function Group() { - Object3D.call( this ); + Object3D.call( this ); - this.type = 'Group'; + this.type = 'Group'; - } + } - Group.prototype = Object.assign( Object.create( Object3D.prototype ), { + Group.prototype = Object.assign( Object.create( Object3D.prototype ), { - constructor: Group, + constructor: Group, - isGroup: true + isGroup: true - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author greggman / http://games.greggman.com/ - * @author zz85 / http://www.lab4games.net/zz85/blog - * @author tschw - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author greggman / http://games.greggman.com/ + * @author zz85 / http://www.lab4games.net/zz85/blog + * @author tschw + */ - function PerspectiveCamera( fov, aspect, near, far ) { + function PerspectiveCamera( fov, aspect, near, far ) { - Camera.call( this ); + Camera.call( this ); - this.type = 'PerspectiveCamera'; + this.type = 'PerspectiveCamera'; - this.fov = fov !== undefined ? fov : 50; - this.zoom = 1; + this.fov = fov !== undefined ? fov : 50; + this.zoom = 1; - this.near = near !== undefined ? near : 0.1; - this.far = far !== undefined ? far : 2000; - this.focus = 10; + this.near = near !== undefined ? near : 0.1; + this.far = far !== undefined ? far : 2000; + this.focus = 10; - this.aspect = aspect !== undefined ? aspect : 1; - this.view = null; + this.aspect = aspect !== undefined ? aspect : 1; + this.view = null; - this.filmGauge = 35; // width of the film (default in millimeters) - this.filmOffset = 0; // horizontal film offset (same unit as gauge) + this.filmGauge = 35; // width of the film (default in millimeters) + this.filmOffset = 0; // horizontal film offset (same unit as gauge) - this.updateProjectionMatrix(); + this.updateProjectionMatrix(); - } + } - PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), { + PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), { - constructor: PerspectiveCamera, + constructor: PerspectiveCamera, - isPerspectiveCamera: true, + isPerspectiveCamera: true, - copy: function ( source, recursive ) { + copy: function ( source, recursive ) { - Camera.prototype.copy.call( this, source, recursive ); + Camera.prototype.copy.call( this, source, recursive ); - this.fov = source.fov; - this.zoom = source.zoom; + this.fov = source.fov; + this.zoom = source.zoom; - this.near = source.near; - this.far = source.far; - this.focus = source.focus; + this.near = source.near; + this.far = source.far; + this.focus = source.focus; - this.aspect = source.aspect; - this.view = source.view === null ? null : Object.assign( {}, source.view ); + this.aspect = source.aspect; + this.view = source.view === null ? null : Object.assign( {}, source.view ); - this.filmGauge = source.filmGauge; - this.filmOffset = source.filmOffset; + this.filmGauge = source.filmGauge; + this.filmOffset = source.filmOffset; - return this; + return this; - }, + }, - /** - * Sets the FOV by focal length in respect to the current .filmGauge. - * - * The default film gauge is 35, so that the focal length can be specified for - * a 35mm (full frame) camera. - * - * Values for focal length and film gauge must have the same unit. - */ - setFocalLength: function ( focalLength ) { + /** + * Sets the FOV by focal length in respect to the current .filmGauge. + * + * The default film gauge is 35, so that the focal length can be specified for + * a 35mm (full frame) camera. + * + * Values for focal length and film gauge must have the same unit. + */ + setFocalLength: function ( focalLength ) { - // see http://www.bobatkins.com/photography/technical/field_of_view.html - var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; + // see http://www.bobatkins.com/photography/technical/field_of_view.html + var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; - this.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope ); - this.updateProjectionMatrix(); + this.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope ); + this.updateProjectionMatrix(); - }, + }, - /** - * Calculates the focal length from the current .fov and .filmGauge. - */ - getFocalLength: function () { + /** + * Calculates the focal length from the current .fov and .filmGauge. + */ + getFocalLength: function () { - var vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov ); + var vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov ); - return 0.5 * this.getFilmHeight() / vExtentSlope; + return 0.5 * this.getFilmHeight() / vExtentSlope; - }, + }, - getEffectiveFOV: function () { + getEffectiveFOV: function () { - return _Math.RAD2DEG * 2 * Math.atan( - Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom ); + return _Math.RAD2DEG * 2 * Math.atan( + Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom ); - }, + }, - getFilmWidth: function () { + getFilmWidth: function () { - // film not completely covered in portrait format (aspect < 1) - return this.filmGauge * Math.min( this.aspect, 1 ); + // film not completely covered in portrait format (aspect < 1) + return this.filmGauge * Math.min( this.aspect, 1 ); - }, + }, - getFilmHeight: function () { + getFilmHeight: function () { - // film not completely covered in landscape format (aspect > 1) - return this.filmGauge / Math.max( this.aspect, 1 ); + // film not completely covered in landscape format (aspect > 1) + return this.filmGauge / Math.max( this.aspect, 1 ); - }, + }, - /** - * Sets an offset in a larger frustum. This is useful for multi-window or - * multi-monitor/multi-machine setups. - * - * For example, if you have 3x2 monitors and each monitor is 1920x1080 and - * the monitors are in grid like this - * - * +---+---+---+ - * | A | B | C | - * +---+---+---+ - * | D | E | F | - * +---+---+---+ - * - * then for each monitor you would call it like this - * - * var w = 1920; - * var h = 1080; - * var fullWidth = w * 3; - * var fullHeight = h * 2; - * - * --A-- - * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); - * --B-- - * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); - * --C-- - * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); - * --D-- - * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); - * --E-- - * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); - * --F-- - * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); - * - * Note there is no reason monitors have to be the same size or in a grid. - */ - setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) { + /** + * Sets an offset in a larger frustum. This is useful for multi-window or + * multi-monitor/multi-machine setups. + * + * For example, if you have 3x2 monitors and each monitor is 1920x1080 and + * the monitors are in grid like this + * + * +---+---+---+ + * | A | B | C | + * +---+---+---+ + * | D | E | F | + * +---+---+---+ + * + * then for each monitor you would call it like this + * + * var w = 1920; + * var h = 1080; + * var fullWidth = w * 3; + * var fullHeight = h * 2; + * + * --A-- + * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); + * --B-- + * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); + * --C-- + * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); + * --D-- + * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); + * --E-- + * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); + * --F-- + * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); + * + * Note there is no reason monitors have to be the same size or in a grid. + */ + setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) { - this.aspect = fullWidth / fullHeight; + this.aspect = fullWidth / fullHeight; - if ( this.view === null ) { + if ( this.view === null ) { - this.view = { - enabled: true, - fullWidth: 1, - fullHeight: 1, - offsetX: 0, - offsetY: 0, - width: 1, - height: 1 - }; + this.view = { + enabled: true, + fullWidth: 1, + fullHeight: 1, + offsetX: 0, + offsetY: 0, + width: 1, + height: 1 + }; - } + } - this.view.enabled = true; - this.view.fullWidth = fullWidth; - this.view.fullHeight = fullHeight; - this.view.offsetX = x; - this.view.offsetY = y; - this.view.width = width; - this.view.height = height; + this.view.enabled = true; + this.view.fullWidth = fullWidth; + this.view.fullHeight = fullHeight; + this.view.offsetX = x; + this.view.offsetY = y; + this.view.width = width; + this.view.height = height; - this.updateProjectionMatrix(); + this.updateProjectionMatrix(); - }, + }, - clearViewOffset: function () { + clearViewOffset: function () { - if ( this.view !== null ) { + if ( this.view !== null ) { - this.view.enabled = false; + this.view.enabled = false; - } + } - this.updateProjectionMatrix(); + this.updateProjectionMatrix(); - }, + }, - updateProjectionMatrix: function () { + updateProjectionMatrix: function () { - var near = this.near, - top = near * Math.tan( - _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom, - height = 2 * top, - width = this.aspect * height, - left = - 0.5 * width, - view = this.view; + var near = this.near, + top = near * Math.tan( + _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom, + height = 2 * top, + width = this.aspect * height, + left = - 0.5 * width, + view = this.view; - if ( this.view !== null && this.view.enabled ) { + if ( this.view !== null && this.view.enabled ) { - var fullWidth = view.fullWidth, - fullHeight = view.fullHeight; + var fullWidth = view.fullWidth, + fullHeight = view.fullHeight; - left += view.offsetX * width / fullWidth; - top -= view.offsetY * height / fullHeight; - width *= view.width / fullWidth; - height *= view.height / fullHeight; + left += view.offsetX * width / fullWidth; + top -= view.offsetY * height / fullHeight; + width *= view.width / fullWidth; + height *= view.height / fullHeight; - } + } - var skew = this.filmOffset; - if ( skew !== 0 ) left += near * skew / this.getFilmWidth(); + var skew = this.filmOffset; + if ( skew !== 0 ) left += near * skew / this.getFilmWidth(); - this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far ); + this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far ); - }, + }, - toJSON: function ( meta ) { + toJSON: function ( meta ) { - var data = Object3D.prototype.toJSON.call( this, meta ); + var data = Object3D.prototype.toJSON.call( this, meta ); - data.object.fov = this.fov; - data.object.zoom = this.zoom; + data.object.fov = this.fov; + data.object.zoom = this.zoom; - data.object.near = this.near; - data.object.far = this.far; - data.object.focus = this.focus; + data.object.near = this.near; + data.object.far = this.far; + data.object.focus = this.focus; - data.object.aspect = this.aspect; + data.object.aspect = this.aspect; - if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); + if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); - data.object.filmGauge = this.filmGauge; - data.object.filmOffset = this.filmOffset; + data.object.filmGauge = this.filmGauge; + data.object.filmOffset = this.filmOffset; - return data; + return data; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function ArrayCamera( array ) { + function ArrayCamera( array ) { - PerspectiveCamera.call( this ); + PerspectiveCamera.call( this ); - this.cameras = array || []; + this.cameras = array || []; - } + } - ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototype ), { + ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototype ), { - constructor: ArrayCamera, + constructor: ArrayCamera, - isArrayCamera: true + isArrayCamera: true - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function WebVRManager( renderer ) { + function WebVRManager( renderer ) { - var scope = this; + var scope = this; - var device = null; - var frameData = null; + var device = null; + var frameData = null; - var poseTarget = null; + var poseTarget = null; - var controllers = []; - var standingMatrix = new Matrix4(); - var standingMatrixInverse = new Matrix4(); + var controllers = []; + var standingMatrix = new Matrix4(); + var standingMatrixInverse = new Matrix4(); - if ( typeof window !== 'undefined' && 'VRFrameData' in window ) { + if ( typeof window !== 'undefined' && 'VRFrameData' in window ) { - frameData = new window.VRFrameData(); - window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false ); + frameData = new window.VRFrameData(); + window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false ); - } + } - var matrixWorldInverse = new Matrix4(); - var tempQuaternion = new Quaternion(); - var tempPosition = new Vector3(); + var matrixWorldInverse = new Matrix4(); + var tempQuaternion = new Quaternion(); + var tempPosition = new Vector3(); - var cameraL = new PerspectiveCamera(); - cameraL.bounds = new Vector4( 0.0, 0.0, 0.5, 1.0 ); - cameraL.layers.enable( 1 ); + var cameraL = new PerspectiveCamera(); + cameraL.bounds = new Vector4( 0.0, 0.0, 0.5, 1.0 ); + cameraL.layers.enable( 1 ); - var cameraR = new PerspectiveCamera(); - cameraR.bounds = new Vector4( 0.5, 0.0, 0.5, 1.0 ); - cameraR.layers.enable( 2 ); + var cameraR = new PerspectiveCamera(); + cameraR.bounds = new Vector4( 0.5, 0.0, 0.5, 1.0 ); + cameraR.layers.enable( 2 ); - var cameraVR = new ArrayCamera( [ cameraL, cameraR ] ); - cameraVR.layers.enable( 1 ); - cameraVR.layers.enable( 2 ); + var cameraVR = new ArrayCamera( [ cameraL, cameraR ] ); + cameraVR.layers.enable( 1 ); + cameraVR.layers.enable( 2 ); - // + // - function isPresenting() { + function isPresenting() { - return device !== null && device.isPresenting === true; + return device !== null && device.isPresenting === true; - } + } - var currentSize, currentPixelRatio; + var currentSize, currentPixelRatio; - function onVRDisplayPresentChange() { + function onVRDisplayPresentChange() { - if ( isPresenting() ) { + if ( isPresenting() ) { - var eyeParameters = device.getEyeParameters( 'left' ); - var renderWidth = eyeParameters.renderWidth; - var renderHeight = eyeParameters.renderHeight; + var eyeParameters = device.getEyeParameters( 'left' ); + var renderWidth = eyeParameters.renderWidth; + var renderHeight = eyeParameters.renderHeight; - currentPixelRatio = renderer.getPixelRatio(); - currentSize = renderer.getSize(); + currentPixelRatio = renderer.getPixelRatio(); + currentSize = renderer.getSize(); - renderer.setDrawingBufferSize( renderWidth * 2, renderHeight, 1 ); + renderer.setDrawingBufferSize( renderWidth * 2, renderHeight, 1 ); - animation.start(); + animation.start(); - } else if ( scope.enabled ) { + } else if ( scope.enabled ) { - renderer.setDrawingBufferSize( currentSize.width, currentSize.height, currentPixelRatio ); + renderer.setDrawingBufferSize( currentSize.width, currentSize.height, currentPixelRatio ); - animation.stop(); + animation.stop(); - } + } - } + } - // + // - var triggers = []; + var triggers = []; - function findGamepad( id ) { + function findGamepad( id ) { - var gamepads = navigator.getGamepads && navigator.getGamepads(); + var gamepads = navigator.getGamepads && navigator.getGamepads(); - for ( var i = 0, j = 0, l = gamepads.length; i < l; i ++ ) { + for ( var i = 0, j = 0, l = gamepads.length; i < l; i ++ ) { - var gamepad = gamepads[ i ]; + var gamepad = gamepads[ i ]; - if ( gamepad && ( gamepad.id === 'Daydream Controller' || - gamepad.id === 'Gear VR Controller' || gamepad.id === 'Oculus Go Controller' || - gamepad.id === 'OpenVR Gamepad' || gamepad.id.startsWith( 'Oculus Touch' ) || - gamepad.id.startsWith( 'Spatial Controller' ) ) ) { + if ( gamepad && ( gamepad.id === 'Daydream Controller' || + gamepad.id === 'Gear VR Controller' || gamepad.id === 'Oculus Go Controller' || + gamepad.id === 'OpenVR Gamepad' || gamepad.id.startsWith( 'Oculus Touch' ) || + gamepad.id.startsWith( 'Spatial Controller' ) ) ) { - if ( j === id ) return gamepad; + if ( j === id ) return gamepad; - j ++; + j ++; - } + } - } + } - } + } - function updateControllers() { + function updateControllers() { - for ( var i = 0; i < controllers.length; i ++ ) { + for ( var i = 0; i < controllers.length; i ++ ) { - var controller = controllers[ i ]; + var controller = controllers[ i ]; - var gamepad = findGamepad( i ); + var gamepad = findGamepad( i ); - if ( gamepad !== undefined && gamepad.pose !== undefined ) { + if ( gamepad !== undefined && gamepad.pose !== undefined ) { - if ( gamepad.pose === null ) return; + if ( gamepad.pose === null ) return; - // Pose + // Pose - var pose = gamepad.pose; + var pose = gamepad.pose; - if ( pose.hasPosition === false ) controller.position.set( 0.2, - 0.6, - 0.05 ); + if ( pose.hasPosition === false ) controller.position.set( 0.2, - 0.6, - 0.05 ); - if ( pose.position !== null ) controller.position.fromArray( pose.position ); - if ( pose.orientation !== null ) controller.quaternion.fromArray( pose.orientation ); - controller.matrix.compose( controller.position, controller.quaternion, controller.scale ); - controller.matrix.premultiply( standingMatrix ); - controller.matrix.decompose( controller.position, controller.quaternion, controller.scale ); - controller.matrixWorldNeedsUpdate = true; - controller.visible = true; + if ( pose.position !== null ) controller.position.fromArray( pose.position ); + if ( pose.orientation !== null ) controller.quaternion.fromArray( pose.orientation ); + controller.matrix.compose( controller.position, controller.quaternion, controller.scale ); + controller.matrix.premultiply( standingMatrix ); + controller.matrix.decompose( controller.position, controller.quaternion, controller.scale ); + controller.matrixWorldNeedsUpdate = true; + controller.visible = true; - // Trigger + // Trigger - var buttonId = gamepad.id === 'Daydream Controller' ? 0 : 1; + var buttonId = gamepad.id === 'Daydream Controller' ? 0 : 1; - if ( triggers[ i ] !== gamepad.buttons[ buttonId ].pressed ) { + if ( triggers[ i ] !== gamepad.buttons[ buttonId ].pressed ) { - triggers[ i ] = gamepad.buttons[ buttonId ].pressed; + triggers[ i ] = gamepad.buttons[ buttonId ].pressed; - if ( triggers[ i ] === true ) { + if ( triggers[ i ] === true ) { - controller.dispatchEvent( { type: 'selectstart' } ); + controller.dispatchEvent( { type: 'selectstart' } ); - } else { + } else { - controller.dispatchEvent( { type: 'selectend' } ); - controller.dispatchEvent( { type: 'select' } ); + controller.dispatchEvent( { type: 'selectend' } ); + controller.dispatchEvent( { type: 'select' } ); - } + } - } + } - } else { + } else { - controller.visible = false; + controller.visible = false; - } + } - } + } - } + } - // + // - this.enabled = false; - this.userHeight = 1.6; + this.enabled = false; + this.userHeight = 1.6; - this.getController = function ( id ) { + this.getController = function ( id ) { - var controller = controllers[ id ]; + var controller = controllers[ id ]; - if ( controller === undefined ) { + if ( controller === undefined ) { - controller = new Group(); - controller.matrixAutoUpdate = false; - controller.visible = false; + controller = new Group(); + controller.matrixAutoUpdate = false; + controller.visible = false; - controllers[ id ] = controller; + controllers[ id ] = controller; - } + } - return controller; + return controller; - }; + }; - this.getDevice = function () { + this.getDevice = function () { - return device; + return device; - }; + }; - this.setDevice = function ( value ) { + this.setDevice = function ( value ) { - if ( value !== undefined ) device = value; + if ( value !== undefined ) device = value; - animation.setContext( value ); + animation.setContext( value ); - }; + }; - this.setPoseTarget = function ( object ) { + this.setPoseTarget = function ( object ) { - if ( object !== undefined ) poseTarget = object; + if ( object !== undefined ) poseTarget = object; - }; + }; - this.getCamera = function ( camera ) { + this.getCamera = function ( camera ) { - if ( device === null ) { + if ( device === null ) { - camera.position.set( 0, scope.userHeight, 0 ); - return camera; + camera.position.set( 0, scope.userHeight, 0 ); + return camera; - } + } - device.depthNear = camera.near; - device.depthFar = camera.far; + device.depthNear = camera.near; + device.depthFar = camera.far; - device.getFrameData( frameData ); + device.getFrameData( frameData ); - // + // - var stageParameters = device.stageParameters; + var stageParameters = device.stageParameters; - if ( stageParameters ) { + if ( stageParameters ) { - standingMatrix.fromArray( stageParameters.sittingToStandingTransform ); + standingMatrix.fromArray( stageParameters.sittingToStandingTransform ); - } else { + } else { - standingMatrix.makeTranslation( 0, scope.userHeight, 0 ); + standingMatrix.makeTranslation( 0, scope.userHeight, 0 ); - } + } - var pose = frameData.pose; - var poseObject = poseTarget !== null ? poseTarget : camera; + var pose = frameData.pose; + var poseObject = poseTarget !== null ? poseTarget : camera; - // We want to manipulate poseObject by its position and quaternion components since users may rely on them. - poseObject.matrix.copy( standingMatrix ); - poseObject.matrix.decompose( poseObject.position, poseObject.quaternion, poseObject.scale ); + // We want to manipulate poseObject by its position and quaternion components since users may rely on them. + poseObject.matrix.copy( standingMatrix ); + poseObject.matrix.decompose( poseObject.position, poseObject.quaternion, poseObject.scale ); - if ( pose.orientation !== null ) { + if ( pose.orientation !== null ) { - tempQuaternion.fromArray( pose.orientation ); - poseObject.quaternion.multiply( tempQuaternion ); + tempQuaternion.fromArray( pose.orientation ); + poseObject.quaternion.multiply( tempQuaternion ); - } + } - if ( pose.position !== null ) { + if ( pose.position !== null ) { - tempQuaternion.setFromRotationMatrix( standingMatrix ); - tempPosition.fromArray( pose.position ); - tempPosition.applyQuaternion( tempQuaternion ); - poseObject.position.add( tempPosition ); + tempQuaternion.setFromRotationMatrix( standingMatrix ); + tempPosition.fromArray( pose.position ); + tempPosition.applyQuaternion( tempQuaternion ); + poseObject.position.add( tempPosition ); - } + } - poseObject.updateMatrixWorld(); + poseObject.updateMatrixWorld(); - if ( device.isPresenting === false ) return camera; + if ( device.isPresenting === false ) return camera; - // + // - cameraL.near = camera.near; - cameraR.near = camera.near; + cameraL.near = camera.near; + cameraR.near = camera.near; - cameraL.far = camera.far; - cameraR.far = camera.far; + cameraL.far = camera.far; + cameraR.far = camera.far; - cameraVR.matrixWorld.copy( camera.matrixWorld ); - cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse ); + cameraVR.matrixWorld.copy( camera.matrixWorld ); + cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse ); - cameraL.matrixWorldInverse.fromArray( frameData.leftViewMatrix ); - cameraR.matrixWorldInverse.fromArray( frameData.rightViewMatrix ); + cameraL.matrixWorldInverse.fromArray( frameData.leftViewMatrix ); + cameraR.matrixWorldInverse.fromArray( frameData.rightViewMatrix ); - // TODO (mrdoob) Double check this code + // TODO (mrdoob) Double check this code - standingMatrixInverse.getInverse( standingMatrix ); + standingMatrixInverse.getInverse( standingMatrix ); - cameraL.matrixWorldInverse.multiply( standingMatrixInverse ); - cameraR.matrixWorldInverse.multiply( standingMatrixInverse ); + cameraL.matrixWorldInverse.multiply( standingMatrixInverse ); + cameraR.matrixWorldInverse.multiply( standingMatrixInverse ); - var parent = poseObject.parent; + var parent = poseObject.parent; - if ( parent !== null ) { + if ( parent !== null ) { - matrixWorldInverse.getInverse( parent.matrixWorld ); + matrixWorldInverse.getInverse( parent.matrixWorld ); - cameraL.matrixWorldInverse.multiply( matrixWorldInverse ); - cameraR.matrixWorldInverse.multiply( matrixWorldInverse ); + cameraL.matrixWorldInverse.multiply( matrixWorldInverse ); + cameraR.matrixWorldInverse.multiply( matrixWorldInverse ); - } + } - // envMap and Mirror needs camera.matrixWorld + // envMap and Mirror needs camera.matrixWorld - cameraL.matrixWorld.getInverse( cameraL.matrixWorldInverse ); - cameraR.matrixWorld.getInverse( cameraR.matrixWorldInverse ); + cameraL.matrixWorld.getInverse( cameraL.matrixWorldInverse ); + cameraR.matrixWorld.getInverse( cameraR.matrixWorldInverse ); - cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix ); - cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix ); + cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix ); + cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix ); - // HACK (mrdoob) - // https://github.com/w3c/webvr/issues/203 + // HACK (mrdoob) + // https://github.com/w3c/webvr/issues/203 - cameraVR.projectionMatrix.copy( cameraL.projectionMatrix ); + cameraVR.projectionMatrix.copy( cameraL.projectionMatrix ); - // + // - var layers = device.getLayers(); + var layers = device.getLayers(); - if ( layers.length ) { + if ( layers.length ) { - var layer = layers[ 0 ]; + var layer = layers[ 0 ]; - if ( layer.leftBounds !== null && layer.leftBounds.length === 4 ) { + if ( layer.leftBounds !== null && layer.leftBounds.length === 4 ) { - cameraL.bounds.fromArray( layer.leftBounds ); + cameraL.bounds.fromArray( layer.leftBounds ); - } + } - if ( layer.rightBounds !== null && layer.rightBounds.length === 4 ) { + if ( layer.rightBounds !== null && layer.rightBounds.length === 4 ) { - cameraR.bounds.fromArray( layer.rightBounds ); + cameraR.bounds.fromArray( layer.rightBounds ); - } + } - } + } - updateControllers(); + updateControllers(); - return cameraVR; + return cameraVR; - }; + }; - this.getStandingMatrix = function () { + this.getStandingMatrix = function () { - return standingMatrix; + return standingMatrix; - }; + }; - this.isPresenting = isPresenting; + this.isPresenting = isPresenting; - // Animation Loop + // Animation Loop - var animation = new WebGLAnimation(); + var animation = new WebGLAnimation(); - this.setAnimationLoop = function ( callback ) { + this.setAnimationLoop = function ( callback ) { - animation.setAnimationLoop( callback ); + animation.setAnimationLoop( callback ); - }; + }; - this.submitFrame = function () { + this.submitFrame = function () { - if ( isPresenting() ) device.submitFrame(); + if ( isPresenting() ) device.submitFrame(); - }; + }; - this.dispose = function () { + this.dispose = function () { - if ( typeof window !== 'undefined' ) { + if ( typeof window !== 'undefined' ) { - window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange ); + window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange ); - } + } - }; + }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function WebXRManager( renderer ) { + function WebXRManager( renderer ) { - var gl = renderer.context; + var gl = renderer.context; - var device = null; - var session = null; + var device = null; + var session = null; - var frameOfRef = null; + var frameOfRef = null; - var pose = null; + var pose = null; - var controllers = []; - var inputSources = []; + var controllers = []; + var inputSources = []; - function isPresenting() { + function isPresenting() { - return session !== null && frameOfRef !== null; + return session !== null && frameOfRef !== null; - } + } - // + // - var cameraL = new PerspectiveCamera(); - cameraL.layers.enable( 1 ); - cameraL.viewport = new Vector4(); + var cameraL = new PerspectiveCamera(); + cameraL.layers.enable( 1 ); + cameraL.viewport = new Vector4(); - var cameraR = new PerspectiveCamera(); - cameraR.layers.enable( 2 ); - cameraR.viewport = new Vector4(); + var cameraR = new PerspectiveCamera(); + cameraR.layers.enable( 2 ); + cameraR.viewport = new Vector4(); - var cameraVR = new ArrayCamera( [ cameraL, cameraR ] ); - cameraVR.layers.enable( 1 ); - cameraVR.layers.enable( 2 ); + var cameraVR = new ArrayCamera( [ cameraL, cameraR ] ); + cameraVR.layers.enable( 1 ); + cameraVR.layers.enable( 2 ); - // + // - this.enabled = false; + this.enabled = false; - this.getController = function ( id ) { + this.getController = function ( id ) { - var controller = controllers[ id ]; + var controller = controllers[ id ]; - if ( controller === undefined ) { + if ( controller === undefined ) { - controller = new Group(); - controller.matrixAutoUpdate = false; - controller.visible = false; + controller = new Group(); + controller.matrixAutoUpdate = false; + controller.visible = false; - controllers[ id ] = controller; + controllers[ id ] = controller; - } + } - return controller; + return controller; - }; + }; - this.getDevice = function () { + this.getDevice = function () { - return device; + return device; - }; + }; - this.setDevice = function ( value ) { + this.setDevice = function ( value ) { - if ( value !== undefined ) device = value; - if ( value instanceof XRDevice ) gl.setCompatibleXRDevice( value ); + if ( value !== undefined ) device = value; + if ( value instanceof XRDevice ) gl.setCompatibleXRDevice( value ); - }; + }; - // + // - function onSessionEvent( event ) { + function onSessionEvent( event ) { - var controller = controllers[ inputSources.indexOf( event.inputSource ) ]; - if ( controller ) controller.dispatchEvent( { type: event.type } ); + var controller = controllers[ inputSources.indexOf( event.inputSource ) ]; + if ( controller ) controller.dispatchEvent( { type: event.type } ); - } + } - function onSessionEnd() { + function onSessionEnd() { - renderer.setFramebuffer( null ); - animation.stop(); + renderer.setFramebuffer( null ); + animation.stop(); - } + } - this.setSession = function ( value, options ) { + this.setSession = function ( value, options ) { - session = value; + session = value; - if ( session !== null ) { + if ( session !== null ) { - session.addEventListener( 'select', onSessionEvent ); - session.addEventListener( 'selectstart', onSessionEvent ); - session.addEventListener( 'selectend', onSessionEvent ); - session.addEventListener( 'end', onSessionEnd ); + session.addEventListener( 'select', onSessionEvent ); + session.addEventListener( 'selectstart', onSessionEvent ); + session.addEventListener( 'selectend', onSessionEvent ); + session.addEventListener( 'end', onSessionEnd ); - session.baseLayer = new XRWebGLLayer( session, gl ); - session.requestFrameOfReference( options.frameOfReferenceType ).then( function ( value ) { + session.baseLayer = new XRWebGLLayer( session, gl ); + session.requestFrameOfReference( options.frameOfReferenceType ).then( function ( value ) { - frameOfRef = value; + frameOfRef = value; - renderer.setFramebuffer( session.baseLayer.framebuffer ); + renderer.setFramebuffer( session.baseLayer.framebuffer ); - animation.setContext( session ); - animation.start(); + animation.setContext( session ); + animation.start(); - } ); + } ); - // + // - inputSources = session.getInputSources(); + inputSources = session.getInputSources(); - session.addEventListener( 'inputsourceschange', function () { + session.addEventListener( 'inputsourceschange', function () { - inputSources = session.getInputSources(); - console.log( inputSources ); + inputSources = session.getInputSources(); + console.log( inputSources ); - } ); + } ); - } + } - }; + }; - function updateCamera( camera, parent ) { + function updateCamera( camera, parent ) { - if ( parent === null ) { + if ( parent === null ) { - camera.matrixWorld.copy( camera.matrix ); + camera.matrixWorld.copy( camera.matrix ); - } else { + } else { - camera.matrixWorld.multiplyMatrices( parent.matrixWorld, camera.matrix ); + camera.matrixWorld.multiplyMatrices( parent.matrixWorld, camera.matrix ); - } + } - camera.matrixWorldInverse.getInverse( camera.matrixWorld ); + camera.matrixWorldInverse.getInverse( camera.matrixWorld ); - } + } - this.getCamera = function ( camera ) { + this.getCamera = function ( camera ) { - if ( isPresenting() ) { + if ( isPresenting() ) { - var parent = camera.parent; - var cameras = cameraVR.cameras; + var parent = camera.parent; + var cameras = cameraVR.cameras; - // apply camera.parent to cameraVR + // apply camera.parent to cameraVR - updateCamera( cameraVR, parent ); + updateCamera( cameraVR, parent ); - for ( var i = 0; i < cameras.length; i ++ ) { + for ( var i = 0; i < cameras.length; i ++ ) { - updateCamera( cameras[ i ], parent ); + updateCamera( cameras[ i ], parent ); - } + } - // update camera and its children + // update camera and its children - camera.matrixWorld.copy( cameraVR.matrixWorld ); + camera.matrixWorld.copy( cameraVR.matrixWorld ); - var children = camera.children; + var children = camera.children; - for ( var i = 0, l = children.length; i < l; i ++ ) { + for ( var i = 0, l = children.length; i < l; i ++ ) { - children[ i ].updateMatrixWorld( true ); + children[ i ].updateMatrixWorld( true ); - } + } - return cameraVR; + return cameraVR; - } + } - return camera; + return camera; - }; + }; - this.isPresenting = isPresenting; + this.isPresenting = isPresenting; - // Animation Loop + // Animation Loop - var onAnimationFrameCallback = null; + var onAnimationFrameCallback = null; - function onAnimationFrame( time, frame ) { + function onAnimationFrame( time, frame ) { - pose = frame.getDevicePose( frameOfRef ); + pose = frame.getDevicePose( frameOfRef ); - if ( pose !== null ) { + if ( pose !== null ) { - var layer = session.baseLayer; - var views = frame.views; + var layer = session.baseLayer; + var views = frame.views; - for ( var i = 0; i < views.length; i ++ ) { + for ( var i = 0; i < views.length; i ++ ) { - var view = views[ i ]; - var viewport = layer.getViewport( view ); - var viewMatrix = pose.getViewMatrix( view ); + var view = views[ i ]; + var viewport = layer.getViewport( view ); + var viewMatrix = pose.getViewMatrix( view ); - var camera = cameraVR.cameras[ i ]; - camera.matrix.fromArray( viewMatrix ).getInverse( camera.matrix ); - camera.projectionMatrix.fromArray( view.projectionMatrix ); - camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height ); + var camera = cameraVR.cameras[ i ]; + camera.matrix.fromArray( viewMatrix ).getInverse( camera.matrix ); + camera.projectionMatrix.fromArray( view.projectionMatrix ); + camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height ); - if ( i === 0 ) { + if ( i === 0 ) { - cameraVR.matrix.copy( camera.matrix ); + cameraVR.matrix.copy( camera.matrix ); - // HACK (mrdoob) - // https://github.com/w3c/webvr/issues/203 + // HACK (mrdoob) + // https://github.com/w3c/webvr/issues/203 - cameraVR.projectionMatrix.copy( camera.projectionMatrix ); + cameraVR.projectionMatrix.copy( camera.projectionMatrix ); - } + } - } + } - } + } - // + // - for ( var i = 0; i < controllers.length; i ++ ) { + for ( var i = 0; i < controllers.length; i ++ ) { - var controller = controllers[ i ]; + var controller = controllers[ i ]; - var inputSource = inputSources[ i ]; + var inputSource = inputSources[ i ]; - if ( inputSource ) { + if ( inputSource ) { - var inputPose = frame.getInputPose( inputSource, frameOfRef ); + var inputPose = frame.getInputPose( inputSource, frameOfRef ); - if ( inputPose !== null ) { + if ( inputPose !== null ) { - controller.matrix.elements = inputPose.pointerMatrix; - controller.matrix.decompose( controller.position, controller.rotation, controller.scale ); - controller.visible = true; + controller.matrix.elements = inputPose.pointerMatrix; + controller.matrix.decompose( controller.position, controller.rotation, controller.scale ); + controller.visible = true; - continue; + continue; - } + } - } + } - controller.visible = false; + controller.visible = false; - } + } - if ( onAnimationFrameCallback ) onAnimationFrameCallback( time ); + if ( onAnimationFrameCallback ) onAnimationFrameCallback( time ); - } + } - var animation = new WebGLAnimation(); - animation.setAnimationLoop( onAnimationFrame ); + var animation = new WebGLAnimation(); + animation.setAnimationLoop( onAnimationFrame ); - this.setAnimationLoop = function ( callback ) { + this.setAnimationLoop = function ( callback ) { - onAnimationFrameCallback = callback; + onAnimationFrameCallback = callback; - }; + }; - this.dispose = function () {}; + this.dispose = function () {}; - // DEPRECATED + // DEPRECATED - this.getStandingMatrix = function () { + this.getStandingMatrix = function () { - console.warn( 'THREE.WebXRManager: getStandingMatrix() is no longer needed.' ); - return new THREE.Matrix4(); + console.warn( 'THREE.WebXRManager: getStandingMatrix() is no longer needed.' ); + return new THREE.Matrix4(); - }; + }; - this.submitFrame = function () {}; + this.submitFrame = function () {}; - } + } - /** - * @author supereggbert / http://www.paulbrunt.co.uk/ - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author szimek / https://github.com/szimek/ - * @author tschw - */ + /** + * @author supereggbert / http://www.paulbrunt.co.uk/ + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author szimek / https://github.com/szimek/ + * @author tschw + */ - function WebGLRenderer( parameters ) { + function WebGLRenderer( parameters ) { - console.log( 'THREE.WebGLRenderer', REVISION ); + console.log( 'THREE.WebGLRenderer', REVISION ); - parameters = parameters || {}; + parameters = parameters || {}; - var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ), - _context = parameters.context !== undefined ? parameters.context : null, + var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ), + _context = parameters.context !== undefined ? parameters.context : null, - _alpha = parameters.alpha !== undefined ? parameters.alpha : false, - _depth = parameters.depth !== undefined ? parameters.depth : true, - _stencil = parameters.stencil !== undefined ? parameters.stencil : true, - _antialias = parameters.antialias !== undefined ? parameters.antialias : false, - _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true, - _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false, - _powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default'; + _alpha = parameters.alpha !== undefined ? parameters.alpha : false, + _depth = parameters.depth !== undefined ? parameters.depth : true, + _stencil = parameters.stencil !== undefined ? parameters.stencil : true, + _antialias = parameters.antialias !== undefined ? parameters.antialias : false, + _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true, + _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false, + _powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default'; - var currentRenderList = null; - var currentRenderState = null; + var currentRenderList = null; + var currentRenderState = null; - // public properties + // public properties - this.domElement = _canvas; - this.context = null; + this.domElement = _canvas; + this.context = null; - // clearing + // clearing - this.autoClear = true; - this.autoClearColor = true; - this.autoClearDepth = true; - this.autoClearStencil = true; + this.autoClear = true; + this.autoClearColor = true; + this.autoClearDepth = true; + this.autoClearStencil = true; - // scene graph + // scene graph - this.sortObjects = true; + this.sortObjects = true; - // user-defined clipping + // user-defined clipping - this.clippingPlanes = []; - this.localClippingEnabled = false; + this.clippingPlanes = []; + this.localClippingEnabled = false; - // physically based shading + // physically based shading - this.gammaFactor = 2.0; // for backwards compatibility - this.gammaInput = false; - this.gammaOutput = false; + this.gammaFactor = 2.0; // for backwards compatibility + this.gammaInput = false; + this.gammaOutput = false; - // physical lights + // physical lights - this.physicallyCorrectLights = false; + this.physicallyCorrectLights = false; - // tone mapping + // tone mapping - this.toneMapping = LinearToneMapping; - this.toneMappingExposure = 1.0; - this.toneMappingWhitePoint = 1.0; + this.toneMapping = LinearToneMapping; + this.toneMappingExposure = 1.0; + this.toneMappingWhitePoint = 1.0; - // morphs + // morphs - this.maxMorphTargets = 8; - this.maxMorphNormals = 4; + this.maxMorphTargets = 8; + this.maxMorphNormals = 4; - // internal properties + // internal properties - var _this = this, + var _this = this, - _isContextLost = false, + _isContextLost = false, - // internal state cache + // internal state cache - _framebuffer = null, + _framebuffer = null, - _currentRenderTarget = null, - _currentFramebuffer = null, - _currentMaterialId = - 1, + _currentRenderTarget = null, + _currentFramebuffer = null, + _currentMaterialId = - 1, - // geometry and program caching + // geometry and program caching - _currentGeometryProgram = { - geometry: null, - program: null, - wireframe: false - }, + _currentGeometryProgram = { + geometry: null, + program: null, + wireframe: false + }, - _currentCamera = null, - _currentArrayCamera = null, + _currentCamera = null, + _currentArrayCamera = null, - _currentViewport = new Vector4(), - _currentScissor = new Vector4(), - _currentScissorTest = null, + _currentViewport = new Vector4(), + _currentScissor = new Vector4(), + _currentScissorTest = null, - // + // - _usedTextureUnits = 0, + _usedTextureUnits = 0, - // + // - _width = _canvas.width, - _height = _canvas.height, + _width = _canvas.width, + _height = _canvas.height, - _pixelRatio = 1, + _pixelRatio = 1, - _viewport = new Vector4( 0, 0, _width, _height ), - _scissor = new Vector4( 0, 0, _width, _height ), - _scissorTest = false, + _viewport = new Vector4( 0, 0, _width, _height ), + _scissor = new Vector4( 0, 0, _width, _height ), + _scissorTest = false, - // frustum + // frustum - _frustum = new Frustum(), + _frustum = new Frustum(), - // clipping + // clipping - _clipping = new WebGLClipping(), - _clippingEnabled = false, - _localClippingEnabled = false, + _clipping = new WebGLClipping(), + _clippingEnabled = false, + _localClippingEnabled = false, - // camera matrices cache + // camera matrices cache - _projScreenMatrix = new Matrix4(), + _projScreenMatrix = new Matrix4(), - _vector3 = new Vector3(); + _vector3 = new Vector3(); - function getTargetPixelRatio() { + function getTargetPixelRatio() { - return _currentRenderTarget === null ? _pixelRatio : 1; + return _currentRenderTarget === null ? _pixelRatio : 1; - } + } - // initialize + // initialize - var _gl; + var _gl; - try { + try { - var contextAttributes = { - alpha: _alpha, - depth: _depth, - stencil: _stencil, - antialias: _antialias, - premultipliedAlpha: _premultipliedAlpha, - preserveDrawingBuffer: _preserveDrawingBuffer, - powerPreference: _powerPreference - }; + var contextAttributes = { + alpha: _alpha, + depth: _depth, + stencil: _stencil, + antialias: _antialias, + premultipliedAlpha: _premultipliedAlpha, + preserveDrawingBuffer: _preserveDrawingBuffer, + powerPreference: _powerPreference + }; - // event listeners must be registered before WebGL context is created, see #12753 + // event listeners must be registered before WebGL context is created, see #12753 - _canvas.addEventListener( 'webglcontextlost', onContextLost, false ); - _canvas.addEventListener( 'webglcontextrestored', onContextRestore, false ); + _canvas.addEventListener( 'webglcontextlost', onContextLost, false ); + _canvas.addEventListener( 'webglcontextrestored', onContextRestore, false ); - _gl = _context || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes ); + _gl = _context || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes ); - if ( _gl === null ) { + if ( _gl === null ) { - if ( _canvas.getContext( 'webgl' ) !== null ) { + if ( _canvas.getContext( 'webgl' ) !== null ) { - throw new Error( 'Error creating WebGL context with your selected attributes.' ); + throw new Error( 'Error creating WebGL context with your selected attributes.' ); - } else { + } else { - throw new Error( 'Error creating WebGL context.' ); + throw new Error( 'Error creating WebGL context.' ); - } + } - } + } - // Some experimental-webgl implementations do not have getShaderPrecisionFormat + // Some experimental-webgl implementations do not have getShaderPrecisionFormat - if ( _gl.getShaderPrecisionFormat === undefined ) { + if ( _gl.getShaderPrecisionFormat === undefined ) { - _gl.getShaderPrecisionFormat = function () { + _gl.getShaderPrecisionFormat = function () { - return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 }; + return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 }; - }; + }; - } + } - } catch ( error ) { + } catch ( error ) { - console.error( 'THREE.WebGLRenderer: ' + error.message ); + console.error( 'THREE.WebGLRenderer: ' + error.message ); - } + } - var extensions, capabilities, state, info; - var properties, textures, attributes, geometries, objects; - var programCache, renderLists, renderStates; + var extensions, capabilities, state, info; + var properties, textures, attributes, geometries, objects; + var programCache, renderLists, renderStates; - var background, morphtargets, bufferRenderer, indexedBufferRenderer; + var background, morphtargets, bufferRenderer, indexedBufferRenderer; - var utils; + var utils; - function initGLContext() { + function initGLContext() { - extensions = new WebGLExtensions( _gl ); + extensions = new WebGLExtensions( _gl ); - capabilities = new WebGLCapabilities( _gl, extensions, parameters ); + capabilities = new WebGLCapabilities( _gl, extensions, parameters ); - if ( ! capabilities.isWebGL2 ) { + if ( ! capabilities.isWebGL2 ) { - extensions.get( 'WEBGL_depth_texture' ); - extensions.get( 'OES_texture_float' ); - extensions.get( 'OES_texture_half_float' ); - extensions.get( 'OES_texture_half_float_linear' ); - extensions.get( 'OES_standard_derivatives' ); - extensions.get( 'OES_element_index_uint' ); - extensions.get( 'ANGLE_instanced_arrays' ); + extensions.get( 'WEBGL_depth_texture' ); + extensions.get( 'OES_texture_float' ); + extensions.get( 'OES_texture_half_float' ); + extensions.get( 'OES_texture_half_float_linear' ); + extensions.get( 'OES_standard_derivatives' ); + extensions.get( 'OES_element_index_uint' ); + extensions.get( 'ANGLE_instanced_arrays' ); - } + } - extensions.get( 'OES_texture_float_linear' ); + extensions.get( 'OES_texture_float_linear' ); - utils = new WebGLUtils( _gl, extensions, capabilities ); + utils = new WebGLUtils( _gl, extensions, capabilities ); - state = new WebGLState( _gl, extensions, utils, capabilities ); - state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) ); - state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) ); + state = new WebGLState( _gl, extensions, utils, capabilities ); + state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) ); + state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) ); - info = new WebGLInfo( _gl ); - properties = new WebGLProperties(); - textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ); - attributes = new WebGLAttributes( _gl ); - geometries = new WebGLGeometries( _gl, attributes, info ); - objects = new WebGLObjects( geometries, info ); - morphtargets = new WebGLMorphtargets( _gl ); - programCache = new WebGLPrograms( _this, extensions, capabilities ); - renderLists = new WebGLRenderLists(); - renderStates = new WebGLRenderStates(); + info = new WebGLInfo( _gl ); + properties = new WebGLProperties(); + textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ); + attributes = new WebGLAttributes( _gl ); + geometries = new WebGLGeometries( _gl, attributes, info ); + objects = new WebGLObjects( geometries, info ); + morphtargets = new WebGLMorphtargets( _gl ); + programCache = new WebGLPrograms( _this, extensions, capabilities ); + renderLists = new WebGLRenderLists(); + renderStates = new WebGLRenderStates(); - background = new WebGLBackground( _this, state, objects, _premultipliedAlpha ); + background = new WebGLBackground( _this, state, objects, _premultipliedAlpha ); - bufferRenderer = new WebGLBufferRenderer( _gl, extensions, info, capabilities ); - indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info, capabilities ); + bufferRenderer = new WebGLBufferRenderer( _gl, extensions, info, capabilities ); + indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info, capabilities ); - info.programs = programCache.programs; + info.programs = programCache.programs; - _this.context = _gl; - _this.capabilities = capabilities; - _this.extensions = extensions; - _this.properties = properties; - _this.renderLists = renderLists; - _this.state = state; - _this.info = info; + _this.context = _gl; + _this.capabilities = capabilities; + _this.extensions = extensions; + _this.properties = properties; + _this.renderLists = renderLists; + _this.state = state; + _this.info = info; - } + } - initGLContext(); + initGLContext(); - // vr + // vr - var vr = ( 'xr' in navigator ) ? new WebXRManager( _this ) : new WebVRManager( _this ); + var vr = ( 'xr' in navigator ) ? new WebXRManager( _this ) : new WebVRManager( _this ); - this.vr = vr; + this.vr = vr; - // shadow map + // shadow map - var shadowMap = new WebGLShadowMap( _this, objects, capabilities.maxTextureSize ); + var shadowMap = new WebGLShadowMap( _this, objects, capabilities.maxTextureSize ); - this.shadowMap = shadowMap; + this.shadowMap = shadowMap; - // API + // API - this.getContext = function () { + this.getContext = function () { - return _gl; + return _gl; - }; + }; - this.getContextAttributes = function () { + this.getContextAttributes = function () { - return _gl.getContextAttributes(); + return _gl.getContextAttributes(); - }; + }; - this.forceContextLoss = function () { + this.forceContextLoss = function () { - var extension = extensions.get( 'WEBGL_lose_context' ); - if ( extension ) extension.loseContext(); + var extension = extensions.get( 'WEBGL_lose_context' ); + if ( extension ) extension.loseContext(); - }; + }; - this.forceContextRestore = function () { + this.forceContextRestore = function () { - var extension = extensions.get( 'WEBGL_lose_context' ); - if ( extension ) extension.restoreContext(); + var extension = extensions.get( 'WEBGL_lose_context' ); + if ( extension ) extension.restoreContext(); - }; + }; - this.getPixelRatio = function () { + this.getPixelRatio = function () { - return _pixelRatio; + return _pixelRatio; - }; + }; - this.setPixelRatio = function ( value ) { + this.setPixelRatio = function ( value ) { - if ( value === undefined ) return; + if ( value === undefined ) return; - _pixelRatio = value; + _pixelRatio = value; - this.setSize( _width, _height, false ); + this.setSize( _width, _height, false ); - }; + }; - this.getSize = function () { + this.getSize = function () { - return { - width: _width, - height: _height - }; + return { + width: _width, + height: _height + }; - }; + }; - this.setSize = function ( width, height, updateStyle ) { + this.setSize = function ( width, height, updateStyle ) { - if ( vr.isPresenting() ) { + if ( vr.isPresenting() ) { - console.warn( 'THREE.WebGLRenderer: Can\'t change size while VR device is presenting.' ); - return; + console.warn( 'THREE.WebGLRenderer: Can\'t change size while VR device is presenting.' ); + return; - } + } - _width = width; - _height = height; + _width = width; + _height = height; - _canvas.width = width * _pixelRatio; - _canvas.height = height * _pixelRatio; + _canvas.width = width * _pixelRatio; + _canvas.height = height * _pixelRatio; - if ( updateStyle !== false ) { + if ( updateStyle !== false ) { - _canvas.style.width = width + 'px'; - _canvas.style.height = height + 'px'; + _canvas.style.width = width + 'px'; + _canvas.style.height = height + 'px'; - } + } - this.setViewport( 0, 0, width, height ); + this.setViewport( 0, 0, width, height ); - }; + }; - this.getDrawingBufferSize = function () { + this.getDrawingBufferSize = function () { - return { - width: _width * _pixelRatio, - height: _height * _pixelRatio - }; + return { + width: _width * _pixelRatio, + height: _height * _pixelRatio + }; - }; + }; - this.setDrawingBufferSize = function ( width, height, pixelRatio ) { + this.setDrawingBufferSize = function ( width, height, pixelRatio ) { - _width = width; - _height = height; + _width = width; + _height = height; - _pixelRatio = pixelRatio; + _pixelRatio = pixelRatio; - _canvas.width = width * pixelRatio; - _canvas.height = height * pixelRatio; + _canvas.width = width * pixelRatio; + _canvas.height = height * pixelRatio; - this.setViewport( 0, 0, width, height ); + this.setViewport( 0, 0, width, height ); - }; + }; - this.getCurrentViewport = function () { + this.getCurrentViewport = function () { - return _currentViewport; + return _currentViewport; - }; + }; - this.setViewport = function ( x, y, width, height ) { + this.setViewport = function ( x, y, width, height ) { - _viewport.set( x, _height - y - height, width, height ); - state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) ); + _viewport.set( x, _height - y - height, width, height ); + state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) ); - }; + }; - this.setScissor = function ( x, y, width, height ) { + this.setScissor = function ( x, y, width, height ) { - _scissor.set( x, _height - y - height, width, height ); - state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) ); + _scissor.set( x, _height - y - height, width, height ); + state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) ); - }; + }; - this.setScissorTest = function ( boolean ) { + this.setScissorTest = function ( boolean ) { - state.setScissorTest( _scissorTest = boolean ); + state.setScissorTest( _scissorTest = boolean ); - }; + }; - // Clearing + // Clearing - this.getClearColor = function () { + this.getClearColor = function () { - return background.getClearColor(); + return background.getClearColor(); - }; + }; - this.setClearColor = function () { + this.setClearColor = function () { - background.setClearColor.apply( background, arguments ); + background.setClearColor.apply( background, arguments ); - }; + }; - this.getClearAlpha = function () { + this.getClearAlpha = function () { - return background.getClearAlpha(); + return background.getClearAlpha(); - }; + }; - this.setClearAlpha = function () { + this.setClearAlpha = function () { - background.setClearAlpha.apply( background, arguments ); + background.setClearAlpha.apply( background, arguments ); - }; + }; - this.clear = function ( color, depth, stencil ) { + this.clear = function ( color, depth, stencil ) { - var bits = 0; + var bits = 0; - if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT; - if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT; - if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT; + if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT; + if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT; + if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT; - _gl.clear( bits ); + _gl.clear( bits ); - }; + }; - this.clearColor = function () { + this.clearColor = function () { - this.clear( true, false, false ); + this.clear( true, false, false ); - }; + }; - this.clearDepth = function () { + this.clearDepth = function () { - this.clear( false, true, false ); + this.clear( false, true, false ); - }; + }; - this.clearStencil = function () { + this.clearStencil = function () { - this.clear( false, false, true ); + this.clear( false, false, true ); - }; + }; - this.clearTarget = function ( renderTarget, color, depth, stencil ) { + this.clearTarget = function ( renderTarget, color, depth, stencil ) { - this.setRenderTarget( renderTarget ); - this.clear( color, depth, stencil ); + this.setRenderTarget( renderTarget ); + this.clear( color, depth, stencil ); - }; + }; - // + // - this.dispose = function () { + this.dispose = function () { - _canvas.removeEventListener( 'webglcontextlost', onContextLost, false ); - _canvas.removeEventListener( 'webglcontextrestored', onContextRestore, false ); + _canvas.removeEventListener( 'webglcontextlost', onContextLost, false ); + _canvas.removeEventListener( 'webglcontextrestored', onContextRestore, false ); - renderLists.dispose(); - renderStates.dispose(); - properties.dispose(); - objects.dispose(); + renderLists.dispose(); + renderStates.dispose(); + properties.dispose(); + objects.dispose(); - vr.dispose(); + vr.dispose(); - animation.stop(); + animation.stop(); - }; + }; - // Events + // Events - function onContextLost( event ) { + function onContextLost( event ) { - event.preventDefault(); + event.preventDefault(); - console.log( 'THREE.WebGLRenderer: Context Lost.' ); + console.log( 'THREE.WebGLRenderer: Context Lost.' ); - _isContextLost = true; + _isContextLost = true; - } + } - function onContextRestore( /* event */ ) { + function onContextRestore( /* event */ ) { - console.log( 'THREE.WebGLRenderer: Context Restored.' ); + console.log( 'THREE.WebGLRenderer: Context Restored.' ); - _isContextLost = false; + _isContextLost = false; - initGLContext(); + initGLContext(); - } + } - function onMaterialDispose( event ) { + function onMaterialDispose( event ) { - var material = event.target; + var material = event.target; - material.removeEventListener( 'dispose', onMaterialDispose ); + material.removeEventListener( 'dispose', onMaterialDispose ); - deallocateMaterial( material ); + deallocateMaterial( material ); - } + } - // Buffer deallocation + // Buffer deallocation - function deallocateMaterial( material ) { + function deallocateMaterial( material ) { - releaseMaterialProgramReference( material ); + releaseMaterialProgramReference( material ); - properties.remove( material ); + properties.remove( material ); - } + } - function releaseMaterialProgramReference( material ) { + function releaseMaterialProgramReference( material ) { - var programInfo = properties.get( material ).program; + var programInfo = properties.get( material ).program; - material.program = undefined; + material.program = undefined; - if ( programInfo !== undefined ) { + if ( programInfo !== undefined ) { - programCache.releaseProgram( programInfo ); + programCache.releaseProgram( programInfo ); - } + } - } + } - // Buffer rendering + // Buffer rendering - function renderObjectImmediate( object, program ) { + function renderObjectImmediate( object, program ) { - object.render( function ( object ) { + object.render( function ( object ) { - _this.renderBufferImmediate( object, program ); + _this.renderBufferImmediate( object, program ); - } ); + } ); - } + } - this.renderBufferImmediate = function ( object, program ) { + this.renderBufferImmediate = function ( object, program ) { - state.initAttributes(); + state.initAttributes(); - var buffers = properties.get( object ); + var buffers = properties.get( object ); - if ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer(); - if ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer(); - if ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer(); - if ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer(); + if ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer(); + if ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer(); + if ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer(); + if ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer(); - var programAttributes = program.getAttributes(); + var programAttributes = program.getAttributes(); - if ( object.hasPositions ) { + if ( object.hasPositions ) { - _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position ); - _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW ); + _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position ); + _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW ); - state.enableAttribute( programAttributes.position ); - _gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 ); + state.enableAttribute( programAttributes.position ); + _gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 ); - } + } - if ( object.hasNormals ) { + if ( object.hasNormals ) { - _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal ); - _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW ); + _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal ); + _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW ); - state.enableAttribute( programAttributes.normal ); - _gl.vertexAttribPointer( programAttributes.normal, 3, _gl.FLOAT, false, 0, 0 ); + state.enableAttribute( programAttributes.normal ); + _gl.vertexAttribPointer( programAttributes.normal, 3, _gl.FLOAT, false, 0, 0 ); - } + } - if ( object.hasUvs ) { + if ( object.hasUvs ) { - _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv ); - _gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW ); + _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv ); + _gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW ); - state.enableAttribute( programAttributes.uv ); - _gl.vertexAttribPointer( programAttributes.uv, 2, _gl.FLOAT, false, 0, 0 ); + state.enableAttribute( programAttributes.uv ); + _gl.vertexAttribPointer( programAttributes.uv, 2, _gl.FLOAT, false, 0, 0 ); - } + } - if ( object.hasColors ) { + if ( object.hasColors ) { - _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color ); - _gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW ); + _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color ); + _gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW ); - state.enableAttribute( programAttributes.color ); - _gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 ); + state.enableAttribute( programAttributes.color ); + _gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 ); - } + } - state.disableUnusedAttributes(); + state.disableUnusedAttributes(); - _gl.drawArrays( _gl.TRIANGLES, 0, object.count ); + _gl.drawArrays( _gl.TRIANGLES, 0, object.count ); - object.count = 0; + object.count = 0; - }; + }; - this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) { + this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) { - var frontFaceCW = ( object.isMesh && object.normalMatrix.determinant() < 0 ); + var frontFaceCW = ( object.isMesh && object.normalMatrix.determinant() < 0 ); - state.setMaterial( material, frontFaceCW ); + state.setMaterial( material, frontFaceCW ); - var program = setProgram( camera, fog, material, object ); + var program = setProgram( camera, fog, material, object ); - var updateBuffers = false; + var updateBuffers = false; - if ( _currentGeometryProgram.geometry !== geometry.id || - _currentGeometryProgram.program !== program.id || - _currentGeometryProgram.wireframe !== ( material.wireframe === true ) ) { + if ( _currentGeometryProgram.geometry !== geometry.id || + _currentGeometryProgram.program !== program.id || + _currentGeometryProgram.wireframe !== ( material.wireframe === true ) ) { - _currentGeometryProgram.geometry = geometry.id; - _currentGeometryProgram.program = program.id; - _currentGeometryProgram.wireframe = material.wireframe === true; - updateBuffers = true; + _currentGeometryProgram.geometry = geometry.id; + _currentGeometryProgram.program = program.id; + _currentGeometryProgram.wireframe = material.wireframe === true; + updateBuffers = true; - } + } - if ( object.morphTargetInfluences ) { + if ( object.morphTargetInfluences ) { - morphtargets.update( object, geometry, material, program ); + morphtargets.update( object, geometry, material, program ); - updateBuffers = true; + updateBuffers = true; - } + } - // + // - var index = geometry.index; - var position = geometry.attributes.position; - var rangeFactor = 1; + var index = geometry.index; + var position = geometry.attributes.position; + var rangeFactor = 1; - if ( material.wireframe === true ) { + if ( material.wireframe === true ) { - index = geometries.getWireframeAttribute( geometry ); - rangeFactor = 2; + index = geometries.getWireframeAttribute( geometry ); + rangeFactor = 2; - } + } - var attribute; - var renderer = bufferRenderer; + var attribute; + var renderer = bufferRenderer; - if ( index !== null ) { + if ( index !== null ) { - attribute = attributes.get( index ); + attribute = attributes.get( index ); - renderer = indexedBufferRenderer; - renderer.setIndex( attribute ); + renderer = indexedBufferRenderer; + renderer.setIndex( attribute ); - } + } - if ( updateBuffers ) { + if ( updateBuffers ) { - setupVertexAttributes( material, program, geometry ); + setupVertexAttributes( material, program, geometry ); - if ( index !== null ) { + if ( index !== null ) { - _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer ); + _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer ); - } + } - } + } - // + // - var dataCount = Infinity; + var dataCount = Infinity; - if ( index !== null ) { + if ( index !== null ) { - dataCount = index.count; + dataCount = index.count; - } else if ( position !== undefined ) { + } else if ( position !== undefined ) { - dataCount = position.count; + dataCount = position.count; - } + } - var rangeStart = geometry.drawRange.start * rangeFactor; - var rangeCount = geometry.drawRange.count * rangeFactor; + var rangeStart = geometry.drawRange.start * rangeFactor; + var rangeCount = geometry.drawRange.count * rangeFactor; - var groupStart = group !== null ? group.start * rangeFactor : 0; - var groupCount = group !== null ? group.count * rangeFactor : Infinity; + var groupStart = group !== null ? group.start * rangeFactor : 0; + var groupCount = group !== null ? group.count * rangeFactor : Infinity; - var drawStart = Math.max( rangeStart, groupStart ); - var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1; + var drawStart = Math.max( rangeStart, groupStart ); + var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1; - var drawCount = Math.max( 0, drawEnd - drawStart + 1 ); + var drawCount = Math.max( 0, drawEnd - drawStart + 1 ); - if ( drawCount === 0 ) return; + if ( drawCount === 0 ) return; - // + // - if ( object.isMesh ) { + if ( object.isMesh ) { - if ( material.wireframe === true ) { + if ( material.wireframe === true ) { - state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() ); - renderer.setMode( _gl.LINES ); + state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() ); + renderer.setMode( _gl.LINES ); - } else { + } else { - switch ( object.drawMode ) { + switch ( object.drawMode ) { - case TrianglesDrawMode: - renderer.setMode( _gl.TRIANGLES ); - break; + case TrianglesDrawMode: + renderer.setMode( _gl.TRIANGLES ); + break; - case TriangleStripDrawMode: - renderer.setMode( _gl.TRIANGLE_STRIP ); - break; + case TriangleStripDrawMode: + renderer.setMode( _gl.TRIANGLE_STRIP ); + break; - case TriangleFanDrawMode: - renderer.setMode( _gl.TRIANGLE_FAN ); - break; + case TriangleFanDrawMode: + renderer.setMode( _gl.TRIANGLE_FAN ); + break; - } + } - } + } - } else if ( object.isLine ) { + } else if ( object.isLine ) { - var lineWidth = material.linewidth; + var lineWidth = material.linewidth; - if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material + if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material - state.setLineWidth( lineWidth * getTargetPixelRatio() ); + state.setLineWidth( lineWidth * getTargetPixelRatio() ); - if ( object.isLineSegments ) { + if ( object.isLineSegments ) { - renderer.setMode( _gl.LINES ); + renderer.setMode( _gl.LINES ); - } else if ( object.isLineLoop ) { + } else if ( object.isLineLoop ) { - renderer.setMode( _gl.LINE_LOOP ); + renderer.setMode( _gl.LINE_LOOP ); - } else { + } else { - renderer.setMode( _gl.LINE_STRIP ); + renderer.setMode( _gl.LINE_STRIP ); - } + } - } else if ( object.isPoints ) { + } else if ( object.isPoints ) { - renderer.setMode( _gl.POINTS ); + renderer.setMode( _gl.POINTS ); - } else if ( object.isSprite ) { + } else if ( object.isSprite ) { - renderer.setMode( _gl.TRIANGLES ); + renderer.setMode( _gl.TRIANGLES ); - } + } - if ( geometry && geometry.isInstancedBufferGeometry ) { + if ( geometry && geometry.isInstancedBufferGeometry ) { - if ( geometry.maxInstancedCount > 0 ) { + if ( geometry.maxInstancedCount > 0 ) { - renderer.renderInstances( geometry, drawStart, drawCount ); + renderer.renderInstances( geometry, drawStart, drawCount ); - } + } - } else { + } else { - renderer.render( drawStart, drawCount ); + renderer.render( drawStart, drawCount ); - } + } - }; + }; - function setupVertexAttributes( material, program, geometry ) { + function setupVertexAttributes( material, program, geometry ) { - if ( geometry && geometry.isInstancedBufferGeometry & ! capabilities.isWebGL2 ) { + if ( geometry && geometry.isInstancedBufferGeometry & ! capabilities.isWebGL2 ) { - if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) { + if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) { - console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); - return; + console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); + return; - } + } - } + } - state.initAttributes(); + state.initAttributes(); - var geometryAttributes = geometry.attributes; + var geometryAttributes = geometry.attributes; - var programAttributes = program.getAttributes(); + var programAttributes = program.getAttributes(); - var materialDefaultAttributeValues = material.defaultAttributeValues; + var materialDefaultAttributeValues = material.defaultAttributeValues; - for ( var name in programAttributes ) { + for ( var name in programAttributes ) { - var programAttribute = programAttributes[ name ]; + var programAttribute = programAttributes[ name ]; - if ( programAttribute >= 0 ) { + if ( programAttribute >= 0 ) { - var geometryAttribute = geometryAttributes[ name ]; + var geometryAttribute = geometryAttributes[ name ]; - if ( geometryAttribute !== undefined ) { + if ( geometryAttribute !== undefined ) { - var normalized = geometryAttribute.normalized; - var size = geometryAttribute.itemSize; + var normalized = geometryAttribute.normalized; + var size = geometryAttribute.itemSize; - var attribute = attributes.get( geometryAttribute ); + var attribute = attributes.get( geometryAttribute ); - // TODO Attribute may not be available on context restore + // TODO Attribute may not be available on context restore - if ( attribute === undefined ) continue; + if ( attribute === undefined ) continue; - var buffer = attribute.buffer; - var type = attribute.type; - var bytesPerElement = attribute.bytesPerElement; + var buffer = attribute.buffer; + var type = attribute.type; + var bytesPerElement = attribute.bytesPerElement; - if ( geometryAttribute.isInterleavedBufferAttribute ) { + if ( geometryAttribute.isInterleavedBufferAttribute ) { - var data = geometryAttribute.data; - var stride = data.stride; - var offset = geometryAttribute.offset; + var data = geometryAttribute.data; + var stride = data.stride; + var offset = geometryAttribute.offset; - if ( data && data.isInstancedInterleavedBuffer ) { + if ( data && data.isInstancedInterleavedBuffer ) { - state.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute ); + state.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute ); - if ( geometry.maxInstancedCount === undefined ) { + if ( geometry.maxInstancedCount === undefined ) { - geometry.maxInstancedCount = data.meshPerAttribute * data.count; + geometry.maxInstancedCount = data.meshPerAttribute * data.count; - } + } - } else { + } else { - state.enableAttribute( programAttribute ); + state.enableAttribute( programAttribute ); - } + } - _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer ); - _gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, offset * bytesPerElement ); + _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer ); + _gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, offset * bytesPerElement ); - } else { + } else { - if ( geometryAttribute.isInstancedBufferAttribute ) { + if ( geometryAttribute.isInstancedBufferAttribute ) { - state.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute ); + state.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute ); - if ( geometry.maxInstancedCount === undefined ) { + if ( geometry.maxInstancedCount === undefined ) { - geometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count; + geometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count; - } + } - } else { + } else { - state.enableAttribute( programAttribute ); + state.enableAttribute( programAttribute ); - } + } - _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer ); - _gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 ); + _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer ); + _gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 ); - } + } - } else if ( materialDefaultAttributeValues !== undefined ) { + } else if ( materialDefaultAttributeValues !== undefined ) { - var value = materialDefaultAttributeValues[ name ]; + var value = materialDefaultAttributeValues[ name ]; - if ( value !== undefined ) { + if ( value !== undefined ) { - switch ( value.length ) { + switch ( value.length ) { - case 2: - _gl.vertexAttrib2fv( programAttribute, value ); - break; + case 2: + _gl.vertexAttrib2fv( programAttribute, value ); + break; - case 3: - _gl.vertexAttrib3fv( programAttribute, value ); - break; + case 3: + _gl.vertexAttrib3fv( programAttribute, value ); + break; - case 4: - _gl.vertexAttrib4fv( programAttribute, value ); - break; + case 4: + _gl.vertexAttrib4fv( programAttribute, value ); + break; - default: - _gl.vertexAttrib1fv( programAttribute, value ); + default: + _gl.vertexAttrib1fv( programAttribute, value ); - } + } - } + } - } + } - } + } - } + } - state.disableUnusedAttributes(); + state.disableUnusedAttributes(); - } + } - // Compile + // Compile - this.compile = function ( scene, camera ) { + this.compile = function ( scene, camera ) { - currentRenderState = renderStates.get( scene, camera ); - currentRenderState.init(); + currentRenderState = renderStates.get( scene, camera ); + currentRenderState.init(); - scene.traverse( function ( object ) { + scene.traverse( function ( object ) { - if ( object.isLight ) { + if ( object.isLight ) { - currentRenderState.pushLight( object ); + currentRenderState.pushLight( object ); - if ( object.castShadow ) { + if ( object.castShadow ) { - currentRenderState.pushShadow( object ); + currentRenderState.pushShadow( object ); - } + } - } + } - } ); + } ); - currentRenderState.setupLights( camera ); + currentRenderState.setupLights( camera ); - scene.traverse( function ( object ) { + scene.traverse( function ( object ) { - if ( object.material ) { + if ( object.material ) { - if ( Array.isArray( object.material ) ) { + if ( Array.isArray( object.material ) ) { - for ( var i = 0; i < object.material.length; i ++ ) { + for ( var i = 0; i < object.material.length; i ++ ) { - initMaterial( object.material[ i ], scene.fog, object ); + initMaterial( object.material[ i ], scene.fog, object ); - } + } - } else { + } else { - initMaterial( object.material, scene.fog, object ); + initMaterial( object.material, scene.fog, object ); - } + } - } + } - } ); + } ); - }; + }; - // Animation Loop + // Animation Loop - var onAnimationFrameCallback = null; + var onAnimationFrameCallback = null; - function onAnimationFrame( time ) { + function onAnimationFrame( time ) { - if ( vr.isPresenting() ) return; - if ( onAnimationFrameCallback ) onAnimationFrameCallback( time ); + if ( vr.isPresenting() ) return; + if ( onAnimationFrameCallback ) onAnimationFrameCallback( time ); - } + } - var animation = new WebGLAnimation(); - animation.setAnimationLoop( onAnimationFrame ); + var animation = new WebGLAnimation(); + animation.setAnimationLoop( onAnimationFrame ); - if ( typeof window !== 'undefined' ) animation.setContext( window ); + if ( typeof window !== 'undefined' ) animation.setContext( window ); - this.setAnimationLoop = function ( callback ) { + this.setAnimationLoop = function ( callback ) { - onAnimationFrameCallback = callback; - vr.setAnimationLoop( callback ); + onAnimationFrameCallback = callback; + vr.setAnimationLoop( callback ); - animation.start(); + animation.start(); - }; + }; - // Rendering + // Rendering - this.render = function ( scene, camera, renderTarget, forceClear ) { + this.render = function ( scene, camera, renderTarget, forceClear ) { - if ( ! ( camera && camera.isCamera ) ) { + if ( ! ( camera && camera.isCamera ) ) { - console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' ); - return; + console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' ); + return; - } + } - if ( _isContextLost ) return; + if ( _isContextLost ) return; - // reset caching for this frame + // reset caching for this frame - _currentGeometryProgram.geometry = null; - _currentGeometryProgram.program = null; - _currentGeometryProgram.wireframe = false; - _currentMaterialId = - 1; - _currentCamera = null; + _currentGeometryProgram.geometry = null; + _currentGeometryProgram.program = null; + _currentGeometryProgram.wireframe = false; + _currentMaterialId = - 1; + _currentCamera = null; - // update scene graph + // update scene graph - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); + if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); - // update camera matrices and frustum + // update camera matrices and frustum - if ( camera.parent === null ) camera.updateMatrixWorld(); + if ( camera.parent === null ) camera.updateMatrixWorld(); - if ( vr.enabled ) { + if ( vr.enabled ) { - camera = vr.getCamera( camera ); + camera = vr.getCamera( camera ); - } + } - // + // - currentRenderState = renderStates.get( scene, camera ); - currentRenderState.init(); + currentRenderState = renderStates.get( scene, camera ); + currentRenderState.init(); - scene.onBeforeRender( _this, scene, camera, renderTarget ); + scene.onBeforeRender( _this, scene, camera, renderTarget ); - _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); - _frustum.setFromMatrix( _projScreenMatrix ); + _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); + _frustum.setFromMatrix( _projScreenMatrix ); - _localClippingEnabled = this.localClippingEnabled; - _clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera ); + _localClippingEnabled = this.localClippingEnabled; + _clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera ); - currentRenderList = renderLists.get( scene, camera ); - currentRenderList.init(); + currentRenderList = renderLists.get( scene, camera ); + currentRenderList.init(); - projectObject( scene, camera, _this.sortObjects ); + projectObject( scene, camera, _this.sortObjects ); - if ( _this.sortObjects === true ) { + if ( _this.sortObjects === true ) { - currentRenderList.sort(); + currentRenderList.sort(); - } + } - // + // - if ( _clippingEnabled ) _clipping.beginShadows(); + if ( _clippingEnabled ) _clipping.beginShadows(); - var shadowsArray = currentRenderState.state.shadowsArray; + var shadowsArray = currentRenderState.state.shadowsArray; - shadowMap.render( shadowsArray, scene, camera ); + shadowMap.render( shadowsArray, scene, camera ); - currentRenderState.setupLights( camera ); + currentRenderState.setupLights( camera ); - if ( _clippingEnabled ) _clipping.endShadows(); + if ( _clippingEnabled ) _clipping.endShadows(); - // + // - if ( this.info.autoReset ) this.info.reset(); + if ( this.info.autoReset ) this.info.reset(); - if ( renderTarget === undefined ) { + if ( renderTarget === undefined ) { - renderTarget = null; + renderTarget = null; - } + } - this.setRenderTarget( renderTarget ); + this.setRenderTarget( renderTarget ); - // + // - background.render( currentRenderList, scene, camera, forceClear ); + background.render( currentRenderList, scene, camera, forceClear ); - // render scene + // render scene - var opaqueObjects = currentRenderList.opaque; - var transparentObjects = currentRenderList.transparent; + var opaqueObjects = currentRenderList.opaque; + var transparentObjects = currentRenderList.transparent; - if ( scene.overrideMaterial ) { + if ( scene.overrideMaterial ) { - var overrideMaterial = scene.overrideMaterial; + var overrideMaterial = scene.overrideMaterial; - if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial ); - if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial ); + if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial ); + if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial ); - } else { + } else { - // opaque pass (front-to-back order) + // opaque pass (front-to-back order) - if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera ); + if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera ); - // transparent pass (back-to-front order) + // transparent pass (back-to-front order) - if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera ); + if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera ); - } + } - // Generate mipmap if we're using any kind of mipmap filtering + // Generate mipmap if we're using any kind of mipmap filtering - if ( renderTarget ) { + if ( renderTarget ) { - textures.updateRenderTargetMipmap( renderTarget ); + textures.updateRenderTargetMipmap( renderTarget ); - } + } - // Ensure depth buffer writing is enabled so it can be cleared on next render + // Ensure depth buffer writing is enabled so it can be cleared on next render - state.buffers.depth.setTest( true ); - state.buffers.depth.setMask( true ); - state.buffers.color.setMask( true ); + state.buffers.depth.setTest( true ); + state.buffers.depth.setMask( true ); + state.buffers.color.setMask( true ); - state.setPolygonOffset( false ); + state.setPolygonOffset( false ); - scene.onAfterRender( _this, scene, camera ); + scene.onAfterRender( _this, scene, camera ); - if ( vr.enabled ) { + if ( vr.enabled ) { - vr.submitFrame(); + vr.submitFrame(); - } + } - // _gl.finish(); + // _gl.finish(); - currentRenderList = null; - currentRenderState = null; + currentRenderList = null; + currentRenderState = null; - }; + }; - /* - // TODO Duplicated code (Frustum) + /* + // TODO Duplicated code (Frustum) - var _sphere = new Sphere(); + var _sphere = new Sphere(); - function isObjectViewable( object ) { + function isObjectViewable( object ) { - var geometry = object.geometry; + var geometry = object.geometry; - if ( geometry.boundingSphere === null ) - geometry.computeBoundingSphere(); + if ( geometry.boundingSphere === null ) + geometry.computeBoundingSphere(); - _sphere.copy( geometry.boundingSphere ). - applyMatrix4( object.matrixWorld ); + _sphere.copy( geometry.boundingSphere ). + applyMatrix4( object.matrixWorld ); - return isSphereViewable( _sphere ); + return isSphereViewable( _sphere ); - } + } - function isSpriteViewable( sprite ) { + function isSpriteViewable( sprite ) { - _sphere.center.set( 0, 0, 0 ); - _sphere.radius = 0.7071067811865476; - _sphere.applyMatrix4( sprite.matrixWorld ); + _sphere.center.set( 0, 0, 0 ); + _sphere.radius = 0.7071067811865476; + _sphere.applyMatrix4( sprite.matrixWorld ); - return isSphereViewable( _sphere ); + return isSphereViewable( _sphere ); - } + } - function isSphereViewable( sphere ) { + function isSphereViewable( sphere ) { - if ( ! _frustum.intersectsSphere( sphere ) ) return false; + if ( ! _frustum.intersectsSphere( sphere ) ) return false; - var numPlanes = _clipping.numPlanes; + var numPlanes = _clipping.numPlanes; - if ( numPlanes === 0 ) return true; + if ( numPlanes === 0 ) return true; - var planes = _this.clippingPlanes, + var planes = _this.clippingPlanes, - center = sphere.center, - negRad = - sphere.radius, - i = 0; + center = sphere.center, + negRad = - sphere.radius, + i = 0; - do { + do { - // out when deeper than radius in the negative halfspace - if ( planes[ i ].distanceToPoint( center ) < negRad ) return false; + // out when deeper than radius in the negative halfspace + if ( planes[ i ].distanceToPoint( center ) < negRad ) return false; - } while ( ++ i !== numPlanes ); + } while ( ++ i !== numPlanes ); - return true; + return true; - } - */ + } + */ - function projectObject( object, camera, sortObjects ) { + function projectObject( object, camera, sortObjects ) { - if ( object.visible === false ) return; + if ( object.visible === false ) return; - var visible = object.layers.test( camera.layers ); + var visible = object.layers.test( camera.layers ); - if ( visible ) { + if ( visible ) { - if ( object.isLight ) { + if ( object.isLight ) { - currentRenderState.pushLight( object ); + currentRenderState.pushLight( object ); - if ( object.castShadow ) { + if ( object.castShadow ) { - currentRenderState.pushShadow( object ); + currentRenderState.pushShadow( object ); - } + } - } else if ( object.isSprite ) { + } else if ( object.isSprite ) { - if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) { + if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) { - if ( sortObjects ) { + if ( sortObjects ) { - _vector3.setFromMatrixPosition( object.matrixWorld ) - .applyMatrix4( _projScreenMatrix ); + _vector3.setFromMatrixPosition( object.matrixWorld ) + .applyMatrix4( _projScreenMatrix ); - } + } - var geometry = objects.update( object ); - var material = object.material; + var geometry = objects.update( object ); + var material = object.material; - currentRenderList.push( object, geometry, material, _vector3.z, null ); + currentRenderList.push( object, geometry, material, _vector3.z, null ); - } + } - } else if ( object.isImmediateRenderObject ) { + } else if ( object.isImmediateRenderObject ) { - if ( sortObjects ) { + if ( sortObjects ) { - _vector3.setFromMatrixPosition( object.matrixWorld ) - .applyMatrix4( _projScreenMatrix ); + _vector3.setFromMatrixPosition( object.matrixWorld ) + .applyMatrix4( _projScreenMatrix ); - } + } - currentRenderList.push( object, null, object.material, _vector3.z, null ); + currentRenderList.push( object, null, object.material, _vector3.z, null ); - } else if ( object.isMesh || object.isLine || object.isPoints ) { + } else if ( object.isMesh || object.isLine || object.isPoints ) { - if ( object.isSkinnedMesh ) { + if ( object.isSkinnedMesh ) { - object.skeleton.update(); + object.skeleton.update(); - } + } - if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) { + if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) { - if ( sortObjects ) { + if ( sortObjects ) { - _vector3.setFromMatrixPosition( object.matrixWorld ) - .applyMatrix4( _projScreenMatrix ); + _vector3.setFromMatrixPosition( object.matrixWorld ) + .applyMatrix4( _projScreenMatrix ); - } + } - var geometry = objects.update( object ); - var material = object.material; + var geometry = objects.update( object ); + var material = object.material; - if ( Array.isArray( material ) ) { + if ( Array.isArray( material ) ) { - var groups = geometry.groups; + var groups = geometry.groups; - for ( var i = 0, l = groups.length; i < l; i ++ ) { + for ( var i = 0, l = groups.length; i < l; i ++ ) { - var group = groups[ i ]; - var groupMaterial = material[ group.materialIndex ]; + var group = groups[ i ]; + var groupMaterial = material[ group.materialIndex ]; - if ( groupMaterial && groupMaterial.visible ) { + if ( groupMaterial && groupMaterial.visible ) { - currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group ); + currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group ); - } + } - } + } - } else if ( material.visible ) { + } else if ( material.visible ) { - currentRenderList.push( object, geometry, material, _vector3.z, null ); + currentRenderList.push( object, geometry, material, _vector3.z, null ); - } + } - } + } - } + } - } + } - var children = object.children; + var children = object.children; - for ( var i = 0, l = children.length; i < l; i ++ ) { + for ( var i = 0, l = children.length; i < l; i ++ ) { - projectObject( children[ i ], camera, sortObjects ); + projectObject( children[ i ], camera, sortObjects ); - } + } - } + } - function renderObjects( renderList, scene, camera, overrideMaterial ) { + function renderObjects( renderList, scene, camera, overrideMaterial ) { - for ( var i = 0, l = renderList.length; i < l; i ++ ) { + for ( var i = 0, l = renderList.length; i < l; i ++ ) { - var renderItem = renderList[ i ]; + var renderItem = renderList[ i ]; - var object = renderItem.object; - var geometry = renderItem.geometry; - var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial; - var group = renderItem.group; + var object = renderItem.object; + var geometry = renderItem.geometry; + var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial; + var group = renderItem.group; - if ( camera.isArrayCamera ) { + if ( camera.isArrayCamera ) { - _currentArrayCamera = camera; + _currentArrayCamera = camera; - var cameras = camera.cameras; + var cameras = camera.cameras; - for ( var j = 0, jl = cameras.length; j < jl; j ++ ) { + for ( var j = 0, jl = cameras.length; j < jl; j ++ ) { - var camera2 = cameras[ j ]; + var camera2 = cameras[ j ]; - if ( object.layers.test( camera2.layers ) ) { + if ( object.layers.test( camera2.layers ) ) { - if ( 'viewport' in camera2 ) { // XR + if ( 'viewport' in camera2 ) { // XR - state.viewport( _currentViewport.copy( camera2.viewport ) ); + state.viewport( _currentViewport.copy( camera2.viewport ) ); - } else { + } else { - var bounds = camera2.bounds; + var bounds = camera2.bounds; - var x = bounds.x * _width; - var y = bounds.y * _height; - var width = bounds.z * _width; - var height = bounds.w * _height; + var x = bounds.x * _width; + var y = bounds.y * _height; + var width = bounds.z * _width; + var height = bounds.w * _height; - state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) ); + state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) ); - } + } - renderObject( object, scene, camera2, geometry, material, group ); + renderObject( object, scene, camera2, geometry, material, group ); - } + } - } + } - } else { + } else { - _currentArrayCamera = null; + _currentArrayCamera = null; - renderObject( object, scene, camera, geometry, material, group ); + renderObject( object, scene, camera, geometry, material, group ); - } + } - } + } - } + } - function renderObject( object, scene, camera, geometry, material, group ) { + function renderObject( object, scene, camera, geometry, material, group ) { - object.onBeforeRender( _this, scene, camera, geometry, material, group ); - currentRenderState = renderStates.get( scene, _currentArrayCamera || camera ); + object.onBeforeRender( _this, scene, camera, geometry, material, group ); + currentRenderState = renderStates.get( scene, _currentArrayCamera || camera ); - object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld ); - object.normalMatrix.getNormalMatrix( object.modelViewMatrix ); + object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld ); + object.normalMatrix.getNormalMatrix( object.modelViewMatrix ); - if ( object.isImmediateRenderObject ) { + if ( object.isImmediateRenderObject ) { - state.setMaterial( material ); + state.setMaterial( material ); - var program = setProgram( camera, scene.fog, material, object ); + var program = setProgram( camera, scene.fog, material, object ); - _currentGeometryProgram.geometry = null; - _currentGeometryProgram.program = null; - _currentGeometryProgram.wireframe = false; + _currentGeometryProgram.geometry = null; + _currentGeometryProgram.program = null; + _currentGeometryProgram.wireframe = false; - renderObjectImmediate( object, program ); + renderObjectImmediate( object, program ); - } else { + } else { - _this.renderBufferDirect( camera, scene.fog, geometry, material, object, group ); + _this.renderBufferDirect( camera, scene.fog, geometry, material, object, group ); - } + } - object.onAfterRender( _this, scene, camera, geometry, material, group ); - currentRenderState = renderStates.get( scene, _currentArrayCamera || camera ); + object.onAfterRender( _this, scene, camera, geometry, material, group ); + currentRenderState = renderStates.get( scene, _currentArrayCamera || camera ); - } + } - function initMaterial( material, fog, object ) { + function initMaterial( material, fog, object ) { - var materialProperties = properties.get( material ); + var materialProperties = properties.get( material ); - var lights = currentRenderState.state.lights; - var shadowsArray = currentRenderState.state.shadowsArray; + var lights = currentRenderState.state.lights; + var shadowsArray = currentRenderState.state.shadowsArray; - var lightsHash = materialProperties.lightsHash; - var lightsStateHash = lights.state.hash; + var lightsHash = materialProperties.lightsHash; + var lightsStateHash = lights.state.hash; - var parameters = programCache.getParameters( - material, lights.state, shadowsArray, fog, _clipping.numPlanes, _clipping.numIntersection, object ); + var parameters = programCache.getParameters( + material, lights.state, shadowsArray, fog, _clipping.numPlanes, _clipping.numIntersection, object ); - var code = programCache.getProgramCode( material, parameters ); + var code = programCache.getProgramCode( material, parameters ); - var program = materialProperties.program; - var programChange = true; + var program = materialProperties.program; + var programChange = true; - if ( program === undefined ) { + if ( program === undefined ) { - // new material - material.addEventListener( 'dispose', onMaterialDispose ); + // new material + material.addEventListener( 'dispose', onMaterialDispose ); - } else if ( program.code !== code ) { + } else if ( program.code !== code ) { - // changed glsl or parameters - releaseMaterialProgramReference( material ); + // changed glsl or parameters + releaseMaterialProgramReference( material ); - } else if ( lightsHash.stateID !== lightsStateHash.stateID || - lightsHash.directionalLength !== lightsStateHash.directionalLength || - lightsHash.pointLength !== lightsStateHash.pointLength || - lightsHash.spotLength !== lightsStateHash.spotLength || - lightsHash.rectAreaLength !== lightsStateHash.rectAreaLength || - lightsHash.hemiLength !== lightsStateHash.hemiLength || - lightsHash.shadowsLength !== lightsStateHash.shadowsLength ) { + } else if ( lightsHash.stateID !== lightsStateHash.stateID || + lightsHash.directionalLength !== lightsStateHash.directionalLength || + lightsHash.pointLength !== lightsStateHash.pointLength || + lightsHash.spotLength !== lightsStateHash.spotLength || + lightsHash.rectAreaLength !== lightsStateHash.rectAreaLength || + lightsHash.hemiLength !== lightsStateHash.hemiLength || + lightsHash.shadowsLength !== lightsStateHash.shadowsLength ) { - lightsHash.stateID = lightsStateHash.stateID; - lightsHash.directionalLength = lightsStateHash.directionalLength; - lightsHash.pointLength = lightsStateHash.pointLength; - lightsHash.spotLength = lightsStateHash.spotLength; - lightsHash.rectAreaLength = lightsStateHash.rectAreaLength; - lightsHash.hemiLength = lightsStateHash.hemiLength; - lightsHash.shadowsLength = lightsStateHash.shadowsLength; + lightsHash.stateID = lightsStateHash.stateID; + lightsHash.directionalLength = lightsStateHash.directionalLength; + lightsHash.pointLength = lightsStateHash.pointLength; + lightsHash.spotLength = lightsStateHash.spotLength; + lightsHash.rectAreaLength = lightsStateHash.rectAreaLength; + lightsHash.hemiLength = lightsStateHash.hemiLength; + lightsHash.shadowsLength = lightsStateHash.shadowsLength; - programChange = false; + programChange = false; - } else if ( parameters.shaderID !== undefined ) { + } else if ( parameters.shaderID !== undefined ) { - // same glsl and uniform list - return; + // same glsl and uniform list + return; - } else { + } else { - // only rebuild uniform list - programChange = false; + // only rebuild uniform list + programChange = false; - } + } - if ( programChange ) { + if ( programChange ) { - if ( parameters.shaderID ) { + if ( parameters.shaderID ) { - var shader = ShaderLib[ parameters.shaderID ]; + var shader = ShaderLib[ parameters.shaderID ]; - materialProperties.shader = { - name: material.type, - uniforms: UniformsUtils.clone( shader.uniforms ), - vertexShader: shader.vertexShader, - fragmentShader: shader.fragmentShader - }; + materialProperties.shader = { + name: material.type, + uniforms: UniformsUtils.clone( shader.uniforms ), + vertexShader: shader.vertexShader, + fragmentShader: shader.fragmentShader + }; - } else { + } else { - materialProperties.shader = { - name: material.type, - uniforms: material.uniforms, - vertexShader: material.vertexShader, - fragmentShader: material.fragmentShader - }; + materialProperties.shader = { + name: material.type, + uniforms: material.uniforms, + vertexShader: material.vertexShader, + fragmentShader: material.fragmentShader + }; - } + } - material.onBeforeCompile( materialProperties.shader, _this ); + material.onBeforeCompile( materialProperties.shader, _this ); - // Computing code again as onBeforeCompile may have changed the shaders - code = programCache.getProgramCode( material, parameters ); + // Computing code again as onBeforeCompile may have changed the shaders + code = programCache.getProgramCode( material, parameters ); - program = programCache.acquireProgram( material, materialProperties.shader, parameters, code ); + program = programCache.acquireProgram( material, materialProperties.shader, parameters, code ); - materialProperties.program = program; - material.program = program; + materialProperties.program = program; + material.program = program; - } + } - var programAttributes = program.getAttributes(); + var programAttributes = program.getAttributes(); - if ( material.morphTargets ) { + if ( material.morphTargets ) { - material.numSupportedMorphTargets = 0; + material.numSupportedMorphTargets = 0; - for ( var i = 0; i < _this.maxMorphTargets; i ++ ) { + for ( var i = 0; i < _this.maxMorphTargets; i ++ ) { - if ( programAttributes[ 'morphTarget' + i ] >= 0 ) { + if ( programAttributes[ 'morphTarget' + i ] >= 0 ) { - material.numSupportedMorphTargets ++; + material.numSupportedMorphTargets ++; - } + } - } + } - } + } - if ( material.morphNormals ) { + if ( material.morphNormals ) { - material.numSupportedMorphNormals = 0; + material.numSupportedMorphNormals = 0; - for ( var i = 0; i < _this.maxMorphNormals; i ++ ) { + for ( var i = 0; i < _this.maxMorphNormals; i ++ ) { - if ( programAttributes[ 'morphNormal' + i ] >= 0 ) { + if ( programAttributes[ 'morphNormal' + i ] >= 0 ) { - material.numSupportedMorphNormals ++; + material.numSupportedMorphNormals ++; - } + } - } + } - } + } - var uniforms = materialProperties.shader.uniforms; + var uniforms = materialProperties.shader.uniforms; - if ( ! material.isShaderMaterial && - ! material.isRawShaderMaterial || - material.clipping === true ) { + if ( ! material.isShaderMaterial && + ! material.isRawShaderMaterial || + material.clipping === true ) { - materialProperties.numClippingPlanes = _clipping.numPlanes; - materialProperties.numIntersection = _clipping.numIntersection; - uniforms.clippingPlanes = _clipping.uniform; + materialProperties.numClippingPlanes = _clipping.numPlanes; + materialProperties.numIntersection = _clipping.numIntersection; + uniforms.clippingPlanes = _clipping.uniform; - } + } - materialProperties.fog = fog; + materialProperties.fog = fog; - // store the light setup it was created for - if ( lightsHash === undefined ) { + // store the light setup it was created for + if ( lightsHash === undefined ) { - materialProperties.lightsHash = lightsHash = {}; + materialProperties.lightsHash = lightsHash = {}; - } + } - lightsHash.stateID = lightsStateHash.stateID; - lightsHash.directionalLength = lightsStateHash.directionalLength; - lightsHash.pointLength = lightsStateHash.pointLength; - lightsHash.spotLength = lightsStateHash.spotLength; - lightsHash.rectAreaLength = lightsStateHash.rectAreaLength; - lightsHash.hemiLength = lightsStateHash.hemiLength; - lightsHash.shadowsLength = lightsStateHash.shadowsLength; + lightsHash.stateID = lightsStateHash.stateID; + lightsHash.directionalLength = lightsStateHash.directionalLength; + lightsHash.pointLength = lightsStateHash.pointLength; + lightsHash.spotLength = lightsStateHash.spotLength; + lightsHash.rectAreaLength = lightsStateHash.rectAreaLength; + lightsHash.hemiLength = lightsStateHash.hemiLength; + lightsHash.shadowsLength = lightsStateHash.shadowsLength; - if ( material.lights ) { + if ( material.lights ) { - // wire up the material to this renderer's lighting state + // wire up the material to this renderer's lighting state - uniforms.ambientLightColor.value = lights.state.ambient; - uniforms.directionalLights.value = lights.state.directional; - uniforms.spotLights.value = lights.state.spot; - uniforms.rectAreaLights.value = lights.state.rectArea; - uniforms.pointLights.value = lights.state.point; - uniforms.hemisphereLights.value = lights.state.hemi; + uniforms.ambientLightColor.value = lights.state.ambient; + uniforms.directionalLights.value = lights.state.directional; + uniforms.spotLights.value = lights.state.spot; + uniforms.rectAreaLights.value = lights.state.rectArea; + uniforms.pointLights.value = lights.state.point; + uniforms.hemisphereLights.value = lights.state.hemi; - uniforms.directionalShadowMap.value = lights.state.directionalShadowMap; - uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix; - uniforms.spotShadowMap.value = lights.state.spotShadowMap; - uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix; - uniforms.pointShadowMap.value = lights.state.pointShadowMap; - uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; - // TODO (abelnation): add area lights shadow info to uniforms + uniforms.directionalShadowMap.value = lights.state.directionalShadowMap; + uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix; + uniforms.spotShadowMap.value = lights.state.spotShadowMap; + uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix; + uniforms.pointShadowMap.value = lights.state.pointShadowMap; + uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; + // TODO (abelnation): add area lights shadow info to uniforms - } + } - var progUniforms = materialProperties.program.getUniforms(), - uniformsList = - WebGLUniforms.seqWithValue( progUniforms.seq, uniforms ); + var progUniforms = materialProperties.program.getUniforms(), + uniformsList = + WebGLUniforms.seqWithValue( progUniforms.seq, uniforms ); - materialProperties.uniformsList = uniformsList; + materialProperties.uniformsList = uniformsList; - } + } - function setProgram( camera, fog, material, object ) { + function setProgram( camera, fog, material, object ) { - _usedTextureUnits = 0; + _usedTextureUnits = 0; - var materialProperties = properties.get( material ); - var lights = currentRenderState.state.lights; + var materialProperties = properties.get( material ); + var lights = currentRenderState.state.lights; - var lightsHash = materialProperties.lightsHash; - var lightsStateHash = lights.state.hash; + var lightsHash = materialProperties.lightsHash; + var lightsStateHash = lights.state.hash; - if ( _clippingEnabled ) { + if ( _clippingEnabled ) { - if ( _localClippingEnabled || camera !== _currentCamera ) { + if ( _localClippingEnabled || camera !== _currentCamera ) { - var useCache = - camera === _currentCamera && - material.id === _currentMaterialId; + var useCache = + camera === _currentCamera && + material.id === _currentMaterialId; - // we might want to call this function with some ClippingGroup - // object instead of the material, once it becomes feasible - // (#8465, #8379) - _clipping.setState( - material.clippingPlanes, material.clipIntersection, material.clipShadows, - camera, materialProperties, useCache ); + // we might want to call this function with some ClippingGroup + // object instead of the material, once it becomes feasible + // (#8465, #8379) + _clipping.setState( + material.clippingPlanes, material.clipIntersection, material.clipShadows, + camera, materialProperties, useCache ); - } + } - } + } - if ( material.needsUpdate === false ) { + if ( material.needsUpdate === false ) { - if ( materialProperties.program === undefined ) { + if ( materialProperties.program === undefined ) { - material.needsUpdate = true; + material.needsUpdate = true; - } else if ( material.fog && materialProperties.fog !== fog ) { + } else if ( material.fog && materialProperties.fog !== fog ) { - material.needsUpdate = true; + material.needsUpdate = true; - } else if ( material.lights && ( lightsHash.stateID !== lightsStateHash.stateID || - lightsHash.directionalLength !== lightsStateHash.directionalLength || - lightsHash.pointLength !== lightsStateHash.pointLength || - lightsHash.spotLength !== lightsStateHash.spotLength || - lightsHash.rectAreaLength !== lightsStateHash.rectAreaLength || - lightsHash.hemiLength !== lightsStateHash.hemiLength || - lightsHash.shadowsLength !== lightsStateHash.shadowsLength ) ) { + } else if ( material.lights && ( lightsHash.stateID !== lightsStateHash.stateID || + lightsHash.directionalLength !== lightsStateHash.directionalLength || + lightsHash.pointLength !== lightsStateHash.pointLength || + lightsHash.spotLength !== lightsStateHash.spotLength || + lightsHash.rectAreaLength !== lightsStateHash.rectAreaLength || + lightsHash.hemiLength !== lightsStateHash.hemiLength || + lightsHash.shadowsLength !== lightsStateHash.shadowsLength ) ) { - material.needsUpdate = true; + material.needsUpdate = true; - } else if ( materialProperties.numClippingPlanes !== undefined && - ( materialProperties.numClippingPlanes !== _clipping.numPlanes || - materialProperties.numIntersection !== _clipping.numIntersection ) ) { + } else if ( materialProperties.numClippingPlanes !== undefined && + ( materialProperties.numClippingPlanes !== _clipping.numPlanes || + materialProperties.numIntersection !== _clipping.numIntersection ) ) { - material.needsUpdate = true; + material.needsUpdate = true; - } + } - } + } - if ( material.needsUpdate ) { + if ( material.needsUpdate ) { - initMaterial( material, fog, object ); - material.needsUpdate = false; + initMaterial( material, fog, object ); + material.needsUpdate = false; - } + } - var refreshProgram = false; - var refreshMaterial = false; - var refreshLights = false; + var refreshProgram = false; + var refreshMaterial = false; + var refreshLights = false; - var program = materialProperties.program, - p_uniforms = program.getUniforms(), - m_uniforms = materialProperties.shader.uniforms; + var program = materialProperties.program, + p_uniforms = program.getUniforms(), + m_uniforms = materialProperties.shader.uniforms; - if ( state.useProgram( program.program ) ) { + if ( state.useProgram( program.program ) ) { - refreshProgram = true; - refreshMaterial = true; - refreshLights = true; + refreshProgram = true; + refreshMaterial = true; + refreshLights = true; - } + } - if ( material.id !== _currentMaterialId ) { + if ( material.id !== _currentMaterialId ) { - _currentMaterialId = material.id; + _currentMaterialId = material.id; - refreshMaterial = true; + refreshMaterial = true; - } + } - if ( refreshProgram || camera !== _currentCamera ) { + if ( refreshProgram || camera !== _currentCamera ) { - p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix ); + p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix ); - if ( capabilities.logarithmicDepthBuffer ) { + if ( capabilities.logarithmicDepthBuffer ) { - p_uniforms.setValue( _gl, 'logDepthBufFC', - 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) ); + p_uniforms.setValue( _gl, 'logDepthBufFC', + 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) ); - } + } - // Avoid unneeded uniform updates per ArrayCamera's sub-camera + // Avoid unneeded uniform updates per ArrayCamera's sub-camera - if ( _currentCamera !== ( _currentArrayCamera || camera ) ) { + if ( _currentCamera !== ( _currentArrayCamera || camera ) ) { - _currentCamera = ( _currentArrayCamera || camera ); + _currentCamera = ( _currentArrayCamera || camera ); - // lighting uniforms depend on the camera so enforce an update - // now, in case this material supports lights - or later, when - // the next material that does gets activated: + // lighting uniforms depend on the camera so enforce an update + // now, in case this material supports lights - or later, when + // the next material that does gets activated: - refreshMaterial = true; // set to true on material change - refreshLights = true; // remains set until update done + refreshMaterial = true; // set to true on material change + refreshLights = true; // remains set until update done - } + } - // load material specific uniforms - // (shader material also gets them for the sake of genericity) + // load material specific uniforms + // (shader material also gets them for the sake of genericity) - if ( material.isShaderMaterial || - material.isMeshPhongMaterial || - material.isMeshStandardMaterial || - material.envMap ) { + if ( material.isShaderMaterial || + material.isMeshPhongMaterial || + material.isMeshStandardMaterial || + material.envMap ) { - var uCamPos = p_uniforms.map.cameraPosition; + var uCamPos = p_uniforms.map.cameraPosition; - if ( uCamPos !== undefined ) { + if ( uCamPos !== undefined ) { - uCamPos.setValue( _gl, - _vector3.setFromMatrixPosition( camera.matrixWorld ) ); + uCamPos.setValue( _gl, + _vector3.setFromMatrixPosition( camera.matrixWorld ) ); - } + } - } + } - if ( material.isMeshPhongMaterial || - material.isMeshLambertMaterial || - material.isMeshBasicMaterial || - material.isMeshStandardMaterial || - material.isShaderMaterial || - material.skinning ) { + if ( material.isMeshPhongMaterial || + material.isMeshLambertMaterial || + material.isMeshBasicMaterial || + material.isMeshStandardMaterial || + material.isShaderMaterial || + material.skinning ) { - p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse ); + p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse ); - } + } - } + } - // skinning uniforms must be set even if material didn't change - // auto-setting of texture unit for bone texture must go before other textures - // not sure why, but otherwise weird things happen + // skinning uniforms must be set even if material didn't change + // auto-setting of texture unit for bone texture must go before other textures + // not sure why, but otherwise weird things happen - if ( material.skinning ) { + if ( material.skinning ) { - p_uniforms.setOptional( _gl, object, 'bindMatrix' ); - p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' ); + p_uniforms.setOptional( _gl, object, 'bindMatrix' ); + p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' ); - var skeleton = object.skeleton; + var skeleton = object.skeleton; - if ( skeleton ) { + if ( skeleton ) { - var bones = skeleton.bones; + var bones = skeleton.bones; - if ( capabilities.floatVertexTextures ) { + if ( capabilities.floatVertexTextures ) { - if ( skeleton.boneTexture === undefined ) { + if ( skeleton.boneTexture === undefined ) { - // layout (1 matrix = 4 pixels) - // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4) - // with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8) - // 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16) - // 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32) - // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64) + // layout (1 matrix = 4 pixels) + // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4) + // with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8) + // 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16) + // 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32) + // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64) - var size = Math.sqrt( bones.length * 4 ); // 4 pixels needed for 1 matrix - size = _Math.ceilPowerOfTwo( size ); - size = Math.max( size, 4 ); + var size = Math.sqrt( bones.length * 4 ); // 4 pixels needed for 1 matrix + size = _Math.ceilPowerOfTwo( size ); + size = Math.max( size, 4 ); - var boneMatrices = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel - boneMatrices.set( skeleton.boneMatrices ); // copy current values + var boneMatrices = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel + boneMatrices.set( skeleton.boneMatrices ); // copy current values - var boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType ); - boneTexture.needsUpdate = true; + var boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType ); + boneTexture.needsUpdate = true; - skeleton.boneMatrices = boneMatrices; - skeleton.boneTexture = boneTexture; - skeleton.boneTextureSize = size; + skeleton.boneMatrices = boneMatrices; + skeleton.boneTexture = boneTexture; + skeleton.boneTextureSize = size; - } + } - p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture ); - p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize ); + p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture ); + p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize ); - } else { + } else { - p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' ); + p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' ); - } + } - } + } - } + } - if ( refreshMaterial ) { + if ( refreshMaterial ) { - p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure ); - p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint ); + p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure ); + p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint ); - if ( material.lights ) { + if ( material.lights ) { - // the current material requires lighting info + // the current material requires lighting info - // note: all lighting uniforms are always set correctly - // they simply reference the renderer's state for their - // values - // - // use the current material's .needsUpdate flags to set - // the GL state when required + // note: all lighting uniforms are always set correctly + // they simply reference the renderer's state for their + // values + // + // use the current material's .needsUpdate flags to set + // the GL state when required - markUniformsLightsNeedsUpdate( m_uniforms, refreshLights ); + markUniformsLightsNeedsUpdate( m_uniforms, refreshLights ); - } + } - // refresh uniforms common to several materials + // refresh uniforms common to several materials - if ( fog && material.fog ) { + if ( fog && material.fog ) { - refreshUniformsFog( m_uniforms, fog ); + refreshUniformsFog( m_uniforms, fog ); - } + } - if ( material.isMeshBasicMaterial ) { + if ( material.isMeshBasicMaterial ) { - refreshUniformsCommon( m_uniforms, material ); + refreshUniformsCommon( m_uniforms, material ); - } else if ( material.isMeshLambertMaterial ) { + } else if ( material.isMeshLambertMaterial ) { - refreshUniformsCommon( m_uniforms, material ); - refreshUniformsLambert( m_uniforms, material ); + refreshUniformsCommon( m_uniforms, material ); + refreshUniformsLambert( m_uniforms, material ); - } else if ( material.isMeshPhongMaterial ) { + } else if ( material.isMeshPhongMaterial ) { - refreshUniformsCommon( m_uniforms, material ); + refreshUniformsCommon( m_uniforms, material ); - if ( material.isMeshToonMaterial ) { + if ( material.isMeshToonMaterial ) { - refreshUniformsToon( m_uniforms, material ); + refreshUniformsToon( m_uniforms, material ); - } else { + } else { - refreshUniformsPhong( m_uniforms, material ); + refreshUniformsPhong( m_uniforms, material ); - } + } - } else if ( material.isMeshStandardMaterial ) { + } else if ( material.isMeshStandardMaterial ) { - refreshUniformsCommon( m_uniforms, material ); + refreshUniformsCommon( m_uniforms, material ); - if ( material.isMeshPhysicalMaterial ) { + if ( material.isMeshPhysicalMaterial ) { - refreshUniformsPhysical( m_uniforms, material ); + refreshUniformsPhysical( m_uniforms, material ); - } else { + } else { - refreshUniformsStandard( m_uniforms, material ); + refreshUniformsStandard( m_uniforms, material ); - } + } - } else if ( material.isMeshDepthMaterial ) { + } else if ( material.isMeshDepthMaterial ) { - refreshUniformsCommon( m_uniforms, material ); - refreshUniformsDepth( m_uniforms, material ); + refreshUniformsCommon( m_uniforms, material ); + refreshUniformsDepth( m_uniforms, material ); - } else if ( material.isMeshDistanceMaterial ) { + } else if ( material.isMeshDistanceMaterial ) { - refreshUniformsCommon( m_uniforms, material ); - refreshUniformsDistance( m_uniforms, material ); + refreshUniformsCommon( m_uniforms, material ); + refreshUniformsDistance( m_uniforms, material ); - } else if ( material.isMeshNormalMaterial ) { + } else if ( material.isMeshNormalMaterial ) { - refreshUniformsCommon( m_uniforms, material ); - refreshUniformsNormal( m_uniforms, material ); + refreshUniformsCommon( m_uniforms, material ); + refreshUniformsNormal( m_uniforms, material ); - } else if ( material.isLineBasicMaterial ) { + } else if ( material.isLineBasicMaterial ) { - refreshUniformsLine( m_uniforms, material ); + refreshUniformsLine( m_uniforms, material ); - if ( material.isLineDashedMaterial ) { + if ( material.isLineDashedMaterial ) { - refreshUniformsDash( m_uniforms, material ); + refreshUniformsDash( m_uniforms, material ); - } + } - } else if ( material.isPointsMaterial ) { + } else if ( material.isPointsMaterial ) { - refreshUniformsPoints( m_uniforms, material ); + refreshUniformsPoints( m_uniforms, material ); - } else if ( material.isSpriteMaterial ) { + } else if ( material.isSpriteMaterial ) { - refreshUniformsSprites( m_uniforms, material ); + refreshUniformsSprites( m_uniforms, material ); - } else if ( material.isShadowMaterial ) { + } else if ( material.isShadowMaterial ) { - m_uniforms.color.value = material.color; - m_uniforms.opacity.value = material.opacity; + m_uniforms.color.value = material.color; + m_uniforms.opacity.value = material.opacity; - } + } - // RectAreaLight Texture - // TODO (mrdoob): Find a nicer implementation + // RectAreaLight Texture + // TODO (mrdoob): Find a nicer implementation - if ( m_uniforms.ltc_1 !== undefined ) m_uniforms.ltc_1.value = UniformsLib.LTC_1; - if ( m_uniforms.ltc_2 !== undefined ) m_uniforms.ltc_2.value = UniformsLib.LTC_2; + if ( m_uniforms.ltc_1 !== undefined ) m_uniforms.ltc_1.value = UniformsLib.LTC_1; + if ( m_uniforms.ltc_2 !== undefined ) m_uniforms.ltc_2.value = UniformsLib.LTC_2; - WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, _this ); + WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, _this ); - } + } - if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) { + if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) { - WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, _this ); - material.uniformsNeedUpdate = false; + WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, _this ); + material.uniformsNeedUpdate = false; - } + } - if ( material.isSpriteMaterial ) { + if ( material.isSpriteMaterial ) { - p_uniforms.setValue( _gl, 'center', object.center ); + p_uniforms.setValue( _gl, 'center', object.center ); - } + } - // common matrices + // common matrices - p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix ); - p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix ); - p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld ); + p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix ); + p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix ); + p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld ); - return program; + return program; - } + } - // Uniforms (refresh uniforms objects) + // Uniforms (refresh uniforms objects) - function refreshUniformsCommon( uniforms, material ) { + function refreshUniformsCommon( uniforms, material ) { - uniforms.opacity.value = material.opacity; + uniforms.opacity.value = material.opacity; - if ( material.color ) { + if ( material.color ) { - uniforms.diffuse.value = material.color; + uniforms.diffuse.value = material.color; - } + } - if ( material.emissive ) { + if ( material.emissive ) { - uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity ); + uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity ); - } + } - if ( material.map ) { + if ( material.map ) { - uniforms.map.value = material.map; + uniforms.map.value = material.map; - } + } - if ( material.alphaMap ) { + if ( material.alphaMap ) { - uniforms.alphaMap.value = material.alphaMap; + uniforms.alphaMap.value = material.alphaMap; - } + } - if ( material.specularMap ) { + if ( material.specularMap ) { - uniforms.specularMap.value = material.specularMap; + uniforms.specularMap.value = material.specularMap; - } + } - if ( material.envMap ) { + if ( material.envMap ) { - uniforms.envMap.value = material.envMap; + uniforms.envMap.value = material.envMap; - // don't flip CubeTexture envMaps, flip everything else: - // WebGLRenderTargetCube will be flipped for backwards compatibility - // WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture - // this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future - uniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1; + // don't flip CubeTexture envMaps, flip everything else: + // WebGLRenderTargetCube will be flipped for backwards compatibility + // WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture + // this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future + uniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1; - uniforms.reflectivity.value = material.reflectivity; - uniforms.refractionRatio.value = material.refractionRatio; + uniforms.reflectivity.value = material.reflectivity; + uniforms.refractionRatio.value = material.refractionRatio; - uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel; + uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel; - } + } - if ( material.lightMap ) { + if ( material.lightMap ) { - uniforms.lightMap.value = material.lightMap; - uniforms.lightMapIntensity.value = material.lightMapIntensity; + uniforms.lightMap.value = material.lightMap; + uniforms.lightMapIntensity.value = material.lightMapIntensity; - } + } - if ( material.aoMap ) { + if ( material.aoMap ) { - uniforms.aoMap.value = material.aoMap; - uniforms.aoMapIntensity.value = material.aoMapIntensity; + uniforms.aoMap.value = material.aoMap; + uniforms.aoMapIntensity.value = material.aoMapIntensity; - } + } - // uv repeat and offset setting priorities - // 1. color map - // 2. specular map - // 3. normal map - // 4. bump map - // 5. alpha map - // 6. emissive map + // uv repeat and offset setting priorities + // 1. color map + // 2. specular map + // 3. normal map + // 4. bump map + // 5. alpha map + // 6. emissive map - var uvScaleMap; + var uvScaleMap; - if ( material.map ) { + if ( material.map ) { - uvScaleMap = material.map; + uvScaleMap = material.map; - } else if ( material.specularMap ) { + } else if ( material.specularMap ) { - uvScaleMap = material.specularMap; + uvScaleMap = material.specularMap; - } else if ( material.displacementMap ) { + } else if ( material.displacementMap ) { - uvScaleMap = material.displacementMap; + uvScaleMap = material.displacementMap; - } else if ( material.normalMap ) { + } else if ( material.normalMap ) { - uvScaleMap = material.normalMap; + uvScaleMap = material.normalMap; - } else if ( material.bumpMap ) { + } else if ( material.bumpMap ) { - uvScaleMap = material.bumpMap; + uvScaleMap = material.bumpMap; - } else if ( material.roughnessMap ) { + } else if ( material.roughnessMap ) { - uvScaleMap = material.roughnessMap; + uvScaleMap = material.roughnessMap; - } else if ( material.metalnessMap ) { + } else if ( material.metalnessMap ) { - uvScaleMap = material.metalnessMap; + uvScaleMap = material.metalnessMap; - } else if ( material.alphaMap ) { + } else if ( material.alphaMap ) { - uvScaleMap = material.alphaMap; + uvScaleMap = material.alphaMap; - } else if ( material.emissiveMap ) { + } else if ( material.emissiveMap ) { - uvScaleMap = material.emissiveMap; + uvScaleMap = material.emissiveMap; - } + } - if ( uvScaleMap !== undefined ) { + if ( uvScaleMap !== undefined ) { - // backwards compatibility - if ( uvScaleMap.isWebGLRenderTarget ) { + // backwards compatibility + if ( uvScaleMap.isWebGLRenderTarget ) { - uvScaleMap = uvScaleMap.texture; + uvScaleMap = uvScaleMap.texture; - } + } - if ( uvScaleMap.matrixAutoUpdate === true ) { + if ( uvScaleMap.matrixAutoUpdate === true ) { - uvScaleMap.updateMatrix(); + uvScaleMap.updateMatrix(); - } + } - uniforms.uvTransform.value.copy( uvScaleMap.matrix ); + uniforms.uvTransform.value.copy( uvScaleMap.matrix ); - } + } - } + } - function refreshUniformsLine( uniforms, material ) { + function refreshUniformsLine( uniforms, material ) { - uniforms.diffuse.value = material.color; - uniforms.opacity.value = material.opacity; + uniforms.diffuse.value = material.color; + uniforms.opacity.value = material.opacity; - } + } - function refreshUniformsDash( uniforms, material ) { + function refreshUniformsDash( uniforms, material ) { - uniforms.dashSize.value = material.dashSize; - uniforms.totalSize.value = material.dashSize + material.gapSize; - uniforms.scale.value = material.scale; + uniforms.dashSize.value = material.dashSize; + uniforms.totalSize.value = material.dashSize + material.gapSize; + uniforms.scale.value = material.scale; - } + } - function refreshUniformsPoints( uniforms, material ) { + function refreshUniformsPoints( uniforms, material ) { - uniforms.diffuse.value = material.color; - uniforms.opacity.value = material.opacity; - uniforms.size.value = material.size * _pixelRatio; - uniforms.scale.value = _height * 0.5; + uniforms.diffuse.value = material.color; + uniforms.opacity.value = material.opacity; + uniforms.size.value = material.size * _pixelRatio; + uniforms.scale.value = _height * 0.5; - uniforms.map.value = material.map; + uniforms.map.value = material.map; - if ( material.map !== null ) { + if ( material.map !== null ) { - if ( material.map.matrixAutoUpdate === true ) { + if ( material.map.matrixAutoUpdate === true ) { - material.map.updateMatrix(); + material.map.updateMatrix(); - } + } - uniforms.uvTransform.value.copy( material.map.matrix ); + uniforms.uvTransform.value.copy( material.map.matrix ); - } + } - } + } - function refreshUniformsSprites( uniforms, material ) { + function refreshUniformsSprites( uniforms, material ) { - uniforms.diffuse.value = material.color; - uniforms.opacity.value = material.opacity; - uniforms.rotation.value = material.rotation; - uniforms.map.value = material.map; + uniforms.diffuse.value = material.color; + uniforms.opacity.value = material.opacity; + uniforms.rotation.value = material.rotation; + uniforms.map.value = material.map; - if ( material.map !== null ) { + if ( material.map !== null ) { - if ( material.map.matrixAutoUpdate === true ) { + if ( material.map.matrixAutoUpdate === true ) { - material.map.updateMatrix(); + material.map.updateMatrix(); - } + } - uniforms.uvTransform.value.copy( material.map.matrix ); + uniforms.uvTransform.value.copy( material.map.matrix ); - } + } - } + } - function refreshUniformsFog( uniforms, fog ) { + function refreshUniformsFog( uniforms, fog ) { - uniforms.fogColor.value = fog.color; + uniforms.fogColor.value = fog.color; - if ( fog.isFog ) { + if ( fog.isFog ) { - uniforms.fogNear.value = fog.near; - uniforms.fogFar.value = fog.far; + uniforms.fogNear.value = fog.near; + uniforms.fogFar.value = fog.far; - } else if ( fog.isFogExp2 ) { + } else if ( fog.isFogExp2 ) { - uniforms.fogDensity.value = fog.density; + uniforms.fogDensity.value = fog.density; - } + } - } + } - function refreshUniformsLambert( uniforms, material ) { + function refreshUniformsLambert( uniforms, material ) { - if ( material.emissiveMap ) { + if ( material.emissiveMap ) { - uniforms.emissiveMap.value = material.emissiveMap; + uniforms.emissiveMap.value = material.emissiveMap; - } + } - } + } - function refreshUniformsPhong( uniforms, material ) { + function refreshUniformsPhong( uniforms, material ) { - uniforms.specular.value = material.specular; - uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 ) + uniforms.specular.value = material.specular; + uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 ) - if ( material.emissiveMap ) { + if ( material.emissiveMap ) { - uniforms.emissiveMap.value = material.emissiveMap; + uniforms.emissiveMap.value = material.emissiveMap; - } + } - if ( material.bumpMap ) { + if ( material.bumpMap ) { - uniforms.bumpMap.value = material.bumpMap; - uniforms.bumpScale.value = material.bumpScale; - if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; + uniforms.bumpMap.value = material.bumpMap; + uniforms.bumpScale.value = material.bumpScale; + if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; - } + } - if ( material.normalMap ) { + if ( material.normalMap ) { - uniforms.normalMap.value = material.normalMap; - uniforms.normalScale.value.copy( material.normalScale ); - if ( material.side === BackSide ) uniforms.normalScale.value.negate(); + uniforms.normalMap.value = material.normalMap; + uniforms.normalScale.value.copy( material.normalScale ); + if ( material.side === BackSide ) uniforms.normalScale.value.negate(); - } + } - if ( material.displacementMap ) { + if ( material.displacementMap ) { - uniforms.displacementMap.value = material.displacementMap; - uniforms.displacementScale.value = material.displacementScale; - uniforms.displacementBias.value = material.displacementBias; + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; - } + } - } + } - function refreshUniformsToon( uniforms, material ) { + function refreshUniformsToon( uniforms, material ) { - refreshUniformsPhong( uniforms, material ); + refreshUniformsPhong( uniforms, material ); - if ( material.gradientMap ) { + if ( material.gradientMap ) { - uniforms.gradientMap.value = material.gradientMap; + uniforms.gradientMap.value = material.gradientMap; - } + } - } + } - function refreshUniformsStandard( uniforms, material ) { + function refreshUniformsStandard( uniforms, material ) { - uniforms.roughness.value = material.roughness; - uniforms.metalness.value = material.metalness; + uniforms.roughness.value = material.roughness; + uniforms.metalness.value = material.metalness; - if ( material.roughnessMap ) { + if ( material.roughnessMap ) { - uniforms.roughnessMap.value = material.roughnessMap; + uniforms.roughnessMap.value = material.roughnessMap; - } + } - if ( material.metalnessMap ) { + if ( material.metalnessMap ) { - uniforms.metalnessMap.value = material.metalnessMap; + uniforms.metalnessMap.value = material.metalnessMap; - } + } - if ( material.emissiveMap ) { + if ( material.emissiveMap ) { - uniforms.emissiveMap.value = material.emissiveMap; + uniforms.emissiveMap.value = material.emissiveMap; - } + } - if ( material.bumpMap ) { + if ( material.bumpMap ) { - uniforms.bumpMap.value = material.bumpMap; - uniforms.bumpScale.value = material.bumpScale; - if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; + uniforms.bumpMap.value = material.bumpMap; + uniforms.bumpScale.value = material.bumpScale; + if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; - } + } - if ( material.normalMap ) { + if ( material.normalMap ) { - uniforms.normalMap.value = material.normalMap; - uniforms.normalScale.value.copy( material.normalScale ); - if ( material.side === BackSide ) uniforms.normalScale.value.negate(); + uniforms.normalMap.value = material.normalMap; + uniforms.normalScale.value.copy( material.normalScale ); + if ( material.side === BackSide ) uniforms.normalScale.value.negate(); - } + } - if ( material.displacementMap ) { + if ( material.displacementMap ) { - uniforms.displacementMap.value = material.displacementMap; - uniforms.displacementScale.value = material.displacementScale; - uniforms.displacementBias.value = material.displacementBias; + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; - } + } - if ( material.envMap ) { + if ( material.envMap ) { - //uniforms.envMap.value = material.envMap; // part of uniforms common - uniforms.envMapIntensity.value = material.envMapIntensity; + //uniforms.envMap.value = material.envMap; // part of uniforms common + uniforms.envMapIntensity.value = material.envMapIntensity; - } + } - } + } - function refreshUniformsPhysical( uniforms, material ) { + function refreshUniformsPhysical( uniforms, material ) { - refreshUniformsStandard( uniforms, material ); + refreshUniformsStandard( uniforms, material ); - uniforms.reflectivity.value = material.reflectivity; // also part of uniforms common + uniforms.reflectivity.value = material.reflectivity; // also part of uniforms common - uniforms.clearCoat.value = material.clearCoat; - uniforms.clearCoatRoughness.value = material.clearCoatRoughness; + uniforms.clearCoat.value = material.clearCoat; + uniforms.clearCoatRoughness.value = material.clearCoatRoughness; - } + } - function refreshUniformsDepth( uniforms, material ) { + function refreshUniformsDepth( uniforms, material ) { - if ( material.displacementMap ) { + if ( material.displacementMap ) { - uniforms.displacementMap.value = material.displacementMap; - uniforms.displacementScale.value = material.displacementScale; - uniforms.displacementBias.value = material.displacementBias; + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; - } + } - } + } - function refreshUniformsDistance( uniforms, material ) { + function refreshUniformsDistance( uniforms, material ) { - if ( material.displacementMap ) { + if ( material.displacementMap ) { - uniforms.displacementMap.value = material.displacementMap; - uniforms.displacementScale.value = material.displacementScale; - uniforms.displacementBias.value = material.displacementBias; + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; - } + } - uniforms.referencePosition.value.copy( material.referencePosition ); - uniforms.nearDistance.value = material.nearDistance; - uniforms.farDistance.value = material.farDistance; + uniforms.referencePosition.value.copy( material.referencePosition ); + uniforms.nearDistance.value = material.nearDistance; + uniforms.farDistance.value = material.farDistance; - } + } - function refreshUniformsNormal( uniforms, material ) { + function refreshUniformsNormal( uniforms, material ) { - if ( material.bumpMap ) { + if ( material.bumpMap ) { - uniforms.bumpMap.value = material.bumpMap; - uniforms.bumpScale.value = material.bumpScale; - if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; + uniforms.bumpMap.value = material.bumpMap; + uniforms.bumpScale.value = material.bumpScale; + if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; - } + } - if ( material.normalMap ) { + if ( material.normalMap ) { - uniforms.normalMap.value = material.normalMap; - uniforms.normalScale.value.copy( material.normalScale ); - if ( material.side === BackSide ) uniforms.normalScale.value.negate(); + uniforms.normalMap.value = material.normalMap; + uniforms.normalScale.value.copy( material.normalScale ); + if ( material.side === BackSide ) uniforms.normalScale.value.negate(); - } + } - if ( material.displacementMap ) { + if ( material.displacementMap ) { - uniforms.displacementMap.value = material.displacementMap; - uniforms.displacementScale.value = material.displacementScale; - uniforms.displacementBias.value = material.displacementBias; + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; - } + } - } + } - // If uniforms are marked as clean, they don't need to be loaded to the GPU. + // If uniforms are marked as clean, they don't need to be loaded to the GPU. - function markUniformsLightsNeedsUpdate( uniforms, value ) { + function markUniformsLightsNeedsUpdate( uniforms, value ) { - uniforms.ambientLightColor.needsUpdate = value; + uniforms.ambientLightColor.needsUpdate = value; - uniforms.directionalLights.needsUpdate = value; - uniforms.pointLights.needsUpdate = value; - uniforms.spotLights.needsUpdate = value; - uniforms.rectAreaLights.needsUpdate = value; - uniforms.hemisphereLights.needsUpdate = value; + uniforms.directionalLights.needsUpdate = value; + uniforms.pointLights.needsUpdate = value; + uniforms.spotLights.needsUpdate = value; + uniforms.rectAreaLights.needsUpdate = value; + uniforms.hemisphereLights.needsUpdate = value; - } + } - // Textures + // Textures - function allocTextureUnit() { + function allocTextureUnit() { - var textureUnit = _usedTextureUnits; + var textureUnit = _usedTextureUnits; - if ( textureUnit >= capabilities.maxTextures ) { + if ( textureUnit >= capabilities.maxTextures ) { - console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures ); + console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures ); - } + } - _usedTextureUnits += 1; + _usedTextureUnits += 1; - return textureUnit; + return textureUnit; - } + } - this.allocTextureUnit = allocTextureUnit; + this.allocTextureUnit = allocTextureUnit; - // this.setTexture2D = setTexture2D; - this.setTexture2D = ( function () { + // this.setTexture2D = setTexture2D; + this.setTexture2D = ( function () { - var warned = false; + var warned = false; - // backwards compatibility: peel texture.texture - return function setTexture2D( texture, slot ) { + // backwards compatibility: peel texture.texture + return function setTexture2D( texture, slot ) { - if ( texture && texture.isWebGLRenderTarget ) { + if ( texture && texture.isWebGLRenderTarget ) { - if ( ! warned ) { + if ( ! warned ) { - console.warn( "THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead." ); - warned = true; + console.warn( "THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead." ); + warned = true; - } + } - texture = texture.texture; + texture = texture.texture; - } + } - textures.setTexture2D( texture, slot ); + textures.setTexture2D( texture, slot ); - }; + }; - }() ); + }() ); - this.setTexture = ( function () { + this.setTexture = ( function () { - var warned = false; + var warned = false; - return function setTexture( texture, slot ) { + return function setTexture( texture, slot ) { - if ( ! warned ) { + if ( ! warned ) { - console.warn( "THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead." ); - warned = true; + console.warn( "THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead." ); + warned = true; - } + } - textures.setTexture2D( texture, slot ); + textures.setTexture2D( texture, slot ); - }; + }; - }() ); + }() ); - this.setTextureCube = ( function () { + this.setTextureCube = ( function () { - var warned = false; + var warned = false; - return function setTextureCube( texture, slot ) { + return function setTextureCube( texture, slot ) { - // backwards compatibility: peel texture.texture - if ( texture && texture.isWebGLRenderTargetCube ) { + // backwards compatibility: peel texture.texture + if ( texture && texture.isWebGLRenderTargetCube ) { - if ( ! warned ) { + if ( ! warned ) { - console.warn( "THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead." ); - warned = true; + console.warn( "THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead." ); + warned = true; - } + } - texture = texture.texture; + texture = texture.texture; - } + } - // currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture - // TODO: unify these code paths - if ( ( texture && texture.isCubeTexture ) || - ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) { + // currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture + // TODO: unify these code paths + if ( ( texture && texture.isCubeTexture ) || + ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) { - // CompressedTexture can have Array in image :/ + // CompressedTexture can have Array in image :/ - // this function alone should take care of cube textures - textures.setTextureCube( texture, slot ); + // this function alone should take care of cube textures + textures.setTextureCube( texture, slot ); - } else { + } else { - // assumed: texture property of THREE.WebGLRenderTargetCube + // assumed: texture property of THREE.WebGLRenderTargetCube - textures.setTextureCubeDynamic( texture, slot ); + textures.setTextureCubeDynamic( texture, slot ); - } + } - }; + }; - }() ); + }() ); - // + // - this.setFramebuffer = function ( value ) { + this.setFramebuffer = function ( value ) { - _framebuffer = value; + _framebuffer = value; - }; + }; - this.getRenderTarget = function () { + this.getRenderTarget = function () { - return _currentRenderTarget; + return _currentRenderTarget; - }; + }; - this.setRenderTarget = function ( renderTarget ) { + this.setRenderTarget = function ( renderTarget ) { - _currentRenderTarget = renderTarget; + _currentRenderTarget = renderTarget; - if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) { + if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) { - textures.setupRenderTarget( renderTarget ); + textures.setupRenderTarget( renderTarget ); - } + } - var framebuffer = _framebuffer; - var isCube = false; + var framebuffer = _framebuffer; + var isCube = false; - if ( renderTarget ) { + if ( renderTarget ) { - var __webglFramebuffer = properties.get( renderTarget ).__webglFramebuffer; + var __webglFramebuffer = properties.get( renderTarget ).__webglFramebuffer; - if ( renderTarget.isWebGLRenderTargetCube ) { + if ( renderTarget.isWebGLRenderTargetCube ) { - framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ]; - isCube = true; + framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ]; + isCube = true; - } else { + } else { - framebuffer = __webglFramebuffer; + framebuffer = __webglFramebuffer; - } + } - _currentViewport.copy( renderTarget.viewport ); - _currentScissor.copy( renderTarget.scissor ); - _currentScissorTest = renderTarget.scissorTest; + _currentViewport.copy( renderTarget.viewport ); + _currentScissor.copy( renderTarget.scissor ); + _currentScissorTest = renderTarget.scissorTest; - } else { + } else { - _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ); - _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ); - _currentScissorTest = _scissorTest; + _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ); + _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ); + _currentScissorTest = _scissorTest; - } + } - if ( _currentFramebuffer !== framebuffer ) { + if ( _currentFramebuffer !== framebuffer ) { - _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); - _currentFramebuffer = framebuffer; + _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); + _currentFramebuffer = framebuffer; - } + } - state.viewport( _currentViewport ); - state.scissor( _currentScissor ); - state.setScissorTest( _currentScissorTest ); + state.viewport( _currentViewport ); + state.scissor( _currentScissor ); + state.setScissorTest( _currentScissorTest ); - if ( isCube ) { + if ( isCube ) { - var textureProperties = properties.get( renderTarget.texture ); - _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel ); + var textureProperties = properties.get( renderTarget.texture ); + _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel ); - } + } - }; + }; - this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) { + this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) { - if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) { + if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) { - console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' ); - return; + console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' ); + return; - } + } - var framebuffer = properties.get( renderTarget ).__webglFramebuffer; + var framebuffer = properties.get( renderTarget ).__webglFramebuffer; - if ( framebuffer ) { + if ( framebuffer ) { - var restore = false; + var restore = false; - if ( framebuffer !== _currentFramebuffer ) { + if ( framebuffer !== _currentFramebuffer ) { - _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); - restore = true; + restore = true; - } + } - try { + try { - var texture = renderTarget.texture; - var textureFormat = texture.format; - var textureType = texture.type; + var texture = renderTarget.texture; + var textureFormat = texture.format; + var textureType = texture.type; - if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) { + if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) { - console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' ); - return; + console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' ); + return; - } + } - if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513) - ! ( textureType === FloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox - ! ( textureType === HalfFloatType && ( capabilities.isWebGL2 ? extensions.get( 'EXT_color_buffer_float' ) : extensions.get( 'EXT_color_buffer_half_float' ) ) ) ) { + if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513) + ! ( textureType === FloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox + ! ( textureType === HalfFloatType && ( capabilities.isWebGL2 ? extensions.get( 'EXT_color_buffer_float' ) : extensions.get( 'EXT_color_buffer_half_float' ) ) ) ) { - console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' ); - return; + console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' ); + return; - } + } - if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) { + if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) { - // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604) + // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604) - if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) { + if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) { - _gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer ); + _gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer ); - } + } - } else { + } else { - console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' ); + console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' ); - } + } - } finally { + } finally { - if ( restore ) { + if ( restore ) { - _gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer ); - } + } - } + } - } + } - }; + }; - this.copyFramebufferToTexture = function ( position, texture, level ) { + this.copyFramebufferToTexture = function ( position, texture, level ) { - var width = texture.image.width; - var height = texture.image.height; - var glFormat = utils.convert( texture.format ); + var width = texture.image.width; + var height = texture.image.height; + var glFormat = utils.convert( texture.format ); - this.setTexture2D( texture, 0 ); + this.setTexture2D( texture, 0 ); - _gl.copyTexImage2D( _gl.TEXTURE_2D, level || 0, glFormat, position.x, position.y, width, height, 0 ); + _gl.copyTexImage2D( _gl.TEXTURE_2D, level || 0, glFormat, position.x, position.y, width, height, 0 ); - }; + }; - this.copyTextureToTexture = function ( position, srcTexture, dstTexture, level ) { + this.copyTextureToTexture = function ( position, srcTexture, dstTexture, level ) { - var width = srcTexture.image.width; - var height = srcTexture.image.height; - var glFormat = utils.convert( dstTexture.format ); - var glType = utils.convert( dstTexture.type ); + var width = srcTexture.image.width; + var height = srcTexture.image.height; + var glFormat = utils.convert( dstTexture.format ); + var glType = utils.convert( dstTexture.type ); - this.setTexture2D( dstTexture, 0 ); + this.setTexture2D( dstTexture, 0 ); - if ( srcTexture.isDataTexture ) { + if ( srcTexture.isDataTexture ) { - _gl.texSubImage2D( _gl.TEXTURE_2D, level || 0, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data ); + _gl.texSubImage2D( _gl.TEXTURE_2D, level || 0, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data ); - } else { + } else { - _gl.texSubImage2D( _gl.TEXTURE_2D, level || 0, position.x, position.y, glFormat, glType, srcTexture.image ); + _gl.texSubImage2D( _gl.TEXTURE_2D, level || 0, position.x, position.y, glFormat, glType, srcTexture.image ); - } + } - }; + }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + */ - function FogExp2( color, density ) { + function FogExp2( color, density ) { - this.name = ''; + this.name = ''; - this.color = new Color( color ); - this.density = ( density !== undefined ) ? density : 0.00025; + this.color = new Color( color ); + this.density = ( density !== undefined ) ? density : 0.00025; - } + } - FogExp2.prototype.isFogExp2 = true; + FogExp2.prototype.isFogExp2 = true; - FogExp2.prototype.clone = function () { + FogExp2.prototype.clone = function () { - return new FogExp2( this.color, this.density ); + return new FogExp2( this.color, this.density ); - }; + }; - FogExp2.prototype.toJSON = function ( /* meta */ ) { + FogExp2.prototype.toJSON = function ( /* meta */ ) { - return { - type: 'FogExp2', - color: this.color.getHex(), - density: this.density - }; + return { + type: 'FogExp2', + color: this.color.getHex(), + density: this.density + }; - }; + }; - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + */ - function Fog( color, near, far ) { + function Fog( color, near, far ) { - this.name = ''; + this.name = ''; - this.color = new Color( color ); + this.color = new Color( color ); - this.near = ( near !== undefined ) ? near : 1; - this.far = ( far !== undefined ) ? far : 1000; + this.near = ( near !== undefined ) ? near : 1; + this.far = ( far !== undefined ) ? far : 1000; - } + } - Fog.prototype.isFog = true; + Fog.prototype.isFog = true; - Fog.prototype.clone = function () { + Fog.prototype.clone = function () { - return new Fog( this.color, this.near, this.far ); + return new Fog( this.color, this.near, this.far ); - }; + }; - Fog.prototype.toJSON = function ( /* meta */ ) { + Fog.prototype.toJSON = function ( /* meta */ ) { - return { - type: 'Fog', - color: this.color.getHex(), - near: this.near, - far: this.far - }; + return { + type: 'Fog', + color: this.color.getHex(), + near: this.near, + far: this.far + }; - }; + }; - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function Scene() { + function Scene() { - Object3D.call( this ); + Object3D.call( this ); - this.type = 'Scene'; + this.type = 'Scene'; - this.background = null; - this.fog = null; - this.overrideMaterial = null; + this.background = null; + this.fog = null; + this.overrideMaterial = null; - this.autoUpdate = true; // checked by the renderer + this.autoUpdate = true; // checked by the renderer - } + } - Scene.prototype = Object.assign( Object.create( Object3D.prototype ), { + Scene.prototype = Object.assign( Object.create( Object3D.prototype ), { - constructor: Scene, + constructor: Scene, - copy: function ( source, recursive ) { + copy: function ( source, recursive ) { - Object3D.prototype.copy.call( this, source, recursive ); + Object3D.prototype.copy.call( this, source, recursive ); - if ( source.background !== null ) this.background = source.background.clone(); - if ( source.fog !== null ) this.fog = source.fog.clone(); - if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); + if ( source.background !== null ) this.background = source.background.clone(); + if ( source.fog !== null ) this.fog = source.fog.clone(); + if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); - this.autoUpdate = source.autoUpdate; - this.matrixAutoUpdate = source.matrixAutoUpdate; + this.autoUpdate = source.autoUpdate; + this.matrixAutoUpdate = source.matrixAutoUpdate; - return this; + return this; - }, + }, - toJSON: function ( meta ) { + toJSON: function ( meta ) { - var data = Object3D.prototype.toJSON.call( this, meta ); + var data = Object3D.prototype.toJSON.call( this, meta ); - if ( this.background !== null ) data.object.background = this.background.toJSON( meta ); - if ( this.fog !== null ) data.object.fog = this.fog.toJSON(); + if ( this.background !== null ) data.object.background = this.background.toJSON( meta ); + if ( this.fog !== null ) data.object.fog = this.fog.toJSON(); - return data; + return data; - } + } - } ); + } ); - /** - * @author benaadams / https://twitter.com/ben_a_adams - */ + /** + * @author benaadams / https://twitter.com/ben_a_adams + */ - function InterleavedBuffer( array, stride ) { + function InterleavedBuffer( array, stride ) { - this.array = array; - this.stride = stride; - this.count = array !== undefined ? array.length / stride : 0; + this.array = array; + this.stride = stride; + this.count = array !== undefined ? array.length / stride : 0; - this.dynamic = false; - this.updateRange = { offset: 0, count: - 1 }; + this.dynamic = false; + this.updateRange = { offset: 0, count: - 1 }; - this.version = 0; + this.version = 0; - } + } - Object.defineProperty( InterleavedBuffer.prototype, 'needsUpdate', { + Object.defineProperty( InterleavedBuffer.prototype, 'needsUpdate', { - set: function ( value ) { + set: function ( value ) { - if ( value === true ) this.version ++; + if ( value === true ) this.version ++; - } + } - } ); + } ); - Object.assign( InterleavedBuffer.prototype, { + Object.assign( InterleavedBuffer.prototype, { - isInterleavedBuffer: true, + isInterleavedBuffer: true, - onUploadCallback: function () {}, + onUploadCallback: function () {}, - setArray: function ( array ) { + setArray: function ( array ) { - if ( Array.isArray( array ) ) { + if ( Array.isArray( array ) ) { - throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); + throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); - } + } - this.count = array !== undefined ? array.length / this.stride : 0; - this.array = array; + this.count = array !== undefined ? array.length / this.stride : 0; + this.array = array; - return this; + return this; - }, + }, - setDynamic: function ( value ) { + setDynamic: function ( value ) { - this.dynamic = value; + this.dynamic = value; - return this; + return this; - }, + }, - copy: function ( source ) { + copy: function ( source ) { - this.array = new source.array.constructor( source.array ); - this.count = source.count; - this.stride = source.stride; - this.dynamic = source.dynamic; + this.array = new source.array.constructor( source.array ); + this.count = source.count; + this.stride = source.stride; + this.dynamic = source.dynamic; - return this; + return this; - }, + }, - copyAt: function ( index1, attribute, index2 ) { + copyAt: function ( index1, attribute, index2 ) { - index1 *= this.stride; - index2 *= attribute.stride; + index1 *= this.stride; + index2 *= attribute.stride; - for ( var i = 0, l = this.stride; i < l; i ++ ) { + for ( var i = 0, l = this.stride; i < l; i ++ ) { - this.array[ index1 + i ] = attribute.array[ index2 + i ]; + this.array[ index1 + i ] = attribute.array[ index2 + i ]; - } + } - return this; + return this; - }, + }, - set: function ( value, offset ) { + set: function ( value, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) offset = 0; - this.array.set( value, offset ); + this.array.set( value, offset ); - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - onUpload: function ( callback ) { + onUpload: function ( callback ) { - this.onUploadCallback = callback; + this.onUploadCallback = callback; - return this; + return this; - } + } - } ); + } ); - /** - * @author benaadams / https://twitter.com/ben_a_adams - */ + /** + * @author benaadams / https://twitter.com/ben_a_adams + */ - function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) { + function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) { - this.data = interleavedBuffer; - this.itemSize = itemSize; - this.offset = offset; + this.data = interleavedBuffer; + this.itemSize = itemSize; + this.offset = offset; - this.normalized = normalized === true; + this.normalized = normalized === true; - } + } - Object.defineProperties( InterleavedBufferAttribute.prototype, { + Object.defineProperties( InterleavedBufferAttribute.prototype, { - count: { + count: { - get: function () { + get: function () { - return this.data.count; + return this.data.count; - } + } - }, + }, - array: { + array: { - get: function () { + get: function () { - return this.data.array; + return this.data.array; - } + } - } + } - } ); + } ); - Object.assign( InterleavedBufferAttribute.prototype, { + Object.assign( InterleavedBufferAttribute.prototype, { - isInterleavedBufferAttribute: true, + isInterleavedBufferAttribute: true, - setX: function ( index, x ) { + setX: function ( index, x ) { - this.data.array[ index * this.data.stride + this.offset ] = x; + this.data.array[ index * this.data.stride + this.offset ] = x; - return this; + return this; - }, + }, - setY: function ( index, y ) { + setY: function ( index, y ) { - this.data.array[ index * this.data.stride + this.offset + 1 ] = y; + this.data.array[ index * this.data.stride + this.offset + 1 ] = y; - return this; + return this; - }, + }, - setZ: function ( index, z ) { + setZ: function ( index, z ) { - this.data.array[ index * this.data.stride + this.offset + 2 ] = z; + this.data.array[ index * this.data.stride + this.offset + 2 ] = z; - return this; + return this; - }, + }, - setW: function ( index, w ) { + setW: function ( index, w ) { - this.data.array[ index * this.data.stride + this.offset + 3 ] = w; + this.data.array[ index * this.data.stride + this.offset + 3 ] = w; - return this; + return this; - }, + }, - getX: function ( index ) { + getX: function ( index ) { - return this.data.array[ index * this.data.stride + this.offset ]; + return this.data.array[ index * this.data.stride + this.offset ]; - }, + }, - getY: function ( index ) { + getY: function ( index ) { - return this.data.array[ index * this.data.stride + this.offset + 1 ]; + return this.data.array[ index * this.data.stride + this.offset + 1 ]; - }, + }, - getZ: function ( index ) { + getZ: function ( index ) { - return this.data.array[ index * this.data.stride + this.offset + 2 ]; + return this.data.array[ index * this.data.stride + this.offset + 2 ]; - }, + }, - getW: function ( index ) { + getW: function ( index ) { - return this.data.array[ index * this.data.stride + this.offset + 3 ]; + return this.data.array[ index * this.data.stride + this.offset + 3 ]; - }, + }, - setXY: function ( index, x, y ) { + setXY: function ( index, x, y ) { - index = index * this.data.stride + this.offset; + index = index * this.data.stride + this.offset; - this.data.array[ index + 0 ] = x; - this.data.array[ index + 1 ] = y; + this.data.array[ index + 0 ] = x; + this.data.array[ index + 1 ] = y; - return this; + return this; - }, + }, - setXYZ: function ( index, x, y, z ) { + setXYZ: function ( index, x, y, z ) { - index = index * this.data.stride + this.offset; + index = index * this.data.stride + this.offset; - this.data.array[ index + 0 ] = x; - this.data.array[ index + 1 ] = y; - this.data.array[ index + 2 ] = z; + this.data.array[ index + 0 ] = x; + this.data.array[ index + 1 ] = y; + this.data.array[ index + 2 ] = z; - return this; + return this; - }, + }, - setXYZW: function ( index, x, y, z, w ) { + setXYZW: function ( index, x, y, z, w ) { - index = index * this.data.stride + this.offset; + index = index * this.data.stride + this.offset; - this.data.array[ index + 0 ] = x; - this.data.array[ index + 1 ] = y; - this.data.array[ index + 2 ] = z; - this.data.array[ index + 3 ] = w; + this.data.array[ index + 0 ] = x; + this.data.array[ index + 1 ] = y; + this.data.array[ index + 2 ] = z; + this.data.array[ index + 3 ] = w; - return this; + return this; - } + } - } ); + } ); - /** - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * opacity: , - * map: new THREE.Texture( ), - * - * uvOffset: new THREE.Vector2(), - * uvScale: new THREE.Vector2() - * } - */ + /** + * @author alteredq / http://alteredqualia.com/ + * + * parameters = { + * color: , + * opacity: , + * map: new THREE.Texture( ), + * + * uvOffset: new THREE.Vector2(), + * uvScale: new THREE.Vector2() + * } + */ - function SpriteMaterial( parameters ) { + function SpriteMaterial( parameters ) { - Material.call( this ); + Material.call( this ); - this.type = 'SpriteMaterial'; + this.type = 'SpriteMaterial'; - this.color = new Color( 0xffffff ); - this.map = null; + this.color = new Color( 0xffffff ); + this.map = null; - this.rotation = 0; + this.rotation = 0; - this.lights = false; - this.transparent = true; + this.lights = false; + this.transparent = true; - this.setValues( parameters ); + this.setValues( parameters ); - } + } - SpriteMaterial.prototype = Object.create( Material.prototype ); - SpriteMaterial.prototype.constructor = SpriteMaterial; - SpriteMaterial.prototype.isSpriteMaterial = true; + SpriteMaterial.prototype = Object.create( Material.prototype ); + SpriteMaterial.prototype.constructor = SpriteMaterial; + SpriteMaterial.prototype.isSpriteMaterial = true; - SpriteMaterial.prototype.copy = function ( source ) { + SpriteMaterial.prototype.copy = function ( source ) { - Material.prototype.copy.call( this, source ); + Material.prototype.copy.call( this, source ); - this.color.copy( source.color ); - this.map = source.map; + this.color.copy( source.color ); + this.map = source.map; - this.rotation = source.rotation; + this.rotation = source.rotation; - return this; + return this; - }; + }; - /** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author mikael emtinger / http://gomo.se/ + * @author alteredq / http://alteredqualia.com/ + */ - var geometry; + var geometry; - function Sprite( material ) { + function Sprite( material ) { - Object3D.call( this ); + Object3D.call( this ); - this.type = 'Sprite'; + this.type = 'Sprite'; - if ( geometry === undefined ) { + if ( geometry === undefined ) { - geometry = new BufferGeometry(); + geometry = new BufferGeometry(); - var float32Array = new Float32Array( [ - - 0.5, - 0.5, 0, 0, 0, - 0.5, - 0.5, 0, 1, 0, - 0.5, 0.5, 0, 1, 1, - - 0.5, 0.5, 0, 0, 1 - ] ); + var float32Array = new Float32Array( [ + - 0.5, - 0.5, 0, 0, 0, + 0.5, - 0.5, 0, 1, 0, + 0.5, 0.5, 0, 1, 1, + - 0.5, 0.5, 0, 0, 1 + ] ); - var interleavedBuffer = new InterleavedBuffer( float32Array, 5 ); + var interleavedBuffer = new InterleavedBuffer( float32Array, 5 ); - geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] ); - geometry.addAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); - geometry.addAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); + geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] ); + geometry.addAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); + geometry.addAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); - } + } - this.geometry = geometry; - this.material = ( material !== undefined ) ? material : new SpriteMaterial(); + this.geometry = geometry; + this.material = ( material !== undefined ) ? material : new SpriteMaterial(); - this.center = new Vector2( 0.5, 0.5 ); + this.center = new Vector2( 0.5, 0.5 ); - } + } - Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), { + Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), { - constructor: Sprite, + constructor: Sprite, - isSprite: true, + isSprite: true, - raycast: ( function () { + raycast: ( function () { - var intersectPoint = new Vector3(); - var worldScale = new Vector3(); - var mvPosition = new Vector3(); + var intersectPoint = new Vector3(); + var worldScale = new Vector3(); + var mvPosition = new Vector3(); - var alignedPosition = new Vector2(); - var rotatedPosition = new Vector2(); - var viewWorldMatrix = new Matrix4(); + var alignedPosition = new Vector2(); + var rotatedPosition = new Vector2(); + var viewWorldMatrix = new Matrix4(); - var vA = new Vector3(); - var vB = new Vector3(); - var vC = new Vector3(); + var vA = new Vector3(); + var vB = new Vector3(); + var vC = new Vector3(); - function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) { + function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) { - // compute position in camera space - alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale ); + // compute position in camera space + alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale ); - // to check if rotation is not zero - if ( sin !== undefined ) { + // to check if rotation is not zero + if ( sin !== undefined ) { - rotatedPosition.x = ( cos * alignedPosition.x ) - ( sin * alignedPosition.y ); - rotatedPosition.y = ( sin * alignedPosition.x ) + ( cos * alignedPosition.y ); + rotatedPosition.x = ( cos * alignedPosition.x ) - ( sin * alignedPosition.y ); + rotatedPosition.y = ( sin * alignedPosition.x ) + ( cos * alignedPosition.y ); - } else { + } else { - rotatedPosition.copy( alignedPosition ); + rotatedPosition.copy( alignedPosition ); - } + } - vertexPosition.copy( mvPosition ); - vertexPosition.x += rotatedPosition.x; - vertexPosition.y += rotatedPosition.y; + vertexPosition.copy( mvPosition ); + vertexPosition.x += rotatedPosition.x; + vertexPosition.y += rotatedPosition.y; - // transform to world space - vertexPosition.applyMatrix4( viewWorldMatrix ); + // transform to world space + vertexPosition.applyMatrix4( viewWorldMatrix ); - } + } - return function raycast( raycaster, intersects ) { + return function raycast( raycaster, intersects ) { - worldScale.setFromMatrixScale( this.matrixWorld ); - viewWorldMatrix.getInverse( this.modelViewMatrix ).premultiply( this.matrixWorld ); - mvPosition.setFromMatrixPosition( this.modelViewMatrix ); + worldScale.setFromMatrixScale( this.matrixWorld ); + viewWorldMatrix.getInverse( this.modelViewMatrix ).premultiply( this.matrixWorld ); + mvPosition.setFromMatrixPosition( this.modelViewMatrix ); - var rotation = this.material.rotation; - var sin, cos; - if ( rotation !== 0 ) { + var rotation = this.material.rotation; + var sin, cos; + if ( rotation !== 0 ) { - cos = Math.cos( rotation ); - sin = Math.sin( rotation ); + cos = Math.cos( rotation ); + sin = Math.sin( rotation ); - } + } - var center = this.center; + var center = this.center; - transformVertex( vA.set( - 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos ); - transformVertex( vB.set( 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos ); - transformVertex( vC.set( 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos ); + transformVertex( vA.set( - 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos ); + transformVertex( vB.set( 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos ); + transformVertex( vC.set( 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos ); - // check first triangle - var intersect = raycaster.ray.intersectTriangle( vA, vB, vC, false, intersectPoint ); + // check first triangle + var intersect = raycaster.ray.intersectTriangle( vA, vB, vC, false, intersectPoint ); - if ( intersect === null ) { + if ( intersect === null ) { - // check second triangle - transformVertex( vB.set( - 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos ); - intersect = raycaster.ray.intersectTriangle( vA, vC, vB, false, intersectPoint ); - if ( intersect === null ) { + // check second triangle + transformVertex( vB.set( - 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos ); + intersect = raycaster.ray.intersectTriangle( vA, vC, vB, false, intersectPoint ); + if ( intersect === null ) { - return; + return; - } + } - } + } - var distance = raycaster.ray.origin.distanceTo( intersectPoint ); + var distance = raycaster.ray.origin.distanceTo( intersectPoint ); - if ( distance < raycaster.near || distance > raycaster.far ) return; + if ( distance < raycaster.near || distance > raycaster.far ) return; - intersects.push( { + intersects.push( { - distance: distance, - point: intersectPoint.clone(), - face: null, - object: this + distance: distance, + point: intersectPoint.clone(), + face: null, + object: this - } ); + } ); - }; + }; - }() ), + }() ), - clone: function () { + clone: function () { - return new this.constructor( this.material ).copy( this ); + return new this.constructor( this.material ).copy( this ); - }, + }, - copy: function ( source ) { + copy: function ( source ) { - Object3D.prototype.copy.call( this, source ); + Object3D.prototype.copy.call( this, source ); - if ( source.center !== undefined ) this.center.copy( source.center ); + if ( source.center !== undefined ) this.center.copy( source.center ); - return this; + return this; - } + } - } ); + } ); - /** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mikael emtinger / http://gomo.se/ + * @author alteredq / http://alteredqualia.com/ + * @author mrdoob / http://mrdoob.com/ + */ - function LOD() { + function LOD() { - Object3D.call( this ); + Object3D.call( this ); - this.type = 'LOD'; + this.type = 'LOD'; - Object.defineProperties( this, { - levels: { - enumerable: true, - value: [] - } - } ); + Object.defineProperties( this, { + levels: { + enumerable: true, + value: [] + } + } ); - } + } - LOD.prototype = Object.assign( Object.create( Object3D.prototype ), { + LOD.prototype = Object.assign( Object.create( Object3D.prototype ), { - constructor: LOD, + constructor: LOD, - copy: function ( source ) { + copy: function ( source ) { - Object3D.prototype.copy.call( this, source, false ); + Object3D.prototype.copy.call( this, source, false ); - var levels = source.levels; + var levels = source.levels; - for ( var i = 0, l = levels.length; i < l; i ++ ) { + for ( var i = 0, l = levels.length; i < l; i ++ ) { - var level = levels[ i ]; + var level = levels[ i ]; - this.addLevel( level.object.clone(), level.distance ); + this.addLevel( level.object.clone(), level.distance ); - } + } - return this; + return this; - }, + }, - addLevel: function ( object, distance ) { + addLevel: function ( object, distance ) { - if ( distance === undefined ) distance = 0; + if ( distance === undefined ) distance = 0; - distance = Math.abs( distance ); + distance = Math.abs( distance ); - var levels = this.levels; + var levels = this.levels; - for ( var l = 0; l < levels.length; l ++ ) { + for ( var l = 0; l < levels.length; l ++ ) { - if ( distance < levels[ l ].distance ) { + if ( distance < levels[ l ].distance ) { - break; + break; - } + } - } + } - levels.splice( l, 0, { distance: distance, object: object } ); + levels.splice( l, 0, { distance: distance, object: object } ); - this.add( object ); + this.add( object ); - }, + }, - getObjectForDistance: function ( distance ) { + getObjectForDistance: function ( distance ) { - var levels = this.levels; + var levels = this.levels; - for ( var i = 1, l = levels.length; i < l; i ++ ) { + for ( var i = 1, l = levels.length; i < l; i ++ ) { - if ( distance < levels[ i ].distance ) { + if ( distance < levels[ i ].distance ) { - break; + break; - } + } - } + } - return levels[ i - 1 ].object; + return levels[ i - 1 ].object; - }, + }, - raycast: ( function () { + raycast: ( function () { - var matrixPosition = new Vector3(); + var matrixPosition = new Vector3(); - return function raycast( raycaster, intersects ) { + return function raycast( raycaster, intersects ) { - matrixPosition.setFromMatrixPosition( this.matrixWorld ); + matrixPosition.setFromMatrixPosition( this.matrixWorld ); - var distance = raycaster.ray.origin.distanceTo( matrixPosition ); + var distance = raycaster.ray.origin.distanceTo( matrixPosition ); - this.getObjectForDistance( distance ).raycast( raycaster, intersects ); + this.getObjectForDistance( distance ).raycast( raycaster, intersects ); - }; + }; - }() ), + }() ), - update: function () { + update: function () { - var v1 = new Vector3(); - var v2 = new Vector3(); + var v1 = new Vector3(); + var v2 = new Vector3(); - return function update( camera ) { + return function update( camera ) { - var levels = this.levels; + var levels = this.levels; - if ( levels.length > 1 ) { + if ( levels.length > 1 ) { - v1.setFromMatrixPosition( camera.matrixWorld ); - v2.setFromMatrixPosition( this.matrixWorld ); + v1.setFromMatrixPosition( camera.matrixWorld ); + v2.setFromMatrixPosition( this.matrixWorld ); - var distance = v1.distanceTo( v2 ); + var distance = v1.distanceTo( v2 ); - levels[ 0 ].object.visible = true; + levels[ 0 ].object.visible = true; - for ( var i = 1, l = levels.length; i < l; i ++ ) { + for ( var i = 1, l = levels.length; i < l; i ++ ) { - if ( distance >= levels[ i ].distance ) { + if ( distance >= levels[ i ].distance ) { - levels[ i - 1 ].object.visible = false; - levels[ i ].object.visible = true; + levels[ i - 1 ].object.visible = false; + levels[ i ].object.visible = true; - } else { + } else { - break; + break; - } + } - } + } - for ( ; i < l; i ++ ) { + for ( ; i < l; i ++ ) { - levels[ i ].object.visible = false; + levels[ i ].object.visible = false; - } + } - } + } - }; + }; - }(), + }(), - toJSON: function ( meta ) { + toJSON: function ( meta ) { - var data = Object3D.prototype.toJSON.call( this, meta ); + var data = Object3D.prototype.toJSON.call( this, meta ); - data.object.levels = []; + data.object.levels = []; - var levels = this.levels; + var levels = this.levels; - for ( var i = 0, l = levels.length; i < l; i ++ ) { + for ( var i = 0, l = levels.length; i < l; i ++ ) { - var level = levels[ i ]; + var level = levels[ i ]; - data.object.levels.push( { - object: level.object.uuid, - distance: level.distance - } ); + data.object.levels.push( { + object: level.object.uuid, + distance: level.distance + } ); - } + } - return data; + return data; - } + } - } ); + } ); - /** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - * @author michael guerrero / http://realitymeltdown.com - * @author ikerr / http://verold.com - */ + /** + * @author mikael emtinger / http://gomo.se/ + * @author alteredq / http://alteredqualia.com/ + * @author michael guerrero / http://realitymeltdown.com + * @author ikerr / http://verold.com + */ - function Skeleton( bones, boneInverses ) { + function Skeleton( bones, boneInverses ) { - // copy the bone array + // copy the bone array - bones = bones || []; + bones = bones || []; - this.bones = bones.slice( 0 ); - this.boneMatrices = new Float32Array( this.bones.length * 16 ); + this.bones = bones.slice( 0 ); + this.boneMatrices = new Float32Array( this.bones.length * 16 ); - // use the supplied bone inverses or calculate the inverses + // use the supplied bone inverses or calculate the inverses - if ( boneInverses === undefined ) { + if ( boneInverses === undefined ) { - this.calculateInverses(); + this.calculateInverses(); - } else { + } else { - if ( this.bones.length === boneInverses.length ) { + if ( this.bones.length === boneInverses.length ) { - this.boneInverses = boneInverses.slice( 0 ); + this.boneInverses = boneInverses.slice( 0 ); - } else { + } else { - console.warn( 'THREE.Skeleton boneInverses is the wrong length.' ); + console.warn( 'THREE.Skeleton boneInverses is the wrong length.' ); - this.boneInverses = []; + this.boneInverses = []; - for ( var i = 0, il = this.bones.length; i < il; i ++ ) { + for ( var i = 0, il = this.bones.length; i < il; i ++ ) { - this.boneInverses.push( new Matrix4() ); + this.boneInverses.push( new Matrix4() ); - } + } - } + } - } + } - } + } - Object.assign( Skeleton.prototype, { + Object.assign( Skeleton.prototype, { - calculateInverses: function () { + calculateInverses: function () { - this.boneInverses = []; + this.boneInverses = []; - for ( var i = 0, il = this.bones.length; i < il; i ++ ) { + for ( var i = 0, il = this.bones.length; i < il; i ++ ) { - var inverse = new Matrix4(); + var inverse = new Matrix4(); - if ( this.bones[ i ] ) { + if ( this.bones[ i ] ) { - inverse.getInverse( this.bones[ i ].matrixWorld ); + inverse.getInverse( this.bones[ i ].matrixWorld ); - } + } - this.boneInverses.push( inverse ); + this.boneInverses.push( inverse ); - } + } - }, + }, - pose: function () { + pose: function () { - var bone, i, il; + var bone, i, il; - // recover the bind-time world matrices + // recover the bind-time world matrices - for ( i = 0, il = this.bones.length; i < il; i ++ ) { + for ( i = 0, il = this.bones.length; i < il; i ++ ) { - bone = this.bones[ i ]; + bone = this.bones[ i ]; - if ( bone ) { + if ( bone ) { - bone.matrixWorld.getInverse( this.boneInverses[ i ] ); + bone.matrixWorld.getInverse( this.boneInverses[ i ] ); - } + } - } + } - // compute the local matrices, positions, rotations and scales + // compute the local matrices, positions, rotations and scales - for ( i = 0, il = this.bones.length; i < il; i ++ ) { + for ( i = 0, il = this.bones.length; i < il; i ++ ) { - bone = this.bones[ i ]; + bone = this.bones[ i ]; - if ( bone ) { + if ( bone ) { - if ( bone.parent && bone.parent.isBone ) { + if ( bone.parent && bone.parent.isBone ) { - bone.matrix.getInverse( bone.parent.matrixWorld ); - bone.matrix.multiply( bone.matrixWorld ); + bone.matrix.getInverse( bone.parent.matrixWorld ); + bone.matrix.multiply( bone.matrixWorld ); - } else { + } else { - bone.matrix.copy( bone.matrixWorld ); + bone.matrix.copy( bone.matrixWorld ); - } + } - bone.matrix.decompose( bone.position, bone.quaternion, bone.scale ); + bone.matrix.decompose( bone.position, bone.quaternion, bone.scale ); - } + } - } + } - }, + }, - update: ( function () { + update: ( function () { - var offsetMatrix = new Matrix4(); - var identityMatrix = new Matrix4(); + var offsetMatrix = new Matrix4(); + var identityMatrix = new Matrix4(); - return function update() { + return function update() { - var bones = this.bones; - var boneInverses = this.boneInverses; - var boneMatrices = this.boneMatrices; - var boneTexture = this.boneTexture; + var bones = this.bones; + var boneInverses = this.boneInverses; + var boneMatrices = this.boneMatrices; + var boneTexture = this.boneTexture; - // flatten bone matrices to array + // flatten bone matrices to array - for ( var i = 0, il = bones.length; i < il; i ++ ) { + for ( var i = 0, il = bones.length; i < il; i ++ ) { - // compute the offset between the current and the original transform + // compute the offset between the current and the original transform - var matrix = bones[ i ] ? bones[ i ].matrixWorld : identityMatrix; + var matrix = bones[ i ] ? bones[ i ].matrixWorld : identityMatrix; - offsetMatrix.multiplyMatrices( matrix, boneInverses[ i ] ); - offsetMatrix.toArray( boneMatrices, i * 16 ); + offsetMatrix.multiplyMatrices( matrix, boneInverses[ i ] ); + offsetMatrix.toArray( boneMatrices, i * 16 ); - } + } - if ( boneTexture !== undefined ) { + if ( boneTexture !== undefined ) { - boneTexture.needsUpdate = true; + boneTexture.needsUpdate = true; - } + } - }; + }; - } )(), + } )(), - clone: function () { + clone: function () { - return new Skeleton( this.bones, this.boneInverses ); + return new Skeleton( this.bones, this.boneInverses ); - }, + }, - getBoneByName: function ( name ) { + getBoneByName: function ( name ) { - for ( var i = 0, il = this.bones.length; i < il; i ++ ) { + for ( var i = 0, il = this.bones.length; i < il; i ++ ) { - var bone = this.bones[ i ]; + var bone = this.bones[ i ]; - if ( bone.name === name ) { + if ( bone.name === name ) { - return bone; + return bone; - } + } - } + } - return undefined; + return undefined; - } + } - } ); + } ); - /** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - * @author ikerr / http://verold.com - */ + /** + * @author mikael emtinger / http://gomo.se/ + * @author alteredq / http://alteredqualia.com/ + * @author ikerr / http://verold.com + */ - function Bone() { + function Bone() { - Object3D.call( this ); + Object3D.call( this ); - this.type = 'Bone'; + this.type = 'Bone'; - } + } - Bone.prototype = Object.assign( Object.create( Object3D.prototype ), { + Bone.prototype = Object.assign( Object.create( Object3D.prototype ), { - constructor: Bone, + constructor: Bone, - isBone: true + isBone: true - } ); + } ); - /** - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - * @author ikerr / http://verold.com - */ + /** + * @author mikael emtinger / http://gomo.se/ + * @author alteredq / http://alteredqualia.com/ + * @author ikerr / http://verold.com + */ - function SkinnedMesh( geometry, material ) { + function SkinnedMesh( geometry, material ) { - Mesh.call( this, geometry, material ); + Mesh.call( this, geometry, material ); - this.type = 'SkinnedMesh'; + this.type = 'SkinnedMesh'; - this.bindMode = 'attached'; - this.bindMatrix = new Matrix4(); - this.bindMatrixInverse = new Matrix4(); + this.bindMode = 'attached'; + this.bindMatrix = new Matrix4(); + this.bindMatrixInverse = new Matrix4(); - var bones = this.initBones(); - var skeleton = new Skeleton( bones ); + var bones = this.initBones(); + var skeleton = new Skeleton( bones ); - this.bind( skeleton, this.matrixWorld ); + this.bind( skeleton, this.matrixWorld ); - this.normalizeSkinWeights(); + this.normalizeSkinWeights(); - } + } - SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), { + SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), { - constructor: SkinnedMesh, + constructor: SkinnedMesh, - isSkinnedMesh: true, + isSkinnedMesh: true, - initBones: function () { + initBones: function () { - var bones = [], bone, gbone; - var i, il; + var bones = [], bone, gbone; + var i, il; - if ( this.geometry && this.geometry.bones !== undefined ) { + if ( this.geometry && this.geometry.bones !== undefined ) { - // first, create array of 'Bone' objects from geometry data + // first, create array of 'Bone' objects from geometry data - for ( i = 0, il = this.geometry.bones.length; i < il; i ++ ) { + for ( i = 0, il = this.geometry.bones.length; i < il; i ++ ) { - gbone = this.geometry.bones[ i ]; + gbone = this.geometry.bones[ i ]; - // create new 'Bone' object + // create new 'Bone' object - bone = new Bone(); - bones.push( bone ); + bone = new Bone(); + bones.push( bone ); - // apply values + // apply values - bone.name = gbone.name; - bone.position.fromArray( gbone.pos ); - bone.quaternion.fromArray( gbone.rotq ); - if ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl ); + bone.name = gbone.name; + bone.position.fromArray( gbone.pos ); + bone.quaternion.fromArray( gbone.rotq ); + if ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl ); - } + } - // second, create bone hierarchy + // second, create bone hierarchy - for ( i = 0, il = this.geometry.bones.length; i < il; i ++ ) { + for ( i = 0, il = this.geometry.bones.length; i < il; i ++ ) { - gbone = this.geometry.bones[ i ]; + gbone = this.geometry.bones[ i ]; - if ( ( gbone.parent !== - 1 ) && ( gbone.parent !== null ) && ( bones[ gbone.parent ] !== undefined ) ) { + if ( ( gbone.parent !== - 1 ) && ( gbone.parent !== null ) && ( bones[ gbone.parent ] !== undefined ) ) { - // subsequent bones in the hierarchy + // subsequent bones in the hierarchy - bones[ gbone.parent ].add( bones[ i ] ); + bones[ gbone.parent ].add( bones[ i ] ); - } else { + } else { - // topmost bone, immediate child of the skinned mesh + // topmost bone, immediate child of the skinned mesh - this.add( bones[ i ] ); + this.add( bones[ i ] ); - } + } - } + } - } + } - // now the bones are part of the scene graph and children of the skinned mesh. - // let's update the corresponding matrices + // now the bones are part of the scene graph and children of the skinned mesh. + // let's update the corresponding matrices - this.updateMatrixWorld( true ); + this.updateMatrixWorld( true ); - return bones; + return bones; - }, + }, - bind: function ( skeleton, bindMatrix ) { + bind: function ( skeleton, bindMatrix ) { - this.skeleton = skeleton; + this.skeleton = skeleton; - if ( bindMatrix === undefined ) { + if ( bindMatrix === undefined ) { - this.updateMatrixWorld( true ); + this.updateMatrixWorld( true ); - this.skeleton.calculateInverses(); + this.skeleton.calculateInverses(); - bindMatrix = this.matrixWorld; + bindMatrix = this.matrixWorld; - } + } - this.bindMatrix.copy( bindMatrix ); - this.bindMatrixInverse.getInverse( bindMatrix ); + this.bindMatrix.copy( bindMatrix ); + this.bindMatrixInverse.getInverse( bindMatrix ); - }, + }, - pose: function () { + pose: function () { - this.skeleton.pose(); + this.skeleton.pose(); - }, + }, - normalizeSkinWeights: function () { + normalizeSkinWeights: function () { - var scale, i; + var scale, i; - if ( this.geometry && this.geometry.isGeometry ) { + if ( this.geometry && this.geometry.isGeometry ) { - for ( i = 0; i < this.geometry.skinWeights.length; i ++ ) { + for ( i = 0; i < this.geometry.skinWeights.length; i ++ ) { - var sw = this.geometry.skinWeights[ i ]; + var sw = this.geometry.skinWeights[ i ]; - scale = 1.0 / sw.manhattanLength(); + scale = 1.0 / sw.manhattanLength(); - if ( scale !== Infinity ) { + if ( scale !== Infinity ) { - sw.multiplyScalar( scale ); + sw.multiplyScalar( scale ); - } else { + } else { - sw.set( 1, 0, 0, 0 ); // do something reasonable + sw.set( 1, 0, 0, 0 ); // do something reasonable - } + } - } + } - } else if ( this.geometry && this.geometry.isBufferGeometry ) { + } else if ( this.geometry && this.geometry.isBufferGeometry ) { - var vec = new Vector4(); + var vec = new Vector4(); - var skinWeight = this.geometry.attributes.skinWeight; + var skinWeight = this.geometry.attributes.skinWeight; - for ( i = 0; i < skinWeight.count; i ++ ) { + for ( i = 0; i < skinWeight.count; i ++ ) { - vec.x = skinWeight.getX( i ); - vec.y = skinWeight.getY( i ); - vec.z = skinWeight.getZ( i ); - vec.w = skinWeight.getW( i ); + vec.x = skinWeight.getX( i ); + vec.y = skinWeight.getY( i ); + vec.z = skinWeight.getZ( i ); + vec.w = skinWeight.getW( i ); - scale = 1.0 / vec.manhattanLength(); + scale = 1.0 / vec.manhattanLength(); - if ( scale !== Infinity ) { + if ( scale !== Infinity ) { - vec.multiplyScalar( scale ); + vec.multiplyScalar( scale ); - } else { + } else { - vec.set( 1, 0, 0, 0 ); // do something reasonable + vec.set( 1, 0, 0, 0 ); // do something reasonable - } + } - skinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w ); + skinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w ); - } + } - } + } - }, + }, - updateMatrixWorld: function ( force ) { + updateMatrixWorld: function ( force ) { - Mesh.prototype.updateMatrixWorld.call( this, force ); + Mesh.prototype.updateMatrixWorld.call( this, force ); - if ( this.bindMode === 'attached' ) { + if ( this.bindMode === 'attached' ) { - this.bindMatrixInverse.getInverse( this.matrixWorld ); + this.bindMatrixInverse.getInverse( this.matrixWorld ); - } else if ( this.bindMode === 'detached' ) { + } else if ( this.bindMode === 'detached' ) { - this.bindMatrixInverse.getInverse( this.bindMatrix ); + this.bindMatrixInverse.getInverse( this.bindMatrix ); - } else { + } else { - console.warn( 'THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode ); + console.warn( 'THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode ); - } + } - }, + }, - clone: function () { + clone: function () { - return new this.constructor( this.geometry, this.material ).copy( this ); + return new this.constructor( this.geometry, this.material ).copy( this ); - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * opacity: , - * - * linewidth: , - * linecap: "round", - * linejoin: "round" - * } - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * + * parameters = { + * color: , + * opacity: , + * + * linewidth: , + * linecap: "round", + * linejoin: "round" + * } + */ - function LineBasicMaterial( parameters ) { + function LineBasicMaterial( parameters ) { - Material.call( this ); + Material.call( this ); - this.type = 'LineBasicMaterial'; + this.type = 'LineBasicMaterial'; - this.color = new Color( 0xffffff ); + this.color = new Color( 0xffffff ); - this.linewidth = 1; - this.linecap = 'round'; - this.linejoin = 'round'; + this.linewidth = 1; + this.linecap = 'round'; + this.linejoin = 'round'; - this.lights = false; + this.lights = false; - this.setValues( parameters ); + this.setValues( parameters ); - } + } - LineBasicMaterial.prototype = Object.create( Material.prototype ); - LineBasicMaterial.prototype.constructor = LineBasicMaterial; + LineBasicMaterial.prototype = Object.create( Material.prototype ); + LineBasicMaterial.prototype.constructor = LineBasicMaterial; - LineBasicMaterial.prototype.isLineBasicMaterial = true; + LineBasicMaterial.prototype.isLineBasicMaterial = true; - LineBasicMaterial.prototype.copy = function ( source ) { + LineBasicMaterial.prototype.copy = function ( source ) { - Material.prototype.copy.call( this, source ); + Material.prototype.copy.call( this, source ); - this.color.copy( source.color ); + this.color.copy( source.color ); - this.linewidth = source.linewidth; - this.linecap = source.linecap; - this.linejoin = source.linejoin; + this.linewidth = source.linewidth; + this.linecap = source.linecap; + this.linejoin = source.linejoin; - return this; + return this; - }; + }; - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function Line( geometry, material, mode ) { + function Line( geometry, material, mode ) { - if ( mode === 1 ) { + if ( mode === 1 ) { - console.error( 'THREE.Line: parameter THREE.LinePieces no longer supported. Use THREE.LineSegments instead.' ); + console.error( 'THREE.Line: parameter THREE.LinePieces no longer supported. Use THREE.LineSegments instead.' ); - } + } - Object3D.call( this ); + Object3D.call( this ); - this.type = 'Line'; + this.type = 'Line'; - this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); - this.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } ); + this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); + this.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } ); - } + } - Line.prototype = Object.assign( Object.create( Object3D.prototype ), { + Line.prototype = Object.assign( Object.create( Object3D.prototype ), { - constructor: Line, + constructor: Line, - isLine: true, + isLine: true, - computeLineDistances: ( function () { + computeLineDistances: ( function () { - var start = new Vector3(); - var end = new Vector3(); + var start = new Vector3(); + var end = new Vector3(); - return function computeLineDistances() { + return function computeLineDistances() { - var geometry = this.geometry; + var geometry = this.geometry; - if ( geometry.isBufferGeometry ) { + if ( geometry.isBufferGeometry ) { - // we assume non-indexed geometry + // we assume non-indexed geometry - if ( geometry.index === null ) { + if ( geometry.index === null ) { - var positionAttribute = geometry.attributes.position; - var lineDistances = [ 0 ]; + var positionAttribute = geometry.attributes.position; + var lineDistances = [ 0 ]; - for ( var i = 1, l = positionAttribute.count; i < l; i ++ ) { + for ( var i = 1, l = positionAttribute.count; i < l; i ++ ) { - start.fromBufferAttribute( positionAttribute, i - 1 ); - end.fromBufferAttribute( positionAttribute, i ); + start.fromBufferAttribute( positionAttribute, i - 1 ); + end.fromBufferAttribute( positionAttribute, i ); - lineDistances[ i ] = lineDistances[ i - 1 ]; - lineDistances[ i ] += start.distanceTo( end ); + lineDistances[ i ] = lineDistances[ i - 1 ]; + lineDistances[ i ] += start.distanceTo( end ); - } + } - geometry.addAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); + geometry.addAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); - } else { + } else { - console.warn( 'THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' ); + console.warn( 'THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' ); - } + } - } else if ( geometry.isGeometry ) { + } else if ( geometry.isGeometry ) { - var vertices = geometry.vertices; - var lineDistances = geometry.lineDistances; + var vertices = geometry.vertices; + var lineDistances = geometry.lineDistances; - lineDistances[ 0 ] = 0; + lineDistances[ 0 ] = 0; - for ( var i = 1, l = vertices.length; i < l; i ++ ) { + for ( var i = 1, l = vertices.length; i < l; i ++ ) { - lineDistances[ i ] = lineDistances[ i - 1 ]; - lineDistances[ i ] += vertices[ i - 1 ].distanceTo( vertices[ i ] ); + lineDistances[ i ] = lineDistances[ i - 1 ]; + lineDistances[ i ] += vertices[ i - 1 ].distanceTo( vertices[ i ] ); - } + } - } + } - return this; + return this; - }; + }; - }() ), + }() ), - raycast: ( function () { + raycast: ( function () { - var inverseMatrix = new Matrix4(); - var ray = new Ray(); - var sphere = new Sphere(); + var inverseMatrix = new Matrix4(); + var ray = new Ray(); + var sphere = new Sphere(); - return function raycast( raycaster, intersects ) { + return function raycast( raycaster, intersects ) { - var precision = raycaster.linePrecision; - var precisionSq = precision * precision; + var precision = raycaster.linePrecision; + var precisionSq = precision * precision; - var geometry = this.geometry; - var matrixWorld = this.matrixWorld; + var geometry = this.geometry; + var matrixWorld = this.matrixWorld; - // Checking boundingSphere distance to ray + // Checking boundingSphere distance to ray - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); - sphere.copy( geometry.boundingSphere ); - sphere.applyMatrix4( matrixWorld ); + sphere.copy( geometry.boundingSphere ); + sphere.applyMatrix4( matrixWorld ); - if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; + if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; - // + // - inverseMatrix.getInverse( matrixWorld ); - ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); + inverseMatrix.getInverse( matrixWorld ); + ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); - var vStart = new Vector3(); - var vEnd = new Vector3(); - var interSegment = new Vector3(); - var interRay = new Vector3(); - var step = ( this && this.isLineSegments ) ? 2 : 1; + var vStart = new Vector3(); + var vEnd = new Vector3(); + var interSegment = new Vector3(); + var interRay = new Vector3(); + var step = ( this && this.isLineSegments ) ? 2 : 1; - if ( geometry.isBufferGeometry ) { + if ( geometry.isBufferGeometry ) { - var index = geometry.index; - var attributes = geometry.attributes; - var positions = attributes.position.array; + var index = geometry.index; + var attributes = geometry.attributes; + var positions = attributes.position.array; - if ( index !== null ) { + if ( index !== null ) { - var indices = index.array; + var indices = index.array; - for ( var i = 0, l = indices.length - 1; i < l; i += step ) { + for ( var i = 0, l = indices.length - 1; i < l; i += step ) { - var a = indices[ i ]; - var b = indices[ i + 1 ]; + var a = indices[ i ]; + var b = indices[ i + 1 ]; - vStart.fromArray( positions, a * 3 ); - vEnd.fromArray( positions, b * 3 ); + vStart.fromArray( positions, a * 3 ); + vEnd.fromArray( positions, b * 3 ); - var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); + var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); - if ( distSq > precisionSq ) continue; + if ( distSq > precisionSq ) continue; - interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation + interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation - var distance = raycaster.ray.origin.distanceTo( interRay ); + var distance = raycaster.ray.origin.distanceTo( interRay ); - if ( distance < raycaster.near || distance > raycaster.far ) continue; + if ( distance < raycaster.near || distance > raycaster.far ) continue; - intersects.push( { + intersects.push( { - distance: distance, - // What do we want? intersection point on the ray or on the segment?? - // point: raycaster.ray.at( distance ), - point: interSegment.clone().applyMatrix4( this.matrixWorld ), - index: i, - face: null, - faceIndex: null, - object: this + distance: distance, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4( this.matrixWorld ), + index: i, + face: null, + faceIndex: null, + object: this - } ); + } ); - } + } - } else { + } else { - for ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) { + for ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) { - vStart.fromArray( positions, 3 * i ); - vEnd.fromArray( positions, 3 * i + 3 ); + vStart.fromArray( positions, 3 * i ); + vEnd.fromArray( positions, 3 * i + 3 ); - var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); + var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); - if ( distSq > precisionSq ) continue; + if ( distSq > precisionSq ) continue; - interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation + interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation - var distance = raycaster.ray.origin.distanceTo( interRay ); + var distance = raycaster.ray.origin.distanceTo( interRay ); - if ( distance < raycaster.near || distance > raycaster.far ) continue; + if ( distance < raycaster.near || distance > raycaster.far ) continue; - intersects.push( { + intersects.push( { - distance: distance, - // What do we want? intersection point on the ray or on the segment?? - // point: raycaster.ray.at( distance ), - point: interSegment.clone().applyMatrix4( this.matrixWorld ), - index: i, - face: null, - faceIndex: null, - object: this + distance: distance, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4( this.matrixWorld ), + index: i, + face: null, + faceIndex: null, + object: this - } ); + } ); - } + } - } + } - } else if ( geometry.isGeometry ) { + } else if ( geometry.isGeometry ) { - var vertices = geometry.vertices; - var nbVertices = vertices.length; + var vertices = geometry.vertices; + var nbVertices = vertices.length; - for ( var i = 0; i < nbVertices - 1; i += step ) { + for ( var i = 0; i < nbVertices - 1; i += step ) { - var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment ); + var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment ); - if ( distSq > precisionSq ) continue; + if ( distSq > precisionSq ) continue; - interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation + interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation - var distance = raycaster.ray.origin.distanceTo( interRay ); + var distance = raycaster.ray.origin.distanceTo( interRay ); - if ( distance < raycaster.near || distance > raycaster.far ) continue; + if ( distance < raycaster.near || distance > raycaster.far ) continue; - intersects.push( { + intersects.push( { - distance: distance, - // What do we want? intersection point on the ray or on the segment?? - // point: raycaster.ray.at( distance ), - point: interSegment.clone().applyMatrix4( this.matrixWorld ), - index: i, - face: null, - faceIndex: null, - object: this + distance: distance, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4( this.matrixWorld ), + index: i, + face: null, + faceIndex: null, + object: this - } ); + } ); - } + } - } + } - }; + }; - }() ), + }() ), - clone: function () { + clone: function () { - return new this.constructor( this.geometry, this.material ).copy( this ); + return new this.constructor( this.geometry, this.material ).copy( this ); - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function LineSegments( geometry, material ) { + function LineSegments( geometry, material ) { - Line.call( this, geometry, material ); + Line.call( this, geometry, material ); - this.type = 'LineSegments'; + this.type = 'LineSegments'; - } + } - LineSegments.prototype = Object.assign( Object.create( Line.prototype ), { + LineSegments.prototype = Object.assign( Object.create( Line.prototype ), { - constructor: LineSegments, + constructor: LineSegments, - isLineSegments: true, + isLineSegments: true, - computeLineDistances: ( function () { + computeLineDistances: ( function () { - var start = new Vector3(); - var end = new Vector3(); + var start = new Vector3(); + var end = new Vector3(); - return function computeLineDistances() { + return function computeLineDistances() { - var geometry = this.geometry; + var geometry = this.geometry; - if ( geometry.isBufferGeometry ) { + if ( geometry.isBufferGeometry ) { - // we assume non-indexed geometry + // we assume non-indexed geometry - if ( geometry.index === null ) { + if ( geometry.index === null ) { - var positionAttribute = geometry.attributes.position; - var lineDistances = []; + var positionAttribute = geometry.attributes.position; + var lineDistances = []; - for ( var i = 0, l = positionAttribute.count; i < l; i += 2 ) { + for ( var i = 0, l = positionAttribute.count; i < l; i += 2 ) { - start.fromBufferAttribute( positionAttribute, i ); - end.fromBufferAttribute( positionAttribute, i + 1 ); + start.fromBufferAttribute( positionAttribute, i ); + end.fromBufferAttribute( positionAttribute, i + 1 ); - lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ]; - lineDistances[ i + 1 ] = lineDistances[ i ] + start.distanceTo( end ); + lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ]; + lineDistances[ i + 1 ] = lineDistances[ i ] + start.distanceTo( end ); - } + } - geometry.addAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); + geometry.addAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); - } else { + } else { - console.warn( 'THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' ); + console.warn( 'THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' ); - } + } - } else if ( geometry.isGeometry ) { + } else if ( geometry.isGeometry ) { - var vertices = geometry.vertices; - var lineDistances = geometry.lineDistances; + var vertices = geometry.vertices; + var lineDistances = geometry.lineDistances; - for ( var i = 0, l = vertices.length; i < l; i += 2 ) { + for ( var i = 0, l = vertices.length; i < l; i += 2 ) { - start.copy( vertices[ i ] ); - end.copy( vertices[ i + 1 ] ); + start.copy( vertices[ i ] ); + end.copy( vertices[ i + 1 ] ); - lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ]; - lineDistances[ i + 1 ] = lineDistances[ i ] + start.distanceTo( end ); + lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ]; + lineDistances[ i + 1 ] = lineDistances[ i ] + start.distanceTo( end ); - } + } - } + } - return this; + return this; - }; + }; - }() ) + }() ) - } ); + } ); - /** - * @author mgreter / http://github.com/mgreter - */ + /** + * @author mgreter / http://github.com/mgreter + */ - function LineLoop( geometry, material ) { + function LineLoop( geometry, material ) { - Line.call( this, geometry, material ); + Line.call( this, geometry, material ); - this.type = 'LineLoop'; + this.type = 'LineLoop'; - } + } - LineLoop.prototype = Object.assign( Object.create( Line.prototype ), { + LineLoop.prototype = Object.assign( Object.create( Line.prototype ), { - constructor: LineLoop, + constructor: LineLoop, - isLineLoop: true, + isLineLoop: true, - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * opacity: , - * map: new THREE.Texture( ), - * - * size: , - * sizeAttenuation: - * - * morphTargets: - * } - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * + * parameters = { + * color: , + * opacity: , + * map: new THREE.Texture( ), + * + * size: , + * sizeAttenuation: + * + * morphTargets: + * } + */ - function PointsMaterial( parameters ) { + function PointsMaterial( parameters ) { - Material.call( this ); + Material.call( this ); - this.type = 'PointsMaterial'; + this.type = 'PointsMaterial'; - this.color = new Color( 0xffffff ); + this.color = new Color( 0xffffff ); - this.map = null; + this.map = null; - this.size = 1; - this.sizeAttenuation = true; + this.size = 1; + this.sizeAttenuation = true; - this.morphTargets = false; + this.morphTargets = false; - this.lights = false; + this.lights = false; - this.setValues( parameters ); + this.setValues( parameters ); - } + } - PointsMaterial.prototype = Object.create( Material.prototype ); - PointsMaterial.prototype.constructor = PointsMaterial; + PointsMaterial.prototype = Object.create( Material.prototype ); + PointsMaterial.prototype.constructor = PointsMaterial; - PointsMaterial.prototype.isPointsMaterial = true; + PointsMaterial.prototype.isPointsMaterial = true; - PointsMaterial.prototype.copy = function ( source ) { + PointsMaterial.prototype.copy = function ( source ) { - Material.prototype.copy.call( this, source ); + Material.prototype.copy.call( this, source ); - this.color.copy( source.color ); + this.color.copy( source.color ); - this.map = source.map; + this.map = source.map; - this.size = source.size; - this.sizeAttenuation = source.sizeAttenuation; + this.size = source.size; + this.sizeAttenuation = source.sizeAttenuation; - this.morphTargets = source.morphTargets; + this.morphTargets = source.morphTargets; - return this; + return this; - }; + }; - /** - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author alteredq / http://alteredqualia.com/ + */ - function Points( geometry, material ) { + function Points( geometry, material ) { - Object3D.call( this ); + Object3D.call( this ); - this.type = 'Points'; + this.type = 'Points'; - this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); - this.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } ); + this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); + this.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } ); - } + } - Points.prototype = Object.assign( Object.create( Object3D.prototype ), { + Points.prototype = Object.assign( Object.create( Object3D.prototype ), { - constructor: Points, + constructor: Points, - isPoints: true, + isPoints: true, - raycast: ( function () { + raycast: ( function () { - var inverseMatrix = new Matrix4(); - var ray = new Ray(); - var sphere = new Sphere(); + var inverseMatrix = new Matrix4(); + var ray = new Ray(); + var sphere = new Sphere(); - return function raycast( raycaster, intersects ) { + return function raycast( raycaster, intersects ) { - var object = this; - var geometry = this.geometry; - var matrixWorld = this.matrixWorld; - var threshold = raycaster.params.Points.threshold; + var object = this; + var geometry = this.geometry; + var matrixWorld = this.matrixWorld; + var threshold = raycaster.params.Points.threshold; - // Checking boundingSphere distance to ray + // Checking boundingSphere distance to ray - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); - sphere.copy( geometry.boundingSphere ); - sphere.applyMatrix4( matrixWorld ); - sphere.radius += threshold; + sphere.copy( geometry.boundingSphere ); + sphere.applyMatrix4( matrixWorld ); + sphere.radius += threshold; - if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; + if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; - // + // - inverseMatrix.getInverse( matrixWorld ); - ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); + inverseMatrix.getInverse( matrixWorld ); + ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); - var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); - var localThresholdSq = localThreshold * localThreshold; - var position = new Vector3(); - var intersectPoint = new Vector3(); + var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); + var localThresholdSq = localThreshold * localThreshold; + var position = new Vector3(); + var intersectPoint = new Vector3(); - function testPoint( point, index ) { + function testPoint( point, index ) { - var rayPointDistanceSq = ray.distanceSqToPoint( point ); + var rayPointDistanceSq = ray.distanceSqToPoint( point ); - if ( rayPointDistanceSq < localThresholdSq ) { + if ( rayPointDistanceSq < localThresholdSq ) { - ray.closestPointToPoint( point, intersectPoint ); - intersectPoint.applyMatrix4( matrixWorld ); + ray.closestPointToPoint( point, intersectPoint ); + intersectPoint.applyMatrix4( matrixWorld ); - var distance = raycaster.ray.origin.distanceTo( intersectPoint ); + var distance = raycaster.ray.origin.distanceTo( intersectPoint ); - if ( distance < raycaster.near || distance > raycaster.far ) return; + if ( distance < raycaster.near || distance > raycaster.far ) return; - intersects.push( { + intersects.push( { - distance: distance, - distanceToRay: Math.sqrt( rayPointDistanceSq ), - point: intersectPoint.clone(), - index: index, - face: null, - object: object + distance: distance, + distanceToRay: Math.sqrt( rayPointDistanceSq ), + point: intersectPoint.clone(), + index: index, + face: null, + object: object - } ); + } ); - } + } - } + } - if ( geometry.isBufferGeometry ) { + if ( geometry.isBufferGeometry ) { - var index = geometry.index; - var attributes = geometry.attributes; - var positions = attributes.position.array; + var index = geometry.index; + var attributes = geometry.attributes; + var positions = attributes.position.array; - if ( index !== null ) { + if ( index !== null ) { - var indices = index.array; + var indices = index.array; - for ( var i = 0, il = indices.length; i < il; i ++ ) { + for ( var i = 0, il = indices.length; i < il; i ++ ) { - var a = indices[ i ]; + var a = indices[ i ]; - position.fromArray( positions, a * 3 ); + position.fromArray( positions, a * 3 ); - testPoint( position, a ); + testPoint( position, a ); - } + } - } else { + } else { - for ( var i = 0, l = positions.length / 3; i < l; i ++ ) { + for ( var i = 0, l = positions.length / 3; i < l; i ++ ) { - position.fromArray( positions, i * 3 ); + position.fromArray( positions, i * 3 ); - testPoint( position, i ); + testPoint( position, i ); - } + } - } + } - } else { + } else { - var vertices = geometry.vertices; + var vertices = geometry.vertices; - for ( var i = 0, l = vertices.length; i < l; i ++ ) { + for ( var i = 0, l = vertices.length; i < l; i ++ ) { - testPoint( vertices[ i ], i ); + testPoint( vertices[ i ], i ); - } + } - } + } - }; + }; - }() ), + }() ), - clone: function () { + clone: function () { - return new this.constructor( this.geometry, this.material ).copy( this ); + return new this.constructor( this.geometry, this.material ).copy( this ); - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { + function VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { - Texture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); + Texture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); - this.generateMipmaps = false; + this.generateMipmaps = false; - } + } - VideoTexture.prototype = Object.assign( Object.create( Texture.prototype ), { + VideoTexture.prototype = Object.assign( Object.create( Texture.prototype ), { - constructor: VideoTexture, + constructor: VideoTexture, - isVideoTexture: true, + isVideoTexture: true, - update: function () { + update: function () { - var video = this.image; + var video = this.image; - if ( video.readyState >= video.HAVE_CURRENT_DATA ) { + if ( video.readyState >= video.HAVE_CURRENT_DATA ) { - this.needsUpdate = true; + this.needsUpdate = true; - } + } - } + } - } ); + } ); - /** - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author alteredq / http://alteredqualia.com/ + */ - function CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { + function CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { - Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); + Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); - this.image = { width: width, height: height }; - this.mipmaps = mipmaps; + this.image = { width: width, height: height }; + this.mipmaps = mipmaps; - // no flipping for cube textures - // (also flipping doesn't work for compressed textures ) + // no flipping for cube textures + // (also flipping doesn't work for compressed textures ) - this.flipY = false; + this.flipY = false; - // can't generate mipmaps for compressed textures - // mips must be embedded in DDS files + // can't generate mipmaps for compressed textures + // mips must be embedded in DDS files - this.generateMipmaps = false; + this.generateMipmaps = false; - } + } - CompressedTexture.prototype = Object.create( Texture.prototype ); - CompressedTexture.prototype.constructor = CompressedTexture; + CompressedTexture.prototype = Object.create( Texture.prototype ); + CompressedTexture.prototype.constructor = CompressedTexture; - CompressedTexture.prototype.isCompressedTexture = true; + CompressedTexture.prototype.isCompressedTexture = true; - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { + function CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { - Texture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); + Texture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); - this.needsUpdate = true; + this.needsUpdate = true; - } + } - CanvasTexture.prototype = Object.create( Texture.prototype ); - CanvasTexture.prototype.constructor = CanvasTexture; - CanvasTexture.prototype.isCanvasTexture = true; + CanvasTexture.prototype = Object.create( Texture.prototype ); + CanvasTexture.prototype.constructor = CanvasTexture; + CanvasTexture.prototype.isCanvasTexture = true; - /** - * @author Matt DesLauriers / @mattdesl - * @author atix / arthursilber.de - */ + /** + * @author Matt DesLauriers / @mattdesl + * @author atix / arthursilber.de + */ - function DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) { + function DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) { - format = format !== undefined ? format : DepthFormat; + format = format !== undefined ? format : DepthFormat; - if ( format !== DepthFormat && format !== DepthStencilFormat ) { + if ( format !== DepthFormat && format !== DepthStencilFormat ) { - throw new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' ); + throw new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' ); - } + } - if ( type === undefined && format === DepthFormat ) type = UnsignedShortType; - if ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type; + if ( type === undefined && format === DepthFormat ) type = UnsignedShortType; + if ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type; - Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); + Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); - this.image = { width: width, height: height }; + this.image = { width: width, height: height }; - this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; - this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; + this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; + this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; - this.flipY = false; - this.generateMipmaps = false; + this.flipY = false; + this.generateMipmaps = false; - } + } - DepthTexture.prototype = Object.create( Texture.prototype ); - DepthTexture.prototype.constructor = DepthTexture; - DepthTexture.prototype.isDepthTexture = true; + DepthTexture.prototype = Object.create( Texture.prototype ); + DepthTexture.prototype.constructor = DepthTexture; + DepthTexture.prototype.isDepthTexture = true; - /** - * @author mrdoob / http://mrdoob.com/ - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author Mugen87 / https://github.com/Mugen87 + */ - function WireframeGeometry( geometry ) { + function WireframeGeometry( geometry ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'WireframeGeometry'; + this.type = 'WireframeGeometry'; - // buffer + // buffer - var vertices = []; + var vertices = []; - // helper variables + // helper variables - var i, j, l, o, ol; - var edge = [ 0, 0 ], edges = {}, e, edge1, edge2; - var key, keys = [ 'a', 'b', 'c' ]; - var vertex; + var i, j, l, o, ol; + var edge = [ 0, 0 ], edges = {}, e, edge1, edge2; + var key, keys = [ 'a', 'b', 'c' ]; + var vertex; - // different logic for Geometry and BufferGeometry + // different logic for Geometry and BufferGeometry - if ( geometry && geometry.isGeometry ) { + if ( geometry && geometry.isGeometry ) { - // create a data structure that contains all edges without duplicates + // create a data structure that contains all edges without duplicates - var faces = geometry.faces; + var faces = geometry.faces; - for ( i = 0, l = faces.length; i < l; i ++ ) { + for ( i = 0, l = faces.length; i < l; i ++ ) { - var face = faces[ i ]; + var face = faces[ i ]; - for ( j = 0; j < 3; j ++ ) { + for ( j = 0; j < 3; j ++ ) { - edge1 = face[ keys[ j ] ]; - edge2 = face[ keys[ ( j + 1 ) % 3 ] ]; - edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates - edge[ 1 ] = Math.max( edge1, edge2 ); + edge1 = face[ keys[ j ] ]; + edge2 = face[ keys[ ( j + 1 ) % 3 ] ]; + edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates + edge[ 1 ] = Math.max( edge1, edge2 ); - key = edge[ 0 ] + ',' + edge[ 1 ]; + key = edge[ 0 ] + ',' + edge[ 1 ]; - if ( edges[ key ] === undefined ) { + if ( edges[ key ] === undefined ) { - edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] }; + edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] }; - } + } - } + } - } + } - // generate vertices + // generate vertices - for ( key in edges ) { + for ( key in edges ) { - e = edges[ key ]; + e = edges[ key ]; - vertex = geometry.vertices[ e.index1 ]; - vertices.push( vertex.x, vertex.y, vertex.z ); + vertex = geometry.vertices[ e.index1 ]; + vertices.push( vertex.x, vertex.y, vertex.z ); - vertex = geometry.vertices[ e.index2 ]; - vertices.push( vertex.x, vertex.y, vertex.z ); + vertex = geometry.vertices[ e.index2 ]; + vertices.push( vertex.x, vertex.y, vertex.z ); - } + } - } else if ( geometry && geometry.isBufferGeometry ) { + } else if ( geometry && geometry.isBufferGeometry ) { - var position, indices, groups; - var group, start, count; - var index1, index2; + var position, indices, groups; + var group, start, count; + var index1, index2; - vertex = new Vector3(); + vertex = new Vector3(); - if ( geometry.index !== null ) { + if ( geometry.index !== null ) { - // indexed BufferGeometry + // indexed BufferGeometry - position = geometry.attributes.position; - indices = geometry.index; - groups = geometry.groups; + position = geometry.attributes.position; + indices = geometry.index; + groups = geometry.groups; - if ( groups.length === 0 ) { + if ( groups.length === 0 ) { - groups = [ { start: 0, count: indices.count, materialIndex: 0 } ]; + groups = [ { start: 0, count: indices.count, materialIndex: 0 } ]; - } + } - // create a data structure that contains all eges without duplicates + // create a data structure that contains all eges without duplicates - for ( o = 0, ol = groups.length; o < ol; ++ o ) { + for ( o = 0, ol = groups.length; o < ol; ++ o ) { - group = groups[ o ]; + group = groups[ o ]; - start = group.start; - count = group.count; + start = group.start; + count = group.count; - for ( i = start, l = ( start + count ); i < l; i += 3 ) { + for ( i = start, l = ( start + count ); i < l; i += 3 ) { - for ( j = 0; j < 3; j ++ ) { + for ( j = 0; j < 3; j ++ ) { - edge1 = indices.getX( i + j ); - edge2 = indices.getX( i + ( j + 1 ) % 3 ); - edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates - edge[ 1 ] = Math.max( edge1, edge2 ); + edge1 = indices.getX( i + j ); + edge2 = indices.getX( i + ( j + 1 ) % 3 ); + edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates + edge[ 1 ] = Math.max( edge1, edge2 ); - key = edge[ 0 ] + ',' + edge[ 1 ]; + key = edge[ 0 ] + ',' + edge[ 1 ]; - if ( edges[ key ] === undefined ) { + if ( edges[ key ] === undefined ) { - edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] }; + edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] }; - } + } - } + } - } + } - } + } - // generate vertices + // generate vertices - for ( key in edges ) { + for ( key in edges ) { - e = edges[ key ]; + e = edges[ key ]; - vertex.fromBufferAttribute( position, e.index1 ); - vertices.push( vertex.x, vertex.y, vertex.z ); + vertex.fromBufferAttribute( position, e.index1 ); + vertices.push( vertex.x, vertex.y, vertex.z ); - vertex.fromBufferAttribute( position, e.index2 ); - vertices.push( vertex.x, vertex.y, vertex.z ); + vertex.fromBufferAttribute( position, e.index2 ); + vertices.push( vertex.x, vertex.y, vertex.z ); - } + } - } else { + } else { - // non-indexed BufferGeometry + // non-indexed BufferGeometry - position = geometry.attributes.position; + position = geometry.attributes.position; - for ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) { + for ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) { - for ( j = 0; j < 3; j ++ ) { + for ( j = 0; j < 3; j ++ ) { - // three edges per triangle, an edge is represented as (index1, index2) - // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0) + // three edges per triangle, an edge is represented as (index1, index2) + // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0) - index1 = 3 * i + j; - vertex.fromBufferAttribute( position, index1 ); - vertices.push( vertex.x, vertex.y, vertex.z ); + index1 = 3 * i + j; + vertex.fromBufferAttribute( position, index1 ); + vertices.push( vertex.x, vertex.y, vertex.z ); - index2 = 3 * i + ( ( j + 1 ) % 3 ); - vertex.fromBufferAttribute( position, index2 ); - vertices.push( vertex.x, vertex.y, vertex.z ); + index2 = 3 * i + ( ( j + 1 ) % 3 ); + vertex.fromBufferAttribute( position, index2 ); + vertices.push( vertex.x, vertex.y, vertex.z ); - } + } - } + } - } + } - } + } - // build geometry + // build geometry - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - } + } - WireframeGeometry.prototype = Object.create( BufferGeometry.prototype ); - WireframeGeometry.prototype.constructor = WireframeGeometry; + WireframeGeometry.prototype = Object.create( BufferGeometry.prototype ); + WireframeGeometry.prototype.constructor = WireframeGeometry; - /** - * @author zz85 / https://github.com/zz85 - * @author Mugen87 / https://github.com/Mugen87 - * - * Parametric Surfaces Geometry - * based on the brilliant article by @prideout http://prideout.net/blog/?p=44 - */ + /** + * @author zz85 / https://github.com/zz85 + * @author Mugen87 / https://github.com/Mugen87 + * + * Parametric Surfaces Geometry + * based on the brilliant article by @prideout http://prideout.net/blog/?p=44 + */ - // ParametricGeometry + // ParametricGeometry - function ParametricGeometry( func, slices, stacks ) { + function ParametricGeometry( func, slices, stacks ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'ParametricGeometry'; + this.type = 'ParametricGeometry'; - this.parameters = { - func: func, - slices: slices, - stacks: stacks - }; + this.parameters = { + func: func, + slices: slices, + stacks: stacks + }; - this.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) ); - this.mergeVertices(); + this.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) ); + this.mergeVertices(); - } + } - ParametricGeometry.prototype = Object.create( Geometry.prototype ); - ParametricGeometry.prototype.constructor = ParametricGeometry; + ParametricGeometry.prototype = Object.create( Geometry.prototype ); + ParametricGeometry.prototype.constructor = ParametricGeometry; - // ParametricBufferGeometry + // ParametricBufferGeometry - function ParametricBufferGeometry( func, slices, stacks ) { + function ParametricBufferGeometry( func, slices, stacks ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'ParametricBufferGeometry'; + this.type = 'ParametricBufferGeometry'; - this.parameters = { - func: func, - slices: slices, - stacks: stacks - }; + this.parameters = { + func: func, + slices: slices, + stacks: stacks + }; - // buffers + // buffers - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - var EPS = 0.00001; + var EPS = 0.00001; - var normal = new Vector3(); + var normal = new Vector3(); - var p0 = new Vector3(), p1 = new Vector3(); - var pu = new Vector3(), pv = new Vector3(); + var p0 = new Vector3(), p1 = new Vector3(); + var pu = new Vector3(), pv = new Vector3(); - var i, j; + var i, j; - if ( func.length < 3 ) { + if ( func.length < 3 ) { - console.error( 'THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.' ); + console.error( 'THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.' ); - } + } - // generate vertices, normals and uvs + // generate vertices, normals and uvs - var sliceCount = slices + 1; + var sliceCount = slices + 1; - for ( i = 0; i <= stacks; i ++ ) { + for ( i = 0; i <= stacks; i ++ ) { - var v = i / stacks; + var v = i / stacks; - for ( j = 0; j <= slices; j ++ ) { + for ( j = 0; j <= slices; j ++ ) { - var u = j / slices; + var u = j / slices; - // vertex + // vertex - func( u, v, p0 ); - vertices.push( p0.x, p0.y, p0.z ); + func( u, v, p0 ); + vertices.push( p0.x, p0.y, p0.z ); - // normal + // normal - // approximate tangent vectors via finite differences + // approximate tangent vectors via finite differences - if ( u - EPS >= 0 ) { + if ( u - EPS >= 0 ) { - func( u - EPS, v, p1 ); - pu.subVectors( p0, p1 ); + func( u - EPS, v, p1 ); + pu.subVectors( p0, p1 ); - } else { + } else { - func( u + EPS, v, p1 ); - pu.subVectors( p1, p0 ); + func( u + EPS, v, p1 ); + pu.subVectors( p1, p0 ); - } + } - if ( v - EPS >= 0 ) { + if ( v - EPS >= 0 ) { - func( u, v - EPS, p1 ); - pv.subVectors( p0, p1 ); + func( u, v - EPS, p1 ); + pv.subVectors( p0, p1 ); - } else { + } else { - func( u, v + EPS, p1 ); - pv.subVectors( p1, p0 ); + func( u, v + EPS, p1 ); + pv.subVectors( p1, p0 ); - } + } - // cross product of tangent vectors returns surface normal + // cross product of tangent vectors returns surface normal - normal.crossVectors( pu, pv ).normalize(); - normals.push( normal.x, normal.y, normal.z ); + normal.crossVectors( pu, pv ).normalize(); + normals.push( normal.x, normal.y, normal.z ); - // uv + // uv - uvs.push( u, v ); + uvs.push( u, v ); - } + } - } + } - // generate indices + // generate indices - for ( i = 0; i < stacks; i ++ ) { + for ( i = 0; i < stacks; i ++ ) { - for ( j = 0; j < slices; j ++ ) { + for ( j = 0; j < slices; j ++ ) { - var a = i * sliceCount + j; - var b = i * sliceCount + j + 1; - var c = ( i + 1 ) * sliceCount + j + 1; - var d = ( i + 1 ) * sliceCount + j; + var a = i * sliceCount + j; + var b = i * sliceCount + j + 1; + var c = ( i + 1 ) * sliceCount + j + 1; + var d = ( i + 1 ) * sliceCount + j; - // faces one and two + // faces one and two - indices.push( a, b, d ); - indices.push( b, c, d ); + indices.push( a, b, d ); + indices.push( b, c, d ); - } + } - } + } - // build geometry + // build geometry - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setIndex( indices ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - } + } - ParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - ParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry; + ParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + ParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry; - /** - * @author clockworkgeek / https://github.com/clockworkgeek - * @author timothypratley / https://github.com/timothypratley - * @author WestLangley / http://github.com/WestLangley - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author clockworkgeek / https://github.com/clockworkgeek + * @author timothypratley / https://github.com/timothypratley + * @author WestLangley / http://github.com/WestLangley + * @author Mugen87 / https://github.com/Mugen87 + */ - // PolyhedronGeometry + // PolyhedronGeometry - function PolyhedronGeometry( vertices, indices, radius, detail ) { + function PolyhedronGeometry( vertices, indices, radius, detail ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'PolyhedronGeometry'; + this.type = 'PolyhedronGeometry'; - this.parameters = { - vertices: vertices, - indices: indices, - radius: radius, - detail: detail - }; + this.parameters = { + vertices: vertices, + indices: indices, + radius: radius, + detail: detail + }; - this.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) ); - this.mergeVertices(); + this.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) ); + this.mergeVertices(); - } + } - PolyhedronGeometry.prototype = Object.create( Geometry.prototype ); - PolyhedronGeometry.prototype.constructor = PolyhedronGeometry; + PolyhedronGeometry.prototype = Object.create( Geometry.prototype ); + PolyhedronGeometry.prototype.constructor = PolyhedronGeometry; - // PolyhedronBufferGeometry + // PolyhedronBufferGeometry - function PolyhedronBufferGeometry( vertices, indices, radius, detail ) { + function PolyhedronBufferGeometry( vertices, indices, radius, detail ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'PolyhedronBufferGeometry'; + this.type = 'PolyhedronBufferGeometry'; - this.parameters = { - vertices: vertices, - indices: indices, - radius: radius, - detail: detail - }; + this.parameters = { + vertices: vertices, + indices: indices, + radius: radius, + detail: detail + }; - radius = radius || 1; - detail = detail || 0; + radius = radius || 1; + detail = detail || 0; - // default buffer data + // default buffer data - var vertexBuffer = []; - var uvBuffer = []; + var vertexBuffer = []; + var uvBuffer = []; - // the subdivision creates the vertex buffer data + // the subdivision creates the vertex buffer data - subdivide( detail ); + subdivide( detail ); - // all vertices should lie on a conceptual sphere with a given radius + // all vertices should lie on a conceptual sphere with a given radius - appplyRadius( radius ); + appplyRadius( radius ); - // finally, create the uv data + // finally, create the uv data - generateUVs(); + generateUVs(); - // build non-indexed geometry + // build non-indexed geometry - this.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) ); + this.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) ); + this.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) ); - if ( detail === 0 ) { + if ( detail === 0 ) { - this.computeVertexNormals(); // flat normals + this.computeVertexNormals(); // flat normals - } else { + } else { - this.normalizeNormals(); // smooth normals + this.normalizeNormals(); // smooth normals - } + } - // helper functions + // helper functions - function subdivide( detail ) { + function subdivide( detail ) { - var a = new Vector3(); - var b = new Vector3(); - var c = new Vector3(); + var a = new Vector3(); + var b = new Vector3(); + var c = new Vector3(); - // iterate over all faces and apply a subdivison with the given detail value + // iterate over all faces and apply a subdivison with the given detail value - for ( var i = 0; i < indices.length; i += 3 ) { + for ( var i = 0; i < indices.length; i += 3 ) { - // get the vertices of the face + // get the vertices of the face - getVertexByIndex( indices[ i + 0 ], a ); - getVertexByIndex( indices[ i + 1 ], b ); - getVertexByIndex( indices[ i + 2 ], c ); + getVertexByIndex( indices[ i + 0 ], a ); + getVertexByIndex( indices[ i + 1 ], b ); + getVertexByIndex( indices[ i + 2 ], c ); - // perform subdivision + // perform subdivision - subdivideFace( a, b, c, detail ); + subdivideFace( a, b, c, detail ); - } + } - } + } - function subdivideFace( a, b, c, detail ) { + function subdivideFace( a, b, c, detail ) { - var cols = Math.pow( 2, detail ); + var cols = Math.pow( 2, detail ); - // we use this multidimensional array as a data structure for creating the subdivision + // we use this multidimensional array as a data structure for creating the subdivision - var v = []; + var v = []; - var i, j; + var i, j; - // construct all of the vertices for this subdivision + // construct all of the vertices for this subdivision - for ( i = 0; i <= cols; i ++ ) { + for ( i = 0; i <= cols; i ++ ) { - v[ i ] = []; + v[ i ] = []; - var aj = a.clone().lerp( c, i / cols ); - var bj = b.clone().lerp( c, i / cols ); + var aj = a.clone().lerp( c, i / cols ); + var bj = b.clone().lerp( c, i / cols ); - var rows = cols - i; + var rows = cols - i; - for ( j = 0; j <= rows; j ++ ) { + for ( j = 0; j <= rows; j ++ ) { - if ( j === 0 && i === cols ) { + if ( j === 0 && i === cols ) { - v[ i ][ j ] = aj; + v[ i ][ j ] = aj; - } else { + } else { - v[ i ][ j ] = aj.clone().lerp( bj, j / rows ); + v[ i ][ j ] = aj.clone().lerp( bj, j / rows ); - } + } - } + } - } + } - // construct all of the faces + // construct all of the faces - for ( i = 0; i < cols; i ++ ) { + for ( i = 0; i < cols; i ++ ) { - for ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) { + for ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) { - var k = Math.floor( j / 2 ); + var k = Math.floor( j / 2 ); - if ( j % 2 === 0 ) { + if ( j % 2 === 0 ) { - pushVertex( v[ i ][ k + 1 ] ); - pushVertex( v[ i + 1 ][ k ] ); - pushVertex( v[ i ][ k ] ); + pushVertex( v[ i ][ k + 1 ] ); + pushVertex( v[ i + 1 ][ k ] ); + pushVertex( v[ i ][ k ] ); - } else { + } else { - pushVertex( v[ i ][ k + 1 ] ); - pushVertex( v[ i + 1 ][ k + 1 ] ); - pushVertex( v[ i + 1 ][ k ] ); + pushVertex( v[ i ][ k + 1 ] ); + pushVertex( v[ i + 1 ][ k + 1 ] ); + pushVertex( v[ i + 1 ][ k ] ); - } + } - } + } - } + } - } + } - function appplyRadius( radius ) { + function appplyRadius( radius ) { - var vertex = new Vector3(); + var vertex = new Vector3(); - // iterate over the entire buffer and apply the radius to each vertex + // iterate over the entire buffer and apply the radius to each vertex - for ( var i = 0; i < vertexBuffer.length; i += 3 ) { + for ( var i = 0; i < vertexBuffer.length; i += 3 ) { - vertex.x = vertexBuffer[ i + 0 ]; - vertex.y = vertexBuffer[ i + 1 ]; - vertex.z = vertexBuffer[ i + 2 ]; + vertex.x = vertexBuffer[ i + 0 ]; + vertex.y = vertexBuffer[ i + 1 ]; + vertex.z = vertexBuffer[ i + 2 ]; - vertex.normalize().multiplyScalar( radius ); + vertex.normalize().multiplyScalar( radius ); - vertexBuffer[ i + 0 ] = vertex.x; - vertexBuffer[ i + 1 ] = vertex.y; - vertexBuffer[ i + 2 ] = vertex.z; + vertexBuffer[ i + 0 ] = vertex.x; + vertexBuffer[ i + 1 ] = vertex.y; + vertexBuffer[ i + 2 ] = vertex.z; - } + } - } + } - function generateUVs() { + function generateUVs() { - var vertex = new Vector3(); + var vertex = new Vector3(); - for ( var i = 0; i < vertexBuffer.length; i += 3 ) { + for ( var i = 0; i < vertexBuffer.length; i += 3 ) { - vertex.x = vertexBuffer[ i + 0 ]; - vertex.y = vertexBuffer[ i + 1 ]; - vertex.z = vertexBuffer[ i + 2 ]; + vertex.x = vertexBuffer[ i + 0 ]; + vertex.y = vertexBuffer[ i + 1 ]; + vertex.z = vertexBuffer[ i + 2 ]; - var u = azimuth( vertex ) / 2 / Math.PI + 0.5; - var v = inclination( vertex ) / Math.PI + 0.5; - uvBuffer.push( u, 1 - v ); + var u = azimuth( vertex ) / 2 / Math.PI + 0.5; + var v = inclination( vertex ) / Math.PI + 0.5; + uvBuffer.push( u, 1 - v ); - } + } - correctUVs(); + correctUVs(); - correctSeam(); + correctSeam(); - } + } - function correctSeam() { + function correctSeam() { - // handle case when face straddles the seam, see #3269 + // handle case when face straddles the seam, see #3269 - for ( var i = 0; i < uvBuffer.length; i += 6 ) { + for ( var i = 0; i < uvBuffer.length; i += 6 ) { - // uv data of a single face + // uv data of a single face - var x0 = uvBuffer[ i + 0 ]; - var x1 = uvBuffer[ i + 2 ]; - var x2 = uvBuffer[ i + 4 ]; + var x0 = uvBuffer[ i + 0 ]; + var x1 = uvBuffer[ i + 2 ]; + var x2 = uvBuffer[ i + 4 ]; - var max = Math.max( x0, x1, x2 ); - var min = Math.min( x0, x1, x2 ); + var max = Math.max( x0, x1, x2 ); + var min = Math.min( x0, x1, x2 ); - // 0.9 is somewhat arbitrary + // 0.9 is somewhat arbitrary - if ( max > 0.9 && min < 0.1 ) { + if ( max > 0.9 && min < 0.1 ) { - if ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1; - if ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1; - if ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1; + if ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1; + if ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1; + if ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1; - } + } - } + } - } + } - function pushVertex( vertex ) { + function pushVertex( vertex ) { - vertexBuffer.push( vertex.x, vertex.y, vertex.z ); + vertexBuffer.push( vertex.x, vertex.y, vertex.z ); - } + } - function getVertexByIndex( index, vertex ) { + function getVertexByIndex( index, vertex ) { - var stride = index * 3; + var stride = index * 3; - vertex.x = vertices[ stride + 0 ]; - vertex.y = vertices[ stride + 1 ]; - vertex.z = vertices[ stride + 2 ]; + vertex.x = vertices[ stride + 0 ]; + vertex.y = vertices[ stride + 1 ]; + vertex.z = vertices[ stride + 2 ]; - } + } - function correctUVs() { + function correctUVs() { - var a = new Vector3(); - var b = new Vector3(); - var c = new Vector3(); + var a = new Vector3(); + var b = new Vector3(); + var c = new Vector3(); - var centroid = new Vector3(); + var centroid = new Vector3(); - var uvA = new Vector2(); - var uvB = new Vector2(); - var uvC = new Vector2(); + var uvA = new Vector2(); + var uvB = new Vector2(); + var uvC = new Vector2(); - for ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) { + for ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) { - a.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] ); - b.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] ); - c.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] ); + a.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] ); + b.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] ); + c.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] ); - uvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] ); - uvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] ); - uvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] ); + uvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] ); + uvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] ); + uvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] ); - centroid.copy( a ).add( b ).add( c ).divideScalar( 3 ); + centroid.copy( a ).add( b ).add( c ).divideScalar( 3 ); - var azi = azimuth( centroid ); + var azi = azimuth( centroid ); - correctUV( uvA, j + 0, a, azi ); - correctUV( uvB, j + 2, b, azi ); - correctUV( uvC, j + 4, c, azi ); + correctUV( uvA, j + 0, a, azi ); + correctUV( uvB, j + 2, b, azi ); + correctUV( uvC, j + 4, c, azi ); - } + } - } + } - function correctUV( uv, stride, vector, azimuth ) { + function correctUV( uv, stride, vector, azimuth ) { - if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) { + if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) { - uvBuffer[ stride ] = uv.x - 1; + uvBuffer[ stride ] = uv.x - 1; - } + } - if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) { + if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) { - uvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5; + uvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5; - } + } - } + } - // Angle around the Y axis, counter-clockwise when looking from above. + // Angle around the Y axis, counter-clockwise when looking from above. - function azimuth( vector ) { + function azimuth( vector ) { - return Math.atan2( vector.z, - vector.x ); + return Math.atan2( vector.z, - vector.x ); - } + } - // Angle above the XZ plane. + // Angle above the XZ plane. - function inclination( vector ) { + function inclination( vector ) { - return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) ); + return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) ); - } + } - } + } - PolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - PolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry; + PolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + PolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry; - /** - * @author timothypratley / https://github.com/timothypratley - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author timothypratley / https://github.com/timothypratley + * @author Mugen87 / https://github.com/Mugen87 + */ - // TetrahedronGeometry + // TetrahedronGeometry - function TetrahedronGeometry( radius, detail ) { + function TetrahedronGeometry( radius, detail ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'TetrahedronGeometry'; + this.type = 'TetrahedronGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; + this.parameters = { + radius: radius, + detail: detail + }; - this.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) ); - this.mergeVertices(); + this.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) ); + this.mergeVertices(); - } + } - TetrahedronGeometry.prototype = Object.create( Geometry.prototype ); - TetrahedronGeometry.prototype.constructor = TetrahedronGeometry; + TetrahedronGeometry.prototype = Object.create( Geometry.prototype ); + TetrahedronGeometry.prototype.constructor = TetrahedronGeometry; - // TetrahedronBufferGeometry + // TetrahedronBufferGeometry - function TetrahedronBufferGeometry( radius, detail ) { + function TetrahedronBufferGeometry( radius, detail ) { - var vertices = [ - 1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1 - ]; + var vertices = [ + 1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1 + ]; - var indices = [ - 2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1 - ]; + var indices = [ + 2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1 + ]; - PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); + PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); - this.type = 'TetrahedronBufferGeometry'; + this.type = 'TetrahedronBufferGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; + this.parameters = { + radius: radius, + detail: detail + }; - } + } - TetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); - TetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry; + TetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); + TetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry; - /** - * @author timothypratley / https://github.com/timothypratley - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author timothypratley / https://github.com/timothypratley + * @author Mugen87 / https://github.com/Mugen87 + */ - // OctahedronGeometry + // OctahedronGeometry - function OctahedronGeometry( radius, detail ) { + function OctahedronGeometry( radius, detail ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'OctahedronGeometry'; + this.type = 'OctahedronGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; + this.parameters = { + radius: radius, + detail: detail + }; - this.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) ); - this.mergeVertices(); + this.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) ); + this.mergeVertices(); - } + } - OctahedronGeometry.prototype = Object.create( Geometry.prototype ); - OctahedronGeometry.prototype.constructor = OctahedronGeometry; + OctahedronGeometry.prototype = Object.create( Geometry.prototype ); + OctahedronGeometry.prototype.constructor = OctahedronGeometry; - // OctahedronBufferGeometry + // OctahedronBufferGeometry - function OctahedronBufferGeometry( radius, detail ) { + function OctahedronBufferGeometry( radius, detail ) { - var vertices = [ - 1, 0, 0, - 1, 0, 0, 0, 1, 0, - 0, - 1, 0, 0, 0, 1, 0, 0, - 1 - ]; + var vertices = [ + 1, 0, 0, - 1, 0, 0, 0, 1, 0, + 0, - 1, 0, 0, 0, 1, 0, 0, - 1 + ]; - var indices = [ - 0, 2, 4, 0, 4, 3, 0, 3, 5, - 0, 5, 2, 1, 2, 5, 1, 5, 3, - 1, 3, 4, 1, 4, 2 - ]; + var indices = [ + 0, 2, 4, 0, 4, 3, 0, 3, 5, + 0, 5, 2, 1, 2, 5, 1, 5, 3, + 1, 3, 4, 1, 4, 2 + ]; - PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); + PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); - this.type = 'OctahedronBufferGeometry'; + this.type = 'OctahedronBufferGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; + this.parameters = { + radius: radius, + detail: detail + }; - } + } - OctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); - OctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry; + OctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); + OctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry; - /** - * @author timothypratley / https://github.com/timothypratley - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author timothypratley / https://github.com/timothypratley + * @author Mugen87 / https://github.com/Mugen87 + */ - // IcosahedronGeometry + // IcosahedronGeometry - function IcosahedronGeometry( radius, detail ) { + function IcosahedronGeometry( radius, detail ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'IcosahedronGeometry'; + this.type = 'IcosahedronGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; + this.parameters = { + radius: radius, + detail: detail + }; - this.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) ); - this.mergeVertices(); + this.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) ); + this.mergeVertices(); - } + } - IcosahedronGeometry.prototype = Object.create( Geometry.prototype ); - IcosahedronGeometry.prototype.constructor = IcosahedronGeometry; + IcosahedronGeometry.prototype = Object.create( Geometry.prototype ); + IcosahedronGeometry.prototype.constructor = IcosahedronGeometry; - // IcosahedronBufferGeometry + // IcosahedronBufferGeometry - function IcosahedronBufferGeometry( radius, detail ) { + function IcosahedronBufferGeometry( radius, detail ) { - var t = ( 1 + Math.sqrt( 5 ) ) / 2; + var t = ( 1 + Math.sqrt( 5 ) ) / 2; - var vertices = [ - - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0, - 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, - t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1 - ]; + var vertices = [ + - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0, + 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, + t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1 + ]; - var indices = [ - 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, - 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, - 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, - 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1 - ]; + var indices = [ + 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, + 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, + 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, + 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1 + ]; - PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); + PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); - this.type = 'IcosahedronBufferGeometry'; + this.type = 'IcosahedronBufferGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; + this.parameters = { + radius: radius, + detail: detail + }; - } + } - IcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); - IcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry; + IcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); + IcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry; - /** - * @author Abe Pazos / https://hamoid.com - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author Abe Pazos / https://hamoid.com + * @author Mugen87 / https://github.com/Mugen87 + */ - // DodecahedronGeometry + // DodecahedronGeometry - function DodecahedronGeometry( radius, detail ) { + function DodecahedronGeometry( radius, detail ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'DodecahedronGeometry'; + this.type = 'DodecahedronGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; + this.parameters = { + radius: radius, + detail: detail + }; - this.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) ); - this.mergeVertices(); + this.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) ); + this.mergeVertices(); - } + } - DodecahedronGeometry.prototype = Object.create( Geometry.prototype ); - DodecahedronGeometry.prototype.constructor = DodecahedronGeometry; + DodecahedronGeometry.prototype = Object.create( Geometry.prototype ); + DodecahedronGeometry.prototype.constructor = DodecahedronGeometry; - // DodecahedronBufferGeometry + // DodecahedronBufferGeometry - function DodecahedronBufferGeometry( radius, detail ) { + function DodecahedronBufferGeometry( radius, detail ) { - var t = ( 1 + Math.sqrt( 5 ) ) / 2; - var r = 1 / t; + var t = ( 1 + Math.sqrt( 5 ) ) / 2; + var r = 1 / t; - var vertices = [ + var vertices = [ - // (±1, ±1, ±1) - - 1, - 1, - 1, - 1, - 1, 1, - - 1, 1, - 1, - 1, 1, 1, - 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, 1, 1, 1, + // (±1, ±1, ±1) + - 1, - 1, - 1, - 1, - 1, 1, + - 1, 1, - 1, - 1, 1, 1, + 1, - 1, - 1, 1, - 1, 1, + 1, 1, - 1, 1, 1, 1, - // (0, ±1/φ, ±φ) - 0, - r, - t, 0, - r, t, - 0, r, - t, 0, r, t, + // (0, ±1/φ, ±φ) + 0, - r, - t, 0, - r, t, + 0, r, - t, 0, r, t, - // (±1/φ, ±φ, 0) - - r, - t, 0, - r, t, 0, - r, - t, 0, r, t, 0, + // (±1/φ, ±φ, 0) + - r, - t, 0, - r, t, 0, + r, - t, 0, r, t, 0, - // (±φ, 0, ±1/φ) - - t, 0, - r, t, 0, - r, - - t, 0, r, t, 0, r - ]; + // (±φ, 0, ±1/φ) + - t, 0, - r, t, 0, - r, + - t, 0, r, t, 0, r + ]; - var indices = [ - 3, 11, 7, 3, 7, 15, 3, 15, 13, - 7, 19, 17, 7, 17, 6, 7, 6, 15, - 17, 4, 8, 17, 8, 10, 17, 10, 6, - 8, 0, 16, 8, 16, 2, 8, 2, 10, - 0, 12, 1, 0, 1, 18, 0, 18, 16, - 6, 10, 2, 6, 2, 13, 6, 13, 15, - 2, 16, 18, 2, 18, 3, 2, 3, 13, - 18, 1, 9, 18, 9, 11, 18, 11, 3, - 4, 14, 12, 4, 12, 0, 4, 0, 8, - 11, 9, 5, 11, 5, 19, 11, 19, 7, - 19, 5, 14, 19, 14, 4, 19, 4, 17, - 1, 12, 14, 1, 14, 5, 1, 5, 9 - ]; + var indices = [ + 3, 11, 7, 3, 7, 15, 3, 15, 13, + 7, 19, 17, 7, 17, 6, 7, 6, 15, + 17, 4, 8, 17, 8, 10, 17, 10, 6, + 8, 0, 16, 8, 16, 2, 8, 2, 10, + 0, 12, 1, 0, 1, 18, 0, 18, 16, + 6, 10, 2, 6, 2, 13, 6, 13, 15, + 2, 16, 18, 2, 18, 3, 2, 3, 13, + 18, 1, 9, 18, 9, 11, 18, 11, 3, + 4, 14, 12, 4, 12, 0, 4, 0, 8, + 11, 9, 5, 11, 5, 19, 11, 19, 7, + 19, 5, 14, 19, 14, 4, 19, 4, 17, + 1, 12, 14, 1, 14, 5, 1, 5, 9 + ]; - PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); + PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail ); - this.type = 'DodecahedronBufferGeometry'; + this.type = 'DodecahedronBufferGeometry'; - this.parameters = { - radius: radius, - detail: detail - }; + this.parameters = { + radius: radius, + detail: detail + }; - } + } - DodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); - DodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry; + DodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype ); + DodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry; - /** - * @author oosmoxiecode / https://github.com/oosmoxiecode - * @author WestLangley / https://github.com/WestLangley - * @author zz85 / https://github.com/zz85 - * @author miningold / https://github.com/miningold - * @author jonobr1 / https://github.com/jonobr1 - * @author Mugen87 / https://github.com/Mugen87 - * - */ + /** + * @author oosmoxiecode / https://github.com/oosmoxiecode + * @author WestLangley / https://github.com/WestLangley + * @author zz85 / https://github.com/zz85 + * @author miningold / https://github.com/miningold + * @author jonobr1 / https://github.com/jonobr1 + * @author Mugen87 / https://github.com/Mugen87 + * + */ - // TubeGeometry + // TubeGeometry - function TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) { + function TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'TubeGeometry'; + this.type = 'TubeGeometry'; - this.parameters = { - path: path, - tubularSegments: tubularSegments, - radius: radius, - radialSegments: radialSegments, - closed: closed - }; + this.parameters = { + path: path, + tubularSegments: tubularSegments, + radius: radius, + radialSegments: radialSegments, + closed: closed + }; - if ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' ); + if ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' ); - var bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ); + var bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ); - // expose internals + // expose internals - this.tangents = bufferGeometry.tangents; - this.normals = bufferGeometry.normals; - this.binormals = bufferGeometry.binormals; + this.tangents = bufferGeometry.tangents; + this.normals = bufferGeometry.normals; + this.binormals = bufferGeometry.binormals; - // create geometry + // create geometry - this.fromBufferGeometry( bufferGeometry ); - this.mergeVertices(); + this.fromBufferGeometry( bufferGeometry ); + this.mergeVertices(); - } + } - TubeGeometry.prototype = Object.create( Geometry.prototype ); - TubeGeometry.prototype.constructor = TubeGeometry; + TubeGeometry.prototype = Object.create( Geometry.prototype ); + TubeGeometry.prototype.constructor = TubeGeometry; - // TubeBufferGeometry + // TubeBufferGeometry - function TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) { + function TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'TubeBufferGeometry'; + this.type = 'TubeBufferGeometry'; - this.parameters = { - path: path, - tubularSegments: tubularSegments, - radius: radius, - radialSegments: radialSegments, - closed: closed - }; + this.parameters = { + path: path, + tubularSegments: tubularSegments, + radius: radius, + radialSegments: radialSegments, + closed: closed + }; - tubularSegments = tubularSegments || 64; - radius = radius || 1; - radialSegments = radialSegments || 8; - closed = closed || false; + tubularSegments = tubularSegments || 64; + radius = radius || 1; + radialSegments = radialSegments || 8; + closed = closed || false; - var frames = path.computeFrenetFrames( tubularSegments, closed ); + var frames = path.computeFrenetFrames( tubularSegments, closed ); - // expose internals + // expose internals - this.tangents = frames.tangents; - this.normals = frames.normals; - this.binormals = frames.binormals; + this.tangents = frames.tangents; + this.normals = frames.normals; + this.binormals = frames.binormals; - // helper variables + // helper variables - var vertex = new Vector3(); - var normal = new Vector3(); - var uv = new Vector2(); - var P = new Vector3(); + var vertex = new Vector3(); + var normal = new Vector3(); + var uv = new Vector2(); + var P = new Vector3(); - var i, j; + var i, j; - // buffer + // buffer - var vertices = []; - var normals = []; - var uvs = []; - var indices = []; + var vertices = []; + var normals = []; + var uvs = []; + var indices = []; - // create buffer data + // create buffer data - generateBufferData(); + generateBufferData(); - // build geometry + // build geometry - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setIndex( indices ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - // functions + // functions - function generateBufferData() { + function generateBufferData() { - for ( i = 0; i < tubularSegments; i ++ ) { + for ( i = 0; i < tubularSegments; i ++ ) { - generateSegment( i ); + generateSegment( i ); - } + } - // if the geometry is not closed, generate the last row of vertices and normals - // at the regular position on the given path - // - // if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ) + // if the geometry is not closed, generate the last row of vertices and normals + // at the regular position on the given path + // + // if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ) - generateSegment( ( closed === false ) ? tubularSegments : 0 ); + generateSegment( ( closed === false ) ? tubularSegments : 0 ); - // uvs are generated in a separate function. - // this makes it easy compute correct values for closed geometries + // uvs are generated in a separate function. + // this makes it easy compute correct values for closed geometries - generateUVs(); + generateUVs(); - // finally create faces + // finally create faces - generateIndices(); + generateIndices(); - } + } - function generateSegment( i ) { + function generateSegment( i ) { - // we use getPointAt to sample evenly distributed points from the given path + // we use getPointAt to sample evenly distributed points from the given path - P = path.getPointAt( i / tubularSegments, P ); + P = path.getPointAt( i / tubularSegments, P ); - // retrieve corresponding normal and binormal + // retrieve corresponding normal and binormal - var N = frames.normals[ i ]; - var B = frames.binormals[ i ]; + var N = frames.normals[ i ]; + var B = frames.binormals[ i ]; - // generate normals and vertices for the current segment + // generate normals and vertices for the current segment - for ( j = 0; j <= radialSegments; j ++ ) { + for ( j = 0; j <= radialSegments; j ++ ) { - var v = j / radialSegments * Math.PI * 2; + var v = j / radialSegments * Math.PI * 2; - var sin = Math.sin( v ); - var cos = - Math.cos( v ); + var sin = Math.sin( v ); + var cos = - Math.cos( v ); - // normal + // normal - normal.x = ( cos * N.x + sin * B.x ); - normal.y = ( cos * N.y + sin * B.y ); - normal.z = ( cos * N.z + sin * B.z ); - normal.normalize(); + normal.x = ( cos * N.x + sin * B.x ); + normal.y = ( cos * N.y + sin * B.y ); + normal.z = ( cos * N.z + sin * B.z ); + normal.normalize(); - normals.push( normal.x, normal.y, normal.z ); + normals.push( normal.x, normal.y, normal.z ); - // vertex + // vertex - vertex.x = P.x + radius * normal.x; - vertex.y = P.y + radius * normal.y; - vertex.z = P.z + radius * normal.z; + vertex.x = P.x + radius * normal.x; + vertex.y = P.y + radius * normal.y; + vertex.z = P.z + radius * normal.z; - vertices.push( vertex.x, vertex.y, vertex.z ); + vertices.push( vertex.x, vertex.y, vertex.z ); - } + } - } + } - function generateIndices() { + function generateIndices() { - for ( j = 1; j <= tubularSegments; j ++ ) { + for ( j = 1; j <= tubularSegments; j ++ ) { - for ( i = 1; i <= radialSegments; i ++ ) { + for ( i = 1; i <= radialSegments; i ++ ) { - var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 ); - var b = ( radialSegments + 1 ) * j + ( i - 1 ); - var c = ( radialSegments + 1 ) * j + i; - var d = ( radialSegments + 1 ) * ( j - 1 ) + i; + var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 ); + var b = ( radialSegments + 1 ) * j + ( i - 1 ); + var c = ( radialSegments + 1 ) * j + i; + var d = ( radialSegments + 1 ) * ( j - 1 ) + i; - // faces + // faces - indices.push( a, b, d ); - indices.push( b, c, d ); + indices.push( a, b, d ); + indices.push( b, c, d ); - } + } - } + } - } + } - function generateUVs() { + function generateUVs() { - for ( i = 0; i <= tubularSegments; i ++ ) { + for ( i = 0; i <= tubularSegments; i ++ ) { - for ( j = 0; j <= radialSegments; j ++ ) { + for ( j = 0; j <= radialSegments; j ++ ) { - uv.x = i / tubularSegments; - uv.y = j / radialSegments; + uv.x = i / tubularSegments; + uv.y = j / radialSegments; - uvs.push( uv.x, uv.y ); + uvs.push( uv.x, uv.y ); - } + } - } + } - } + } - } + } - TubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - TubeBufferGeometry.prototype.constructor = TubeBufferGeometry; + TubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + TubeBufferGeometry.prototype.constructor = TubeBufferGeometry; - /** - * @author oosmoxiecode - * @author Mugen87 / https://github.com/Mugen87 - * - * based on http://www.blackpawn.com/texts/pqtorus/ - */ + /** + * @author oosmoxiecode + * @author Mugen87 / https://github.com/Mugen87 + * + * based on http://www.blackpawn.com/texts/pqtorus/ + */ - // TorusKnotGeometry + // TorusKnotGeometry - function TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) { + function TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'TorusKnotGeometry'; + this.type = 'TorusKnotGeometry'; - this.parameters = { - radius: radius, - tube: tube, - tubularSegments: tubularSegments, - radialSegments: radialSegments, - p: p, - q: q - }; + this.parameters = { + radius: radius, + tube: tube, + tubularSegments: tubularSegments, + radialSegments: radialSegments, + p: p, + q: q + }; - if ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' ); + if ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' ); - this.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) ); - this.mergeVertices(); + this.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) ); + this.mergeVertices(); - } + } - TorusKnotGeometry.prototype = Object.create( Geometry.prototype ); - TorusKnotGeometry.prototype.constructor = TorusKnotGeometry; + TorusKnotGeometry.prototype = Object.create( Geometry.prototype ); + TorusKnotGeometry.prototype.constructor = TorusKnotGeometry; - // TorusKnotBufferGeometry + // TorusKnotBufferGeometry - function TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) { + function TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'TorusKnotBufferGeometry'; + this.type = 'TorusKnotBufferGeometry'; - this.parameters = { - radius: radius, - tube: tube, - tubularSegments: tubularSegments, - radialSegments: radialSegments, - p: p, - q: q - }; + this.parameters = { + radius: radius, + tube: tube, + tubularSegments: tubularSegments, + radialSegments: radialSegments, + p: p, + q: q + }; - radius = radius || 1; - tube = tube || 0.4; - tubularSegments = Math.floor( tubularSegments ) || 64; - radialSegments = Math.floor( radialSegments ) || 8; - p = p || 2; - q = q || 3; + radius = radius || 1; + tube = tube || 0.4; + tubularSegments = Math.floor( tubularSegments ) || 64; + radialSegments = Math.floor( radialSegments ) || 8; + p = p || 2; + q = q || 3; - // buffers + // buffers - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - // helper variables + // helper variables - var i, j; + var i, j; - var vertex = new Vector3(); - var normal = new Vector3(); + var vertex = new Vector3(); + var normal = new Vector3(); - var P1 = new Vector3(); - var P2 = new Vector3(); + var P1 = new Vector3(); + var P2 = new Vector3(); - var B = new Vector3(); - var T = new Vector3(); - var N = new Vector3(); + var B = new Vector3(); + var T = new Vector3(); + var N = new Vector3(); - // generate vertices, normals and uvs + // generate vertices, normals and uvs - for ( i = 0; i <= tubularSegments; ++ i ) { + for ( i = 0; i <= tubularSegments; ++ i ) { - // the radian "u" is used to calculate the position on the torus curve of the current tubular segement + // the radian "u" is used to calculate the position on the torus curve of the current tubular segement - var u = i / tubularSegments * p * Math.PI * 2; + var u = i / tubularSegments * p * Math.PI * 2; - // now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead. - // these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions + // now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead. + // these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions - calculatePositionOnCurve( u, p, q, radius, P1 ); - calculatePositionOnCurve( u + 0.01, p, q, radius, P2 ); + calculatePositionOnCurve( u, p, q, radius, P1 ); + calculatePositionOnCurve( u + 0.01, p, q, radius, P2 ); - // calculate orthonormal basis + // calculate orthonormal basis - T.subVectors( P2, P1 ); - N.addVectors( P2, P1 ); - B.crossVectors( T, N ); - N.crossVectors( B, T ); + T.subVectors( P2, P1 ); + N.addVectors( P2, P1 ); + B.crossVectors( T, N ); + N.crossVectors( B, T ); - // normalize B, N. T can be ignored, we don't use it + // normalize B, N. T can be ignored, we don't use it - B.normalize(); - N.normalize(); + B.normalize(); + N.normalize(); - for ( j = 0; j <= radialSegments; ++ j ) { + for ( j = 0; j <= radialSegments; ++ j ) { - // now calculate the vertices. they are nothing more than an extrusion of the torus curve. - // because we extrude a shape in the xy-plane, there is no need to calculate a z-value. + // now calculate the vertices. they are nothing more than an extrusion of the torus curve. + // because we extrude a shape in the xy-plane, there is no need to calculate a z-value. - var v = j / radialSegments * Math.PI * 2; - var cx = - tube * Math.cos( v ); - var cy = tube * Math.sin( v ); + var v = j / radialSegments * Math.PI * 2; + var cx = - tube * Math.cos( v ); + var cy = tube * Math.sin( v ); - // now calculate the final vertex position. - // first we orient the extrusion with our basis vectos, then we add it to the current position on the curve + // now calculate the final vertex position. + // first we orient the extrusion with our basis vectos, then we add it to the current position on the curve - vertex.x = P1.x + ( cx * N.x + cy * B.x ); - vertex.y = P1.y + ( cx * N.y + cy * B.y ); - vertex.z = P1.z + ( cx * N.z + cy * B.z ); + vertex.x = P1.x + ( cx * N.x + cy * B.x ); + vertex.y = P1.y + ( cx * N.y + cy * B.y ); + vertex.z = P1.z + ( cx * N.z + cy * B.z ); - vertices.push( vertex.x, vertex.y, vertex.z ); + vertices.push( vertex.x, vertex.y, vertex.z ); - // normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal) + // normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal) - normal.subVectors( vertex, P1 ).normalize(); + normal.subVectors( vertex, P1 ).normalize(); - normals.push( normal.x, normal.y, normal.z ); + normals.push( normal.x, normal.y, normal.z ); - // uv + // uv - uvs.push( i / tubularSegments ); - uvs.push( j / radialSegments ); + uvs.push( i / tubularSegments ); + uvs.push( j / radialSegments ); - } + } - } + } - // generate indices + // generate indices - for ( j = 1; j <= tubularSegments; j ++ ) { + for ( j = 1; j <= tubularSegments; j ++ ) { - for ( i = 1; i <= radialSegments; i ++ ) { + for ( i = 1; i <= radialSegments; i ++ ) { - // indices + // indices - var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 ); - var b = ( radialSegments + 1 ) * j + ( i - 1 ); - var c = ( radialSegments + 1 ) * j + i; - var d = ( radialSegments + 1 ) * ( j - 1 ) + i; + var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 ); + var b = ( radialSegments + 1 ) * j + ( i - 1 ); + var c = ( radialSegments + 1 ) * j + i; + var d = ( radialSegments + 1 ) * ( j - 1 ) + i; - // faces + // faces - indices.push( a, b, d ); - indices.push( b, c, d ); + indices.push( a, b, d ); + indices.push( b, c, d ); - } + } - } + } - // build geometry + // build geometry - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setIndex( indices ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - // this function calculates the current position on the torus curve + // this function calculates the current position on the torus curve - function calculatePositionOnCurve( u, p, q, radius, position ) { + function calculatePositionOnCurve( u, p, q, radius, position ) { - var cu = Math.cos( u ); - var su = Math.sin( u ); - var quOverP = q / p * u; - var cs = Math.cos( quOverP ); + var cu = Math.cos( u ); + var su = Math.sin( u ); + var quOverP = q / p * u; + var cs = Math.cos( quOverP ); - position.x = radius * ( 2 + cs ) * 0.5 * cu; - position.y = radius * ( 2 + cs ) * su * 0.5; - position.z = radius * Math.sin( quOverP ) * 0.5; + position.x = radius * ( 2 + cs ) * 0.5 * cu; + position.y = radius * ( 2 + cs ) * su * 0.5; + position.z = radius * Math.sin( quOverP ) * 0.5; - } + } - } + } - TorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - TorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry; + TorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + TorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry; - /** - * @author oosmoxiecode - * @author mrdoob / http://mrdoob.com/ - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author oosmoxiecode + * @author mrdoob / http://mrdoob.com/ + * @author Mugen87 / https://github.com/Mugen87 + */ - // TorusGeometry + // TorusGeometry - function TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) { + function TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'TorusGeometry'; + this.type = 'TorusGeometry'; - this.parameters = { - radius: radius, - tube: tube, - radialSegments: radialSegments, - tubularSegments: tubularSegments, - arc: arc - }; + this.parameters = { + radius: radius, + tube: tube, + radialSegments: radialSegments, + tubularSegments: tubularSegments, + arc: arc + }; - this.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) ); - this.mergeVertices(); + this.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) ); + this.mergeVertices(); - } + } - TorusGeometry.prototype = Object.create( Geometry.prototype ); - TorusGeometry.prototype.constructor = TorusGeometry; + TorusGeometry.prototype = Object.create( Geometry.prototype ); + TorusGeometry.prototype.constructor = TorusGeometry; - // TorusBufferGeometry + // TorusBufferGeometry - function TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) { + function TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'TorusBufferGeometry'; + this.type = 'TorusBufferGeometry'; - this.parameters = { - radius: radius, - tube: tube, - radialSegments: radialSegments, - tubularSegments: tubularSegments, - arc: arc - }; + this.parameters = { + radius: radius, + tube: tube, + radialSegments: radialSegments, + tubularSegments: tubularSegments, + arc: arc + }; - radius = radius || 1; - tube = tube || 0.4; - radialSegments = Math.floor( radialSegments ) || 8; - tubularSegments = Math.floor( tubularSegments ) || 6; - arc = arc || Math.PI * 2; + radius = radius || 1; + tube = tube || 0.4; + radialSegments = Math.floor( radialSegments ) || 8; + tubularSegments = Math.floor( tubularSegments ) || 6; + arc = arc || Math.PI * 2; - // buffers + // buffers - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - // helper variables + // helper variables - var center = new Vector3(); - var vertex = new Vector3(); - var normal = new Vector3(); + var center = new Vector3(); + var vertex = new Vector3(); + var normal = new Vector3(); - var j, i; + var j, i; - // generate vertices, normals and uvs + // generate vertices, normals and uvs - for ( j = 0; j <= radialSegments; j ++ ) { + for ( j = 0; j <= radialSegments; j ++ ) { - for ( i = 0; i <= tubularSegments; i ++ ) { + for ( i = 0; i <= tubularSegments; i ++ ) { - var u = i / tubularSegments * arc; - var v = j / radialSegments * Math.PI * 2; + var u = i / tubularSegments * arc; + var v = j / radialSegments * Math.PI * 2; - // vertex + // vertex - vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u ); - vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u ); - vertex.z = tube * Math.sin( v ); + vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u ); + vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u ); + vertex.z = tube * Math.sin( v ); - vertices.push( vertex.x, vertex.y, vertex.z ); + vertices.push( vertex.x, vertex.y, vertex.z ); - // normal + // normal - center.x = radius * Math.cos( u ); - center.y = radius * Math.sin( u ); - normal.subVectors( vertex, center ).normalize(); + center.x = radius * Math.cos( u ); + center.y = radius * Math.sin( u ); + normal.subVectors( vertex, center ).normalize(); - normals.push( normal.x, normal.y, normal.z ); + normals.push( normal.x, normal.y, normal.z ); - // uv + // uv - uvs.push( i / tubularSegments ); - uvs.push( j / radialSegments ); + uvs.push( i / tubularSegments ); + uvs.push( j / radialSegments ); - } + } - } + } - // generate indices + // generate indices - for ( j = 1; j <= radialSegments; j ++ ) { + for ( j = 1; j <= radialSegments; j ++ ) { - for ( i = 1; i <= tubularSegments; i ++ ) { + for ( i = 1; i <= tubularSegments; i ++ ) { - // indices + // indices - var a = ( tubularSegments + 1 ) * j + i - 1; - var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1; - var c = ( tubularSegments + 1 ) * ( j - 1 ) + i; - var d = ( tubularSegments + 1 ) * j + i; + var a = ( tubularSegments + 1 ) * j + i - 1; + var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1; + var c = ( tubularSegments + 1 ) * ( j - 1 ) + i; + var d = ( tubularSegments + 1 ) * j + i; - // faces + // faces - indices.push( a, b, d ); - indices.push( b, c, d ); + indices.push( a, b, d ); + indices.push( b, c, d ); - } + } - } + } - // build geometry + // build geometry - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setIndex( indices ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - } + } - TorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - TorusBufferGeometry.prototype.constructor = TorusBufferGeometry; + TorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + TorusBufferGeometry.prototype.constructor = TorusBufferGeometry; - /** - * @author Mugen87 / https://github.com/Mugen87 - * Port from https://github.com/mapbox/earcut (v2.1.2) - */ + /** + * @author Mugen87 / https://github.com/Mugen87 + * Port from https://github.com/mapbox/earcut (v2.1.2) + */ - var Earcut = { + var Earcut = { - triangulate: function ( data, holeIndices, dim ) { + triangulate: function ( data, holeIndices, dim ) { - dim = dim || 2; + dim = dim || 2; - var hasHoles = holeIndices && holeIndices.length, - outerLen = hasHoles ? holeIndices[ 0 ] * dim : data.length, - outerNode = linkedList( data, 0, outerLen, dim, true ), - triangles = []; + var hasHoles = holeIndices && holeIndices.length, + outerLen = hasHoles ? holeIndices[ 0 ] * dim : data.length, + outerNode = linkedList( data, 0, outerLen, dim, true ), + triangles = []; - if ( ! outerNode ) return triangles; + if ( ! outerNode ) return triangles; - var minX, minY, maxX, maxY, x, y, invSize; + var minX, minY, maxX, maxY, x, y, invSize; - if ( hasHoles ) outerNode = eliminateHoles( data, holeIndices, outerNode, dim ); + if ( hasHoles ) outerNode = eliminateHoles( data, holeIndices, outerNode, dim ); - // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox + // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox - if ( data.length > 80 * dim ) { + if ( data.length > 80 * dim ) { - minX = maxX = data[ 0 ]; - minY = maxY = data[ 1 ]; + minX = maxX = data[ 0 ]; + minY = maxY = data[ 1 ]; - for ( var i = dim; i < outerLen; i += dim ) { + for ( var i = dim; i < outerLen; i += dim ) { - x = data[ i ]; - y = data[ i + 1 ]; - if ( x < minX ) minX = x; - if ( y < minY ) minY = y; - if ( x > maxX ) maxX = x; - if ( y > maxY ) maxY = y; + x = data[ i ]; + y = data[ i + 1 ]; + if ( x < minX ) minX = x; + if ( y < minY ) minY = y; + if ( x > maxX ) maxX = x; + if ( y > maxY ) maxY = y; - } + } - // minX, minY and invSize are later used to transform coords into integers for z-order calculation + // minX, minY and invSize are later used to transform coords into integers for z-order calculation - invSize = Math.max( maxX - minX, maxY - minY ); - invSize = invSize !== 0 ? 1 / invSize : 0; + invSize = Math.max( maxX - minX, maxY - minY ); + invSize = invSize !== 0 ? 1 / invSize : 0; - } + } - earcutLinked( outerNode, triangles, dim, minX, minY, invSize ); + earcutLinked( outerNode, triangles, dim, minX, minY, invSize ); - return triangles; + return triangles; - } + } - }; + }; - // create a circular doubly linked list from polygon points in the specified winding order + // create a circular doubly linked list from polygon points in the specified winding order - function linkedList( data, start, end, dim, clockwise ) { + function linkedList( data, start, end, dim, clockwise ) { - var i, last; + var i, last; - if ( clockwise === ( signedArea( data, start, end, dim ) > 0 ) ) { + if ( clockwise === ( signedArea( data, start, end, dim ) > 0 ) ) { - for ( i = start; i < end; i += dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last ); + for ( i = start; i < end; i += dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last ); - } else { + } else { - for ( i = end - dim; i >= start; i -= dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last ); + for ( i = end - dim; i >= start; i -= dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last ); - } + } - if ( last && equals( last, last.next ) ) { + if ( last && equals( last, last.next ) ) { - removeNode( last ); - last = last.next; + removeNode( last ); + last = last.next; - } + } - return last; + return last; - } + } - // eliminate colinear or duplicate points + // eliminate colinear or duplicate points - function filterPoints( start, end ) { + function filterPoints( start, end ) { - if ( ! start ) return start; - if ( ! end ) end = start; + if ( ! start ) return start; + if ( ! end ) end = start; - var p = start, again; + var p = start, again; - do { + do { - again = false; + again = false; - if ( ! p.steiner && ( equals( p, p.next ) || area( p.prev, p, p.next ) === 0 ) ) { + if ( ! p.steiner && ( equals( p, p.next ) || area( p.prev, p, p.next ) === 0 ) ) { - removeNode( p ); - p = end = p.prev; - if ( p === p.next ) break; - again = true; + removeNode( p ); + p = end = p.prev; + if ( p === p.next ) break; + again = true; - } else { + } else { - p = p.next; + p = p.next; - } + } - } while ( again || p !== end ); + } while ( again || p !== end ); - return end; + return end; - } + } - // main ear slicing loop which triangulates a polygon (given as a linked list) + // main ear slicing loop which triangulates a polygon (given as a linked list) - function earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) { + function earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) { - if ( ! ear ) return; + if ( ! ear ) return; - // interlink polygon nodes in z-order + // interlink polygon nodes in z-order - if ( ! pass && invSize ) indexCurve( ear, minX, minY, invSize ); + if ( ! pass && invSize ) indexCurve( ear, minX, minY, invSize ); - var stop = ear, prev, next; + var stop = ear, prev, next; - // iterate through ears, slicing them one by one + // iterate through ears, slicing them one by one - while ( ear.prev !== ear.next ) { + while ( ear.prev !== ear.next ) { - prev = ear.prev; - next = ear.next; + prev = ear.prev; + next = ear.next; - if ( invSize ? isEarHashed( ear, minX, minY, invSize ) : isEar( ear ) ) { + if ( invSize ? isEarHashed( ear, minX, minY, invSize ) : isEar( ear ) ) { - // cut off the triangle - triangles.push( prev.i / dim ); - triangles.push( ear.i / dim ); - triangles.push( next.i / dim ); + // cut off the triangle + triangles.push( prev.i / dim ); + triangles.push( ear.i / dim ); + triangles.push( next.i / dim ); - removeNode( ear ); + removeNode( ear ); - // skipping the next vertice leads to less sliver triangles - ear = next.next; - stop = next.next; + // skipping the next vertice leads to less sliver triangles + ear = next.next; + stop = next.next; - continue; + continue; - } + } - ear = next; + ear = next; - // if we looped through the whole remaining polygon and can't find any more ears + // if we looped through the whole remaining polygon and can't find any more ears - if ( ear === stop ) { + if ( ear === stop ) { - // try filtering points and slicing again + // try filtering points and slicing again - if ( ! pass ) { + if ( ! pass ) { - earcutLinked( filterPoints( ear ), triangles, dim, minX, minY, invSize, 1 ); + earcutLinked( filterPoints( ear ), triangles, dim, minX, minY, invSize, 1 ); - // if this didn't work, try curing all small self-intersections locally + // if this didn't work, try curing all small self-intersections locally - } else if ( pass === 1 ) { + } else if ( pass === 1 ) { - ear = cureLocalIntersections( ear, triangles, dim ); - earcutLinked( ear, triangles, dim, minX, minY, invSize, 2 ); + ear = cureLocalIntersections( ear, triangles, dim ); + earcutLinked( ear, triangles, dim, minX, minY, invSize, 2 ); - // as a last resort, try splitting the remaining polygon into two + // as a last resort, try splitting the remaining polygon into two - } else if ( pass === 2 ) { + } else if ( pass === 2 ) { - splitEarcut( ear, triangles, dim, minX, minY, invSize ); + splitEarcut( ear, triangles, dim, minX, minY, invSize ); - } + } - break; + break; - } + } - } + } - } + } - // check whether a polygon node forms a valid ear with adjacent nodes + // check whether a polygon node forms a valid ear with adjacent nodes - function isEar( ear ) { + function isEar( ear ) { - var a = ear.prev, - b = ear, - c = ear.next; + var a = ear.prev, + b = ear, + c = ear.next; - if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear + if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear - // now make sure we don't have other points inside the potential ear - var p = ear.next.next; + // now make sure we don't have other points inside the potential ear + var p = ear.next.next; - while ( p !== ear.prev ) { + while ( p !== ear.prev ) { - if ( pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && area( p.prev, p, p.next ) >= 0 ) { + if ( pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && area( p.prev, p, p.next ) >= 0 ) { - return false; + return false; - } + } - p = p.next; + p = p.next; - } + } - return true; + return true; - } + } - function isEarHashed( ear, minX, minY, invSize ) { + function isEarHashed( ear, minX, minY, invSize ) { - var a = ear.prev, - b = ear, - c = ear.next; + var a = ear.prev, + b = ear, + c = ear.next; - if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear + if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear - // triangle bbox; min & max are calculated like this for speed + // triangle bbox; min & max are calculated like this for speed - var minTX = a.x < b.x ? ( a.x < c.x ? a.x : c.x ) : ( b.x < c.x ? b.x : c.x ), - minTY = a.y < b.y ? ( a.y < c.y ? a.y : c.y ) : ( b.y < c.y ? b.y : c.y ), - maxTX = a.x > b.x ? ( a.x > c.x ? a.x : c.x ) : ( b.x > c.x ? b.x : c.x ), - maxTY = a.y > b.y ? ( a.y > c.y ? a.y : c.y ) : ( b.y > c.y ? b.y : c.y ); + var minTX = a.x < b.x ? ( a.x < c.x ? a.x : c.x ) : ( b.x < c.x ? b.x : c.x ), + minTY = a.y < b.y ? ( a.y < c.y ? a.y : c.y ) : ( b.y < c.y ? b.y : c.y ), + maxTX = a.x > b.x ? ( a.x > c.x ? a.x : c.x ) : ( b.x > c.x ? b.x : c.x ), + maxTY = a.y > b.y ? ( a.y > c.y ? a.y : c.y ) : ( b.y > c.y ? b.y : c.y ); - // z-order range for the current triangle bbox; + // z-order range for the current triangle bbox; - var minZ = zOrder( minTX, minTY, minX, minY, invSize ), - maxZ = zOrder( maxTX, maxTY, minX, minY, invSize ); + var minZ = zOrder( minTX, minTY, minX, minY, invSize ), + maxZ = zOrder( maxTX, maxTY, minX, minY, invSize ); - // first look for points inside the triangle in increasing z-order + // first look for points inside the triangle in increasing z-order - var p = ear.nextZ; + var p = ear.nextZ; - while ( p && p.z <= maxZ ) { + while ( p && p.z <= maxZ ) { - if ( p !== ear.prev && p !== ear.next && - pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && - area( p.prev, p, p.next ) >= 0 ) return false; - p = p.nextZ; + if ( p !== ear.prev && p !== ear.next && + pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && + area( p.prev, p, p.next ) >= 0 ) return false; + p = p.nextZ; - } + } - // then look for points in decreasing z-order + // then look for points in decreasing z-order - p = ear.prevZ; + p = ear.prevZ; - while ( p && p.z >= minZ ) { + while ( p && p.z >= minZ ) { - if ( p !== ear.prev && p !== ear.next && - pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && - area( p.prev, p, p.next ) >= 0 ) return false; + if ( p !== ear.prev && p !== ear.next && + pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && + area( p.prev, p, p.next ) >= 0 ) return false; - p = p.prevZ; + p = p.prevZ; - } + } - return true; + return true; - } + } - // go through all polygon nodes and cure small local self-intersections + // go through all polygon nodes and cure small local self-intersections - function cureLocalIntersections( start, triangles, dim ) { + function cureLocalIntersections( start, triangles, dim ) { - var p = start; + var p = start; - do { + do { - var a = p.prev, b = p.next.next; + var a = p.prev, b = p.next.next; - if ( ! equals( a, b ) && intersects( a, p, p.next, b ) && locallyInside( a, b ) && locallyInside( b, a ) ) { + if ( ! equals( a, b ) && intersects( a, p, p.next, b ) && locallyInside( a, b ) && locallyInside( b, a ) ) { - triangles.push( a.i / dim ); - triangles.push( p.i / dim ); - triangles.push( b.i / dim ); + triangles.push( a.i / dim ); + triangles.push( p.i / dim ); + triangles.push( b.i / dim ); - // remove two nodes involved + // remove two nodes involved - removeNode( p ); - removeNode( p.next ); + removeNode( p ); + removeNode( p.next ); - p = start = b; + p = start = b; - } + } - p = p.next; + p = p.next; - } while ( p !== start ); + } while ( p !== start ); - return p; + return p; - } + } - // try splitting polygon into two and triangulate them independently + // try splitting polygon into two and triangulate them independently - function splitEarcut( start, triangles, dim, minX, minY, invSize ) { + function splitEarcut( start, triangles, dim, minX, minY, invSize ) { - // look for a valid diagonal that divides the polygon into two + // look for a valid diagonal that divides the polygon into two - var a = start; + var a = start; - do { + do { - var b = a.next.next; + var b = a.next.next; - while ( b !== a.prev ) { + while ( b !== a.prev ) { - if ( a.i !== b.i && isValidDiagonal( a, b ) ) { + if ( a.i !== b.i && isValidDiagonal( a, b ) ) { - // split the polygon in two by the diagonal + // split the polygon in two by the diagonal - var c = splitPolygon( a, b ); + var c = splitPolygon( a, b ); - // filter colinear points around the cuts + // filter colinear points around the cuts - a = filterPoints( a, a.next ); - c = filterPoints( c, c.next ); + a = filterPoints( a, a.next ); + c = filterPoints( c, c.next ); - // run earcut on each half + // run earcut on each half - earcutLinked( a, triangles, dim, minX, minY, invSize ); - earcutLinked( c, triangles, dim, minX, minY, invSize ); - return; + earcutLinked( a, triangles, dim, minX, minY, invSize ); + earcutLinked( c, triangles, dim, minX, minY, invSize ); + return; - } + } - b = b.next; + b = b.next; - } + } - a = a.next; + a = a.next; - } while ( a !== start ); + } while ( a !== start ); - } + } - // link every hole into the outer loop, producing a single-ring polygon without holes + // link every hole into the outer loop, producing a single-ring polygon without holes - function eliminateHoles( data, holeIndices, outerNode, dim ) { + function eliminateHoles( data, holeIndices, outerNode, dim ) { - var queue = [], i, len, start, end, list; + var queue = [], i, len, start, end, list; - for ( i = 0, len = holeIndices.length; i < len; i ++ ) { + for ( i = 0, len = holeIndices.length; i < len; i ++ ) { - start = holeIndices[ i ] * dim; - end = i < len - 1 ? holeIndices[ i + 1 ] * dim : data.length; - list = linkedList( data, start, end, dim, false ); - if ( list === list.next ) list.steiner = true; - queue.push( getLeftmost( list ) ); + start = holeIndices[ i ] * dim; + end = i < len - 1 ? holeIndices[ i + 1 ] * dim : data.length; + list = linkedList( data, start, end, dim, false ); + if ( list === list.next ) list.steiner = true; + queue.push( getLeftmost( list ) ); - } + } - queue.sort( compareX ); + queue.sort( compareX ); - // process holes from left to right + // process holes from left to right - for ( i = 0; i < queue.length; i ++ ) { + for ( i = 0; i < queue.length; i ++ ) { - eliminateHole( queue[ i ], outerNode ); - outerNode = filterPoints( outerNode, outerNode.next ); + eliminateHole( queue[ i ], outerNode ); + outerNode = filterPoints( outerNode, outerNode.next ); - } + } - return outerNode; + return outerNode; - } + } - function compareX( a, b ) { + function compareX( a, b ) { - return a.x - b.x; + return a.x - b.x; - } + } - // find a bridge between vertices that connects hole with an outer ring and and link it + // find a bridge between vertices that connects hole with an outer ring and and link it - function eliminateHole( hole, outerNode ) { + function eliminateHole( hole, outerNode ) { - outerNode = findHoleBridge( hole, outerNode ); + outerNode = findHoleBridge( hole, outerNode ); - if ( outerNode ) { + if ( outerNode ) { - var b = splitPolygon( outerNode, hole ); + var b = splitPolygon( outerNode, hole ); - filterPoints( b, b.next ); + filterPoints( b, b.next ); - } + } - } + } - // David Eberly's algorithm for finding a bridge between hole and outer polygon + // David Eberly's algorithm for finding a bridge between hole and outer polygon - function findHoleBridge( hole, outerNode ) { + function findHoleBridge( hole, outerNode ) { - var p = outerNode, - hx = hole.x, - hy = hole.y, - qx = - Infinity, - m; + var p = outerNode, + hx = hole.x, + hy = hole.y, + qx = - Infinity, + m; - // find a segment intersected by a ray from the hole's leftmost point to the left; - // segment's endpoint with lesser x will be potential connection point + // find a segment intersected by a ray from the hole's leftmost point to the left; + // segment's endpoint with lesser x will be potential connection point - do { + do { - if ( hy <= p.y && hy >= p.next.y && p.next.y !== p.y ) { + if ( hy <= p.y && hy >= p.next.y && p.next.y !== p.y ) { - var x = p.x + ( hy - p.y ) * ( p.next.x - p.x ) / ( p.next.y - p.y ); + var x = p.x + ( hy - p.y ) * ( p.next.x - p.x ) / ( p.next.y - p.y ); - if ( x <= hx && x > qx ) { + if ( x <= hx && x > qx ) { - qx = x; + qx = x; - if ( x === hx ) { + if ( x === hx ) { - if ( hy === p.y ) return p; - if ( hy === p.next.y ) return p.next; + if ( hy === p.y ) return p; + if ( hy === p.next.y ) return p.next; - } + } - m = p.x < p.next.x ? p : p.next; + m = p.x < p.next.x ? p : p.next; - } + } - } + } - p = p.next; + p = p.next; - } while ( p !== outerNode ); + } while ( p !== outerNode ); - if ( ! m ) return null; + if ( ! m ) return null; - if ( hx === qx ) return m.prev; // hole touches outer segment; pick lower endpoint + if ( hx === qx ) return m.prev; // hole touches outer segment; pick lower endpoint - // look for points inside the triangle of hole point, segment intersection and endpoint; - // if there are no points found, we have a valid connection; - // otherwise choose the point of the minimum angle with the ray as connection point + // look for points inside the triangle of hole point, segment intersection and endpoint; + // if there are no points found, we have a valid connection; + // otherwise choose the point of the minimum angle with the ray as connection point - var stop = m, - mx = m.x, - my = m.y, - tanMin = Infinity, - tan; + var stop = m, + mx = m.x, + my = m.y, + tanMin = Infinity, + tan; - p = m.next; + p = m.next; - while ( p !== stop ) { + while ( p !== stop ) { - if ( hx >= p.x && p.x >= mx && hx !== p.x && - pointInTriangle( hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y ) ) { + if ( hx >= p.x && p.x >= mx && hx !== p.x && + pointInTriangle( hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y ) ) { - tan = Math.abs( hy - p.y ) / ( hx - p.x ); // tangential + tan = Math.abs( hy - p.y ) / ( hx - p.x ); // tangential - if ( ( tan < tanMin || ( tan === tanMin && p.x > m.x ) ) && locallyInside( p, hole ) ) { + if ( ( tan < tanMin || ( tan === tanMin && p.x > m.x ) ) && locallyInside( p, hole ) ) { - m = p; - tanMin = tan; + m = p; + tanMin = tan; - } + } - } + } - p = p.next; + p = p.next; - } + } - return m; + return m; - } + } - // interlink polygon nodes in z-order + // interlink polygon nodes in z-order - function indexCurve( start, minX, minY, invSize ) { + function indexCurve( start, minX, minY, invSize ) { - var p = start; + var p = start; - do { + do { - if ( p.z === null ) p.z = zOrder( p.x, p.y, minX, minY, invSize ); - p.prevZ = p.prev; - p.nextZ = p.next; - p = p.next; + if ( p.z === null ) p.z = zOrder( p.x, p.y, minX, minY, invSize ); + p.prevZ = p.prev; + p.nextZ = p.next; + p = p.next; - } while ( p !== start ); + } while ( p !== start ); - p.prevZ.nextZ = null; - p.prevZ = null; + p.prevZ.nextZ = null; + p.prevZ = null; - sortLinked( p ); + sortLinked( p ); - } + } - // Simon Tatham's linked list merge sort algorithm - // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html + // Simon Tatham's linked list merge sort algorithm + // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html - function sortLinked( list ) { + function sortLinked( list ) { - var i, p, q, e, tail, numMerges, pSize, qSize, inSize = 1; + var i, p, q, e, tail, numMerges, pSize, qSize, inSize = 1; - do { + do { - p = list; - list = null; - tail = null; - numMerges = 0; + p = list; + list = null; + tail = null; + numMerges = 0; - while ( p ) { + while ( p ) { - numMerges ++; - q = p; - pSize = 0; + numMerges ++; + q = p; + pSize = 0; - for ( i = 0; i < inSize; i ++ ) { + for ( i = 0; i < inSize; i ++ ) { - pSize ++; - q = q.nextZ; - if ( ! q ) break; + pSize ++; + q = q.nextZ; + if ( ! q ) break; - } + } - qSize = inSize; + qSize = inSize; - while ( pSize > 0 || ( qSize > 0 && q ) ) { + while ( pSize > 0 || ( qSize > 0 && q ) ) { - if ( pSize !== 0 && ( qSize === 0 || ! q || p.z <= q.z ) ) { + if ( pSize !== 0 && ( qSize === 0 || ! q || p.z <= q.z ) ) { - e = p; - p = p.nextZ; - pSize --; + e = p; + p = p.nextZ; + pSize --; - } else { + } else { - e = q; - q = q.nextZ; - qSize --; + e = q; + q = q.nextZ; + qSize --; - } + } - if ( tail ) tail.nextZ = e; - else list = e; + if ( tail ) tail.nextZ = e; + else list = e; - e.prevZ = tail; - tail = e; + e.prevZ = tail; + tail = e; - } + } - p = q; + p = q; - } + } - tail.nextZ = null; - inSize *= 2; + tail.nextZ = null; + inSize *= 2; - } while ( numMerges > 1 ); + } while ( numMerges > 1 ); - return list; + return list; - } + } - // z-order of a point given coords and inverse of the longer side of data bbox + // z-order of a point given coords and inverse of the longer side of data bbox - function zOrder( x, y, minX, minY, invSize ) { + function zOrder( x, y, minX, minY, invSize ) { - // coords are transformed into non-negative 15-bit integer range + // coords are transformed into non-negative 15-bit integer range - x = 32767 * ( x - minX ) * invSize; - y = 32767 * ( y - minY ) * invSize; + x = 32767 * ( x - minX ) * invSize; + y = 32767 * ( y - minY ) * invSize; - x = ( x | ( x << 8 ) ) & 0x00FF00FF; - x = ( x | ( x << 4 ) ) & 0x0F0F0F0F; - x = ( x | ( x << 2 ) ) & 0x33333333; - x = ( x | ( x << 1 ) ) & 0x55555555; + x = ( x | ( x << 8 ) ) & 0x00FF00FF; + x = ( x | ( x << 4 ) ) & 0x0F0F0F0F; + x = ( x | ( x << 2 ) ) & 0x33333333; + x = ( x | ( x << 1 ) ) & 0x55555555; - y = ( y | ( y << 8 ) ) & 0x00FF00FF; - y = ( y | ( y << 4 ) ) & 0x0F0F0F0F; - y = ( y | ( y << 2 ) ) & 0x33333333; - y = ( y | ( y << 1 ) ) & 0x55555555; + y = ( y | ( y << 8 ) ) & 0x00FF00FF; + y = ( y | ( y << 4 ) ) & 0x0F0F0F0F; + y = ( y | ( y << 2 ) ) & 0x33333333; + y = ( y | ( y << 1 ) ) & 0x55555555; - return x | ( y << 1 ); + return x | ( y << 1 ); - } + } - // find the leftmost node of a polygon ring + // find the leftmost node of a polygon ring - function getLeftmost( start ) { + function getLeftmost( start ) { - var p = start, leftmost = start; + var p = start, leftmost = start; - do { + do { - if ( p.x < leftmost.x ) leftmost = p; - p = p.next; + if ( p.x < leftmost.x ) leftmost = p; + p = p.next; - } while ( p !== start ); + } while ( p !== start ); - return leftmost; + return leftmost; - } + } - // check if a point lies within a convex triangle + // check if a point lies within a convex triangle - function pointInTriangle( ax, ay, bx, by, cx, cy, px, py ) { + function pointInTriangle( ax, ay, bx, by, cx, cy, px, py ) { - return ( cx - px ) * ( ay - py ) - ( ax - px ) * ( cy - py ) >= 0 && - ( ax - px ) * ( by - py ) - ( bx - px ) * ( ay - py ) >= 0 && - ( bx - px ) * ( cy - py ) - ( cx - px ) * ( by - py ) >= 0; + return ( cx - px ) * ( ay - py ) - ( ax - px ) * ( cy - py ) >= 0 && + ( ax - px ) * ( by - py ) - ( bx - px ) * ( ay - py ) >= 0 && + ( bx - px ) * ( cy - py ) - ( cx - px ) * ( by - py ) >= 0; - } + } - // check if a diagonal between two polygon nodes is valid (lies in polygon interior) + // check if a diagonal between two polygon nodes is valid (lies in polygon interior) - function isValidDiagonal( a, b ) { + function isValidDiagonal( a, b ) { - return a.next.i !== b.i && a.prev.i !== b.i && ! intersectsPolygon( a, b ) && - locallyInside( a, b ) && locallyInside( b, a ) && middleInside( a, b ); + return a.next.i !== b.i && a.prev.i !== b.i && ! intersectsPolygon( a, b ) && + locallyInside( a, b ) && locallyInside( b, a ) && middleInside( a, b ); - } + } - // signed area of a triangle + // signed area of a triangle - function area( p, q, r ) { + function area( p, q, r ) { - return ( q.y - p.y ) * ( r.x - q.x ) - ( q.x - p.x ) * ( r.y - q.y ); + return ( q.y - p.y ) * ( r.x - q.x ) - ( q.x - p.x ) * ( r.y - q.y ); - } + } - // check if two points are equal + // check if two points are equal - function equals( p1, p2 ) { + function equals( p1, p2 ) { - return p1.x === p2.x && p1.y === p2.y; + return p1.x === p2.x && p1.y === p2.y; - } + } - // check if two segments intersect + // check if two segments intersect - function intersects( p1, q1, p2, q2 ) { + function intersects( p1, q1, p2, q2 ) { - if ( ( equals( p1, q1 ) && equals( p2, q2 ) ) || - ( equals( p1, q2 ) && equals( p2, q1 ) ) ) return true; + if ( ( equals( p1, q1 ) && equals( p2, q2 ) ) || + ( equals( p1, q2 ) && equals( p2, q1 ) ) ) return true; - return area( p1, q1, p2 ) > 0 !== area( p1, q1, q2 ) > 0 && - area( p2, q2, p1 ) > 0 !== area( p2, q2, q1 ) > 0; + return area( p1, q1, p2 ) > 0 !== area( p1, q1, q2 ) > 0 && + area( p2, q2, p1 ) > 0 !== area( p2, q2, q1 ) > 0; - } + } - // check if a polygon diagonal intersects any polygon segments + // check if a polygon diagonal intersects any polygon segments - function intersectsPolygon( a, b ) { + function intersectsPolygon( a, b ) { - var p = a; + var p = a; - do { + do { - if ( p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && - intersects( p, p.next, a, b ) ) { + if ( p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && + intersects( p, p.next, a, b ) ) { - return true; + return true; - } + } - p = p.next; + p = p.next; - } while ( p !== a ); + } while ( p !== a ); - return false; + return false; - } + } - // check if a polygon diagonal is locally inside the polygon + // check if a polygon diagonal is locally inside the polygon - function locallyInside( a, b ) { + function locallyInside( a, b ) { - return area( a.prev, a, a.next ) < 0 ? - area( a, b, a.next ) >= 0 && area( a, a.prev, b ) >= 0 : - area( a, b, a.prev ) < 0 || area( a, a.next, b ) < 0; + return area( a.prev, a, a.next ) < 0 ? + area( a, b, a.next ) >= 0 && area( a, a.prev, b ) >= 0 : + area( a, b, a.prev ) < 0 || area( a, a.next, b ) < 0; - } + } - // check if the middle point of a polygon diagonal is inside the polygon + // check if the middle point of a polygon diagonal is inside the polygon - function middleInside( a, b ) { + function middleInside( a, b ) { - var p = a, - inside = false, - px = ( a.x + b.x ) / 2, - py = ( a.y + b.y ) / 2; + var p = a, + inside = false, + px = ( a.x + b.x ) / 2, + py = ( a.y + b.y ) / 2; - do { + do { - if ( ( ( p.y > py ) !== ( p.next.y > py ) ) && p.next.y !== p.y && - ( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) ) { + if ( ( ( p.y > py ) !== ( p.next.y > py ) ) && p.next.y !== p.y && + ( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) ) { - inside = ! inside; + inside = ! inside; - } + } - p = p.next; + p = p.next; - } while ( p !== a ); + } while ( p !== a ); - return inside; + return inside; - } + } - // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; - // if one belongs to the outer ring and another to a hole, it merges it into a single ring + // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; + // if one belongs to the outer ring and another to a hole, it merges it into a single ring - function splitPolygon( a, b ) { + function splitPolygon( a, b ) { - var a2 = new Node( a.i, a.x, a.y ), - b2 = new Node( b.i, b.x, b.y ), - an = a.next, - bp = b.prev; + var a2 = new Node( a.i, a.x, a.y ), + b2 = new Node( b.i, b.x, b.y ), + an = a.next, + bp = b.prev; - a.next = b; - b.prev = a; + a.next = b; + b.prev = a; - a2.next = an; - an.prev = a2; + a2.next = an; + an.prev = a2; - b2.next = a2; - a2.prev = b2; + b2.next = a2; + a2.prev = b2; - bp.next = b2; - b2.prev = bp; + bp.next = b2; + b2.prev = bp; - return b2; + return b2; - } + } - // create a node and optionally link it with previous one (in a circular doubly linked list) + // create a node and optionally link it with previous one (in a circular doubly linked list) - function insertNode( i, x, y, last ) { + function insertNode( i, x, y, last ) { - var p = new Node( i, x, y ); + var p = new Node( i, x, y ); - if ( ! last ) { + if ( ! last ) { - p.prev = p; - p.next = p; + p.prev = p; + p.next = p; - } else { + } else { - p.next = last.next; - p.prev = last; - last.next.prev = p; - last.next = p; + p.next = last.next; + p.prev = last; + last.next.prev = p; + last.next = p; - } + } - return p; + return p; - } + } - function removeNode( p ) { + function removeNode( p ) { - p.next.prev = p.prev; - p.prev.next = p.next; + p.next.prev = p.prev; + p.prev.next = p.next; - if ( p.prevZ ) p.prevZ.nextZ = p.nextZ; - if ( p.nextZ ) p.nextZ.prevZ = p.prevZ; + if ( p.prevZ ) p.prevZ.nextZ = p.nextZ; + if ( p.nextZ ) p.nextZ.prevZ = p.prevZ; - } + } - function Node( i, x, y ) { + function Node( i, x, y ) { - // vertice index in coordinates array - this.i = i; + // vertice index in coordinates array + this.i = i; - // vertex coordinates - this.x = x; - this.y = y; + // vertex coordinates + this.x = x; + this.y = y; - // previous and next vertice nodes in a polygon ring - this.prev = null; - this.next = null; + // previous and next vertice nodes in a polygon ring + this.prev = null; + this.next = null; - // z-order curve value - this.z = null; + // z-order curve value + this.z = null; - // previous and next nodes in z-order - this.prevZ = null; - this.nextZ = null; + // previous and next nodes in z-order + this.prevZ = null; + this.nextZ = null; - // indicates whether this is a steiner point - this.steiner = false; + // indicates whether this is a steiner point + this.steiner = false; - } + } - function signedArea( data, start, end, dim ) { + function signedArea( data, start, end, dim ) { - var sum = 0; + var sum = 0; - for ( var i = start, j = end - dim; i < end; i += dim ) { + for ( var i = start, j = end - dim; i < end; i += dim ) { - sum += ( data[ j ] - data[ i ] ) * ( data[ i + 1 ] + data[ j + 1 ] ); - j = i; + sum += ( data[ j ] - data[ i ] ) * ( data[ i + 1 ] + data[ j + 1 ] ); + j = i; - } + } - return sum; + return sum; - } + } - /** - * @author zz85 / http://www.lab4games.net/zz85/blog - */ + /** + * @author zz85 / http://www.lab4games.net/zz85/blog + */ - var ShapeUtils = { + var ShapeUtils = { - // calculate area of the contour polygon + // calculate area of the contour polygon - area: function ( contour ) { + area: function ( contour ) { - var n = contour.length; - var a = 0.0; + var n = contour.length; + var a = 0.0; - for ( var p = n - 1, q = 0; q < n; p = q ++ ) { + for ( var p = n - 1, q = 0; q < n; p = q ++ ) { - a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y; + a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y; - } + } - return a * 0.5; + return a * 0.5; - }, + }, - isClockWise: function ( pts ) { + isClockWise: function ( pts ) { - return ShapeUtils.area( pts ) < 0; + return ShapeUtils.area( pts ) < 0; - }, + }, - triangulateShape: function ( contour, holes ) { + triangulateShape: function ( contour, holes ) { - var vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ] - var holeIndices = []; // array of hole indices - var faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ] + var vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ] + var holeIndices = []; // array of hole indices + var faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ] - removeDupEndPts( contour ); - addContour( vertices, contour ); + removeDupEndPts( contour ); + addContour( vertices, contour ); - // + // - var holeIndex = contour.length; + var holeIndex = contour.length; - holes.forEach( removeDupEndPts ); + holes.forEach( removeDupEndPts ); - for ( var i = 0; i < holes.length; i ++ ) { + for ( var i = 0; i < holes.length; i ++ ) { - holeIndices.push( holeIndex ); - holeIndex += holes[ i ].length; - addContour( vertices, holes[ i ] ); + holeIndices.push( holeIndex ); + holeIndex += holes[ i ].length; + addContour( vertices, holes[ i ] ); - } + } - // + // - var triangles = Earcut.triangulate( vertices, holeIndices ); + var triangles = Earcut.triangulate( vertices, holeIndices ); - // + // - for ( var i = 0; i < triangles.length; i += 3 ) { + for ( var i = 0; i < triangles.length; i += 3 ) { - faces.push( triangles.slice( i, i + 3 ) ); + faces.push( triangles.slice( i, i + 3 ) ); - } + } - return faces; + return faces; - } + } - }; + }; - function removeDupEndPts( points ) { + function removeDupEndPts( points ) { - var l = points.length; + var l = points.length; - if ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) { + if ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) { - points.pop(); + points.pop(); - } + } - } + } - function addContour( vertices, contour ) { + function addContour( vertices, contour ) { - for ( var i = 0; i < contour.length; i ++ ) { + for ( var i = 0; i < contour.length; i ++ ) { - vertices.push( contour[ i ].x ); - vertices.push( contour[ i ].y ); + vertices.push( contour[ i ].x ); + vertices.push( contour[ i ].y ); - } + } - } + } - /** - * @author zz85 / http://www.lab4games.net/zz85/blog - * - * Creates extruded geometry from a path shape. - * - * parameters = { - * - * curveSegments: , // number of points on the curves - * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too - * depth: , // Depth to extrude the shape - * - * bevelEnabled: , // turn on bevel - * bevelThickness: , // how deep into the original shape bevel goes - * bevelSize: , // how far from shape outline is bevel - * bevelSegments: , // number of bevel layers - * - * extrudePath: // curve to extrude shape along - * - * UVGenerator: // object that provides UV generator functions - * - * } - */ + /** + * @author zz85 / http://www.lab4games.net/zz85/blog + * + * Creates extruded geometry from a path shape. + * + * parameters = { + * + * curveSegments: , // number of points on the curves + * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too + * depth: , // Depth to extrude the shape + * + * bevelEnabled: , // turn on bevel + * bevelThickness: , // how deep into the original shape bevel goes + * bevelSize: , // how far from shape outline is bevel + * bevelSegments: , // number of bevel layers + * + * extrudePath: // curve to extrude shape along + * + * UVGenerator: // object that provides UV generator functions + * + * } + */ - // ExtrudeGeometry + // ExtrudeGeometry - function ExtrudeGeometry( shapes, options ) { + function ExtrudeGeometry( shapes, options ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'ExtrudeGeometry'; + this.type = 'ExtrudeGeometry'; - this.parameters = { - shapes: shapes, - options: options - }; + this.parameters = { + shapes: shapes, + options: options + }; - this.fromBufferGeometry( new ExtrudeBufferGeometry( shapes, options ) ); - this.mergeVertices(); + this.fromBufferGeometry( new ExtrudeBufferGeometry( shapes, options ) ); + this.mergeVertices(); - } + } - ExtrudeGeometry.prototype = Object.create( Geometry.prototype ); - ExtrudeGeometry.prototype.constructor = ExtrudeGeometry; + ExtrudeGeometry.prototype = Object.create( Geometry.prototype ); + ExtrudeGeometry.prototype.constructor = ExtrudeGeometry; - ExtrudeGeometry.prototype.toJSON = function () { + ExtrudeGeometry.prototype.toJSON = function () { - var data = Geometry.prototype.toJSON.call( this ); + var data = Geometry.prototype.toJSON.call( this ); - var shapes = this.parameters.shapes; - var options = this.parameters.options; + var shapes = this.parameters.shapes; + var options = this.parameters.options; - return toJSON( shapes, options, data ); + return toJSON( shapes, options, data ); - }; + }; - // ExtrudeBufferGeometry + // ExtrudeBufferGeometry - function ExtrudeBufferGeometry( shapes, options ) { + function ExtrudeBufferGeometry( shapes, options ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'ExtrudeBufferGeometry'; + this.type = 'ExtrudeBufferGeometry'; - this.parameters = { - shapes: shapes, - options: options - }; + this.parameters = { + shapes: shapes, + options: options + }; - shapes = Array.isArray( shapes ) ? shapes : [ shapes ]; + shapes = Array.isArray( shapes ) ? shapes : [ shapes ]; - var scope = this; + var scope = this; - var verticesArray = []; - var uvArray = []; + var verticesArray = []; + var uvArray = []; - for ( var i = 0, l = shapes.length; i < l; i ++ ) { + for ( var i = 0, l = shapes.length; i < l; i ++ ) { - var shape = shapes[ i ]; - addShape( shape ); + var shape = shapes[ i ]; + addShape( shape ); - } + } - // build geometry + // build geometry - this.addAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) ); + this.addAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) ); - this.computeVertexNormals(); + this.computeVertexNormals(); - // functions + // functions - function addShape( shape ) { + function addShape( shape ) { - var placeholder = []; + var placeholder = []; - // options + // options - var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; - var steps = options.steps !== undefined ? options.steps : 1; - var depth = options.depth !== undefined ? options.depth : 100; + var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12; + var steps = options.steps !== undefined ? options.steps : 1; + var depth = options.depth !== undefined ? options.depth : 100; - var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; - var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; - var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; - var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3; + var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; + var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; + var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; + var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3; - var extrudePath = options.extrudePath; + var extrudePath = options.extrudePath; - var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator; + var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator; - // deprecated options + // deprecated options - if ( options.amount !== undefined ) { + if ( options.amount !== undefined ) { - console.warn( 'THREE.ExtrudeBufferGeometry: amount has been renamed to depth.' ); - depth = options.amount; + console.warn( 'THREE.ExtrudeBufferGeometry: amount has been renamed to depth.' ); + depth = options.amount; - } + } - // + // - var extrudePts, extrudeByPath = false; - var splineTube, binormal, normal, position2; + var extrudePts, extrudeByPath = false; + var splineTube, binormal, normal, position2; - if ( extrudePath ) { + if ( extrudePath ) { - extrudePts = extrudePath.getSpacedPoints( steps ); + extrudePts = extrudePath.getSpacedPoints( steps ); - extrudeByPath = true; - bevelEnabled = false; // bevels not supported for path extrusion + extrudeByPath = true; + bevelEnabled = false; // bevels not supported for path extrusion - // SETUP TNB variables + // SETUP TNB variables - // TODO1 - have a .isClosed in spline? + // TODO1 - have a .isClosed in spline? - splineTube = extrudePath.computeFrenetFrames( steps, false ); + splineTube = extrudePath.computeFrenetFrames( steps, false ); - // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length); + // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length); - binormal = new Vector3(); - normal = new Vector3(); - position2 = new Vector3(); + binormal = new Vector3(); + normal = new Vector3(); + position2 = new Vector3(); - } + } - // Safeguards if bevels are not enabled + // Safeguards if bevels are not enabled - if ( ! bevelEnabled ) { + if ( ! bevelEnabled ) { - bevelSegments = 0; - bevelThickness = 0; - bevelSize = 0; + bevelSegments = 0; + bevelThickness = 0; + bevelSize = 0; - } + } - // Variables initialization + // Variables initialization - var ahole, h, hl; // looping of holes + var ahole, h, hl; // looping of holes - var shapePoints = shape.extractPoints( curveSegments ); + var shapePoints = shape.extractPoints( curveSegments ); - var vertices = shapePoints.shape; - var holes = shapePoints.holes; + var vertices = shapePoints.shape; + var holes = shapePoints.holes; - var reverse = ! ShapeUtils.isClockWise( vertices ); + var reverse = ! ShapeUtils.isClockWise( vertices ); - if ( reverse ) { + if ( reverse ) { - vertices = vertices.reverse(); + vertices = vertices.reverse(); - // Maybe we should also check if holes are in the opposite direction, just to be safe ... + // Maybe we should also check if holes are in the opposite direction, just to be safe ... - for ( h = 0, hl = holes.length; h < hl; h ++ ) { + for ( h = 0, hl = holes.length; h < hl; h ++ ) { - ahole = holes[ h ]; + ahole = holes[ h ]; - if ( ShapeUtils.isClockWise( ahole ) ) { + if ( ShapeUtils.isClockWise( ahole ) ) { - holes[ h ] = ahole.reverse(); + holes[ h ] = ahole.reverse(); - } + } - } + } - } + } - var faces = ShapeUtils.triangulateShape( vertices, holes ); + var faces = ShapeUtils.triangulateShape( vertices, holes ); - /* Vertices */ + /* Vertices */ - var contour = vertices; // vertices has all points but contour has only points of circumference + var contour = vertices; // vertices has all points but contour has only points of circumference - for ( h = 0, hl = holes.length; h < hl; h ++ ) { + for ( h = 0, hl = holes.length; h < hl; h ++ ) { - ahole = holes[ h ]; + ahole = holes[ h ]; - vertices = vertices.concat( ahole ); + vertices = vertices.concat( ahole ); - } + } - function scalePt2( pt, vec, size ) { + function scalePt2( pt, vec, size ) { - if ( ! vec ) console.error( "THREE.ExtrudeGeometry: vec does not exist" ); + if ( ! vec ) console.error( "THREE.ExtrudeGeometry: vec does not exist" ); - return vec.clone().multiplyScalar( size ).add( pt ); + return vec.clone().multiplyScalar( size ).add( pt ); - } + } - var b, bs, t, z, - vert, vlen = vertices.length, - face, flen = faces.length; + var b, bs, t, z, + vert, vlen = vertices.length, + face, flen = faces.length; - // Find directions for point movement + // Find directions for point movement - function getBevelVec( inPt, inPrev, inNext ) { + function getBevelVec( inPt, inPrev, inNext ) { - // computes for inPt the corresponding point inPt' on a new contour - // shifted by 1 unit (length of normalized vector) to the left - // if we walk along contour clockwise, this new contour is outside the old one - // - // inPt' is the intersection of the two lines parallel to the two - // adjacent edges of inPt at a distance of 1 unit on the left side. + // computes for inPt the corresponding point inPt' on a new contour + // shifted by 1 unit (length of normalized vector) to the left + // if we walk along contour clockwise, this new contour is outside the old one + // + // inPt' is the intersection of the two lines parallel to the two + // adjacent edges of inPt at a distance of 1 unit on the left side. - var v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt + var v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt - // good reading for geometry algorithms (here: line-line intersection) - // http://geomalgorithms.com/a05-_intersect-1.html + // good reading for geometry algorithms (here: line-line intersection) + // http://geomalgorithms.com/a05-_intersect-1.html - var v_prev_x = inPt.x - inPrev.x, - v_prev_y = inPt.y - inPrev.y; - var v_next_x = inNext.x - inPt.x, - v_next_y = inNext.y - inPt.y; + var v_prev_x = inPt.x - inPrev.x, + v_prev_y = inPt.y - inPrev.y; + var v_next_x = inNext.x - inPt.x, + v_next_y = inNext.y - inPt.y; - var v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y ); + var v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y ); - // check for collinear edges - var collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x ); + // check for collinear edges + var collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x ); - if ( Math.abs( collinear0 ) > Number.EPSILON ) { + if ( Math.abs( collinear0 ) > Number.EPSILON ) { - // not collinear + // not collinear - // length of vectors for normalizing + // length of vectors for normalizing - var v_prev_len = Math.sqrt( v_prev_lensq ); - var v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y ); + var v_prev_len = Math.sqrt( v_prev_lensq ); + var v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y ); - // shift adjacent points by unit vectors to the left + // shift adjacent points by unit vectors to the left - var ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len ); - var ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len ); + var ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len ); + var ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len ); - var ptNextShift_x = ( inNext.x - v_next_y / v_next_len ); - var ptNextShift_y = ( inNext.y + v_next_x / v_next_len ); + var ptNextShift_x = ( inNext.x - v_next_y / v_next_len ); + var ptNextShift_y = ( inNext.y + v_next_x / v_next_len ); - // scaling factor for v_prev to intersection point + // scaling factor for v_prev to intersection point - var sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y - - ( ptNextShift_y - ptPrevShift_y ) * v_next_x ) / - ( v_prev_x * v_next_y - v_prev_y * v_next_x ); + var sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y - + ( ptNextShift_y - ptPrevShift_y ) * v_next_x ) / + ( v_prev_x * v_next_y - v_prev_y * v_next_x ); - // vector from inPt to intersection point + // vector from inPt to intersection point - v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x ); - v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y ); + v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x ); + v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y ); - // Don't normalize!, otherwise sharp corners become ugly - // but prevent crazy spikes - var v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y ); - if ( v_trans_lensq <= 2 ) { + // Don't normalize!, otherwise sharp corners become ugly + // but prevent crazy spikes + var v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y ); + if ( v_trans_lensq <= 2 ) { - return new Vector2( v_trans_x, v_trans_y ); + return new Vector2( v_trans_x, v_trans_y ); - } else { + } else { - shrink_by = Math.sqrt( v_trans_lensq / 2 ); + shrink_by = Math.sqrt( v_trans_lensq / 2 ); - } + } - } else { + } else { - // handle special case of collinear edges + // handle special case of collinear edges - var direction_eq = false; // assumes: opposite - if ( v_prev_x > Number.EPSILON ) { + var direction_eq = false; // assumes: opposite + if ( v_prev_x > Number.EPSILON ) { - if ( v_next_x > Number.EPSILON ) { + if ( v_next_x > Number.EPSILON ) { - direction_eq = true; + direction_eq = true; - } + } - } else { + } else { - if ( v_prev_x < - Number.EPSILON ) { + if ( v_prev_x < - Number.EPSILON ) { - if ( v_next_x < - Number.EPSILON ) { + if ( v_next_x < - Number.EPSILON ) { - direction_eq = true; + direction_eq = true; - } + } - } else { + } else { - if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) { + if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) { - direction_eq = true; + direction_eq = true; - } + } - } + } - } + } - if ( direction_eq ) { + if ( direction_eq ) { - // console.log("Warning: lines are a straight sequence"); - v_trans_x = - v_prev_y; - v_trans_y = v_prev_x; - shrink_by = Math.sqrt( v_prev_lensq ); + // console.log("Warning: lines are a straight sequence"); + v_trans_x = - v_prev_y; + v_trans_y = v_prev_x; + shrink_by = Math.sqrt( v_prev_lensq ); - } else { + } else { - // console.log("Warning: lines are a straight spike"); - v_trans_x = v_prev_x; - v_trans_y = v_prev_y; - shrink_by = Math.sqrt( v_prev_lensq / 2 ); + // console.log("Warning: lines are a straight spike"); + v_trans_x = v_prev_x; + v_trans_y = v_prev_y; + shrink_by = Math.sqrt( v_prev_lensq / 2 ); - } + } - } + } - return new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by ); + return new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by ); - } + } - var contourMovements = []; + var contourMovements = []; - for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) { + for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) { - if ( j === il ) j = 0; - if ( k === il ) k = 0; + if ( j === il ) j = 0; + if ( k === il ) k = 0; - // (j)---(i)---(k) - // console.log('i,j,k', i, j , k) + // (j)---(i)---(k) + // console.log('i,j,k', i, j , k) - contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] ); + contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] ); - } + } - var holesMovements = [], - oneHoleMovements, verticesMovements = contourMovements.concat(); + var holesMovements = [], + oneHoleMovements, verticesMovements = contourMovements.concat(); - for ( h = 0, hl = holes.length; h < hl; h ++ ) { + for ( h = 0, hl = holes.length; h < hl; h ++ ) { - ahole = holes[ h ]; + ahole = holes[ h ]; - oneHoleMovements = []; + oneHoleMovements = []; - for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) { + for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) { - if ( j === il ) j = 0; - if ( k === il ) k = 0; + if ( j === il ) j = 0; + if ( k === il ) k = 0; - // (j)---(i)---(k) - oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] ); + // (j)---(i)---(k) + oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] ); - } + } - holesMovements.push( oneHoleMovements ); - verticesMovements = verticesMovements.concat( oneHoleMovements ); + holesMovements.push( oneHoleMovements ); + verticesMovements = verticesMovements.concat( oneHoleMovements ); - } + } - // Loop bevelSegments, 1 for the front, 1 for the back + // Loop bevelSegments, 1 for the front, 1 for the back - for ( b = 0; b < bevelSegments; b ++ ) { + for ( b = 0; b < bevelSegments; b ++ ) { - //for ( b = bevelSegments; b > 0; b -- ) { + //for ( b = bevelSegments; b > 0; b -- ) { - t = b / bevelSegments; - z = bevelThickness * Math.cos( t * Math.PI / 2 ); - bs = bevelSize * Math.sin( t * Math.PI / 2 ); + t = b / bevelSegments; + z = bevelThickness * Math.cos( t * Math.PI / 2 ); + bs = bevelSize * Math.sin( t * Math.PI / 2 ); - // contract shape + // contract shape - for ( i = 0, il = contour.length; i < il; i ++ ) { + for ( i = 0, il = contour.length; i < il; i ++ ) { - vert = scalePt2( contour[ i ], contourMovements[ i ], bs ); + vert = scalePt2( contour[ i ], contourMovements[ i ], bs ); - v( vert.x, vert.y, - z ); + v( vert.x, vert.y, - z ); - } + } - // expand holes + // expand holes - for ( h = 0, hl = holes.length; h < hl; h ++ ) { + for ( h = 0, hl = holes.length; h < hl; h ++ ) { - ahole = holes[ h ]; - oneHoleMovements = holesMovements[ h ]; + ahole = holes[ h ]; + oneHoleMovements = holesMovements[ h ]; - for ( i = 0, il = ahole.length; i < il; i ++ ) { + for ( i = 0, il = ahole.length; i < il; i ++ ) { - vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs ); + vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs ); - v( vert.x, vert.y, - z ); + v( vert.x, vert.y, - z ); - } + } - } + } - } + } - bs = bevelSize; + bs = bevelSize; - // Back facing vertices + // Back facing vertices - for ( i = 0; i < vlen; i ++ ) { + for ( i = 0; i < vlen; i ++ ) { - vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ]; + vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ]; - if ( ! extrudeByPath ) { + if ( ! extrudeByPath ) { - v( vert.x, vert.y, 0 ); + v( vert.x, vert.y, 0 ); - } else { + } else { - // v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x ); + // v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x ); - normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x ); - binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y ); + normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x ); + binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y ); - position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal ); + position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal ); - v( position2.x, position2.y, position2.z ); + v( position2.x, position2.y, position2.z ); - } + } - } + } - // Add stepped vertices... - // Including front facing vertices + // Add stepped vertices... + // Including front facing vertices - var s; + var s; - for ( s = 1; s <= steps; s ++ ) { + for ( s = 1; s <= steps; s ++ ) { - for ( i = 0; i < vlen; i ++ ) { + for ( i = 0; i < vlen; i ++ ) { - vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ]; + vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ]; - if ( ! extrudeByPath ) { + if ( ! extrudeByPath ) { - v( vert.x, vert.y, depth / steps * s ); + v( vert.x, vert.y, depth / steps * s ); - } else { + } else { - // v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x ); + // v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x ); - normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x ); - binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y ); + normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x ); + binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y ); - position2.copy( extrudePts[ s ] ).add( normal ).add( binormal ); + position2.copy( extrudePts[ s ] ).add( normal ).add( binormal ); - v( position2.x, position2.y, position2.z ); + v( position2.x, position2.y, position2.z ); - } + } - } + } - } + } - // Add bevel segments planes + // Add bevel segments planes - //for ( b = 1; b <= bevelSegments; b ++ ) { - for ( b = bevelSegments - 1; b >= 0; b -- ) { + //for ( b = 1; b <= bevelSegments; b ++ ) { + for ( b = bevelSegments - 1; b >= 0; b -- ) { - t = b / bevelSegments; - z = bevelThickness * Math.cos( t * Math.PI / 2 ); - bs = bevelSize * Math.sin( t * Math.PI / 2 ); + t = b / bevelSegments; + z = bevelThickness * Math.cos( t * Math.PI / 2 ); + bs = bevelSize * Math.sin( t * Math.PI / 2 ); - // contract shape + // contract shape - for ( i = 0, il = contour.length; i < il; i ++ ) { + for ( i = 0, il = contour.length; i < il; i ++ ) { - vert = scalePt2( contour[ i ], contourMovements[ i ], bs ); - v( vert.x, vert.y, depth + z ); + vert = scalePt2( contour[ i ], contourMovements[ i ], bs ); + v( vert.x, vert.y, depth + z ); - } + } - // expand holes + // expand holes - for ( h = 0, hl = holes.length; h < hl; h ++ ) { + for ( h = 0, hl = holes.length; h < hl; h ++ ) { - ahole = holes[ h ]; - oneHoleMovements = holesMovements[ h ]; + ahole = holes[ h ]; + oneHoleMovements = holesMovements[ h ]; - for ( i = 0, il = ahole.length; i < il; i ++ ) { + for ( i = 0, il = ahole.length; i < il; i ++ ) { - vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs ); + vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs ); - if ( ! extrudeByPath ) { + if ( ! extrudeByPath ) { - v( vert.x, vert.y, depth + z ); + v( vert.x, vert.y, depth + z ); - } else { + } else { - v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z ); + v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z ); - } + } - } + } - } + } - } + } - /* Faces */ + /* Faces */ - // Top and bottom faces + // Top and bottom faces - buildLidFaces(); + buildLidFaces(); - // Sides faces + // Sides faces - buildSideFaces(); + buildSideFaces(); - ///// Internal functions + ///// Internal functions - function buildLidFaces() { + function buildLidFaces() { - var start = verticesArray.length / 3; + var start = verticesArray.length / 3; - if ( bevelEnabled ) { + if ( bevelEnabled ) { - var layer = 0; // steps + 1 - var offset = vlen * layer; + var layer = 0; // steps + 1 + var offset = vlen * layer; - // Bottom faces + // Bottom faces - for ( i = 0; i < flen; i ++ ) { + for ( i = 0; i < flen; i ++ ) { - face = faces[ i ]; - f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset ); + face = faces[ i ]; + f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset ); - } + } - layer = steps + bevelSegments * 2; - offset = vlen * layer; + layer = steps + bevelSegments * 2; + offset = vlen * layer; - // Top faces + // Top faces - for ( i = 0; i < flen; i ++ ) { + for ( i = 0; i < flen; i ++ ) { - face = faces[ i ]; - f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset ); + face = faces[ i ]; + f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset ); - } + } - } else { + } else { - // Bottom faces + // Bottom faces - for ( i = 0; i < flen; i ++ ) { + for ( i = 0; i < flen; i ++ ) { - face = faces[ i ]; - f3( face[ 2 ], face[ 1 ], face[ 0 ] ); + face = faces[ i ]; + f3( face[ 2 ], face[ 1 ], face[ 0 ] ); - } + } - // Top faces + // Top faces - for ( i = 0; i < flen; i ++ ) { + for ( i = 0; i < flen; i ++ ) { - face = faces[ i ]; - f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps ); + face = faces[ i ]; + f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps ); - } + } - } + } - scope.addGroup( start, verticesArray.length / 3 - start, 0 ); + scope.addGroup( start, verticesArray.length / 3 - start, 0 ); - } + } - // Create faces for the z-sides of the shape + // Create faces for the z-sides of the shape - function buildSideFaces() { + function buildSideFaces() { - var start = verticesArray.length / 3; - var layeroffset = 0; - sidewalls( contour, layeroffset ); - layeroffset += contour.length; + var start = verticesArray.length / 3; + var layeroffset = 0; + sidewalls( contour, layeroffset ); + layeroffset += contour.length; - for ( h = 0, hl = holes.length; h < hl; h ++ ) { + for ( h = 0, hl = holes.length; h < hl; h ++ ) { - ahole = holes[ h ]; - sidewalls( ahole, layeroffset ); + ahole = holes[ h ]; + sidewalls( ahole, layeroffset ); - //, true - layeroffset += ahole.length; + //, true + layeroffset += ahole.length; - } + } - scope.addGroup( start, verticesArray.length / 3 - start, 1 ); + scope.addGroup( start, verticesArray.length / 3 - start, 1 ); - } + } - function sidewalls( contour, layeroffset ) { + function sidewalls( contour, layeroffset ) { - var j, k; - i = contour.length; + var j, k; + i = contour.length; - while ( -- i >= 0 ) { + while ( -- i >= 0 ) { - j = i; - k = i - 1; - if ( k < 0 ) k = contour.length - 1; + j = i; + k = i - 1; + if ( k < 0 ) k = contour.length - 1; - //console.log('b', i,j, i-1, k,vertices.length); + //console.log('b', i,j, i-1, k,vertices.length); - var s = 0, - sl = steps + bevelSegments * 2; + var s = 0, + sl = steps + bevelSegments * 2; - for ( s = 0; s < sl; s ++ ) { + for ( s = 0; s < sl; s ++ ) { - var slen1 = vlen * s; - var slen2 = vlen * ( s + 1 ); + var slen1 = vlen * s; + var slen2 = vlen * ( s + 1 ); - var a = layeroffset + j + slen1, - b = layeroffset + k + slen1, - c = layeroffset + k + slen2, - d = layeroffset + j + slen2; + var a = layeroffset + j + slen1, + b = layeroffset + k + slen1, + c = layeroffset + k + slen2, + d = layeroffset + j + slen2; - f4( a, b, c, d ); + f4( a, b, c, d ); - } + } - } + } - } + } - function v( x, y, z ) { + function v( x, y, z ) { - placeholder.push( x ); - placeholder.push( y ); - placeholder.push( z ); + placeholder.push( x ); + placeholder.push( y ); + placeholder.push( z ); - } + } - function f3( a, b, c ) { + function f3( a, b, c ) { - addVertex( a ); - addVertex( b ); - addVertex( c ); + addVertex( a ); + addVertex( b ); + addVertex( c ); - var nextIndex = verticesArray.length / 3; - var uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 ); + var nextIndex = verticesArray.length / 3; + var uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 ); - addUV( uvs[ 0 ] ); - addUV( uvs[ 1 ] ); - addUV( uvs[ 2 ] ); + addUV( uvs[ 0 ] ); + addUV( uvs[ 1 ] ); + addUV( uvs[ 2 ] ); - } + } - function f4( a, b, c, d ) { + function f4( a, b, c, d ) { - addVertex( a ); - addVertex( b ); - addVertex( d ); + addVertex( a ); + addVertex( b ); + addVertex( d ); - addVertex( b ); - addVertex( c ); - addVertex( d ); + addVertex( b ); + addVertex( c ); + addVertex( d ); - var nextIndex = verticesArray.length / 3; - var uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 ); + var nextIndex = verticesArray.length / 3; + var uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 ); - addUV( uvs[ 0 ] ); - addUV( uvs[ 1 ] ); - addUV( uvs[ 3 ] ); + addUV( uvs[ 0 ] ); + addUV( uvs[ 1 ] ); + addUV( uvs[ 3 ] ); - addUV( uvs[ 1 ] ); - addUV( uvs[ 2 ] ); - addUV( uvs[ 3 ] ); + addUV( uvs[ 1 ] ); + addUV( uvs[ 2 ] ); + addUV( uvs[ 3 ] ); - } + } - function addVertex( index ) { + function addVertex( index ) { - verticesArray.push( placeholder[ index * 3 + 0 ] ); - verticesArray.push( placeholder[ index * 3 + 1 ] ); - verticesArray.push( placeholder[ index * 3 + 2 ] ); + verticesArray.push( placeholder[ index * 3 + 0 ] ); + verticesArray.push( placeholder[ index * 3 + 1 ] ); + verticesArray.push( placeholder[ index * 3 + 2 ] ); - } + } - function addUV( vector2 ) { + function addUV( vector2 ) { - uvArray.push( vector2.x ); - uvArray.push( vector2.y ); + uvArray.push( vector2.x ); + uvArray.push( vector2.y ); - } + } - } + } - } + } - ExtrudeBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - ExtrudeBufferGeometry.prototype.constructor = ExtrudeBufferGeometry; + ExtrudeBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + ExtrudeBufferGeometry.prototype.constructor = ExtrudeBufferGeometry; - ExtrudeBufferGeometry.prototype.toJSON = function () { + ExtrudeBufferGeometry.prototype.toJSON = function () { - var data = BufferGeometry.prototype.toJSON.call( this ); + var data = BufferGeometry.prototype.toJSON.call( this ); - var shapes = this.parameters.shapes; - var options = this.parameters.options; + var shapes = this.parameters.shapes; + var options = this.parameters.options; - return toJSON( shapes, options, data ); + return toJSON( shapes, options, data ); - }; + }; - // + // - var WorldUVGenerator = { + var WorldUVGenerator = { - generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) { + generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) { - var a_x = vertices[ indexA * 3 ]; - var a_y = vertices[ indexA * 3 + 1 ]; - var b_x = vertices[ indexB * 3 ]; - var b_y = vertices[ indexB * 3 + 1 ]; - var c_x = vertices[ indexC * 3 ]; - var c_y = vertices[ indexC * 3 + 1 ]; + var a_x = vertices[ indexA * 3 ]; + var a_y = vertices[ indexA * 3 + 1 ]; + var b_x = vertices[ indexB * 3 ]; + var b_y = vertices[ indexB * 3 + 1 ]; + var c_x = vertices[ indexC * 3 ]; + var c_y = vertices[ indexC * 3 + 1 ]; - return [ - new Vector2( a_x, a_y ), - new Vector2( b_x, b_y ), - new Vector2( c_x, c_y ) - ]; + return [ + new Vector2( a_x, a_y ), + new Vector2( b_x, b_y ), + new Vector2( c_x, c_y ) + ]; - }, + }, - generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) { + generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) { - var a_x = vertices[ indexA * 3 ]; - var a_y = vertices[ indexA * 3 + 1 ]; - var a_z = vertices[ indexA * 3 + 2 ]; - var b_x = vertices[ indexB * 3 ]; - var b_y = vertices[ indexB * 3 + 1 ]; - var b_z = vertices[ indexB * 3 + 2 ]; - var c_x = vertices[ indexC * 3 ]; - var c_y = vertices[ indexC * 3 + 1 ]; - var c_z = vertices[ indexC * 3 + 2 ]; - var d_x = vertices[ indexD * 3 ]; - var d_y = vertices[ indexD * 3 + 1 ]; - var d_z = vertices[ indexD * 3 + 2 ]; + var a_x = vertices[ indexA * 3 ]; + var a_y = vertices[ indexA * 3 + 1 ]; + var a_z = vertices[ indexA * 3 + 2 ]; + var b_x = vertices[ indexB * 3 ]; + var b_y = vertices[ indexB * 3 + 1 ]; + var b_z = vertices[ indexB * 3 + 2 ]; + var c_x = vertices[ indexC * 3 ]; + var c_y = vertices[ indexC * 3 + 1 ]; + var c_z = vertices[ indexC * 3 + 2 ]; + var d_x = vertices[ indexD * 3 ]; + var d_y = vertices[ indexD * 3 + 1 ]; + var d_z = vertices[ indexD * 3 + 2 ]; - if ( Math.abs( a_y - b_y ) < 0.01 ) { + if ( Math.abs( a_y - b_y ) < 0.01 ) { - return [ - new Vector2( a_x, 1 - a_z ), - new Vector2( b_x, 1 - b_z ), - new Vector2( c_x, 1 - c_z ), - new Vector2( d_x, 1 - d_z ) - ]; + return [ + new Vector2( a_x, 1 - a_z ), + new Vector2( b_x, 1 - b_z ), + new Vector2( c_x, 1 - c_z ), + new Vector2( d_x, 1 - d_z ) + ]; - } else { + } else { - return [ - new Vector2( a_y, 1 - a_z ), - new Vector2( b_y, 1 - b_z ), - new Vector2( c_y, 1 - c_z ), - new Vector2( d_y, 1 - d_z ) - ]; + return [ + new Vector2( a_y, 1 - a_z ), + new Vector2( b_y, 1 - b_z ), + new Vector2( c_y, 1 - c_z ), + new Vector2( d_y, 1 - d_z ) + ]; - } + } - } - }; + } + }; - function toJSON( shapes, options, data ) { + function toJSON( shapes, options, data ) { - // + // - data.shapes = []; + data.shapes = []; - if ( Array.isArray( shapes ) ) { + if ( Array.isArray( shapes ) ) { - for ( var i = 0, l = shapes.length; i < l; i ++ ) { + for ( var i = 0, l = shapes.length; i < l; i ++ ) { - var shape = shapes[ i ]; + var shape = shapes[ i ]; - data.shapes.push( shape.uuid ); + data.shapes.push( shape.uuid ); - } + } - } else { + } else { - data.shapes.push( shapes.uuid ); + data.shapes.push( shapes.uuid ); - } + } - // + // - if ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON(); + if ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON(); - return data; + return data; - } + } - /** - * @author zz85 / http://www.lab4games.net/zz85/blog - * @author alteredq / http://alteredqualia.com/ - * - * Text = 3D Text - * - * parameters = { - * font: , // font - * - * size: , // size of the text - * height: , // thickness to extrude text - * curveSegments: , // number of points on the curves - * - * bevelEnabled: , // turn on bevel - * bevelThickness: , // how deep into text bevel goes - * bevelSize: // how far from text outline is bevel - * } - */ + /** + * @author zz85 / http://www.lab4games.net/zz85/blog + * @author alteredq / http://alteredqualia.com/ + * + * Text = 3D Text + * + * parameters = { + * font: , // font + * + * size: , // size of the text + * height: , // thickness to extrude text + * curveSegments: , // number of points on the curves + * + * bevelEnabled: , // turn on bevel + * bevelThickness: , // how deep into text bevel goes + * bevelSize: // how far from text outline is bevel + * } + */ - // TextGeometry + // TextGeometry - function TextGeometry( text, parameters ) { + function TextGeometry( text, parameters ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'TextGeometry'; + this.type = 'TextGeometry'; - this.parameters = { - text: text, - parameters: parameters - }; + this.parameters = { + text: text, + parameters: parameters + }; - this.fromBufferGeometry( new TextBufferGeometry( text, parameters ) ); - this.mergeVertices(); + this.fromBufferGeometry( new TextBufferGeometry( text, parameters ) ); + this.mergeVertices(); - } + } - TextGeometry.prototype = Object.create( Geometry.prototype ); - TextGeometry.prototype.constructor = TextGeometry; + TextGeometry.prototype = Object.create( Geometry.prototype ); + TextGeometry.prototype.constructor = TextGeometry; - // TextBufferGeometry + // TextBufferGeometry - function TextBufferGeometry( text, parameters ) { + function TextBufferGeometry( text, parameters ) { - parameters = parameters || {}; + parameters = parameters || {}; - var font = parameters.font; + var font = parameters.font; - if ( ! ( font && font.isFont ) ) { + if ( ! ( font && font.isFont ) ) { - console.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' ); - return new Geometry(); + console.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' ); + return new Geometry(); - } + } - var shapes = font.generateShapes( text, parameters.size ); + var shapes = font.generateShapes( text, parameters.size ); - // translate parameters to ExtrudeGeometry API + // translate parameters to ExtrudeGeometry API - parameters.depth = parameters.height !== undefined ? parameters.height : 50; + parameters.depth = parameters.height !== undefined ? parameters.height : 50; - // defaults + // defaults - if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10; - if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8; - if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false; + if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10; + if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8; + if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false; - ExtrudeBufferGeometry.call( this, shapes, parameters ); + ExtrudeBufferGeometry.call( this, shapes, parameters ); - this.type = 'TextBufferGeometry'; + this.type = 'TextBufferGeometry'; - } + } - TextBufferGeometry.prototype = Object.create( ExtrudeBufferGeometry.prototype ); - TextBufferGeometry.prototype.constructor = TextBufferGeometry; + TextBufferGeometry.prototype = Object.create( ExtrudeBufferGeometry.prototype ); + TextBufferGeometry.prototype.constructor = TextBufferGeometry; - /** - * @author mrdoob / http://mrdoob.com/ - * @author benaadams / https://twitter.com/ben_a_adams - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author benaadams / https://twitter.com/ben_a_adams + * @author Mugen87 / https://github.com/Mugen87 + */ - // SphereGeometry + // SphereGeometry - function SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) { + function SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'SphereGeometry'; + this.type = 'SphereGeometry'; - this.parameters = { - radius: radius, - widthSegments: widthSegments, - heightSegments: heightSegments, - phiStart: phiStart, - phiLength: phiLength, - thetaStart: thetaStart, - thetaLength: thetaLength - }; + this.parameters = { + radius: radius, + widthSegments: widthSegments, + heightSegments: heightSegments, + phiStart: phiStart, + phiLength: phiLength, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - this.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) ); - this.mergeVertices(); + this.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) ); + this.mergeVertices(); - } + } - SphereGeometry.prototype = Object.create( Geometry.prototype ); - SphereGeometry.prototype.constructor = SphereGeometry; + SphereGeometry.prototype = Object.create( Geometry.prototype ); + SphereGeometry.prototype.constructor = SphereGeometry; - // SphereBufferGeometry + // SphereBufferGeometry - function SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) { + function SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'SphereBufferGeometry'; + this.type = 'SphereBufferGeometry'; - this.parameters = { - radius: radius, - widthSegments: widthSegments, - heightSegments: heightSegments, - phiStart: phiStart, - phiLength: phiLength, - thetaStart: thetaStart, - thetaLength: thetaLength - }; + this.parameters = { + radius: radius, + widthSegments: widthSegments, + heightSegments: heightSegments, + phiStart: phiStart, + phiLength: phiLength, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - radius = radius || 1; + radius = radius || 1; - widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 ); - heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 ); + widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 ); + heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 ); - phiStart = phiStart !== undefined ? phiStart : 0; - phiLength = phiLength !== undefined ? phiLength : Math.PI * 2; + phiStart = phiStart !== undefined ? phiStart : 0; + phiLength = phiLength !== undefined ? phiLength : Math.PI * 2; - thetaStart = thetaStart !== undefined ? thetaStart : 0; - thetaLength = thetaLength !== undefined ? thetaLength : Math.PI; + thetaStart = thetaStart !== undefined ? thetaStart : 0; + thetaLength = thetaLength !== undefined ? thetaLength : Math.PI; - var thetaEnd = thetaStart + thetaLength; + var thetaEnd = thetaStart + thetaLength; - var ix, iy; + var ix, iy; - var index = 0; - var grid = []; + var index = 0; + var grid = []; - var vertex = new Vector3(); - var normal = new Vector3(); + var vertex = new Vector3(); + var normal = new Vector3(); - // buffers + // buffers - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - // generate vertices, normals and uvs + // generate vertices, normals and uvs - for ( iy = 0; iy <= heightSegments; iy ++ ) { + for ( iy = 0; iy <= heightSegments; iy ++ ) { - var verticesRow = []; + var verticesRow = []; - var v = iy / heightSegments; + var v = iy / heightSegments; - for ( ix = 0; ix <= widthSegments; ix ++ ) { + for ( ix = 0; ix <= widthSegments; ix ++ ) { - var u = ix / widthSegments; + var u = ix / widthSegments; - // vertex + // vertex - vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ); - vertex.y = radius * Math.cos( thetaStart + v * thetaLength ); - vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ); + vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ); + vertex.y = radius * Math.cos( thetaStart + v * thetaLength ); + vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ); - vertices.push( vertex.x, vertex.y, vertex.z ); + vertices.push( vertex.x, vertex.y, vertex.z ); - // normal + // normal - normal.set( vertex.x, vertex.y, vertex.z ).normalize(); - normals.push( normal.x, normal.y, normal.z ); + normal.set( vertex.x, vertex.y, vertex.z ).normalize(); + normals.push( normal.x, normal.y, normal.z ); - // uv + // uv - uvs.push( u, 1 - v ); + uvs.push( u, 1 - v ); - verticesRow.push( index ++ ); + verticesRow.push( index ++ ); - } + } - grid.push( verticesRow ); + grid.push( verticesRow ); - } + } - // indices + // indices - for ( iy = 0; iy < heightSegments; iy ++ ) { + for ( iy = 0; iy < heightSegments; iy ++ ) { - for ( ix = 0; ix < widthSegments; ix ++ ) { + for ( ix = 0; ix < widthSegments; ix ++ ) { - var a = grid[ iy ][ ix + 1 ]; - var b = grid[ iy ][ ix ]; - var c = grid[ iy + 1 ][ ix ]; - var d = grid[ iy + 1 ][ ix + 1 ]; + var a = grid[ iy ][ ix + 1 ]; + var b = grid[ iy ][ ix ]; + var c = grid[ iy + 1 ][ ix ]; + var d = grid[ iy + 1 ][ ix + 1 ]; - if ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d ); - if ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d ); + if ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d ); + if ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d ); - } + } - } + } - // build geometry + // build geometry - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setIndex( indices ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - } + } - SphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - SphereBufferGeometry.prototype.constructor = SphereBufferGeometry; + SphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + SphereBufferGeometry.prototype.constructor = SphereBufferGeometry; - /** - * @author Kaleb Murphy - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author Kaleb Murphy + * @author Mugen87 / https://github.com/Mugen87 + */ - // RingGeometry + // RingGeometry - function RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { + function RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'RingGeometry'; + this.type = 'RingGeometry'; - this.parameters = { - innerRadius: innerRadius, - outerRadius: outerRadius, - thetaSegments: thetaSegments, - phiSegments: phiSegments, - thetaStart: thetaStart, - thetaLength: thetaLength - }; + this.parameters = { + innerRadius: innerRadius, + outerRadius: outerRadius, + thetaSegments: thetaSegments, + phiSegments: phiSegments, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - this.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) ); - this.mergeVertices(); + this.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) ); + this.mergeVertices(); - } + } - RingGeometry.prototype = Object.create( Geometry.prototype ); - RingGeometry.prototype.constructor = RingGeometry; + RingGeometry.prototype = Object.create( Geometry.prototype ); + RingGeometry.prototype.constructor = RingGeometry; - // RingBufferGeometry + // RingBufferGeometry - function RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { + function RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'RingBufferGeometry'; + this.type = 'RingBufferGeometry'; - this.parameters = { - innerRadius: innerRadius, - outerRadius: outerRadius, - thetaSegments: thetaSegments, - phiSegments: phiSegments, - thetaStart: thetaStart, - thetaLength: thetaLength - }; + this.parameters = { + innerRadius: innerRadius, + outerRadius: outerRadius, + thetaSegments: thetaSegments, + phiSegments: phiSegments, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - innerRadius = innerRadius || 0.5; - outerRadius = outerRadius || 1; + innerRadius = innerRadius || 0.5; + outerRadius = outerRadius || 1; - thetaStart = thetaStart !== undefined ? thetaStart : 0; - thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; + thetaStart = thetaStart !== undefined ? thetaStart : 0; + thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; - thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8; - phiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1; + thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8; + phiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1; - // buffers + // buffers - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - // some helper variables + // some helper variables - var segment; - var radius = innerRadius; - var radiusStep = ( ( outerRadius - innerRadius ) / phiSegments ); - var vertex = new Vector3(); - var uv = new Vector2(); - var j, i; + var segment; + var radius = innerRadius; + var radiusStep = ( ( outerRadius - innerRadius ) / phiSegments ); + var vertex = new Vector3(); + var uv = new Vector2(); + var j, i; - // generate vertices, normals and uvs + // generate vertices, normals and uvs - for ( j = 0; j <= phiSegments; j ++ ) { + for ( j = 0; j <= phiSegments; j ++ ) { - for ( i = 0; i <= thetaSegments; i ++ ) { + for ( i = 0; i <= thetaSegments; i ++ ) { - // values are generate from the inside of the ring to the outside + // values are generate from the inside of the ring to the outside - segment = thetaStart + i / thetaSegments * thetaLength; + segment = thetaStart + i / thetaSegments * thetaLength; - // vertex + // vertex - vertex.x = radius * Math.cos( segment ); - vertex.y = radius * Math.sin( segment ); + vertex.x = radius * Math.cos( segment ); + vertex.y = radius * Math.sin( segment ); - vertices.push( vertex.x, vertex.y, vertex.z ); + vertices.push( vertex.x, vertex.y, vertex.z ); - // normal + // normal - normals.push( 0, 0, 1 ); + normals.push( 0, 0, 1 ); - // uv + // uv - uv.x = ( vertex.x / outerRadius + 1 ) / 2; - uv.y = ( vertex.y / outerRadius + 1 ) / 2; + uv.x = ( vertex.x / outerRadius + 1 ) / 2; + uv.y = ( vertex.y / outerRadius + 1 ) / 2; - uvs.push( uv.x, uv.y ); + uvs.push( uv.x, uv.y ); - } + } - // increase the radius for next row of vertices + // increase the radius for next row of vertices - radius += radiusStep; + radius += radiusStep; - } + } - // indices + // indices - for ( j = 0; j < phiSegments; j ++ ) { + for ( j = 0; j < phiSegments; j ++ ) { - var thetaSegmentLevel = j * ( thetaSegments + 1 ); + var thetaSegmentLevel = j * ( thetaSegments + 1 ); - for ( i = 0; i < thetaSegments; i ++ ) { + for ( i = 0; i < thetaSegments; i ++ ) { - segment = i + thetaSegmentLevel; + segment = i + thetaSegmentLevel; - var a = segment; - var b = segment + thetaSegments + 1; - var c = segment + thetaSegments + 2; - var d = segment + 1; + var a = segment; + var b = segment + thetaSegments + 1; + var c = segment + thetaSegments + 2; + var d = segment + 1; - // faces + // faces - indices.push( a, b, d ); - indices.push( b, c, d ); + indices.push( a, b, d ); + indices.push( b, c, d ); - } + } - } + } - // build geometry + // build geometry - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setIndex( indices ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - } + } - RingBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - RingBufferGeometry.prototype.constructor = RingBufferGeometry; + RingBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + RingBufferGeometry.prototype.constructor = RingBufferGeometry; - /** - * @author astrodud / http://astrodud.isgreat.org/ - * @author zz85 / https://github.com/zz85 - * @author bhouston / http://clara.io - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author astrodud / http://astrodud.isgreat.org/ + * @author zz85 / https://github.com/zz85 + * @author bhouston / http://clara.io + * @author Mugen87 / https://github.com/Mugen87 + */ - // LatheGeometry + // LatheGeometry - function LatheGeometry( points, segments, phiStart, phiLength ) { + function LatheGeometry( points, segments, phiStart, phiLength ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'LatheGeometry'; + this.type = 'LatheGeometry'; - this.parameters = { - points: points, - segments: segments, - phiStart: phiStart, - phiLength: phiLength - }; + this.parameters = { + points: points, + segments: segments, + phiStart: phiStart, + phiLength: phiLength + }; - this.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) ); - this.mergeVertices(); + this.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) ); + this.mergeVertices(); - } + } - LatheGeometry.prototype = Object.create( Geometry.prototype ); - LatheGeometry.prototype.constructor = LatheGeometry; + LatheGeometry.prototype = Object.create( Geometry.prototype ); + LatheGeometry.prototype.constructor = LatheGeometry; - // LatheBufferGeometry + // LatheBufferGeometry - function LatheBufferGeometry( points, segments, phiStart, phiLength ) { + function LatheBufferGeometry( points, segments, phiStart, phiLength ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'LatheBufferGeometry'; + this.type = 'LatheBufferGeometry'; - this.parameters = { - points: points, - segments: segments, - phiStart: phiStart, - phiLength: phiLength - }; + this.parameters = { + points: points, + segments: segments, + phiStart: phiStart, + phiLength: phiLength + }; - segments = Math.floor( segments ) || 12; - phiStart = phiStart || 0; - phiLength = phiLength || Math.PI * 2; + segments = Math.floor( segments ) || 12; + phiStart = phiStart || 0; + phiLength = phiLength || Math.PI * 2; - // clamp phiLength so it's in range of [ 0, 2PI ] + // clamp phiLength so it's in range of [ 0, 2PI ] - phiLength = _Math.clamp( phiLength, 0, Math.PI * 2 ); + phiLength = _Math.clamp( phiLength, 0, Math.PI * 2 ); - // buffers + // buffers - var indices = []; - var vertices = []; - var uvs = []; + var indices = []; + var vertices = []; + var uvs = []; - // helper variables + // helper variables - var base; - var inverseSegments = 1.0 / segments; - var vertex = new Vector3(); - var uv = new Vector2(); - var i, j; + var base; + var inverseSegments = 1.0 / segments; + var vertex = new Vector3(); + var uv = new Vector2(); + var i, j; - // generate vertices and uvs + // generate vertices and uvs - for ( i = 0; i <= segments; i ++ ) { + for ( i = 0; i <= segments; i ++ ) { - var phi = phiStart + i * inverseSegments * phiLength; + var phi = phiStart + i * inverseSegments * phiLength; - var sin = Math.sin( phi ); - var cos = Math.cos( phi ); + var sin = Math.sin( phi ); + var cos = Math.cos( phi ); - for ( j = 0; j <= ( points.length - 1 ); j ++ ) { + for ( j = 0; j <= ( points.length - 1 ); j ++ ) { - // vertex + // vertex - vertex.x = points[ j ].x * sin; - vertex.y = points[ j ].y; - vertex.z = points[ j ].x * cos; + vertex.x = points[ j ].x * sin; + vertex.y = points[ j ].y; + vertex.z = points[ j ].x * cos; - vertices.push( vertex.x, vertex.y, vertex.z ); + vertices.push( vertex.x, vertex.y, vertex.z ); - // uv + // uv - uv.x = i / segments; - uv.y = j / ( points.length - 1 ); + uv.x = i / segments; + uv.y = j / ( points.length - 1 ); - uvs.push( uv.x, uv.y ); + uvs.push( uv.x, uv.y ); - } + } - } + } - // indices + // indices - for ( i = 0; i < segments; i ++ ) { + for ( i = 0; i < segments; i ++ ) { - for ( j = 0; j < ( points.length - 1 ); j ++ ) { + for ( j = 0; j < ( points.length - 1 ); j ++ ) { - base = j + i * points.length; + base = j + i * points.length; - var a = base; - var b = base + points.length; - var c = base + points.length + 1; - var d = base + 1; + var a = base; + var b = base + points.length; + var c = base + points.length + 1; + var d = base + 1; - // faces + // faces - indices.push( a, b, d ); - indices.push( b, c, d ); + indices.push( a, b, d ); + indices.push( b, c, d ); - } + } - } + } - // build geometry + // build geometry - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setIndex( indices ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - // generate normals + // generate normals - this.computeVertexNormals(); + this.computeVertexNormals(); - // if the geometry is closed, we need to average the normals along the seam. - // because the corresponding vertices are identical (but still have different UVs). + // if the geometry is closed, we need to average the normals along the seam. + // because the corresponding vertices are identical (but still have different UVs). - if ( phiLength === Math.PI * 2 ) { + if ( phiLength === Math.PI * 2 ) { - var normals = this.attributes.normal.array; - var n1 = new Vector3(); - var n2 = new Vector3(); - var n = new Vector3(); + var normals = this.attributes.normal.array; + var n1 = new Vector3(); + var n2 = new Vector3(); + var n = new Vector3(); - // this is the buffer offset for the last line of vertices + // this is the buffer offset for the last line of vertices - base = segments * points.length * 3; + base = segments * points.length * 3; - for ( i = 0, j = 0; i < points.length; i ++, j += 3 ) { + for ( i = 0, j = 0; i < points.length; i ++, j += 3 ) { - // select the normal of the vertex in the first line + // select the normal of the vertex in the first line - n1.x = normals[ j + 0 ]; - n1.y = normals[ j + 1 ]; - n1.z = normals[ j + 2 ]; + n1.x = normals[ j + 0 ]; + n1.y = normals[ j + 1 ]; + n1.z = normals[ j + 2 ]; - // select the normal of the vertex in the last line + // select the normal of the vertex in the last line - n2.x = normals[ base + j + 0 ]; - n2.y = normals[ base + j + 1 ]; - n2.z = normals[ base + j + 2 ]; + n2.x = normals[ base + j + 0 ]; + n2.y = normals[ base + j + 1 ]; + n2.z = normals[ base + j + 2 ]; - // average normals + // average normals - n.addVectors( n1, n2 ).normalize(); + n.addVectors( n1, n2 ).normalize(); - // assign the new values to both normals + // assign the new values to both normals - normals[ j + 0 ] = normals[ base + j + 0 ] = n.x; - normals[ j + 1 ] = normals[ base + j + 1 ] = n.y; - normals[ j + 2 ] = normals[ base + j + 2 ] = n.z; + normals[ j + 0 ] = normals[ base + j + 0 ] = n.x; + normals[ j + 1 ] = normals[ base + j + 1 ] = n.y; + normals[ j + 2 ] = normals[ base + j + 2 ] = n.z; - } + } - } + } - } + } - LatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - LatheBufferGeometry.prototype.constructor = LatheBufferGeometry; + LatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + LatheBufferGeometry.prototype.constructor = LatheBufferGeometry; - /** - * @author jonobr1 / http://jonobr1.com - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author jonobr1 / http://jonobr1.com + * @author Mugen87 / https://github.com/Mugen87 + */ - // ShapeGeometry + // ShapeGeometry - function ShapeGeometry( shapes, curveSegments ) { + function ShapeGeometry( shapes, curveSegments ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'ShapeGeometry'; + this.type = 'ShapeGeometry'; - if ( typeof curveSegments === 'object' ) { + if ( typeof curveSegments === 'object' ) { - console.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' ); + console.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' ); - curveSegments = curveSegments.curveSegments; + curveSegments = curveSegments.curveSegments; - } + } - this.parameters = { - shapes: shapes, - curveSegments: curveSegments - }; + this.parameters = { + shapes: shapes, + curveSegments: curveSegments + }; - this.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) ); - this.mergeVertices(); + this.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) ); + this.mergeVertices(); - } + } - ShapeGeometry.prototype = Object.create( Geometry.prototype ); - ShapeGeometry.prototype.constructor = ShapeGeometry; + ShapeGeometry.prototype = Object.create( Geometry.prototype ); + ShapeGeometry.prototype.constructor = ShapeGeometry; - ShapeGeometry.prototype.toJSON = function () { + ShapeGeometry.prototype.toJSON = function () { - var data = Geometry.prototype.toJSON.call( this ); + var data = Geometry.prototype.toJSON.call( this ); - var shapes = this.parameters.shapes; + var shapes = this.parameters.shapes; - return toJSON$1( shapes, data ); + return toJSON$1( shapes, data ); - }; + }; - // ShapeBufferGeometry + // ShapeBufferGeometry - function ShapeBufferGeometry( shapes, curveSegments ) { + function ShapeBufferGeometry( shapes, curveSegments ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'ShapeBufferGeometry'; + this.type = 'ShapeBufferGeometry'; - this.parameters = { - shapes: shapes, - curveSegments: curveSegments - }; + this.parameters = { + shapes: shapes, + curveSegments: curveSegments + }; - curveSegments = curveSegments || 12; + curveSegments = curveSegments || 12; - // buffers + // buffers - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - // helper variables + // helper variables - var groupStart = 0; - var groupCount = 0; + var groupStart = 0; + var groupCount = 0; - // allow single and array values for "shapes" parameter + // allow single and array values for "shapes" parameter - if ( Array.isArray( shapes ) === false ) { + if ( Array.isArray( shapes ) === false ) { - addShape( shapes ); + addShape( shapes ); - } else { + } else { - for ( var i = 0; i < shapes.length; i ++ ) { + for ( var i = 0; i < shapes.length; i ++ ) { - addShape( shapes[ i ] ); + addShape( shapes[ i ] ); - this.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support + this.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support - groupStart += groupCount; - groupCount = 0; + groupStart += groupCount; + groupCount = 0; - } + } - } + } - // build geometry + // build geometry - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setIndex( indices ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - // helper functions + // helper functions - function addShape( shape ) { + function addShape( shape ) { - var i, l, shapeHole; + var i, l, shapeHole; - var indexOffset = vertices.length / 3; - var points = shape.extractPoints( curveSegments ); + var indexOffset = vertices.length / 3; + var points = shape.extractPoints( curveSegments ); - var shapeVertices = points.shape; - var shapeHoles = points.holes; + var shapeVertices = points.shape; + var shapeHoles = points.holes; - // check direction of vertices + // check direction of vertices - if ( ShapeUtils.isClockWise( shapeVertices ) === false ) { + if ( ShapeUtils.isClockWise( shapeVertices ) === false ) { - shapeVertices = shapeVertices.reverse(); + shapeVertices = shapeVertices.reverse(); - // also check if holes are in the opposite direction + // also check if holes are in the opposite direction - for ( i = 0, l = shapeHoles.length; i < l; i ++ ) { + for ( i = 0, l = shapeHoles.length; i < l; i ++ ) { - shapeHole = shapeHoles[ i ]; + shapeHole = shapeHoles[ i ]; - if ( ShapeUtils.isClockWise( shapeHole ) === true ) { + if ( ShapeUtils.isClockWise( shapeHole ) === true ) { - shapeHoles[ i ] = shapeHole.reverse(); + shapeHoles[ i ] = shapeHole.reverse(); - } + } - } + } - } + } - var faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles ); + var faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles ); - // join vertices of inner and outer paths to a single array + // join vertices of inner and outer paths to a single array - for ( i = 0, l = shapeHoles.length; i < l; i ++ ) { + for ( i = 0, l = shapeHoles.length; i < l; i ++ ) { - shapeHole = shapeHoles[ i ]; - shapeVertices = shapeVertices.concat( shapeHole ); + shapeHole = shapeHoles[ i ]; + shapeVertices = shapeVertices.concat( shapeHole ); - } + } - // vertices, normals, uvs + // vertices, normals, uvs - for ( i = 0, l = shapeVertices.length; i < l; i ++ ) { + for ( i = 0, l = shapeVertices.length; i < l; i ++ ) { - var vertex = shapeVertices[ i ]; + var vertex = shapeVertices[ i ]; - vertices.push( vertex.x, vertex.y, 0 ); - normals.push( 0, 0, 1 ); - uvs.push( vertex.x, vertex.y ); // world uvs + vertices.push( vertex.x, vertex.y, 0 ); + normals.push( 0, 0, 1 ); + uvs.push( vertex.x, vertex.y ); // world uvs - } + } - // incides + // incides - for ( i = 0, l = faces.length; i < l; i ++ ) { + for ( i = 0, l = faces.length; i < l; i ++ ) { - var face = faces[ i ]; + var face = faces[ i ]; - var a = face[ 0 ] + indexOffset; - var b = face[ 1 ] + indexOffset; - var c = face[ 2 ] + indexOffset; + var a = face[ 0 ] + indexOffset; + var b = face[ 1 ] + indexOffset; + var c = face[ 2 ] + indexOffset; - indices.push( a, b, c ); - groupCount += 3; + indices.push( a, b, c ); + groupCount += 3; - } + } - } + } - } + } - ShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - ShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry; + ShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + ShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry; - ShapeBufferGeometry.prototype.toJSON = function () { + ShapeBufferGeometry.prototype.toJSON = function () { - var data = BufferGeometry.prototype.toJSON.call( this ); + var data = BufferGeometry.prototype.toJSON.call( this ); - var shapes = this.parameters.shapes; + var shapes = this.parameters.shapes; - return toJSON$1( shapes, data ); + return toJSON$1( shapes, data ); - }; + }; - // + // - function toJSON$1( shapes, data ) { + function toJSON$1( shapes, data ) { - data.shapes = []; + data.shapes = []; - if ( Array.isArray( shapes ) ) { + if ( Array.isArray( shapes ) ) { - for ( var i = 0, l = shapes.length; i < l; i ++ ) { + for ( var i = 0, l = shapes.length; i < l; i ++ ) { - var shape = shapes[ i ]; + var shape = shapes[ i ]; - data.shapes.push( shape.uuid ); + data.shapes.push( shape.uuid ); - } + } - } else { + } else { - data.shapes.push( shapes.uuid ); + data.shapes.push( shapes.uuid ); - } + } - return data; + return data; - } + } - /** - * @author WestLangley / http://github.com/WestLangley - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author WestLangley / http://github.com/WestLangley + * @author Mugen87 / https://github.com/Mugen87 + */ - function EdgesGeometry( geometry, thresholdAngle ) { + function EdgesGeometry( geometry, thresholdAngle ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'EdgesGeometry'; + this.type = 'EdgesGeometry'; - this.parameters = { - thresholdAngle: thresholdAngle - }; + this.parameters = { + thresholdAngle: thresholdAngle + }; - thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1; + thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1; - // buffer + // buffer - var vertices = []; + var vertices = []; - // helper variables + // helper variables - var thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle ); - var edge = [ 0, 0 ], edges = {}, edge1, edge2; - var key, keys = [ 'a', 'b', 'c' ]; + var thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle ); + var edge = [ 0, 0 ], edges = {}, edge1, edge2; + var key, keys = [ 'a', 'b', 'c' ]; - // prepare source geometry + // prepare source geometry - var geometry2; + var geometry2; - if ( geometry.isBufferGeometry ) { + if ( geometry.isBufferGeometry ) { - geometry2 = new Geometry(); - geometry2.fromBufferGeometry( geometry ); + geometry2 = new Geometry(); + geometry2.fromBufferGeometry( geometry ); - } else { + } else { - geometry2 = geometry.clone(); + geometry2 = geometry.clone(); - } + } - geometry2.mergeVertices(); - geometry2.computeFaceNormals(); + geometry2.mergeVertices(); + geometry2.computeFaceNormals(); - var sourceVertices = geometry2.vertices; - var faces = geometry2.faces; + var sourceVertices = geometry2.vertices; + var faces = geometry2.faces; - // now create a data structure where each entry represents an edge with its adjoining faces + // now create a data structure where each entry represents an edge with its adjoining faces - for ( var i = 0, l = faces.length; i < l; i ++ ) { + for ( var i = 0, l = faces.length; i < l; i ++ ) { - var face = faces[ i ]; + var face = faces[ i ]; - for ( var j = 0; j < 3; j ++ ) { + for ( var j = 0; j < 3; j ++ ) { - edge1 = face[ keys[ j ] ]; - edge2 = face[ keys[ ( j + 1 ) % 3 ] ]; - edge[ 0 ] = Math.min( edge1, edge2 ); - edge[ 1 ] = Math.max( edge1, edge2 ); + edge1 = face[ keys[ j ] ]; + edge2 = face[ keys[ ( j + 1 ) % 3 ] ]; + edge[ 0 ] = Math.min( edge1, edge2 ); + edge[ 1 ] = Math.max( edge1, edge2 ); - key = edge[ 0 ] + ',' + edge[ 1 ]; + key = edge[ 0 ] + ',' + edge[ 1 ]; - if ( edges[ key ] === undefined ) { + if ( edges[ key ] === undefined ) { - edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined }; + edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined }; - } else { + } else { - edges[ key ].face2 = i; + edges[ key ].face2 = i; - } + } - } + } - } + } - // generate vertices + // generate vertices - for ( key in edges ) { + for ( key in edges ) { - var e = edges[ key ]; + var e = edges[ key ]; - // an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree. + // an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree. - if ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) { + if ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) { - var vertex = sourceVertices[ e.index1 ]; - vertices.push( vertex.x, vertex.y, vertex.z ); + var vertex = sourceVertices[ e.index1 ]; + vertices.push( vertex.x, vertex.y, vertex.z ); - vertex = sourceVertices[ e.index2 ]; - vertices.push( vertex.x, vertex.y, vertex.z ); + vertex = sourceVertices[ e.index2 ]; + vertices.push( vertex.x, vertex.y, vertex.z ); - } + } - } + } - // build geometry + // build geometry - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - } + } - EdgesGeometry.prototype = Object.create( BufferGeometry.prototype ); - EdgesGeometry.prototype.constructor = EdgesGeometry; + EdgesGeometry.prototype = Object.create( BufferGeometry.prototype ); + EdgesGeometry.prototype.constructor = EdgesGeometry; - /** - * @author mrdoob / http://mrdoob.com/ - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author Mugen87 / https://github.com/Mugen87 + */ - // CylinderGeometry + // CylinderGeometry - function CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { + function CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'CylinderGeometry'; + this.type = 'CylinderGeometry'; - this.parameters = { - radiusTop: radiusTop, - radiusBottom: radiusBottom, - height: height, - radialSegments: radialSegments, - heightSegments: heightSegments, - openEnded: openEnded, - thetaStart: thetaStart, - thetaLength: thetaLength - }; + this.parameters = { + radiusTop: radiusTop, + radiusBottom: radiusBottom, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + openEnded: openEnded, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - this.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) ); - this.mergeVertices(); + this.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) ); + this.mergeVertices(); - } + } - CylinderGeometry.prototype = Object.create( Geometry.prototype ); - CylinderGeometry.prototype.constructor = CylinderGeometry; + CylinderGeometry.prototype = Object.create( Geometry.prototype ); + CylinderGeometry.prototype.constructor = CylinderGeometry; - // CylinderBufferGeometry + // CylinderBufferGeometry - function CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { + function CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'CylinderBufferGeometry'; + this.type = 'CylinderBufferGeometry'; - this.parameters = { - radiusTop: radiusTop, - radiusBottom: radiusBottom, - height: height, - radialSegments: radialSegments, - heightSegments: heightSegments, - openEnded: openEnded, - thetaStart: thetaStart, - thetaLength: thetaLength - }; + this.parameters = { + radiusTop: radiusTop, + radiusBottom: radiusBottom, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + openEnded: openEnded, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - var scope = this; + var scope = this; - radiusTop = radiusTop !== undefined ? radiusTop : 1; - radiusBottom = radiusBottom !== undefined ? radiusBottom : 1; - height = height || 1; + radiusTop = radiusTop !== undefined ? radiusTop : 1; + radiusBottom = radiusBottom !== undefined ? radiusBottom : 1; + height = height || 1; - radialSegments = Math.floor( radialSegments ) || 8; - heightSegments = Math.floor( heightSegments ) || 1; + radialSegments = Math.floor( radialSegments ) || 8; + heightSegments = Math.floor( heightSegments ) || 1; - openEnded = openEnded !== undefined ? openEnded : false; - thetaStart = thetaStart !== undefined ? thetaStart : 0.0; - thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; + openEnded = openEnded !== undefined ? openEnded : false; + thetaStart = thetaStart !== undefined ? thetaStart : 0.0; + thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; - // buffers + // buffers - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - // helper variables + // helper variables - var index = 0; - var indexArray = []; - var halfHeight = height / 2; - var groupStart = 0; + var index = 0; + var indexArray = []; + var halfHeight = height / 2; + var groupStart = 0; - // generate geometry + // generate geometry - generateTorso(); + generateTorso(); - if ( openEnded === false ) { + if ( openEnded === false ) { - if ( radiusTop > 0 ) generateCap( true ); - if ( radiusBottom > 0 ) generateCap( false ); + if ( radiusTop > 0 ) generateCap( true ); + if ( radiusBottom > 0 ) generateCap( false ); - } + } - // build geometry + // build geometry - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setIndex( indices ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - function generateTorso() { + function generateTorso() { - var x, y; - var normal = new Vector3(); - var vertex = new Vector3(); + var x, y; + var normal = new Vector3(); + var vertex = new Vector3(); - var groupCount = 0; + var groupCount = 0; - // this will be used to calculate the normal - var slope = ( radiusBottom - radiusTop ) / height; + // this will be used to calculate the normal + var slope = ( radiusBottom - radiusTop ) / height; - // generate vertices, normals and uvs + // generate vertices, normals and uvs - for ( y = 0; y <= heightSegments; y ++ ) { + for ( y = 0; y <= heightSegments; y ++ ) { - var indexRow = []; + var indexRow = []; - var v = y / heightSegments; + var v = y / heightSegments; - // calculate the radius of the current row + // calculate the radius of the current row - var radius = v * ( radiusBottom - radiusTop ) + radiusTop; + var radius = v * ( radiusBottom - radiusTop ) + radiusTop; - for ( x = 0; x <= radialSegments; x ++ ) { + for ( x = 0; x <= radialSegments; x ++ ) { - var u = x / radialSegments; + var u = x / radialSegments; - var theta = u * thetaLength + thetaStart; + var theta = u * thetaLength + thetaStart; - var sinTheta = Math.sin( theta ); - var cosTheta = Math.cos( theta ); + var sinTheta = Math.sin( theta ); + var cosTheta = Math.cos( theta ); - // vertex + // vertex - vertex.x = radius * sinTheta; - vertex.y = - v * height + halfHeight; - vertex.z = radius * cosTheta; - vertices.push( vertex.x, vertex.y, vertex.z ); + vertex.x = radius * sinTheta; + vertex.y = - v * height + halfHeight; + vertex.z = radius * cosTheta; + vertices.push( vertex.x, vertex.y, vertex.z ); - // normal + // normal - normal.set( sinTheta, slope, cosTheta ).normalize(); - normals.push( normal.x, normal.y, normal.z ); + normal.set( sinTheta, slope, cosTheta ).normalize(); + normals.push( normal.x, normal.y, normal.z ); - // uv + // uv - uvs.push( u, 1 - v ); + uvs.push( u, 1 - v ); - // save index of vertex in respective row + // save index of vertex in respective row - indexRow.push( index ++ ); + indexRow.push( index ++ ); - } + } - // now save vertices of the row in our index array + // now save vertices of the row in our index array - indexArray.push( indexRow ); + indexArray.push( indexRow ); - } + } - // generate indices + // generate indices - for ( x = 0; x < radialSegments; x ++ ) { + for ( x = 0; x < radialSegments; x ++ ) { - for ( y = 0; y < heightSegments; y ++ ) { + for ( y = 0; y < heightSegments; y ++ ) { - // we use the index array to access the correct indices + // we use the index array to access the correct indices - var a = indexArray[ y ][ x ]; - var b = indexArray[ y + 1 ][ x ]; - var c = indexArray[ y + 1 ][ x + 1 ]; - var d = indexArray[ y ][ x + 1 ]; + var a = indexArray[ y ][ x ]; + var b = indexArray[ y + 1 ][ x ]; + var c = indexArray[ y + 1 ][ x + 1 ]; + var d = indexArray[ y ][ x + 1 ]; - // faces + // faces - indices.push( a, b, d ); - indices.push( b, c, d ); + indices.push( a, b, d ); + indices.push( b, c, d ); - // update group counter + // update group counter - groupCount += 6; + groupCount += 6; - } + } - } + } - // add a group to the geometry. this will ensure multi material support + // add a group to the geometry. this will ensure multi material support - scope.addGroup( groupStart, groupCount, 0 ); + scope.addGroup( groupStart, groupCount, 0 ); - // calculate new start value for groups + // calculate new start value for groups - groupStart += groupCount; + groupStart += groupCount; - } + } - function generateCap( top ) { + function generateCap( top ) { - var x, centerIndexStart, centerIndexEnd; + var x, centerIndexStart, centerIndexEnd; - var uv = new Vector2(); - var vertex = new Vector3(); + var uv = new Vector2(); + var vertex = new Vector3(); - var groupCount = 0; + var groupCount = 0; - var radius = ( top === true ) ? radiusTop : radiusBottom; - var sign = ( top === true ) ? 1 : - 1; + var radius = ( top === true ) ? radiusTop : radiusBottom; + var sign = ( top === true ) ? 1 : - 1; - // save the index of the first center vertex - centerIndexStart = index; + // save the index of the first center vertex + centerIndexStart = index; - // first we generate the center vertex data of the cap. - // because the geometry needs one set of uvs per face, - // we must generate a center vertex per face/segment + // first we generate the center vertex data of the cap. + // because the geometry needs one set of uvs per face, + // we must generate a center vertex per face/segment - for ( x = 1; x <= radialSegments; x ++ ) { + for ( x = 1; x <= radialSegments; x ++ ) { - // vertex + // vertex - vertices.push( 0, halfHeight * sign, 0 ); + vertices.push( 0, halfHeight * sign, 0 ); - // normal + // normal - normals.push( 0, sign, 0 ); + normals.push( 0, sign, 0 ); - // uv + // uv - uvs.push( 0.5, 0.5 ); + uvs.push( 0.5, 0.5 ); - // increase index + // increase index - index ++; + index ++; - } + } - // save the index of the last center vertex + // save the index of the last center vertex - centerIndexEnd = index; + centerIndexEnd = index; - // now we generate the surrounding vertices, normals and uvs + // now we generate the surrounding vertices, normals and uvs - for ( x = 0; x <= radialSegments; x ++ ) { + for ( x = 0; x <= radialSegments; x ++ ) { - var u = x / radialSegments; - var theta = u * thetaLength + thetaStart; + var u = x / radialSegments; + var theta = u * thetaLength + thetaStart; - var cosTheta = Math.cos( theta ); - var sinTheta = Math.sin( theta ); + var cosTheta = Math.cos( theta ); + var sinTheta = Math.sin( theta ); - // vertex + // vertex - vertex.x = radius * sinTheta; - vertex.y = halfHeight * sign; - vertex.z = radius * cosTheta; - vertices.push( vertex.x, vertex.y, vertex.z ); + vertex.x = radius * sinTheta; + vertex.y = halfHeight * sign; + vertex.z = radius * cosTheta; + vertices.push( vertex.x, vertex.y, vertex.z ); - // normal + // normal - normals.push( 0, sign, 0 ); + normals.push( 0, sign, 0 ); - // uv + // uv - uv.x = ( cosTheta * 0.5 ) + 0.5; - uv.y = ( sinTheta * 0.5 * sign ) + 0.5; - uvs.push( uv.x, uv.y ); + uv.x = ( cosTheta * 0.5 ) + 0.5; + uv.y = ( sinTheta * 0.5 * sign ) + 0.5; + uvs.push( uv.x, uv.y ); - // increase index + // increase index - index ++; + index ++; - } + } - // generate indices + // generate indices - for ( x = 0; x < radialSegments; x ++ ) { + for ( x = 0; x < radialSegments; x ++ ) { - var c = centerIndexStart + x; - var i = centerIndexEnd + x; + var c = centerIndexStart + x; + var i = centerIndexEnd + x; - if ( top === true ) { + if ( top === true ) { - // face top + // face top - indices.push( i, i + 1, c ); + indices.push( i, i + 1, c ); - } else { + } else { - // face bottom + // face bottom - indices.push( i + 1, i, c ); + indices.push( i + 1, i, c ); - } + } - groupCount += 3; + groupCount += 3; - } + } - // add a group to the geometry. this will ensure multi material support + // add a group to the geometry. this will ensure multi material support - scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 ); + scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 ); - // calculate new start value for groups + // calculate new start value for groups - groupStart += groupCount; + groupStart += groupCount; - } + } - } + } - CylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - CylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry; + CylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + CylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry; - /** - * @author abelnation / http://github.com/abelnation - */ + /** + * @author abelnation / http://github.com/abelnation + */ - // ConeGeometry + // ConeGeometry - function ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { + function ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { - CylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); + CylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); - this.type = 'ConeGeometry'; + this.type = 'ConeGeometry'; - this.parameters = { - radius: radius, - height: height, - radialSegments: radialSegments, - heightSegments: heightSegments, - openEnded: openEnded, - thetaStart: thetaStart, - thetaLength: thetaLength - }; + this.parameters = { + radius: radius, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + openEnded: openEnded, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - } + } - ConeGeometry.prototype = Object.create( CylinderGeometry.prototype ); - ConeGeometry.prototype.constructor = ConeGeometry; + ConeGeometry.prototype = Object.create( CylinderGeometry.prototype ); + ConeGeometry.prototype.constructor = ConeGeometry; - // ConeBufferGeometry + // ConeBufferGeometry - function ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { + function ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { - CylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); + CylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ); - this.type = 'ConeBufferGeometry'; + this.type = 'ConeBufferGeometry'; - this.parameters = { - radius: radius, - height: height, - radialSegments: radialSegments, - heightSegments: heightSegments, - openEnded: openEnded, - thetaStart: thetaStart, - thetaLength: thetaLength - }; + this.parameters = { + radius: radius, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + openEnded: openEnded, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - } + } - ConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype ); - ConeBufferGeometry.prototype.constructor = ConeBufferGeometry; + ConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype ); + ConeBufferGeometry.prototype.constructor = ConeBufferGeometry; - /** - * @author benaadams / https://twitter.com/ben_a_adams - * @author Mugen87 / https://github.com/Mugen87 - * @author hughes - */ + /** + * @author benaadams / https://twitter.com/ben_a_adams + * @author Mugen87 / https://github.com/Mugen87 + * @author hughes + */ - // CircleGeometry + // CircleGeometry - function CircleGeometry( radius, segments, thetaStart, thetaLength ) { + function CircleGeometry( radius, segments, thetaStart, thetaLength ) { - Geometry.call( this ); + Geometry.call( this ); - this.type = 'CircleGeometry'; + this.type = 'CircleGeometry'; - this.parameters = { - radius: radius, - segments: segments, - thetaStart: thetaStart, - thetaLength: thetaLength - }; + this.parameters = { + radius: radius, + segments: segments, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - this.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) ); - this.mergeVertices(); + this.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) ); + this.mergeVertices(); - } + } - CircleGeometry.prototype = Object.create( Geometry.prototype ); - CircleGeometry.prototype.constructor = CircleGeometry; + CircleGeometry.prototype = Object.create( Geometry.prototype ); + CircleGeometry.prototype.constructor = CircleGeometry; - // CircleBufferGeometry + // CircleBufferGeometry - function CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) { + function CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'CircleBufferGeometry'; + this.type = 'CircleBufferGeometry'; - this.parameters = { - radius: radius, - segments: segments, - thetaStart: thetaStart, - thetaLength: thetaLength - }; + this.parameters = { + radius: radius, + segments: segments, + thetaStart: thetaStart, + thetaLength: thetaLength + }; - radius = radius || 1; - segments = segments !== undefined ? Math.max( 3, segments ) : 8; + radius = radius || 1; + segments = segments !== undefined ? Math.max( 3, segments ) : 8; - thetaStart = thetaStart !== undefined ? thetaStart : 0; - thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; + thetaStart = thetaStart !== undefined ? thetaStart : 0; + thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; - // buffers + // buffers - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - // helper variables + // helper variables - var i, s; - var vertex = new Vector3(); - var uv = new Vector2(); + var i, s; + var vertex = new Vector3(); + var uv = new Vector2(); - // center point + // center point - vertices.push( 0, 0, 0 ); - normals.push( 0, 0, 1 ); - uvs.push( 0.5, 0.5 ); + vertices.push( 0, 0, 0 ); + normals.push( 0, 0, 1 ); + uvs.push( 0.5, 0.5 ); - for ( s = 0, i = 3; s <= segments; s ++, i += 3 ) { + for ( s = 0, i = 3; s <= segments; s ++, i += 3 ) { - var segment = thetaStart + s / segments * thetaLength; + var segment = thetaStart + s / segments * thetaLength; - // vertex + // vertex - vertex.x = radius * Math.cos( segment ); - vertex.y = radius * Math.sin( segment ); + vertex.x = radius * Math.cos( segment ); + vertex.y = radius * Math.sin( segment ); - vertices.push( vertex.x, vertex.y, vertex.z ); + vertices.push( vertex.x, vertex.y, vertex.z ); - // normal + // normal - normals.push( 0, 0, 1 ); + normals.push( 0, 0, 1 ); - // uvs + // uvs - uv.x = ( vertices[ i ] / radius + 1 ) / 2; - uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2; + uv.x = ( vertices[ i ] / radius + 1 ) / 2; + uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2; - uvs.push( uv.x, uv.y ); + uvs.push( uv.x, uv.y ); - } + } - // indices + // indices - for ( i = 1; i <= segments; i ++ ) { + for ( i = 1; i <= segments; i ++ ) { - indices.push( i, i + 1, 0 ); + indices.push( i, i + 1, 0 ); - } + } - // build geometry + // build geometry - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setIndex( indices ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - } + } - CircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - CircleBufferGeometry.prototype.constructor = CircleBufferGeometry; + CircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + CircleBufferGeometry.prototype.constructor = CircleBufferGeometry; - var Geometries = /*#__PURE__*/Object.freeze({ - WireframeGeometry: WireframeGeometry, - ParametricGeometry: ParametricGeometry, - ParametricBufferGeometry: ParametricBufferGeometry, - TetrahedronGeometry: TetrahedronGeometry, - TetrahedronBufferGeometry: TetrahedronBufferGeometry, - OctahedronGeometry: OctahedronGeometry, - OctahedronBufferGeometry: OctahedronBufferGeometry, - IcosahedronGeometry: IcosahedronGeometry, - IcosahedronBufferGeometry: IcosahedronBufferGeometry, - DodecahedronGeometry: DodecahedronGeometry, - DodecahedronBufferGeometry: DodecahedronBufferGeometry, - PolyhedronGeometry: PolyhedronGeometry, - PolyhedronBufferGeometry: PolyhedronBufferGeometry, - TubeGeometry: TubeGeometry, - TubeBufferGeometry: TubeBufferGeometry, - TorusKnotGeometry: TorusKnotGeometry, - TorusKnotBufferGeometry: TorusKnotBufferGeometry, - TorusGeometry: TorusGeometry, - TorusBufferGeometry: TorusBufferGeometry, - TextGeometry: TextGeometry, - TextBufferGeometry: TextBufferGeometry, - SphereGeometry: SphereGeometry, - SphereBufferGeometry: SphereBufferGeometry, - RingGeometry: RingGeometry, - RingBufferGeometry: RingBufferGeometry, - PlaneGeometry: PlaneGeometry, - PlaneBufferGeometry: PlaneBufferGeometry, - LatheGeometry: LatheGeometry, - LatheBufferGeometry: LatheBufferGeometry, - ShapeGeometry: ShapeGeometry, - ShapeBufferGeometry: ShapeBufferGeometry, - ExtrudeGeometry: ExtrudeGeometry, - ExtrudeBufferGeometry: ExtrudeBufferGeometry, - EdgesGeometry: EdgesGeometry, - ConeGeometry: ConeGeometry, - ConeBufferGeometry: ConeBufferGeometry, - CylinderGeometry: CylinderGeometry, - CylinderBufferGeometry: CylinderBufferGeometry, - CircleGeometry: CircleGeometry, - CircleBufferGeometry: CircleBufferGeometry, - BoxGeometry: BoxGeometry, - BoxBufferGeometry: BoxBufferGeometry - }); - - /** - * @author mrdoob / http://mrdoob.com/ - * - * parameters = { - * color: - * } - */ - - function ShadowMaterial( parameters ) { - - Material.call( this ); - - this.type = 'ShadowMaterial'; - - this.color = new Color( 0x000000 ); - this.transparent = true; - - this.setValues( parameters ); - - } - - ShadowMaterial.prototype = Object.create( Material.prototype ); - ShadowMaterial.prototype.constructor = ShadowMaterial; - - ShadowMaterial.prototype.isShadowMaterial = true; - - ShadowMaterial.prototype.copy = function ( source ) { - - Material.prototype.copy.call( this, source ); - - this.color.copy( source.color ); - - return this; - - }; - - /** - * @author mrdoob / http://mrdoob.com/ - */ - - function RawShaderMaterial( parameters ) { - - ShaderMaterial.call( this, parameters ); - - this.type = 'RawShaderMaterial'; - - } - - RawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype ); - RawShaderMaterial.prototype.constructor = RawShaderMaterial; - - RawShaderMaterial.prototype.isRawShaderMaterial = true; - - /** - * @author WestLangley / http://github.com/WestLangley - * - * parameters = { - * color: , - * roughness: , - * metalness: , - * opacity: , - * - * map: new THREE.Texture( ), - * - * lightMap: new THREE.Texture( ), - * lightMapIntensity: - * - * aoMap: new THREE.Texture( ), - * aoMapIntensity: - * - * emissive: , - * emissiveIntensity: - * emissiveMap: new THREE.Texture( ), - * - * bumpMap: new THREE.Texture( ), - * bumpScale: , - * - * normalMap: new THREE.Texture( ), - * normalMapType: THREE.TangentSpaceNormalMap, - * normalScale: , - * - * displacementMap: new THREE.Texture( ), - * displacementScale: , - * displacementBias: , - * - * roughnessMap: new THREE.Texture( ), - * - * metalnessMap: new THREE.Texture( ), - * - * alphaMap: new THREE.Texture( ), - * - * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), - * envMapIntensity: - * - * refractionRatio: , - * - * wireframe: , - * wireframeLinewidth: , - * - * skinning: , - * morphTargets: , - * morphNormals: - * } - */ + var Geometries = /*#__PURE__*/Object.freeze({ + WireframeGeometry: WireframeGeometry, + ParametricGeometry: ParametricGeometry, + ParametricBufferGeometry: ParametricBufferGeometry, + TetrahedronGeometry: TetrahedronGeometry, + TetrahedronBufferGeometry: TetrahedronBufferGeometry, + OctahedronGeometry: OctahedronGeometry, + OctahedronBufferGeometry: OctahedronBufferGeometry, + IcosahedronGeometry: IcosahedronGeometry, + IcosahedronBufferGeometry: IcosahedronBufferGeometry, + DodecahedronGeometry: DodecahedronGeometry, + DodecahedronBufferGeometry: DodecahedronBufferGeometry, + PolyhedronGeometry: PolyhedronGeometry, + PolyhedronBufferGeometry: PolyhedronBufferGeometry, + TubeGeometry: TubeGeometry, + TubeBufferGeometry: TubeBufferGeometry, + TorusKnotGeometry: TorusKnotGeometry, + TorusKnotBufferGeometry: TorusKnotBufferGeometry, + TorusGeometry: TorusGeometry, + TorusBufferGeometry: TorusBufferGeometry, + TextGeometry: TextGeometry, + TextBufferGeometry: TextBufferGeometry, + SphereGeometry: SphereGeometry, + SphereBufferGeometry: SphereBufferGeometry, + RingGeometry: RingGeometry, + RingBufferGeometry: RingBufferGeometry, + PlaneGeometry: PlaneGeometry, + PlaneBufferGeometry: PlaneBufferGeometry, + LatheGeometry: LatheGeometry, + LatheBufferGeometry: LatheBufferGeometry, + ShapeGeometry: ShapeGeometry, + ShapeBufferGeometry: ShapeBufferGeometry, + ExtrudeGeometry: ExtrudeGeometry, + ExtrudeBufferGeometry: ExtrudeBufferGeometry, + EdgesGeometry: EdgesGeometry, + ConeGeometry: ConeGeometry, + ConeBufferGeometry: ConeBufferGeometry, + CylinderGeometry: CylinderGeometry, + CylinderBufferGeometry: CylinderBufferGeometry, + CircleGeometry: CircleGeometry, + CircleBufferGeometry: CircleBufferGeometry, + BoxGeometry: BoxGeometry, + BoxBufferGeometry: BoxBufferGeometry + }); + + /** + * @author mrdoob / http://mrdoob.com/ + * + * parameters = { + * color: + * } + */ + + function ShadowMaterial( parameters ) { + + Material.call( this ); + + this.type = 'ShadowMaterial'; + + this.color = new Color( 0x000000 ); + this.transparent = true; + + this.setValues( parameters ); + + } + + ShadowMaterial.prototype = Object.create( Material.prototype ); + ShadowMaterial.prototype.constructor = ShadowMaterial; + + ShadowMaterial.prototype.isShadowMaterial = true; + + ShadowMaterial.prototype.copy = function ( source ) { + + Material.prototype.copy.call( this, source ); + + this.color.copy( source.color ); + + return this; + + }; + + /** + * @author mrdoob / http://mrdoob.com/ + */ + + function RawShaderMaterial( parameters ) { + + ShaderMaterial.call( this, parameters ); + + this.type = 'RawShaderMaterial'; + + } + + RawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype ); + RawShaderMaterial.prototype.constructor = RawShaderMaterial; + + RawShaderMaterial.prototype.isRawShaderMaterial = true; + + /** + * @author WestLangley / http://github.com/WestLangley + * + * parameters = { + * color: , + * roughness: , + * metalness: , + * opacity: , + * + * map: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * emissive: , + * emissiveIntensity: + * emissiveMap: new THREE.Texture( ), + * + * bumpMap: new THREE.Texture( ), + * bumpScale: , + * + * normalMap: new THREE.Texture( ), + * normalMapType: THREE.TangentSpaceNormalMap, + * normalScale: , + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * roughnessMap: new THREE.Texture( ), + * + * metalnessMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), + * envMapIntensity: + * + * refractionRatio: , + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ - function MeshStandardMaterial( parameters ) { + function MeshStandardMaterial( parameters ) { - Material.call( this ); + Material.call( this ); - this.defines = { 'STANDARD': '' }; + this.defines = { 'STANDARD': '' }; - this.type = 'MeshStandardMaterial'; + this.type = 'MeshStandardMaterial'; - this.color = new Color( 0xffffff ); // diffuse - this.roughness = 0.5; - this.metalness = 0.5; + this.color = new Color( 0xffffff ); // diffuse + this.roughness = 0.5; + this.metalness = 0.5; - this.map = null; + this.map = null; - this.lightMap = null; - this.lightMapIntensity = 1.0; + this.lightMap = null; + this.lightMapIntensity = 1.0; - this.aoMap = null; - this.aoMapIntensity = 1.0; + this.aoMap = null; + this.aoMapIntensity = 1.0; - this.emissive = new Color( 0x000000 ); - this.emissiveIntensity = 1.0; - this.emissiveMap = null; + this.emissive = new Color( 0x000000 ); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; - this.bumpMap = null; - this.bumpScale = 1; + this.bumpMap = null; + this.bumpScale = 1; - this.normalMap = null; - this.normalMapType = TangentSpaceNormalMap; - this.normalScale = new Vector2( 1, 1 ); + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; - this.roughnessMap = null; + this.roughnessMap = null; - this.metalnessMap = null; + this.metalnessMap = null; - this.alphaMap = null; + this.alphaMap = null; - this.envMap = null; - this.envMapIntensity = 1.0; + this.envMap = null; + this.envMapIntensity = 1.0; - this.refractionRatio = 0.98; + this.refractionRatio = 0.98; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; - this.skinning = false; - this.morphTargets = false; - this.morphNormals = false; + this.skinning = false; + this.morphTargets = false; + this.morphNormals = false; - this.setValues( parameters ); + this.setValues( parameters ); - } + } - MeshStandardMaterial.prototype = Object.create( Material.prototype ); - MeshStandardMaterial.prototype.constructor = MeshStandardMaterial; + MeshStandardMaterial.prototype = Object.create( Material.prototype ); + MeshStandardMaterial.prototype.constructor = MeshStandardMaterial; - MeshStandardMaterial.prototype.isMeshStandardMaterial = true; + MeshStandardMaterial.prototype.isMeshStandardMaterial = true; - MeshStandardMaterial.prototype.copy = function ( source ) { + MeshStandardMaterial.prototype.copy = function ( source ) { - Material.prototype.copy.call( this, source ); + Material.prototype.copy.call( this, source ); - this.defines = { 'STANDARD': '' }; + this.defines = { 'STANDARD': '' }; - this.color.copy( source.color ); - this.roughness = source.roughness; - this.metalness = source.metalness; + this.color.copy( source.color ); + this.roughness = source.roughness; + this.metalness = source.metalness; - this.map = source.map; + this.map = source.map; - this.lightMap = source.lightMap; - this.lightMapIntensity = source.lightMapIntensity; + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; - this.aoMap = source.aoMap; - this.aoMapIntensity = source.aoMapIntensity; + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; - this.emissive.copy( source.emissive ); - this.emissiveMap = source.emissiveMap; - this.emissiveIntensity = source.emissiveIntensity; + this.emissive.copy( source.emissive ); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; - this.bumpMap = source.bumpMap; - this.bumpScale = source.bumpScale; + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; - this.normalMap = source.normalMap; - this.normalMapType = source.normalMapType; - this.normalScale.copy( source.normalScale ); + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; - this.roughnessMap = source.roughnessMap; + this.roughnessMap = source.roughnessMap; - this.metalnessMap = source.metalnessMap; + this.metalnessMap = source.metalnessMap; - this.alphaMap = source.alphaMap; + this.alphaMap = source.alphaMap; - this.envMap = source.envMap; - this.envMapIntensity = source.envMapIntensity; + this.envMap = source.envMap; + this.envMapIntensity = source.envMapIntensity; - this.refractionRatio = source.refractionRatio; + this.refractionRatio = source.refractionRatio; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.wireframeLinecap = source.wireframeLinecap; - this.wireframeLinejoin = source.wireframeLinejoin; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; - this.skinning = source.skinning; - this.morphTargets = source.morphTargets; - this.morphNormals = source.morphNormals; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.morphNormals = source.morphNormals; - return this; + return this; - }; + }; - /** - * @author WestLangley / http://github.com/WestLangley - * - * parameters = { - * reflectivity: - * } - */ + /** + * @author WestLangley / http://github.com/WestLangley + * + * parameters = { + * reflectivity: + * } + */ - function MeshPhysicalMaterial( parameters ) { + function MeshPhysicalMaterial( parameters ) { - MeshStandardMaterial.call( this ); + MeshStandardMaterial.call( this ); - this.defines = { 'PHYSICAL': '' }; + this.defines = { 'PHYSICAL': '' }; - this.type = 'MeshPhysicalMaterial'; + this.type = 'MeshPhysicalMaterial'; - this.reflectivity = 0.5; // maps to F0 = 0.04 + this.reflectivity = 0.5; // maps to F0 = 0.04 - this.clearCoat = 0.0; - this.clearCoatRoughness = 0.0; + this.clearCoat = 0.0; + this.clearCoatRoughness = 0.0; - this.setValues( parameters ); + this.setValues( parameters ); - } + } - MeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype ); - MeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial; + MeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype ); + MeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial; - MeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true; + MeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true; - MeshPhysicalMaterial.prototype.copy = function ( source ) { + MeshPhysicalMaterial.prototype.copy = function ( source ) { - MeshStandardMaterial.prototype.copy.call( this, source ); + MeshStandardMaterial.prototype.copy.call( this, source ); - this.defines = { 'PHYSICAL': '' }; + this.defines = { 'PHYSICAL': '' }; - this.reflectivity = source.reflectivity; + this.reflectivity = source.reflectivity; - this.clearCoat = source.clearCoat; - this.clearCoatRoughness = source.clearCoatRoughness; + this.clearCoat = source.clearCoat; + this.clearCoatRoughness = source.clearCoatRoughness; - return this; + return this; - }; + }; - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * specular: , - * shininess: , - * opacity: , - * - * map: new THREE.Texture( ), - * - * lightMap: new THREE.Texture( ), - * lightMapIntensity: - * - * aoMap: new THREE.Texture( ), - * aoMapIntensity: - * - * emissive: , - * emissiveIntensity: - * emissiveMap: new THREE.Texture( ), - * - * bumpMap: new THREE.Texture( ), - * bumpScale: , - * - * normalMap: new THREE.Texture( ), - * normalMapType: THREE.TangentSpaceNormalMap, - * normalScale: , - * - * displacementMap: new THREE.Texture( ), - * displacementScale: , - * displacementBias: , - * - * specularMap: new THREE.Texture( ), - * - * alphaMap: new THREE.Texture( ), - * - * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), - * combine: THREE.Multiply, - * reflectivity: , - * refractionRatio: , - * - * wireframe: , - * wireframeLinewidth: , - * - * skinning: , - * morphTargets: , - * morphNormals: - * } - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * + * parameters = { + * color: , + * specular: , + * shininess: , + * opacity: , + * + * map: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * emissive: , + * emissiveIntensity: + * emissiveMap: new THREE.Texture( ), + * + * bumpMap: new THREE.Texture( ), + * bumpScale: , + * + * normalMap: new THREE.Texture( ), + * normalMapType: THREE.TangentSpaceNormalMap, + * normalScale: , + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * specularMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), + * combine: THREE.Multiply, + * reflectivity: , + * refractionRatio: , + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ - function MeshPhongMaterial( parameters ) { + function MeshPhongMaterial( parameters ) { - Material.call( this ); + Material.call( this ); - this.type = 'MeshPhongMaterial'; + this.type = 'MeshPhongMaterial'; - this.color = new Color( 0xffffff ); // diffuse - this.specular = new Color( 0x111111 ); - this.shininess = 30; + this.color = new Color( 0xffffff ); // diffuse + this.specular = new Color( 0x111111 ); + this.shininess = 30; - this.map = null; + this.map = null; - this.lightMap = null; - this.lightMapIntensity = 1.0; + this.lightMap = null; + this.lightMapIntensity = 1.0; - this.aoMap = null; - this.aoMapIntensity = 1.0; + this.aoMap = null; + this.aoMapIntensity = 1.0; - this.emissive = new Color( 0x000000 ); - this.emissiveIntensity = 1.0; - this.emissiveMap = null; + this.emissive = new Color( 0x000000 ); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; - this.bumpMap = null; - this.bumpScale = 1; + this.bumpMap = null; + this.bumpScale = 1; - this.normalMap = null; - this.normalMapType = TangentSpaceNormalMap; - this.normalScale = new Vector2( 1, 1 ); + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; - this.specularMap = null; + this.specularMap = null; - this.alphaMap = null; + this.alphaMap = null; - this.envMap = null; - this.combine = MultiplyOperation; - this.reflectivity = 1; - this.refractionRatio = 0.98; + this.envMap = null; + this.combine = MultiplyOperation; + this.reflectivity = 1; + this.refractionRatio = 0.98; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; - this.skinning = false; - this.morphTargets = false; - this.morphNormals = false; + this.skinning = false; + this.morphTargets = false; + this.morphNormals = false; - this.setValues( parameters ); + this.setValues( parameters ); - } + } - MeshPhongMaterial.prototype = Object.create( Material.prototype ); - MeshPhongMaterial.prototype.constructor = MeshPhongMaterial; + MeshPhongMaterial.prototype = Object.create( Material.prototype ); + MeshPhongMaterial.prototype.constructor = MeshPhongMaterial; - MeshPhongMaterial.prototype.isMeshPhongMaterial = true; + MeshPhongMaterial.prototype.isMeshPhongMaterial = true; - MeshPhongMaterial.prototype.copy = function ( source ) { + MeshPhongMaterial.prototype.copy = function ( source ) { - Material.prototype.copy.call( this, source ); + Material.prototype.copy.call( this, source ); - this.color.copy( source.color ); - this.specular.copy( source.specular ); - this.shininess = source.shininess; + this.color.copy( source.color ); + this.specular.copy( source.specular ); + this.shininess = source.shininess; - this.map = source.map; + this.map = source.map; - this.lightMap = source.lightMap; - this.lightMapIntensity = source.lightMapIntensity; + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; - this.aoMap = source.aoMap; - this.aoMapIntensity = source.aoMapIntensity; + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; - this.emissive.copy( source.emissive ); - this.emissiveMap = source.emissiveMap; - this.emissiveIntensity = source.emissiveIntensity; + this.emissive.copy( source.emissive ); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; - this.bumpMap = source.bumpMap; - this.bumpScale = source.bumpScale; + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; - this.normalMap = source.normalMap; - this.normalMapType = source.normalMapType; - this.normalScale.copy( source.normalScale ); + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; - this.specularMap = source.specularMap; + this.specularMap = source.specularMap; - this.alphaMap = source.alphaMap; + this.alphaMap = source.alphaMap; - this.envMap = source.envMap; - this.combine = source.combine; - this.reflectivity = source.reflectivity; - this.refractionRatio = source.refractionRatio; + this.envMap = source.envMap; + this.combine = source.combine; + this.reflectivity = source.reflectivity; + this.refractionRatio = source.refractionRatio; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.wireframeLinecap = source.wireframeLinecap; - this.wireframeLinejoin = source.wireframeLinejoin; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; - this.skinning = source.skinning; - this.morphTargets = source.morphTargets; - this.morphNormals = source.morphNormals; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.morphNormals = source.morphNormals; - return this; + return this; - }; + }; - /** - * @author takahirox / http://github.com/takahirox - * - * parameters = { - * gradientMap: new THREE.Texture( ) - * } - */ + /** + * @author takahirox / http://github.com/takahirox + * + * parameters = { + * gradientMap: new THREE.Texture( ) + * } + */ - function MeshToonMaterial( parameters ) { + function MeshToonMaterial( parameters ) { - MeshPhongMaterial.call( this ); + MeshPhongMaterial.call( this ); - this.defines = { 'TOON': '' }; + this.defines = { 'TOON': '' }; - this.type = 'MeshToonMaterial'; + this.type = 'MeshToonMaterial'; - this.gradientMap = null; + this.gradientMap = null; - this.setValues( parameters ); + this.setValues( parameters ); - } + } - MeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype ); - MeshToonMaterial.prototype.constructor = MeshToonMaterial; + MeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype ); + MeshToonMaterial.prototype.constructor = MeshToonMaterial; - MeshToonMaterial.prototype.isMeshToonMaterial = true; + MeshToonMaterial.prototype.isMeshToonMaterial = true; - MeshToonMaterial.prototype.copy = function ( source ) { + MeshToonMaterial.prototype.copy = function ( source ) { - MeshPhongMaterial.prototype.copy.call( this, source ); + MeshPhongMaterial.prototype.copy.call( this, source ); - this.gradientMap = source.gradientMap; + this.gradientMap = source.gradientMap; - return this; + return this; - }; + }; - /** - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley - * - * parameters = { - * opacity: , - * - * bumpMap: new THREE.Texture( ), - * bumpScale: , - * - * normalMap: new THREE.Texture( ), - * normalMapType: THREE.TangentSpaceNormalMap, - * normalScale: , - * - * displacementMap: new THREE.Texture( ), - * displacementScale: , - * displacementBias: , - * - * wireframe: , - * wireframeLinewidth: - * - * skinning: , - * morphTargets: , - * morphNormals: - * } - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author WestLangley / http://github.com/WestLangley + * + * parameters = { + * opacity: , + * + * bumpMap: new THREE.Texture( ), + * bumpScale: , + * + * normalMap: new THREE.Texture( ), + * normalMapType: THREE.TangentSpaceNormalMap, + * normalScale: , + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * wireframe: , + * wireframeLinewidth: + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ - function MeshNormalMaterial( parameters ) { + function MeshNormalMaterial( parameters ) { - Material.call( this ); + Material.call( this ); - this.type = 'MeshNormalMaterial'; + this.type = 'MeshNormalMaterial'; - this.bumpMap = null; - this.bumpScale = 1; + this.bumpMap = null; + this.bumpScale = 1; - this.normalMap = null; - this.normalMapType = TangentSpaceNormalMap; - this.normalScale = new Vector2( 1, 1 ); + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; - this.wireframe = false; - this.wireframeLinewidth = 1; + this.wireframe = false; + this.wireframeLinewidth = 1; - this.fog = false; - this.lights = false; + this.fog = false; + this.lights = false; - this.skinning = false; - this.morphTargets = false; - this.morphNormals = false; + this.skinning = false; + this.morphTargets = false; + this.morphNormals = false; - this.setValues( parameters ); + this.setValues( parameters ); - } + } - MeshNormalMaterial.prototype = Object.create( Material.prototype ); - MeshNormalMaterial.prototype.constructor = MeshNormalMaterial; + MeshNormalMaterial.prototype = Object.create( Material.prototype ); + MeshNormalMaterial.prototype.constructor = MeshNormalMaterial; - MeshNormalMaterial.prototype.isMeshNormalMaterial = true; + MeshNormalMaterial.prototype.isMeshNormalMaterial = true; - MeshNormalMaterial.prototype.copy = function ( source ) { + MeshNormalMaterial.prototype.copy = function ( source ) { - Material.prototype.copy.call( this, source ); + Material.prototype.copy.call( this, source ); - this.bumpMap = source.bumpMap; - this.bumpScale = source.bumpScale; + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; - this.normalMap = source.normalMap; - this.normalMapType = source.normalMapType; - this.normalScale.copy( source.normalScale ); + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; - this.skinning = source.skinning; - this.morphTargets = source.morphTargets; - this.morphNormals = source.morphNormals; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.morphNormals = source.morphNormals; - return this; + return this; - }; + }; - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * opacity: , - * - * map: new THREE.Texture( ), - * - * lightMap: new THREE.Texture( ), - * lightMapIntensity: - * - * aoMap: new THREE.Texture( ), - * aoMapIntensity: - * - * emissive: , - * emissiveIntensity: - * emissiveMap: new THREE.Texture( ), - * - * specularMap: new THREE.Texture( ), - * - * alphaMap: new THREE.Texture( ), - * - * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), - * combine: THREE.Multiply, - * reflectivity: , - * refractionRatio: , - * - * wireframe: , - * wireframeLinewidth: , - * - * skinning: , - * morphTargets: , - * morphNormals: - * } - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * + * parameters = { + * color: , + * opacity: , + * + * map: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * emissive: , + * emissiveIntensity: + * emissiveMap: new THREE.Texture( ), + * + * specularMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), + * combine: THREE.Multiply, + * reflectivity: , + * refractionRatio: , + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: , + * morphNormals: + * } + */ - function MeshLambertMaterial( parameters ) { + function MeshLambertMaterial( parameters ) { - Material.call( this ); + Material.call( this ); - this.type = 'MeshLambertMaterial'; + this.type = 'MeshLambertMaterial'; - this.color = new Color( 0xffffff ); // diffuse + this.color = new Color( 0xffffff ); // diffuse - this.map = null; + this.map = null; - this.lightMap = null; - this.lightMapIntensity = 1.0; + this.lightMap = null; + this.lightMapIntensity = 1.0; - this.aoMap = null; - this.aoMapIntensity = 1.0; + this.aoMap = null; + this.aoMapIntensity = 1.0; - this.emissive = new Color( 0x000000 ); - this.emissiveIntensity = 1.0; - this.emissiveMap = null; + this.emissive = new Color( 0x000000 ); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; - this.specularMap = null; + this.specularMap = null; - this.alphaMap = null; + this.alphaMap = null; - this.envMap = null; - this.combine = MultiplyOperation; - this.reflectivity = 1; - this.refractionRatio = 0.98; + this.envMap = null; + this.combine = MultiplyOperation; + this.reflectivity = 1; + this.refractionRatio = 0.98; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; - this.skinning = false; - this.morphTargets = false; - this.morphNormals = false; + this.skinning = false; + this.morphTargets = false; + this.morphNormals = false; - this.setValues( parameters ); + this.setValues( parameters ); - } + } - MeshLambertMaterial.prototype = Object.create( Material.prototype ); - MeshLambertMaterial.prototype.constructor = MeshLambertMaterial; + MeshLambertMaterial.prototype = Object.create( Material.prototype ); + MeshLambertMaterial.prototype.constructor = MeshLambertMaterial; - MeshLambertMaterial.prototype.isMeshLambertMaterial = true; + MeshLambertMaterial.prototype.isMeshLambertMaterial = true; - MeshLambertMaterial.prototype.copy = function ( source ) { + MeshLambertMaterial.prototype.copy = function ( source ) { - Material.prototype.copy.call( this, source ); + Material.prototype.copy.call( this, source ); - this.color.copy( source.color ); + this.color.copy( source.color ); - this.map = source.map; + this.map = source.map; - this.lightMap = source.lightMap; - this.lightMapIntensity = source.lightMapIntensity; + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; - this.aoMap = source.aoMap; - this.aoMapIntensity = source.aoMapIntensity; + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; - this.emissive.copy( source.emissive ); - this.emissiveMap = source.emissiveMap; - this.emissiveIntensity = source.emissiveIntensity; + this.emissive.copy( source.emissive ); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; - this.specularMap = source.specularMap; + this.specularMap = source.specularMap; - this.alphaMap = source.alphaMap; + this.alphaMap = source.alphaMap; - this.envMap = source.envMap; - this.combine = source.combine; - this.reflectivity = source.reflectivity; - this.refractionRatio = source.refractionRatio; + this.envMap = source.envMap; + this.combine = source.combine; + this.reflectivity = source.reflectivity; + this.refractionRatio = source.refractionRatio; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.wireframeLinecap = source.wireframeLinecap; - this.wireframeLinejoin = source.wireframeLinejoin; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; - this.skinning = source.skinning; - this.morphTargets = source.morphTargets; - this.morphNormals = source.morphNormals; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.morphNormals = source.morphNormals; - return this; + return this; - }; + }; - /** - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * opacity: , - * - * linewidth: , - * - * scale: , - * dashSize: , - * gapSize: - * } - */ + /** + * @author alteredq / http://alteredqualia.com/ + * + * parameters = { + * color: , + * opacity: , + * + * linewidth: , + * + * scale: , + * dashSize: , + * gapSize: + * } + */ - function LineDashedMaterial( parameters ) { + function LineDashedMaterial( parameters ) { - LineBasicMaterial.call( this ); + LineBasicMaterial.call( this ); - this.type = 'LineDashedMaterial'; + this.type = 'LineDashedMaterial'; - this.scale = 1; - this.dashSize = 3; - this.gapSize = 1; + this.scale = 1; + this.dashSize = 3; + this.gapSize = 1; - this.setValues( parameters ); + this.setValues( parameters ); - } + } - LineDashedMaterial.prototype = Object.create( LineBasicMaterial.prototype ); - LineDashedMaterial.prototype.constructor = LineDashedMaterial; + LineDashedMaterial.prototype = Object.create( LineBasicMaterial.prototype ); + LineDashedMaterial.prototype.constructor = LineDashedMaterial; - LineDashedMaterial.prototype.isLineDashedMaterial = true; + LineDashedMaterial.prototype.isLineDashedMaterial = true; - LineDashedMaterial.prototype.copy = function ( source ) { + LineDashedMaterial.prototype.copy = function ( source ) { - LineBasicMaterial.prototype.copy.call( this, source ); + LineBasicMaterial.prototype.copy.call( this, source ); - this.scale = source.scale; - this.dashSize = source.dashSize; - this.gapSize = source.gapSize; + this.scale = source.scale; + this.dashSize = source.dashSize; + this.gapSize = source.gapSize; - return this; + return this; - }; + }; - var Materials = /*#__PURE__*/Object.freeze({ - ShadowMaterial: ShadowMaterial, - SpriteMaterial: SpriteMaterial, - RawShaderMaterial: RawShaderMaterial, - ShaderMaterial: ShaderMaterial, - PointsMaterial: PointsMaterial, - MeshPhysicalMaterial: MeshPhysicalMaterial, - MeshStandardMaterial: MeshStandardMaterial, - MeshPhongMaterial: MeshPhongMaterial, - MeshToonMaterial: MeshToonMaterial, - MeshNormalMaterial: MeshNormalMaterial, - MeshLambertMaterial: MeshLambertMaterial, - MeshDepthMaterial: MeshDepthMaterial, - MeshDistanceMaterial: MeshDistanceMaterial, - MeshBasicMaterial: MeshBasicMaterial, - LineDashedMaterial: LineDashedMaterial, - LineBasicMaterial: LineBasicMaterial, - Material: Material - }); + var Materials = /*#__PURE__*/Object.freeze({ + ShadowMaterial: ShadowMaterial, + SpriteMaterial: SpriteMaterial, + RawShaderMaterial: RawShaderMaterial, + ShaderMaterial: ShaderMaterial, + PointsMaterial: PointsMaterial, + MeshPhysicalMaterial: MeshPhysicalMaterial, + MeshStandardMaterial: MeshStandardMaterial, + MeshPhongMaterial: MeshPhongMaterial, + MeshToonMaterial: MeshToonMaterial, + MeshNormalMaterial: MeshNormalMaterial, + MeshLambertMaterial: MeshLambertMaterial, + MeshDepthMaterial: MeshDepthMaterial, + MeshDistanceMaterial: MeshDistanceMaterial, + MeshBasicMaterial: MeshBasicMaterial, + LineDashedMaterial: LineDashedMaterial, + LineBasicMaterial: LineBasicMaterial, + Material: Material + }); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - var Cache = { + var Cache = { - enabled: false, + enabled: false, - files: {}, + files: {}, - add: function ( key, file ) { + add: function ( key, file ) { - if ( this.enabled === false ) return; + if ( this.enabled === false ) return; - // console.log( 'THREE.Cache', 'Adding key:', key ); + // console.log( 'THREE.Cache', 'Adding key:', key ); - this.files[ key ] = file; + this.files[ key ] = file; - }, + }, - get: function ( key ) { + get: function ( key ) { - if ( this.enabled === false ) return; + if ( this.enabled === false ) return; - // console.log( 'THREE.Cache', 'Checking key:', key ); + // console.log( 'THREE.Cache', 'Checking key:', key ); - return this.files[ key ]; + return this.files[ key ]; - }, + }, - remove: function ( key ) { + remove: function ( key ) { - delete this.files[ key ]; + delete this.files[ key ]; - }, + }, - clear: function () { + clear: function () { - this.files = {}; + this.files = {}; - } + } - }; + }; - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function LoadingManager( onLoad, onProgress, onError ) { + function LoadingManager( onLoad, onProgress, onError ) { - var scope = this; + var scope = this; - var isLoading = false; - var itemsLoaded = 0; - var itemsTotal = 0; - var urlModifier = undefined; + var isLoading = false; + var itemsLoaded = 0; + var itemsTotal = 0; + var urlModifier = undefined; - this.onStart = undefined; - this.onLoad = onLoad; - this.onProgress = onProgress; - this.onError = onError; + this.onStart = undefined; + this.onLoad = onLoad; + this.onProgress = onProgress; + this.onError = onError; - this.itemStart = function ( url ) { + this.itemStart = function ( url ) { - itemsTotal ++; + itemsTotal ++; - if ( isLoading === false ) { + if ( isLoading === false ) { - if ( scope.onStart !== undefined ) { + if ( scope.onStart !== undefined ) { - scope.onStart( url, itemsLoaded, itemsTotal ); + scope.onStart( url, itemsLoaded, itemsTotal ); - } + } - } + } - isLoading = true; + isLoading = true; - }; + }; - this.itemEnd = function ( url ) { + this.itemEnd = function ( url ) { - itemsLoaded ++; + itemsLoaded ++; - if ( scope.onProgress !== undefined ) { + if ( scope.onProgress !== undefined ) { - scope.onProgress( url, itemsLoaded, itemsTotal ); + scope.onProgress( url, itemsLoaded, itemsTotal ); - } + } - if ( itemsLoaded === itemsTotal ) { + if ( itemsLoaded === itemsTotal ) { - isLoading = false; + isLoading = false; - if ( scope.onLoad !== undefined ) { + if ( scope.onLoad !== undefined ) { - scope.onLoad(); + scope.onLoad(); - } + } - } + } - }; + }; - this.itemError = function ( url ) { + this.itemError = function ( url ) { - if ( scope.onError !== undefined ) { + if ( scope.onError !== undefined ) { - scope.onError( url ); + scope.onError( url ); - } + } - }; + }; - this.resolveURL = function ( url ) { + this.resolveURL = function ( url ) { - if ( urlModifier ) { + if ( urlModifier ) { - return urlModifier( url ); + return urlModifier( url ); - } + } - return url; + return url; - }; + }; - this.setURLModifier = function ( transform ) { + this.setURLModifier = function ( transform ) { - urlModifier = transform; - return this; + urlModifier = transform; + return this; - }; + }; - } + } - var DefaultLoadingManager = new LoadingManager(); + var DefaultLoadingManager = new LoadingManager(); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - var loading = {}; + var loading = {}; - function FileLoader( manager ) { + function FileLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - } + } - Object.assign( FileLoader.prototype, { + Object.assign( FileLoader.prototype, { - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - if ( url === undefined ) url = ''; + if ( url === undefined ) url = ''; - if ( this.path !== undefined ) url = this.path + url; + if ( this.path !== undefined ) url = this.path + url; - url = this.manager.resolveURL( url ); + url = this.manager.resolveURL( url ); - var scope = this; + var scope = this; - var cached = Cache.get( url ); + var cached = Cache.get( url ); - if ( cached !== undefined ) { + if ( cached !== undefined ) { - scope.manager.itemStart( url ); + scope.manager.itemStart( url ); - setTimeout( function () { + setTimeout( function () { - if ( onLoad ) onLoad( cached ); + if ( onLoad ) onLoad( cached ); - scope.manager.itemEnd( url ); + scope.manager.itemEnd( url ); - }, 0 ); + }, 0 ); - return cached; + return cached; - } + } - // Check if request is duplicate + // Check if request is duplicate - if ( loading[ url ] !== undefined ) { + if ( loading[ url ] !== undefined ) { - loading[ url ].push( { + loading[ url ].push( { - onLoad: onLoad, - onProgress: onProgress, - onError: onError + onLoad: onLoad, + onProgress: onProgress, + onError: onError - } ); + } ); - return; + return; - } + } - // Check for data: URI - var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; - var dataUriRegexResult = url.match( dataUriRegex ); + // Check for data: URI + var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; + var dataUriRegexResult = url.match( dataUriRegex ); - // Safari can not handle Data URIs through XMLHttpRequest so process manually - if ( dataUriRegexResult ) { + // Safari can not handle Data URIs through XMLHttpRequest so process manually + if ( dataUriRegexResult ) { - var mimeType = dataUriRegexResult[ 1 ]; - var isBase64 = !! dataUriRegexResult[ 2 ]; - var data = dataUriRegexResult[ 3 ]; + var mimeType = dataUriRegexResult[ 1 ]; + var isBase64 = !! dataUriRegexResult[ 2 ]; + var data = dataUriRegexResult[ 3 ]; - data = window.decodeURIComponent( data ); + data = window.decodeURIComponent( data ); - if ( isBase64 ) data = window.atob( data ); + if ( isBase64 ) data = window.atob( data ); - try { + try { - var response; - var responseType = ( this.responseType || '' ).toLowerCase(); + var response; + var responseType = ( this.responseType || '' ).toLowerCase(); - switch ( responseType ) { + switch ( responseType ) { - case 'arraybuffer': - case 'blob': + case 'arraybuffer': + case 'blob': - var view = new Uint8Array( data.length ); + var view = new Uint8Array( data.length ); - for ( var i = 0; i < data.length; i ++ ) { + for ( var i = 0; i < data.length; i ++ ) { - view[ i ] = data.charCodeAt( i ); + view[ i ] = data.charCodeAt( i ); - } + } - if ( responseType === 'blob' ) { + if ( responseType === 'blob' ) { - response = new Blob( [ view.buffer ], { type: mimeType } ); + response = new Blob( [ view.buffer ], { type: mimeType } ); - } else { + } else { - response = view.buffer; + response = view.buffer; - } + } - break; + break; - case 'document': + case 'document': - var parser = new DOMParser(); - response = parser.parseFromString( data, mimeType ); + var parser = new DOMParser(); + response = parser.parseFromString( data, mimeType ); - break; + break; - case 'json': + case 'json': - response = JSON.parse( data ); + response = JSON.parse( data ); - break; + break; - default: // 'text' or other + default: // 'text' or other - response = data; + response = data; - break; + break; - } + } - // Wait for next browser tick like standard XMLHttpRequest event dispatching does - window.setTimeout( function () { + // Wait for next browser tick like standard XMLHttpRequest event dispatching does + window.setTimeout( function () { - if ( onLoad ) onLoad( response ); + if ( onLoad ) onLoad( response ); - scope.manager.itemEnd( url ); + scope.manager.itemEnd( url ); - }, 0 ); + }, 0 ); - } catch ( error ) { + } catch ( error ) { - // Wait for next browser tick like standard XMLHttpRequest event dispatching does - window.setTimeout( function () { + // Wait for next browser tick like standard XMLHttpRequest event dispatching does + window.setTimeout( function () { - if ( onError ) onError( error ); + if ( onError ) onError( error ); - scope.manager.itemEnd( url ); - scope.manager.itemError( url ); + scope.manager.itemEnd( url ); + scope.manager.itemError( url ); - }, 0 ); + }, 0 ); - } + } - } else { + } else { - // Initialise array for duplicate requests + // Initialise array for duplicate requests - loading[ url ] = []; + loading[ url ] = []; - loading[ url ].push( { + loading[ url ].push( { - onLoad: onLoad, - onProgress: onProgress, - onError: onError + onLoad: onLoad, + onProgress: onProgress, + onError: onError - } ); + } ); - var request = new XMLHttpRequest(); + var request = new XMLHttpRequest(); - request.open( 'GET', url, true ); + request.open( 'GET', url, true ); - request.addEventListener( 'load', function ( event ) { + request.addEventListener( 'load', function ( event ) { - var response = this.response; + var response = this.response; - Cache.add( url, response ); + Cache.add( url, response ); - var callbacks = loading[ url ]; + var callbacks = loading[ url ]; - delete loading[ url ]; + delete loading[ url ]; - if ( this.status === 200 || this.status === 0 ) { + if ( this.status === 200 || this.status === 0 ) { - // Some browsers return HTTP Status 0 when using non-http protocol - // e.g. 'file://' or 'data://'. Handle as success. + // Some browsers return HTTP Status 0 when using non-http protocol + // e.g. 'file://' or 'data://'. Handle as success. - if ( this.status === 0 ) console.warn( 'THREE.FileLoader: HTTP Status 0 received.' ); + if ( this.status === 0 ) console.warn( 'THREE.FileLoader: HTTP Status 0 received.' ); - for ( var i = 0, il = callbacks.length; i < il; i ++ ) { + for ( var i = 0, il = callbacks.length; i < il; i ++ ) { - var callback = callbacks[ i ]; - if ( callback.onLoad ) callback.onLoad( response ); + var callback = callbacks[ i ]; + if ( callback.onLoad ) callback.onLoad( response ); - } + } - scope.manager.itemEnd( url ); + scope.manager.itemEnd( url ); - } else { + } else { - for ( var i = 0, il = callbacks.length; i < il; i ++ ) { + for ( var i = 0, il = callbacks.length; i < il; i ++ ) { - var callback = callbacks[ i ]; - if ( callback.onError ) callback.onError( event ); + var callback = callbacks[ i ]; + if ( callback.onError ) callback.onError( event ); - } + } - scope.manager.itemEnd( url ); - scope.manager.itemError( url ); + scope.manager.itemEnd( url ); + scope.manager.itemError( url ); - } + } - }, false ); + }, false ); - request.addEventListener( 'progress', function ( event ) { + request.addEventListener( 'progress', function ( event ) { - var callbacks = loading[ url ]; + var callbacks = loading[ url ]; + console.log('three.js fileload progress', url); - for ( var i = 0, il = callbacks.length; i < il; i ++ ) { + for ( var i = 0, il = callbacks.length; i < il; i ++ ) { - var callback = callbacks[ i ]; - if ( callback.onProgress ) callback.onProgress( event ); + var callback = callbacks[ i ]; + if ( callback.onProgress ) callback.onProgress( event ); - } + } - }, false ); + }, false ); - request.addEventListener( 'error', function ( event ) { + request.addEventListener( 'error', function ( event ) { - var callbacks = loading[ url ]; + var callbacks = loading[ url ]; - delete loading[ url ]; + console.log('three.js fileload error', url); + delete loading[ url ]; - for ( var i = 0, il = callbacks.length; i < il; i ++ ) { + for ( var i = 0, il = callbacks.length; i < il; i ++ ) { - var callback = callbacks[ i ]; - if ( callback.onError ) callback.onError( event ); + var callback = callbacks[ i ]; + if ( callback.onError ) callback.onError( event ); - } + } - scope.manager.itemEnd( url ); - scope.manager.itemError( url ); + scope.manager.itemEnd( url ); + scope.manager.itemError( url ); - }, false ); + }, false ); - if ( this.responseType !== undefined ) request.responseType = this.responseType; - if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials; + if ( this.responseType !== undefined ) request.responseType = this.responseType; + if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials; - if ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' ); + if ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' ); - for ( var header in this.requestHeader ) { + for ( var header in this.requestHeader ) { - request.setRequestHeader( header, this.requestHeader[ header ] ); + request.setRequestHeader( header, this.requestHeader[ header ] ); - } + } - request.send( null ); + request.send( null ); - } + } - scope.manager.itemStart( url ); + scope.manager.itemStart( url ); - return request; + return request; - }, + }, - setPath: function ( value ) { + setPath: function ( value ) { - this.path = value; - return this; + this.path = value; + return this; - }, + }, - setResponseType: function ( value ) { + setResponseType: function ( value ) { - this.responseType = value; - return this; + this.responseType = value; + return this; - }, + }, - setWithCredentials: function ( value ) { + setWithCredentials: function ( value ) { - this.withCredentials = value; - return this; + this.withCredentials = value; + return this; - }, + }, - setMimeType: function ( value ) { + setMimeType: function ( value ) { - this.mimeType = value; - return this; + this.mimeType = value; + return this; - }, + }, - setRequestHeader: function ( value ) { + setRequestHeader: function ( value ) { - this.requestHeader = value; - return this; + this.requestHeader = value; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * - * Abstract Base class to block based textures loader (dds, pvr, ...) - */ + /** + * @author mrdoob / http://mrdoob.com/ + * + * Abstract Base class to block based textures loader (dds, pvr, ...) + */ - function CompressedTextureLoader( manager ) { + function CompressedTextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - // override in sub classes - this._parser = null; + // override in sub classes + this._parser = null; - } + } - Object.assign( CompressedTextureLoader.prototype, { + Object.assign( CompressedTextureLoader.prototype, { - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - var scope = this; + var scope = this; - var images = []; + var images = []; - var texture = new CompressedTexture(); - texture.image = images; + var texture = new CompressedTexture(); + texture.image = images; - var loader = new FileLoader( this.manager ); - loader.setPath( this.path ); - loader.setResponseType( 'arraybuffer' ); + var loader = new FileLoader( this.manager ); + loader.setPath( this.path ); + loader.setResponseType( 'arraybuffer' ); - function loadTexture( i ) { + function loadTexture( i ) { - loader.load( url[ i ], function ( buffer ) { + loader.load( url[ i ], function ( buffer ) { - var texDatas = scope._parser( buffer, true ); + var texDatas = scope._parser( buffer, true ); - images[ i ] = { - width: texDatas.width, - height: texDatas.height, - format: texDatas.format, - mipmaps: texDatas.mipmaps - }; + images[ i ] = { + width: texDatas.width, + height: texDatas.height, + format: texDatas.format, + mipmaps: texDatas.mipmaps + }; - loaded += 1; + loaded += 1; - if ( loaded === 6 ) { + if ( loaded === 6 ) { - if ( texDatas.mipmapCount === 1 ) - texture.minFilter = LinearFilter; + if ( texDatas.mipmapCount === 1 ) + texture.minFilter = LinearFilter; - texture.format = texDatas.format; - texture.needsUpdate = true; + texture.format = texDatas.format; + texture.needsUpdate = true; - if ( onLoad ) onLoad( texture ); + if ( onLoad ) onLoad( texture ); - } + } - }, onProgress, onError ); + }, onProgress, onError ); - } + } - if ( Array.isArray( url ) ) { + if ( Array.isArray( url ) ) { - var loaded = 0; + var loaded = 0; - for ( var i = 0, il = url.length; i < il; ++ i ) { + for ( var i = 0, il = url.length; i < il; ++ i ) { - loadTexture( i ); + loadTexture( i ); - } + } - } else { + } else { - // compressed cubemap texture stored in a single DDS file + // compressed cubemap texture stored in a single DDS file - loader.load( url, function ( buffer ) { + loader.load( url, function ( buffer ) { - var texDatas = scope._parser( buffer, true ); + var texDatas = scope._parser( buffer, true ); - if ( texDatas.isCubemap ) { + if ( texDatas.isCubemap ) { - var faces = texDatas.mipmaps.length / texDatas.mipmapCount; + var faces = texDatas.mipmaps.length / texDatas.mipmapCount; - for ( var f = 0; f < faces; f ++ ) { + for ( var f = 0; f < faces; f ++ ) { - images[ f ] = { mipmaps: [] }; + images[ f ] = { mipmaps: [] }; - for ( var i = 0; i < texDatas.mipmapCount; i ++ ) { + for ( var i = 0; i < texDatas.mipmapCount; i ++ ) { - images[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] ); - images[ f ].format = texDatas.format; - images[ f ].width = texDatas.width; - images[ f ].height = texDatas.height; + images[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] ); + images[ f ].format = texDatas.format; + images[ f ].width = texDatas.width; + images[ f ].height = texDatas.height; - } + } - } + } - } else { + } else { - texture.image.width = texDatas.width; - texture.image.height = texDatas.height; - texture.mipmaps = texDatas.mipmaps; + texture.image.width = texDatas.width; + texture.image.height = texDatas.height; + texture.mipmaps = texDatas.mipmaps; - } + } - if ( texDatas.mipmapCount === 1 ) { + if ( texDatas.mipmapCount === 1 ) { - texture.minFilter = LinearFilter; + texture.minFilter = LinearFilter; - } + } - texture.format = texDatas.format; - texture.needsUpdate = true; + texture.format = texDatas.format; + texture.needsUpdate = true; - if ( onLoad ) onLoad( texture ); + if ( onLoad ) onLoad( texture ); - }, onProgress, onError ); + }, onProgress, onError ); - } + } - return texture; + return texture; - }, + }, - setPath: function ( value ) { + setPath: function ( value ) { - this.path = value; - return this; + this.path = value; + return this; - } + } - } ); + } ); - /** - * @author Nikos M. / https://github.com/foo123/ - * - * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...) - */ + /** + * @author Nikos M. / https://github.com/foo123/ + * + * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...) + */ - function DataTextureLoader( manager ) { + function DataTextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - // override in sub classes - this._parser = null; + // override in sub classes + this._parser = null; - } + } - Object.assign( DataTextureLoader.prototype, { + Object.assign( DataTextureLoader.prototype, { - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - var scope = this; + var scope = this; - var texture = new DataTexture(); + var texture = new DataTexture(); - var loader = new FileLoader( this.manager ); - loader.setResponseType( 'arraybuffer' ); + var loader = new FileLoader( this.manager ); + loader.setResponseType( 'arraybuffer' ); - loader.load( url, function ( buffer ) { + loader.load( url, function ( buffer ) { - var texData = scope._parser( buffer ); + var texData = scope._parser( buffer ); - if ( ! texData ) return; + if ( ! texData ) return; - if ( undefined !== texData.image ) { + if ( undefined !== texData.image ) { - texture.image = texData.image; + texture.image = texData.image; - } else if ( undefined !== texData.data ) { + } else if ( undefined !== texData.data ) { - texture.image.width = texData.width; - texture.image.height = texData.height; - texture.image.data = texData.data; + texture.image.width = texData.width; + texture.image.height = texData.height; + texture.image.data = texData.data; - } + } - texture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping; - texture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping; + texture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping; + texture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping; - texture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter; - texture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter; + texture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter; + texture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter; - texture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1; + texture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1; - if ( undefined !== texData.format ) { + if ( undefined !== texData.format ) { - texture.format = texData.format; + texture.format = texData.format; - } - if ( undefined !== texData.type ) { + } + if ( undefined !== texData.type ) { - texture.type = texData.type; + texture.type = texData.type; - } + } - if ( undefined !== texData.mipmaps ) { + if ( undefined !== texData.mipmaps ) { - texture.mipmaps = texData.mipmaps; + texture.mipmaps = texData.mipmaps; - } + } - if ( 1 === texData.mipmapCount ) { + if ( 1 === texData.mipmapCount ) { - texture.minFilter = LinearFilter; + texture.minFilter = LinearFilter; - } + } - texture.needsUpdate = true; + texture.needsUpdate = true; - if ( onLoad ) onLoad( texture, texData ); + if ( onLoad ) onLoad( texture, texData ); - }, onProgress, onError ); + }, onProgress, onError ); - return texture; + return texture; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function ImageLoader( manager ) { + function ImageLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - } + } - Object.assign( ImageLoader.prototype, { + Object.assign( ImageLoader.prototype, { - crossOrigin: 'anonymous', + crossOrigin: 'anonymous', - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - if ( url === undefined ) url = ''; + if ( url === undefined ) url = ''; - if ( this.path !== undefined ) url = this.path + url; + if ( this.path !== undefined ) url = this.path + url; - url = this.manager.resolveURL( url ); + url = this.manager.resolveURL( url ); - var scope = this; + var scope = this; - var cached = Cache.get( url ); + var cached = Cache.get( url ); - if ( cached !== undefined ) { + if ( cached !== undefined ) { - scope.manager.itemStart( url ); + scope.manager.itemStart( url ); - setTimeout( function () { + setTimeout( function () { - if ( onLoad ) onLoad( cached ); + if ( onLoad ) onLoad( cached ); - scope.manager.itemEnd( url ); + scope.manager.itemEnd( url ); - }, 0 ); + }, 0 ); - return cached; + return cached; - } + } - var image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' ); + var image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' ); - function onImageLoad() { + function onImageLoad() { - image.removeEventListener( 'load', onImageLoad, false ); - image.removeEventListener( 'error', onImageError, false ); + image.removeEventListener( 'load', onImageLoad, false ); + image.removeEventListener( 'error', onImageError, false ); - Cache.add( url, this ); + Cache.add( url, this ); - if ( onLoad ) onLoad( this ); + if ( onLoad ) onLoad( this ); - scope.manager.itemEnd( url ); + scope.manager.itemEnd( url ); - } + } - function onImageError( event ) { + function onImageError( event ) { - image.removeEventListener( 'load', onImageLoad, false ); - image.removeEventListener( 'error', onImageError, false ); + image.removeEventListener( 'load', onImageLoad, false ); + image.removeEventListener( 'error', onImageError, false ); - if ( onError ) onError( event ); + if ( onError ) onError( event ); - scope.manager.itemEnd( url ); - scope.manager.itemError( url ); + scope.manager.itemEnd( url ); + scope.manager.itemError( url ); - } + } - image.addEventListener( 'load', onImageLoad, false ); - image.addEventListener( 'error', onImageError, false ); + image.addEventListener( 'load', onImageLoad, false ); + image.addEventListener( 'error', onImageError, false ); - if ( url.substr( 0, 5 ) !== 'data:' ) { + if ( url.substr( 0, 5 ) !== 'data:' ) { - if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin; + if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin; - } + } - scope.manager.itemStart( url ); + scope.manager.itemStart( url ); - image.src = url; + image.src = url; - return image; + return image; - }, + }, - setCrossOrigin: function ( value ) { + setCrossOrigin: function ( value ) { - this.crossOrigin = value; - return this; + this.crossOrigin = value; + return this; - }, + }, - setPath: function ( value ) { + setPath: function ( value ) { - this.path = value; - return this; + this.path = value; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function CubeTextureLoader( manager ) { + function CubeTextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - } + } - Object.assign( CubeTextureLoader.prototype, { + Object.assign( CubeTextureLoader.prototype, { - crossOrigin: 'anonymous', + crossOrigin: 'anonymous', - load: function ( urls, onLoad, onProgress, onError ) { + load: function ( urls, onLoad, onProgress, onError ) { - var texture = new CubeTexture(); + var texture = new CubeTexture(); - var loader = new ImageLoader( this.manager ); - loader.setCrossOrigin( this.crossOrigin ); - loader.setPath( this.path ); + var loader = new ImageLoader( this.manager ); + loader.setCrossOrigin( this.crossOrigin ); + loader.setPath( this.path ); - var loaded = 0; + var loaded = 0; - function loadTexture( i ) { + function loadTexture( i ) { - loader.load( urls[ i ], function ( image ) { + loader.load( urls[ i ], function ( image ) { - texture.images[ i ] = image; + texture.images[ i ] = image; - loaded ++; + loaded ++; - if ( loaded === 6 ) { + if ( loaded === 6 ) { - texture.needsUpdate = true; + texture.needsUpdate = true; - if ( onLoad ) onLoad( texture ); + if ( onLoad ) onLoad( texture ); - } + } - }, undefined, onError ); + }, undefined, onError ); - } + } - for ( var i = 0; i < urls.length; ++ i ) { + for ( var i = 0; i < urls.length; ++ i ) { - loadTexture( i ); + loadTexture( i ); - } + } - return texture; + return texture; - }, + }, - setCrossOrigin: function ( value ) { + setCrossOrigin: function ( value ) { - this.crossOrigin = value; - return this; + this.crossOrigin = value; + return this; - }, + }, - setPath: function ( value ) { + setPath: function ( value ) { - this.path = value; - return this; + this.path = value; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function TextureLoader( manager ) { + function TextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - } + } - Object.assign( TextureLoader.prototype, { + Object.assign( TextureLoader.prototype, { - crossOrigin: 'anonymous', + crossOrigin: 'anonymous', - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - var texture = new Texture(); + var texture = new Texture(); - var loader = new ImageLoader( this.manager ); - loader.setCrossOrigin( this.crossOrigin ); - loader.setPath( this.path ); + var loader = new ImageLoader( this.manager ); + loader.setCrossOrigin( this.crossOrigin ); + loader.setPath( this.path ); - loader.load( url, function ( image ) { + loader.load( url, function ( image ) { - texture.image = image; + texture.image = image; - // JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB. - var isJPEG = url.search( /\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\:image\/jpeg/ ) === 0; + // JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB. + var isJPEG = url.search( /\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\:image\/jpeg/ ) === 0; - texture.format = isJPEG ? RGBFormat : RGBAFormat; - texture.needsUpdate = true; + texture.format = isJPEG ? RGBFormat : RGBAFormat; + texture.needsUpdate = true; - if ( onLoad !== undefined ) { + if ( onLoad !== undefined ) { - onLoad( texture ); + onLoad( texture ); - } + } - }, onProgress, onError ); + }, onProgress, onError ); - return texture; + return texture; - }, + }, - setCrossOrigin: function ( value ) { + setCrossOrigin: function ( value ) { - this.crossOrigin = value; - return this; + this.crossOrigin = value; + return this; - }, + }, - setPath: function ( value ) { + setPath: function ( value ) { - this.path = value; - return this; + this.path = value; + return this; - } + } - } ); + } ); - /** - * @author zz85 / http://www.lab4games.net/zz85/blog - * Extensible curve object - * - * Some common of curve methods: - * .getPoint( t, optionalTarget ), .getTangent( t ) - * .getPointAt( u, optionalTarget ), .getTangentAt( u ) - * .getPoints(), .getSpacedPoints() - * .getLength() - * .updateArcLengths() - * - * This following curves inherit from THREE.Curve: - * - * -- 2D curves -- - * THREE.ArcCurve - * THREE.CubicBezierCurve - * THREE.EllipseCurve - * THREE.LineCurve - * THREE.QuadraticBezierCurve - * THREE.SplineCurve - * - * -- 3D curves -- - * THREE.CatmullRomCurve3 - * THREE.CubicBezierCurve3 - * THREE.LineCurve3 - * THREE.QuadraticBezierCurve3 - * - * A series of curves can be represented as a THREE.CurvePath. - * - **/ + /** + * @author zz85 / http://www.lab4games.net/zz85/blog + * Extensible curve object + * + * Some common of curve methods: + * .getPoint( t, optionalTarget ), .getTangent( t ) + * .getPointAt( u, optionalTarget ), .getTangentAt( u ) + * .getPoints(), .getSpacedPoints() + * .getLength() + * .updateArcLengths() + * + * This following curves inherit from THREE.Curve: + * + * -- 2D curves -- + * THREE.ArcCurve + * THREE.CubicBezierCurve + * THREE.EllipseCurve + * THREE.LineCurve + * THREE.QuadraticBezierCurve + * THREE.SplineCurve + * + * -- 3D curves -- + * THREE.CatmullRomCurve3 + * THREE.CubicBezierCurve3 + * THREE.LineCurve3 + * THREE.QuadraticBezierCurve3 + * + * A series of curves can be represented as a THREE.CurvePath. + * + **/ - /************************************************************** - * Abstract Curve base class - **************************************************************/ + /************************************************************** + * Abstract Curve base class + **************************************************************/ - function Curve() { + function Curve() { - this.type = 'Curve'; + this.type = 'Curve'; - this.arcLengthDivisions = 200; + this.arcLengthDivisions = 200; - } + } - Object.assign( Curve.prototype, { + Object.assign( Curve.prototype, { - // Virtual base class method to overwrite and implement in subclasses - // - t [0 .. 1] + // Virtual base class method to overwrite and implement in subclasses + // - t [0 .. 1] - getPoint: function ( /* t, optionalTarget */ ) { + getPoint: function ( /* t, optionalTarget */ ) { - console.warn( 'THREE.Curve: .getPoint() not implemented.' ); - return null; + console.warn( 'THREE.Curve: .getPoint() not implemented.' ); + return null; - }, + }, - // Get point at relative position in curve according to arc length - // - u [0 .. 1] + // Get point at relative position in curve according to arc length + // - u [0 .. 1] - getPointAt: function ( u, optionalTarget ) { + getPointAt: function ( u, optionalTarget ) { - var t = this.getUtoTmapping( u ); - return this.getPoint( t, optionalTarget ); + var t = this.getUtoTmapping( u ); + return this.getPoint( t, optionalTarget ); - }, + }, - // Get sequence of points using getPoint( t ) + // Get sequence of points using getPoint( t ) - getPoints: function ( divisions ) { + getPoints: function ( divisions ) { - if ( divisions === undefined ) divisions = 5; + if ( divisions === undefined ) divisions = 5; - var points = []; + var points = []; - for ( var d = 0; d <= divisions; d ++ ) { + for ( var d = 0; d <= divisions; d ++ ) { - points.push( this.getPoint( d / divisions ) ); + points.push( this.getPoint( d / divisions ) ); - } + } - return points; + return points; - }, + }, - // Get sequence of points using getPointAt( u ) + // Get sequence of points using getPointAt( u ) - getSpacedPoints: function ( divisions ) { + getSpacedPoints: function ( divisions ) { - if ( divisions === undefined ) divisions = 5; + if ( divisions === undefined ) divisions = 5; - var points = []; + var points = []; - for ( var d = 0; d <= divisions; d ++ ) { + for ( var d = 0; d <= divisions; d ++ ) { - points.push( this.getPointAt( d / divisions ) ); + points.push( this.getPointAt( d / divisions ) ); - } + } - return points; + return points; - }, + }, - // Get total curve arc length + // Get total curve arc length - getLength: function () { + getLength: function () { - var lengths = this.getLengths(); - return lengths[ lengths.length - 1 ]; + var lengths = this.getLengths(); + return lengths[ lengths.length - 1 ]; - }, + }, - // Get list of cumulative segment lengths + // Get list of cumulative segment lengths - getLengths: function ( divisions ) { + getLengths: function ( divisions ) { - if ( divisions === undefined ) divisions = this.arcLengthDivisions; + if ( divisions === undefined ) divisions = this.arcLengthDivisions; - if ( this.cacheArcLengths && - ( this.cacheArcLengths.length === divisions + 1 ) && - ! this.needsUpdate ) { + if ( this.cacheArcLengths && + ( this.cacheArcLengths.length === divisions + 1 ) && + ! this.needsUpdate ) { - return this.cacheArcLengths; + return this.cacheArcLengths; - } + } - this.needsUpdate = false; + this.needsUpdate = false; - var cache = []; - var current, last = this.getPoint( 0 ); - var p, sum = 0; + var cache = []; + var current, last = this.getPoint( 0 ); + var p, sum = 0; - cache.push( 0 ); + cache.push( 0 ); - for ( p = 1; p <= divisions; p ++ ) { + for ( p = 1; p <= divisions; p ++ ) { - current = this.getPoint( p / divisions ); - sum += current.distanceTo( last ); - cache.push( sum ); - last = current; + current = this.getPoint( p / divisions ); + sum += current.distanceTo( last ); + cache.push( sum ); + last = current; - } + } - this.cacheArcLengths = cache; + this.cacheArcLengths = cache; - return cache; // { sums: cache, sum: sum }; Sum is in the last element. + return cache; // { sums: cache, sum: sum }; Sum is in the last element. - }, + }, - updateArcLengths: function () { + updateArcLengths: function () { - this.needsUpdate = true; - this.getLengths(); + this.needsUpdate = true; + this.getLengths(); - }, + }, - // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant + // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant - getUtoTmapping: function ( u, distance ) { + getUtoTmapping: function ( u, distance ) { - var arcLengths = this.getLengths(); + var arcLengths = this.getLengths(); - var i = 0, il = arcLengths.length; + var i = 0, il = arcLengths.length; - var targetArcLength; // The targeted u distance value to get + var targetArcLength; // The targeted u distance value to get - if ( distance ) { + if ( distance ) { - targetArcLength = distance; + targetArcLength = distance; - } else { + } else { - targetArcLength = u * arcLengths[ il - 1 ]; + targetArcLength = u * arcLengths[ il - 1 ]; - } + } - // binary search for the index with largest value smaller than target u distance + // binary search for the index with largest value smaller than target u distance - var low = 0, high = il - 1, comparison; + var low = 0, high = il - 1, comparison; - while ( low <= high ) { + while ( low <= high ) { - i = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats + i = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats - comparison = arcLengths[ i ] - targetArcLength; + comparison = arcLengths[ i ] - targetArcLength; - if ( comparison < 0 ) { + if ( comparison < 0 ) { - low = i + 1; + low = i + 1; - } else if ( comparison > 0 ) { + } else if ( comparison > 0 ) { - high = i - 1; + high = i - 1; - } else { + } else { - high = i; - break; + high = i; + break; - // DONE + // DONE - } + } - } + } - i = high; + i = high; - if ( arcLengths[ i ] === targetArcLength ) { + if ( arcLengths[ i ] === targetArcLength ) { - return i / ( il - 1 ); + return i / ( il - 1 ); - } + } - // we could get finer grain at lengths, or use simple interpolation between two points + // we could get finer grain at lengths, or use simple interpolation between two points - var lengthBefore = arcLengths[ i ]; - var lengthAfter = arcLengths[ i + 1 ]; + var lengthBefore = arcLengths[ i ]; + var lengthAfter = arcLengths[ i + 1 ]; - var segmentLength = lengthAfter - lengthBefore; + var segmentLength = lengthAfter - lengthBefore; - // determine where we are between the 'before' and 'after' points + // determine where we are between the 'before' and 'after' points - var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength; + var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength; - // add that fractional amount to t + // add that fractional amount to t - var t = ( i + segmentFraction ) / ( il - 1 ); + var t = ( i + segmentFraction ) / ( il - 1 ); - return t; + return t; - }, + }, - // Returns a unit vector tangent at t - // In case any sub curve does not implement its tangent derivation, - // 2 points a small delta apart will be used to find its gradient - // which seems to give a reasonable approximation + // Returns a unit vector tangent at t + // In case any sub curve does not implement its tangent derivation, + // 2 points a small delta apart will be used to find its gradient + // which seems to give a reasonable approximation - getTangent: function ( t ) { + getTangent: function ( t ) { - var delta = 0.0001; - var t1 = t - delta; - var t2 = t + delta; + var delta = 0.0001; + var t1 = t - delta; + var t2 = t + delta; - // Capping in case of danger + // Capping in case of danger - if ( t1 < 0 ) t1 = 0; - if ( t2 > 1 ) t2 = 1; + if ( t1 < 0 ) t1 = 0; + if ( t2 > 1 ) t2 = 1; - var pt1 = this.getPoint( t1 ); - var pt2 = this.getPoint( t2 ); + var pt1 = this.getPoint( t1 ); + var pt2 = this.getPoint( t2 ); - var vec = pt2.clone().sub( pt1 ); - return vec.normalize(); + var vec = pt2.clone().sub( pt1 ); + return vec.normalize(); - }, + }, - getTangentAt: function ( u ) { + getTangentAt: function ( u ) { - var t = this.getUtoTmapping( u ); - return this.getTangent( t ); + var t = this.getUtoTmapping( u ); + return this.getTangent( t ); - }, + }, - computeFrenetFrames: function ( segments, closed ) { + computeFrenetFrames: function ( segments, closed ) { - // see http://www.cs.indiana.edu/pub/techreports/TR425.pdf + // see http://www.cs.indiana.edu/pub/techreports/TR425.pdf - var normal = new Vector3(); + var normal = new Vector3(); - var tangents = []; - var normals = []; - var binormals = []; + var tangents = []; + var normals = []; + var binormals = []; - var vec = new Vector3(); - var mat = new Matrix4(); + var vec = new Vector3(); + var mat = new Matrix4(); - var i, u, theta; + var i, u, theta; - // compute the tangent vectors for each segment on the curve + // compute the tangent vectors for each segment on the curve - for ( i = 0; i <= segments; i ++ ) { + for ( i = 0; i <= segments; i ++ ) { - u = i / segments; + u = i / segments; - tangents[ i ] = this.getTangentAt( u ); - tangents[ i ].normalize(); + tangents[ i ] = this.getTangentAt( u ); + tangents[ i ].normalize(); - } + } - // select an initial normal vector perpendicular to the first tangent vector, - // and in the direction of the minimum tangent xyz component + // select an initial normal vector perpendicular to the first tangent vector, + // and in the direction of the minimum tangent xyz component - normals[ 0 ] = new Vector3(); - binormals[ 0 ] = new Vector3(); - var min = Number.MAX_VALUE; - var tx = Math.abs( tangents[ 0 ].x ); - var ty = Math.abs( tangents[ 0 ].y ); - var tz = Math.abs( tangents[ 0 ].z ); + normals[ 0 ] = new Vector3(); + binormals[ 0 ] = new Vector3(); + var min = Number.MAX_VALUE; + var tx = Math.abs( tangents[ 0 ].x ); + var ty = Math.abs( tangents[ 0 ].y ); + var tz = Math.abs( tangents[ 0 ].z ); - if ( tx <= min ) { + if ( tx <= min ) { - min = tx; - normal.set( 1, 0, 0 ); + min = tx; + normal.set( 1, 0, 0 ); - } + } - if ( ty <= min ) { + if ( ty <= min ) { - min = ty; - normal.set( 0, 1, 0 ); + min = ty; + normal.set( 0, 1, 0 ); - } + } - if ( tz <= min ) { + if ( tz <= min ) { - normal.set( 0, 0, 1 ); + normal.set( 0, 0, 1 ); - } + } - vec.crossVectors( tangents[ 0 ], normal ).normalize(); + vec.crossVectors( tangents[ 0 ], normal ).normalize(); - normals[ 0 ].crossVectors( tangents[ 0 ], vec ); - binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] ); + normals[ 0 ].crossVectors( tangents[ 0 ], vec ); + binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] ); - // compute the slowly-varying normal and binormal vectors for each segment on the curve + // compute the slowly-varying normal and binormal vectors for each segment on the curve - for ( i = 1; i <= segments; i ++ ) { + for ( i = 1; i <= segments; i ++ ) { - normals[ i ] = normals[ i - 1 ].clone(); + normals[ i ] = normals[ i - 1 ].clone(); - binormals[ i ] = binormals[ i - 1 ].clone(); + binormals[ i ] = binormals[ i - 1 ].clone(); - vec.crossVectors( tangents[ i - 1 ], tangents[ i ] ); + vec.crossVectors( tangents[ i - 1 ], tangents[ i ] ); - if ( vec.length() > Number.EPSILON ) { + if ( vec.length() > Number.EPSILON ) { - vec.normalize(); + vec.normalize(); - theta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors + theta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors - normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) ); + normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) ); - } + } - binormals[ i ].crossVectors( tangents[ i ], normals[ i ] ); + binormals[ i ].crossVectors( tangents[ i ], normals[ i ] ); - } + } - // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same + // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same - if ( closed === true ) { + if ( closed === true ) { - theta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) ); - theta /= segments; + theta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) ); + theta /= segments; - if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) { + if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) { - theta = - theta; + theta = - theta; - } + } - for ( i = 1; i <= segments; i ++ ) { + for ( i = 1; i <= segments; i ++ ) { - // twist a little... - normals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) ); - binormals[ i ].crossVectors( tangents[ i ], normals[ i ] ); + // twist a little... + normals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) ); + binormals[ i ].crossVectors( tangents[ i ], normals[ i ] ); - } + } - } + } - return { - tangents: tangents, - normals: normals, - binormals: binormals - }; + return { + tangents: tangents, + normals: normals, + binormals: binormals + }; - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( source ) { + copy: function ( source ) { - this.arcLengthDivisions = source.arcLengthDivisions; + this.arcLengthDivisions = source.arcLengthDivisions; - return this; + return this; - }, + }, - toJSON: function () { + toJSON: function () { - var data = { - metadata: { - version: 4.5, - type: 'Curve', - generator: 'Curve.toJSON' - } - }; + var data = { + metadata: { + version: 4.5, + type: 'Curve', + generator: 'Curve.toJSON' + } + }; - data.arcLengthDivisions = this.arcLengthDivisions; - data.type = this.type; + data.arcLengthDivisions = this.arcLengthDivisions; + data.type = this.type; - return data; + return data; - }, + }, - fromJSON: function ( json ) { + fromJSON: function ( json ) { - this.arcLengthDivisions = json.arcLengthDivisions; + this.arcLengthDivisions = json.arcLengthDivisions; - return this; + return this; - } + } - } ); + } ); - function EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { + function EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { - Curve.call( this ); + Curve.call( this ); - this.type = 'EllipseCurve'; + this.type = 'EllipseCurve'; - this.aX = aX || 0; - this.aY = aY || 0; + this.aX = aX || 0; + this.aY = aY || 0; - this.xRadius = xRadius || 1; - this.yRadius = yRadius || 1; + this.xRadius = xRadius || 1; + this.yRadius = yRadius || 1; - this.aStartAngle = aStartAngle || 0; - this.aEndAngle = aEndAngle || 2 * Math.PI; + this.aStartAngle = aStartAngle || 0; + this.aEndAngle = aEndAngle || 2 * Math.PI; - this.aClockwise = aClockwise || false; + this.aClockwise = aClockwise || false; - this.aRotation = aRotation || 0; + this.aRotation = aRotation || 0; - } + } - EllipseCurve.prototype = Object.create( Curve.prototype ); - EllipseCurve.prototype.constructor = EllipseCurve; + EllipseCurve.prototype = Object.create( Curve.prototype ); + EllipseCurve.prototype.constructor = EllipseCurve; - EllipseCurve.prototype.isEllipseCurve = true; + EllipseCurve.prototype.isEllipseCurve = true; - EllipseCurve.prototype.getPoint = function ( t, optionalTarget ) { + EllipseCurve.prototype.getPoint = function ( t, optionalTarget ) { - var point = optionalTarget || new Vector2(); + var point = optionalTarget || new Vector2(); - var twoPi = Math.PI * 2; - var deltaAngle = this.aEndAngle - this.aStartAngle; - var samePoints = Math.abs( deltaAngle ) < Number.EPSILON; + var twoPi = Math.PI * 2; + var deltaAngle = this.aEndAngle - this.aStartAngle; + var samePoints = Math.abs( deltaAngle ) < Number.EPSILON; - // ensures that deltaAngle is 0 .. 2 PI - while ( deltaAngle < 0 ) deltaAngle += twoPi; - while ( deltaAngle > twoPi ) deltaAngle -= twoPi; + // ensures that deltaAngle is 0 .. 2 PI + while ( deltaAngle < 0 ) deltaAngle += twoPi; + while ( deltaAngle > twoPi ) deltaAngle -= twoPi; - if ( deltaAngle < Number.EPSILON ) { + if ( deltaAngle < Number.EPSILON ) { - if ( samePoints ) { + if ( samePoints ) { - deltaAngle = 0; + deltaAngle = 0; - } else { + } else { - deltaAngle = twoPi; + deltaAngle = twoPi; - } + } - } + } - if ( this.aClockwise === true && ! samePoints ) { + if ( this.aClockwise === true && ! samePoints ) { - if ( deltaAngle === twoPi ) { + if ( deltaAngle === twoPi ) { - deltaAngle = - twoPi; + deltaAngle = - twoPi; - } else { + } else { - deltaAngle = deltaAngle - twoPi; + deltaAngle = deltaAngle - twoPi; - } + } - } + } - var angle = this.aStartAngle + t * deltaAngle; - var x = this.aX + this.xRadius * Math.cos( angle ); - var y = this.aY + this.yRadius * Math.sin( angle ); + var angle = this.aStartAngle + t * deltaAngle; + var x = this.aX + this.xRadius * Math.cos( angle ); + var y = this.aY + this.yRadius * Math.sin( angle ); - if ( this.aRotation !== 0 ) { + if ( this.aRotation !== 0 ) { - var cos = Math.cos( this.aRotation ); - var sin = Math.sin( this.aRotation ); + var cos = Math.cos( this.aRotation ); + var sin = Math.sin( this.aRotation ); - var tx = x - this.aX; - var ty = y - this.aY; + var tx = x - this.aX; + var ty = y - this.aY; - // Rotate the point about the center of the ellipse. - x = tx * cos - ty * sin + this.aX; - y = tx * sin + ty * cos + this.aY; + // Rotate the point about the center of the ellipse. + x = tx * cos - ty * sin + this.aX; + y = tx * sin + ty * cos + this.aY; - } + } - return point.set( x, y ); + return point.set( x, y ); - }; + }; - EllipseCurve.prototype.copy = function ( source ) { + EllipseCurve.prototype.copy = function ( source ) { - Curve.prototype.copy.call( this, source ); + Curve.prototype.copy.call( this, source ); - this.aX = source.aX; - this.aY = source.aY; + this.aX = source.aX; + this.aY = source.aY; - this.xRadius = source.xRadius; - this.yRadius = source.yRadius; + this.xRadius = source.xRadius; + this.yRadius = source.yRadius; - this.aStartAngle = source.aStartAngle; - this.aEndAngle = source.aEndAngle; + this.aStartAngle = source.aStartAngle; + this.aEndAngle = source.aEndAngle; - this.aClockwise = source.aClockwise; + this.aClockwise = source.aClockwise; - this.aRotation = source.aRotation; + this.aRotation = source.aRotation; - return this; + return this; - }; + }; - EllipseCurve.prototype.toJSON = function () { + EllipseCurve.prototype.toJSON = function () { - var data = Curve.prototype.toJSON.call( this ); + var data = Curve.prototype.toJSON.call( this ); - data.aX = this.aX; - data.aY = this.aY; + data.aX = this.aX; + data.aY = this.aY; - data.xRadius = this.xRadius; - data.yRadius = this.yRadius; + data.xRadius = this.xRadius; + data.yRadius = this.yRadius; - data.aStartAngle = this.aStartAngle; - data.aEndAngle = this.aEndAngle; + data.aStartAngle = this.aStartAngle; + data.aEndAngle = this.aEndAngle; - data.aClockwise = this.aClockwise; + data.aClockwise = this.aClockwise; - data.aRotation = this.aRotation; + data.aRotation = this.aRotation; - return data; + return data; - }; + }; - EllipseCurve.prototype.fromJSON = function ( json ) { + EllipseCurve.prototype.fromJSON = function ( json ) { - Curve.prototype.fromJSON.call( this, json ); + Curve.prototype.fromJSON.call( this, json ); - this.aX = json.aX; - this.aY = json.aY; + this.aX = json.aX; + this.aY = json.aY; - this.xRadius = json.xRadius; - this.yRadius = json.yRadius; + this.xRadius = json.xRadius; + this.yRadius = json.yRadius; - this.aStartAngle = json.aStartAngle; - this.aEndAngle = json.aEndAngle; + this.aStartAngle = json.aStartAngle; + this.aEndAngle = json.aEndAngle; - this.aClockwise = json.aClockwise; + this.aClockwise = json.aClockwise; - this.aRotation = json.aRotation; + this.aRotation = json.aRotation; - return this; + return this; - }; + }; - function ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { + function ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { - EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise ); + EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise ); - this.type = 'ArcCurve'; + this.type = 'ArcCurve'; - } + } - ArcCurve.prototype = Object.create( EllipseCurve.prototype ); - ArcCurve.prototype.constructor = ArcCurve; + ArcCurve.prototype = Object.create( EllipseCurve.prototype ); + ArcCurve.prototype.constructor = ArcCurve; - ArcCurve.prototype.isArcCurve = true; + ArcCurve.prototype.isArcCurve = true; - /** - * @author zz85 https://github.com/zz85 - * - * Centripetal CatmullRom Curve - which is useful for avoiding - * cusps and self-intersections in non-uniform catmull rom curves. - * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf - * - * curve.type accepts centripetal(default), chordal and catmullrom - * curve.tension is used for catmullrom which defaults to 0.5 - */ + /** + * @author zz85 https://github.com/zz85 + * + * Centripetal CatmullRom Curve - which is useful for avoiding + * cusps and self-intersections in non-uniform catmull rom curves. + * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf + * + * curve.type accepts centripetal(default), chordal and catmullrom + * curve.tension is used for catmullrom which defaults to 0.5 + */ - /* - Based on an optimized c++ solution in - - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/ - - http://ideone.com/NoEbVM + /* + Based on an optimized c++ solution in + - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/ + - http://ideone.com/NoEbVM - This CubicPoly class could be used for reusing some variables and calculations, - but for three.js curve use, it could be possible inlined and flatten into a single function call - which can be placed in CurveUtils. - */ + This CubicPoly class could be used for reusing some variables and calculations, + but for three.js curve use, it could be possible inlined and flatten into a single function call + which can be placed in CurveUtils. + */ - function CubicPoly() { + function CubicPoly() { - var c0 = 0, c1 = 0, c2 = 0, c3 = 0; + var c0 = 0, c1 = 0, c2 = 0, c3 = 0; - /* - * Compute coefficients for a cubic polynomial - * p(s) = c0 + c1*s + c2*s^2 + c3*s^3 - * such that - * p(0) = x0, p(1) = x1 - * and - * p'(0) = t0, p'(1) = t1. - */ - function init( x0, x1, t0, t1 ) { + /* + * Compute coefficients for a cubic polynomial + * p(s) = c0 + c1*s + c2*s^2 + c3*s^3 + * such that + * p(0) = x0, p(1) = x1 + * and + * p'(0) = t0, p'(1) = t1. + */ + function init( x0, x1, t0, t1 ) { - c0 = x0; - c1 = t0; - c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1; - c3 = 2 * x0 - 2 * x1 + t0 + t1; + c0 = x0; + c1 = t0; + c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1; + c3 = 2 * x0 - 2 * x1 + t0 + t1; - } + } - return { + return { - initCatmullRom: function ( x0, x1, x2, x3, tension ) { + initCatmullRom: function ( x0, x1, x2, x3, tension ) { - init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) ); + init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) ); - }, + }, - initNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) { + initNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) { - // compute tangents when parameterized in [t1,t2] - var t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1; - var t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2; + // compute tangents when parameterized in [t1,t2] + var t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1; + var t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2; - // rescale tangents for parametrization in [0,1] - t1 *= dt1; - t2 *= dt1; + // rescale tangents for parametrization in [0,1] + t1 *= dt1; + t2 *= dt1; - init( x1, x2, t1, t2 ); + init( x1, x2, t1, t2 ); - }, + }, - calc: function ( t ) { + calc: function ( t ) { - var t2 = t * t; - var t3 = t2 * t; - return c0 + c1 * t + c2 * t2 + c3 * t3; + var t2 = t * t; + var t3 = t2 * t; + return c0 + c1 * t + c2 * t2 + c3 * t3; - } + } - }; + }; - } + } - // + // - var tmp = new Vector3(); - var px = new CubicPoly(), py = new CubicPoly(), pz = new CubicPoly(); + var tmp = new Vector3(); + var px = new CubicPoly(), py = new CubicPoly(), pz = new CubicPoly(); - function CatmullRomCurve3( points, closed, curveType, tension ) { + function CatmullRomCurve3( points, closed, curveType, tension ) { - Curve.call( this ); + Curve.call( this ); - this.type = 'CatmullRomCurve3'; + this.type = 'CatmullRomCurve3'; - this.points = points || []; - this.closed = closed || false; - this.curveType = curveType || 'centripetal'; - this.tension = tension || 0.5; + this.points = points || []; + this.closed = closed || false; + this.curveType = curveType || 'centripetal'; + this.tension = tension || 0.5; - } + } - CatmullRomCurve3.prototype = Object.create( Curve.prototype ); - CatmullRomCurve3.prototype.constructor = CatmullRomCurve3; + CatmullRomCurve3.prototype = Object.create( Curve.prototype ); + CatmullRomCurve3.prototype.constructor = CatmullRomCurve3; - CatmullRomCurve3.prototype.isCatmullRomCurve3 = true; + CatmullRomCurve3.prototype.isCatmullRomCurve3 = true; - CatmullRomCurve3.prototype.getPoint = function ( t, optionalTarget ) { + CatmullRomCurve3.prototype.getPoint = function ( t, optionalTarget ) { - var point = optionalTarget || new Vector3(); + var point = optionalTarget || new Vector3(); - var points = this.points; - var l = points.length; + var points = this.points; + var l = points.length; - var p = ( l - ( this.closed ? 0 : 1 ) ) * t; - var intPoint = Math.floor( p ); - var weight = p - intPoint; + var p = ( l - ( this.closed ? 0 : 1 ) ) * t; + var intPoint = Math.floor( p ); + var weight = p - intPoint; - if ( this.closed ) { + if ( this.closed ) { - intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / l ) + 1 ) * l; + intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / l ) + 1 ) * l; - } else if ( weight === 0 && intPoint === l - 1 ) { + } else if ( weight === 0 && intPoint === l - 1 ) { - intPoint = l - 2; - weight = 1; + intPoint = l - 2; + weight = 1; - } + } - var p0, p1, p2, p3; // 4 points + var p0, p1, p2, p3; // 4 points - if ( this.closed || intPoint > 0 ) { + if ( this.closed || intPoint > 0 ) { - p0 = points[ ( intPoint - 1 ) % l ]; + p0 = points[ ( intPoint - 1 ) % l ]; - } else { + } else { - // extrapolate first point - tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] ); - p0 = tmp; + // extrapolate first point + tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] ); + p0 = tmp; - } + } - p1 = points[ intPoint % l ]; - p2 = points[ ( intPoint + 1 ) % l ]; + p1 = points[ intPoint % l ]; + p2 = points[ ( intPoint + 1 ) % l ]; - if ( this.closed || intPoint + 2 < l ) { + if ( this.closed || intPoint + 2 < l ) { - p3 = points[ ( intPoint + 2 ) % l ]; + p3 = points[ ( intPoint + 2 ) % l ]; - } else { + } else { - // extrapolate last point - tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] ); - p3 = tmp; + // extrapolate last point + tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] ); + p3 = tmp; - } + } - if ( this.curveType === 'centripetal' || this.curveType === 'chordal' ) { + if ( this.curveType === 'centripetal' || this.curveType === 'chordal' ) { - // init Centripetal / Chordal Catmull-Rom - var pow = this.curveType === 'chordal' ? 0.5 : 0.25; - var dt0 = Math.pow( p0.distanceToSquared( p1 ), pow ); - var dt1 = Math.pow( p1.distanceToSquared( p2 ), pow ); - var dt2 = Math.pow( p2.distanceToSquared( p3 ), pow ); + // init Centripetal / Chordal Catmull-Rom + var pow = this.curveType === 'chordal' ? 0.5 : 0.25; + var dt0 = Math.pow( p0.distanceToSquared( p1 ), pow ); + var dt1 = Math.pow( p1.distanceToSquared( p2 ), pow ); + var dt2 = Math.pow( p2.distanceToSquared( p3 ), pow ); - // safety check for repeated points - if ( dt1 < 1e-4 ) dt1 = 1.0; - if ( dt0 < 1e-4 ) dt0 = dt1; - if ( dt2 < 1e-4 ) dt2 = dt1; + // safety check for repeated points + if ( dt1 < 1e-4 ) dt1 = 1.0; + if ( dt0 < 1e-4 ) dt0 = dt1; + if ( dt2 < 1e-4 ) dt2 = dt1; - px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 ); - py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 ); - pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 ); + px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 ); + py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 ); + pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 ); - } else if ( this.curveType === 'catmullrom' ) { + } else if ( this.curveType === 'catmullrom' ) { - px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, this.tension ); - py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, this.tension ); - pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, this.tension ); + px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, this.tension ); + py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, this.tension ); + pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, this.tension ); - } + } - point.set( - px.calc( weight ), - py.calc( weight ), - pz.calc( weight ) - ); + point.set( + px.calc( weight ), + py.calc( weight ), + pz.calc( weight ) + ); - return point; + return point; - }; + }; - CatmullRomCurve3.prototype.copy = function ( source ) { + CatmullRomCurve3.prototype.copy = function ( source ) { - Curve.prototype.copy.call( this, source ); + Curve.prototype.copy.call( this, source ); - this.points = []; + this.points = []; - for ( var i = 0, l = source.points.length; i < l; i ++ ) { + for ( var i = 0, l = source.points.length; i < l; i ++ ) { - var point = source.points[ i ]; + var point = source.points[ i ]; - this.points.push( point.clone() ); + this.points.push( point.clone() ); - } + } - this.closed = source.closed; - this.curveType = source.curveType; - this.tension = source.tension; + this.closed = source.closed; + this.curveType = source.curveType; + this.tension = source.tension; - return this; + return this; - }; + }; - CatmullRomCurve3.prototype.toJSON = function () { + CatmullRomCurve3.prototype.toJSON = function () { - var data = Curve.prototype.toJSON.call( this ); + var data = Curve.prototype.toJSON.call( this ); - data.points = []; + data.points = []; - for ( var i = 0, l = this.points.length; i < l; i ++ ) { + for ( var i = 0, l = this.points.length; i < l; i ++ ) { - var point = this.points[ i ]; - data.points.push( point.toArray() ); + var point = this.points[ i ]; + data.points.push( point.toArray() ); - } + } - data.closed = this.closed; - data.curveType = this.curveType; - data.tension = this.tension; + data.closed = this.closed; + data.curveType = this.curveType; + data.tension = this.tension; - return data; + return data; - }; + }; - CatmullRomCurve3.prototype.fromJSON = function ( json ) { + CatmullRomCurve3.prototype.fromJSON = function ( json ) { - Curve.prototype.fromJSON.call( this, json ); + Curve.prototype.fromJSON.call( this, json ); - this.points = []; + this.points = []; - for ( var i = 0, l = json.points.length; i < l; i ++ ) { + for ( var i = 0, l = json.points.length; i < l; i ++ ) { - var point = json.points[ i ]; - this.points.push( new Vector3().fromArray( point ) ); + var point = json.points[ i ]; + this.points.push( new Vector3().fromArray( point ) ); - } + } - this.closed = json.closed; - this.curveType = json.curveType; - this.tension = json.tension; + this.closed = json.closed; + this.curveType = json.curveType; + this.tension = json.tension; - return this; + return this; - }; + }; - /** - * @author zz85 / http://www.lab4games.net/zz85/blog - * - * Bezier Curves formulas obtained from - * http://en.wikipedia.org/wiki/Bézier_curve - */ + /** + * @author zz85 / http://www.lab4games.net/zz85/blog + * + * Bezier Curves formulas obtained from + * http://en.wikipedia.org/wiki/Bézier_curve + */ - function CatmullRom( t, p0, p1, p2, p3 ) { + function CatmullRom( t, p0, p1, p2, p3 ) { - var v0 = ( p2 - p0 ) * 0.5; - var v1 = ( p3 - p1 ) * 0.5; - var t2 = t * t; - var t3 = t * t2; - return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1; + var v0 = ( p2 - p0 ) * 0.5; + var v1 = ( p3 - p1 ) * 0.5; + var t2 = t * t; + var t3 = t * t2; + return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1; - } + } - // + // - function QuadraticBezierP0( t, p ) { + function QuadraticBezierP0( t, p ) { - var k = 1 - t; - return k * k * p; + var k = 1 - t; + return k * k * p; - } + } - function QuadraticBezierP1( t, p ) { + function QuadraticBezierP1( t, p ) { - return 2 * ( 1 - t ) * t * p; + return 2 * ( 1 - t ) * t * p; - } + } - function QuadraticBezierP2( t, p ) { + function QuadraticBezierP2( t, p ) { - return t * t * p; + return t * t * p; - } + } - function QuadraticBezier( t, p0, p1, p2 ) { + function QuadraticBezier( t, p0, p1, p2 ) { - return QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) + - QuadraticBezierP2( t, p2 ); + return QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) + + QuadraticBezierP2( t, p2 ); - } + } - // + // - function CubicBezierP0( t, p ) { + function CubicBezierP0( t, p ) { - var k = 1 - t; - return k * k * k * p; + var k = 1 - t; + return k * k * k * p; - } + } - function CubicBezierP1( t, p ) { + function CubicBezierP1( t, p ) { - var k = 1 - t; - return 3 * k * k * t * p; + var k = 1 - t; + return 3 * k * k * t * p; - } + } - function CubicBezierP2( t, p ) { + function CubicBezierP2( t, p ) { - return 3 * ( 1 - t ) * t * t * p; + return 3 * ( 1 - t ) * t * t * p; - } + } - function CubicBezierP3( t, p ) { + function CubicBezierP3( t, p ) { - return t * t * t * p; + return t * t * t * p; - } + } - function CubicBezier( t, p0, p1, p2, p3 ) { + function CubicBezier( t, p0, p1, p2, p3 ) { - return CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) + - CubicBezierP3( t, p3 ); + return CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) + + CubicBezierP3( t, p3 ); - } + } - function CubicBezierCurve( v0, v1, v2, v3 ) { + function CubicBezierCurve( v0, v1, v2, v3 ) { - Curve.call( this ); + Curve.call( this ); - this.type = 'CubicBezierCurve'; + this.type = 'CubicBezierCurve'; - this.v0 = v0 || new Vector2(); - this.v1 = v1 || new Vector2(); - this.v2 = v2 || new Vector2(); - this.v3 = v3 || new Vector2(); + this.v0 = v0 || new Vector2(); + this.v1 = v1 || new Vector2(); + this.v2 = v2 || new Vector2(); + this.v3 = v3 || new Vector2(); - } + } - CubicBezierCurve.prototype = Object.create( Curve.prototype ); - CubicBezierCurve.prototype.constructor = CubicBezierCurve; + CubicBezierCurve.prototype = Object.create( Curve.prototype ); + CubicBezierCurve.prototype.constructor = CubicBezierCurve; - CubicBezierCurve.prototype.isCubicBezierCurve = true; + CubicBezierCurve.prototype.isCubicBezierCurve = true; - CubicBezierCurve.prototype.getPoint = function ( t, optionalTarget ) { + CubicBezierCurve.prototype.getPoint = function ( t, optionalTarget ) { - var point = optionalTarget || new Vector2(); + var point = optionalTarget || new Vector2(); - var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3; + var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3; - point.set( - CubicBezier( t, v0.x, v1.x, v2.x, v3.x ), - CubicBezier( t, v0.y, v1.y, v2.y, v3.y ) - ); + point.set( + CubicBezier( t, v0.x, v1.x, v2.x, v3.x ), + CubicBezier( t, v0.y, v1.y, v2.y, v3.y ) + ); - return point; + return point; - }; + }; - CubicBezierCurve.prototype.copy = function ( source ) { + CubicBezierCurve.prototype.copy = function ( source ) { - Curve.prototype.copy.call( this, source ); + Curve.prototype.copy.call( this, source ); - this.v0.copy( source.v0 ); - this.v1.copy( source.v1 ); - this.v2.copy( source.v2 ); - this.v3.copy( source.v3 ); + this.v0.copy( source.v0 ); + this.v1.copy( source.v1 ); + this.v2.copy( source.v2 ); + this.v3.copy( source.v3 ); - return this; + return this; - }; + }; - CubicBezierCurve.prototype.toJSON = function () { + CubicBezierCurve.prototype.toJSON = function () { - var data = Curve.prototype.toJSON.call( this ); + var data = Curve.prototype.toJSON.call( this ); - data.v0 = this.v0.toArray(); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); - data.v3 = this.v3.toArray(); + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + data.v3 = this.v3.toArray(); - return data; + return data; - }; + }; - CubicBezierCurve.prototype.fromJSON = function ( json ) { + CubicBezierCurve.prototype.fromJSON = function ( json ) { - Curve.prototype.fromJSON.call( this, json ); + Curve.prototype.fromJSON.call( this, json ); - this.v0.fromArray( json.v0 ); - this.v1.fromArray( json.v1 ); - this.v2.fromArray( json.v2 ); - this.v3.fromArray( json.v3 ); + this.v0.fromArray( json.v0 ); + this.v1.fromArray( json.v1 ); + this.v2.fromArray( json.v2 ); + this.v3.fromArray( json.v3 ); - return this; + return this; - }; + }; - function CubicBezierCurve3( v0, v1, v2, v3 ) { + function CubicBezierCurve3( v0, v1, v2, v3 ) { - Curve.call( this ); + Curve.call( this ); - this.type = 'CubicBezierCurve3'; + this.type = 'CubicBezierCurve3'; - this.v0 = v0 || new Vector3(); - this.v1 = v1 || new Vector3(); - this.v2 = v2 || new Vector3(); - this.v3 = v3 || new Vector3(); + this.v0 = v0 || new Vector3(); + this.v1 = v1 || new Vector3(); + this.v2 = v2 || new Vector3(); + this.v3 = v3 || new Vector3(); - } + } - CubicBezierCurve3.prototype = Object.create( Curve.prototype ); - CubicBezierCurve3.prototype.constructor = CubicBezierCurve3; + CubicBezierCurve3.prototype = Object.create( Curve.prototype ); + CubicBezierCurve3.prototype.constructor = CubicBezierCurve3; - CubicBezierCurve3.prototype.isCubicBezierCurve3 = true; + CubicBezierCurve3.prototype.isCubicBezierCurve3 = true; - CubicBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) { + CubicBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) { - var point = optionalTarget || new Vector3(); + var point = optionalTarget || new Vector3(); - var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3; + var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3; - point.set( - CubicBezier( t, v0.x, v1.x, v2.x, v3.x ), - CubicBezier( t, v0.y, v1.y, v2.y, v3.y ), - CubicBezier( t, v0.z, v1.z, v2.z, v3.z ) - ); + point.set( + CubicBezier( t, v0.x, v1.x, v2.x, v3.x ), + CubicBezier( t, v0.y, v1.y, v2.y, v3.y ), + CubicBezier( t, v0.z, v1.z, v2.z, v3.z ) + ); - return point; + return point; - }; + }; - CubicBezierCurve3.prototype.copy = function ( source ) { + CubicBezierCurve3.prototype.copy = function ( source ) { - Curve.prototype.copy.call( this, source ); + Curve.prototype.copy.call( this, source ); - this.v0.copy( source.v0 ); - this.v1.copy( source.v1 ); - this.v2.copy( source.v2 ); - this.v3.copy( source.v3 ); + this.v0.copy( source.v0 ); + this.v1.copy( source.v1 ); + this.v2.copy( source.v2 ); + this.v3.copy( source.v3 ); - return this; + return this; - }; + }; - CubicBezierCurve3.prototype.toJSON = function () { + CubicBezierCurve3.prototype.toJSON = function () { - var data = Curve.prototype.toJSON.call( this ); + var data = Curve.prototype.toJSON.call( this ); - data.v0 = this.v0.toArray(); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); - data.v3 = this.v3.toArray(); + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); + data.v3 = this.v3.toArray(); - return data; + return data; - }; + }; - CubicBezierCurve3.prototype.fromJSON = function ( json ) { + CubicBezierCurve3.prototype.fromJSON = function ( json ) { - Curve.prototype.fromJSON.call( this, json ); + Curve.prototype.fromJSON.call( this, json ); - this.v0.fromArray( json.v0 ); - this.v1.fromArray( json.v1 ); - this.v2.fromArray( json.v2 ); - this.v3.fromArray( json.v3 ); + this.v0.fromArray( json.v0 ); + this.v1.fromArray( json.v1 ); + this.v2.fromArray( json.v2 ); + this.v3.fromArray( json.v3 ); - return this; + return this; - }; + }; - function LineCurve( v1, v2 ) { + function LineCurve( v1, v2 ) { - Curve.call( this ); + Curve.call( this ); - this.type = 'LineCurve'; + this.type = 'LineCurve'; - this.v1 = v1 || new Vector2(); - this.v2 = v2 || new Vector2(); + this.v1 = v1 || new Vector2(); + this.v2 = v2 || new Vector2(); - } + } - LineCurve.prototype = Object.create( Curve.prototype ); - LineCurve.prototype.constructor = LineCurve; + LineCurve.prototype = Object.create( Curve.prototype ); + LineCurve.prototype.constructor = LineCurve; - LineCurve.prototype.isLineCurve = true; + LineCurve.prototype.isLineCurve = true; - LineCurve.prototype.getPoint = function ( t, optionalTarget ) { + LineCurve.prototype.getPoint = function ( t, optionalTarget ) { - var point = optionalTarget || new Vector2(); + var point = optionalTarget || new Vector2(); - if ( t === 1 ) { + if ( t === 1 ) { - point.copy( this.v2 ); + point.copy( this.v2 ); - } else { + } else { - point.copy( this.v2 ).sub( this.v1 ); - point.multiplyScalar( t ).add( this.v1 ); + point.copy( this.v2 ).sub( this.v1 ); + point.multiplyScalar( t ).add( this.v1 ); - } + } - return point; + return point; - }; + }; - // Line curve is linear, so we can overwrite default getPointAt + // Line curve is linear, so we can overwrite default getPointAt - LineCurve.prototype.getPointAt = function ( u, optionalTarget ) { + LineCurve.prototype.getPointAt = function ( u, optionalTarget ) { - return this.getPoint( u, optionalTarget ); + return this.getPoint( u, optionalTarget ); - }; + }; - LineCurve.prototype.getTangent = function ( /* t */ ) { + LineCurve.prototype.getTangent = function ( /* t */ ) { - var tangent = this.v2.clone().sub( this.v1 ); + var tangent = this.v2.clone().sub( this.v1 ); - return tangent.normalize(); + return tangent.normalize(); - }; + }; - LineCurve.prototype.copy = function ( source ) { + LineCurve.prototype.copy = function ( source ) { - Curve.prototype.copy.call( this, source ); + Curve.prototype.copy.call( this, source ); - this.v1.copy( source.v1 ); - this.v2.copy( source.v2 ); + this.v1.copy( source.v1 ); + this.v2.copy( source.v2 ); - return this; + return this; - }; + }; - LineCurve.prototype.toJSON = function () { + LineCurve.prototype.toJSON = function () { - var data = Curve.prototype.toJSON.call( this ); + var data = Curve.prototype.toJSON.call( this ); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); - return data; + return data; - }; + }; - LineCurve.prototype.fromJSON = function ( json ) { + LineCurve.prototype.fromJSON = function ( json ) { - Curve.prototype.fromJSON.call( this, json ); + Curve.prototype.fromJSON.call( this, json ); - this.v1.fromArray( json.v1 ); - this.v2.fromArray( json.v2 ); + this.v1.fromArray( json.v1 ); + this.v2.fromArray( json.v2 ); - return this; + return this; - }; + }; - function LineCurve3( v1, v2 ) { + function LineCurve3( v1, v2 ) { - Curve.call( this ); + Curve.call( this ); - this.type = 'LineCurve3'; + this.type = 'LineCurve3'; - this.v1 = v1 || new Vector3(); - this.v2 = v2 || new Vector3(); + this.v1 = v1 || new Vector3(); + this.v2 = v2 || new Vector3(); - } + } - LineCurve3.prototype = Object.create( Curve.prototype ); - LineCurve3.prototype.constructor = LineCurve3; + LineCurve3.prototype = Object.create( Curve.prototype ); + LineCurve3.prototype.constructor = LineCurve3; - LineCurve3.prototype.isLineCurve3 = true; + LineCurve3.prototype.isLineCurve3 = true; - LineCurve3.prototype.getPoint = function ( t, optionalTarget ) { + LineCurve3.prototype.getPoint = function ( t, optionalTarget ) { - var point = optionalTarget || new Vector3(); + var point = optionalTarget || new Vector3(); - if ( t === 1 ) { + if ( t === 1 ) { - point.copy( this.v2 ); + point.copy( this.v2 ); - } else { + } else { - point.copy( this.v2 ).sub( this.v1 ); - point.multiplyScalar( t ).add( this.v1 ); + point.copy( this.v2 ).sub( this.v1 ); + point.multiplyScalar( t ).add( this.v1 ); - } + } - return point; + return point; - }; + }; - // Line curve is linear, so we can overwrite default getPointAt + // Line curve is linear, so we can overwrite default getPointAt - LineCurve3.prototype.getPointAt = function ( u, optionalTarget ) { + LineCurve3.prototype.getPointAt = function ( u, optionalTarget ) { - return this.getPoint( u, optionalTarget ); + return this.getPoint( u, optionalTarget ); - }; + }; - LineCurve3.prototype.copy = function ( source ) { + LineCurve3.prototype.copy = function ( source ) { - Curve.prototype.copy.call( this, source ); + Curve.prototype.copy.call( this, source ); - this.v1.copy( source.v1 ); - this.v2.copy( source.v2 ); + this.v1.copy( source.v1 ); + this.v2.copy( source.v2 ); - return this; + return this; - }; + }; - LineCurve3.prototype.toJSON = function () { + LineCurve3.prototype.toJSON = function () { - var data = Curve.prototype.toJSON.call( this ); + var data = Curve.prototype.toJSON.call( this ); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); - return data; + return data; - }; + }; - LineCurve3.prototype.fromJSON = function ( json ) { + LineCurve3.prototype.fromJSON = function ( json ) { - Curve.prototype.fromJSON.call( this, json ); + Curve.prototype.fromJSON.call( this, json ); - this.v1.fromArray( json.v1 ); - this.v2.fromArray( json.v2 ); + this.v1.fromArray( json.v1 ); + this.v2.fromArray( json.v2 ); - return this; + return this; - }; + }; - function QuadraticBezierCurve( v0, v1, v2 ) { + function QuadraticBezierCurve( v0, v1, v2 ) { - Curve.call( this ); + Curve.call( this ); - this.type = 'QuadraticBezierCurve'; + this.type = 'QuadraticBezierCurve'; - this.v0 = v0 || new Vector2(); - this.v1 = v1 || new Vector2(); - this.v2 = v2 || new Vector2(); + this.v0 = v0 || new Vector2(); + this.v1 = v1 || new Vector2(); + this.v2 = v2 || new Vector2(); - } + } - QuadraticBezierCurve.prototype = Object.create( Curve.prototype ); - QuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve; + QuadraticBezierCurve.prototype = Object.create( Curve.prototype ); + QuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve; - QuadraticBezierCurve.prototype.isQuadraticBezierCurve = true; + QuadraticBezierCurve.prototype.isQuadraticBezierCurve = true; - QuadraticBezierCurve.prototype.getPoint = function ( t, optionalTarget ) { + QuadraticBezierCurve.prototype.getPoint = function ( t, optionalTarget ) { - var point = optionalTarget || new Vector2(); + var point = optionalTarget || new Vector2(); - var v0 = this.v0, v1 = this.v1, v2 = this.v2; + var v0 = this.v0, v1 = this.v1, v2 = this.v2; - point.set( - QuadraticBezier( t, v0.x, v1.x, v2.x ), - QuadraticBezier( t, v0.y, v1.y, v2.y ) - ); + point.set( + QuadraticBezier( t, v0.x, v1.x, v2.x ), + QuadraticBezier( t, v0.y, v1.y, v2.y ) + ); - return point; + return point; - }; + }; - QuadraticBezierCurve.prototype.copy = function ( source ) { + QuadraticBezierCurve.prototype.copy = function ( source ) { - Curve.prototype.copy.call( this, source ); + Curve.prototype.copy.call( this, source ); - this.v0.copy( source.v0 ); - this.v1.copy( source.v1 ); - this.v2.copy( source.v2 ); + this.v0.copy( source.v0 ); + this.v1.copy( source.v1 ); + this.v2.copy( source.v2 ); - return this; + return this; - }; + }; - QuadraticBezierCurve.prototype.toJSON = function () { + QuadraticBezierCurve.prototype.toJSON = function () { - var data = Curve.prototype.toJSON.call( this ); + var data = Curve.prototype.toJSON.call( this ); - data.v0 = this.v0.toArray(); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); - return data; + return data; - }; + }; - QuadraticBezierCurve.prototype.fromJSON = function ( json ) { + QuadraticBezierCurve.prototype.fromJSON = function ( json ) { - Curve.prototype.fromJSON.call( this, json ); + Curve.prototype.fromJSON.call( this, json ); - this.v0.fromArray( json.v0 ); - this.v1.fromArray( json.v1 ); - this.v2.fromArray( json.v2 ); + this.v0.fromArray( json.v0 ); + this.v1.fromArray( json.v1 ); + this.v2.fromArray( json.v2 ); - return this; + return this; - }; + }; - function QuadraticBezierCurve3( v0, v1, v2 ) { + function QuadraticBezierCurve3( v0, v1, v2 ) { - Curve.call( this ); + Curve.call( this ); - this.type = 'QuadraticBezierCurve3'; + this.type = 'QuadraticBezierCurve3'; - this.v0 = v0 || new Vector3(); - this.v1 = v1 || new Vector3(); - this.v2 = v2 || new Vector3(); + this.v0 = v0 || new Vector3(); + this.v1 = v1 || new Vector3(); + this.v2 = v2 || new Vector3(); - } + } - QuadraticBezierCurve3.prototype = Object.create( Curve.prototype ); - QuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3; + QuadraticBezierCurve3.prototype = Object.create( Curve.prototype ); + QuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3; - QuadraticBezierCurve3.prototype.isQuadraticBezierCurve3 = true; + QuadraticBezierCurve3.prototype.isQuadraticBezierCurve3 = true; - QuadraticBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) { + QuadraticBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) { - var point = optionalTarget || new Vector3(); + var point = optionalTarget || new Vector3(); - var v0 = this.v0, v1 = this.v1, v2 = this.v2; + var v0 = this.v0, v1 = this.v1, v2 = this.v2; - point.set( - QuadraticBezier( t, v0.x, v1.x, v2.x ), - QuadraticBezier( t, v0.y, v1.y, v2.y ), - QuadraticBezier( t, v0.z, v1.z, v2.z ) - ); + point.set( + QuadraticBezier( t, v0.x, v1.x, v2.x ), + QuadraticBezier( t, v0.y, v1.y, v2.y ), + QuadraticBezier( t, v0.z, v1.z, v2.z ) + ); - return point; + return point; - }; + }; - QuadraticBezierCurve3.prototype.copy = function ( source ) { + QuadraticBezierCurve3.prototype.copy = function ( source ) { - Curve.prototype.copy.call( this, source ); + Curve.prototype.copy.call( this, source ); - this.v0.copy( source.v0 ); - this.v1.copy( source.v1 ); - this.v2.copy( source.v2 ); + this.v0.copy( source.v0 ); + this.v1.copy( source.v1 ); + this.v2.copy( source.v2 ); - return this; + return this; - }; + }; - QuadraticBezierCurve3.prototype.toJSON = function () { + QuadraticBezierCurve3.prototype.toJSON = function () { - var data = Curve.prototype.toJSON.call( this ); + var data = Curve.prototype.toJSON.call( this ); - data.v0 = this.v0.toArray(); - data.v1 = this.v1.toArray(); - data.v2 = this.v2.toArray(); + data.v0 = this.v0.toArray(); + data.v1 = this.v1.toArray(); + data.v2 = this.v2.toArray(); - return data; + return data; - }; + }; - QuadraticBezierCurve3.prototype.fromJSON = function ( json ) { + QuadraticBezierCurve3.prototype.fromJSON = function ( json ) { - Curve.prototype.fromJSON.call( this, json ); + Curve.prototype.fromJSON.call( this, json ); - this.v0.fromArray( json.v0 ); - this.v1.fromArray( json.v1 ); - this.v2.fromArray( json.v2 ); + this.v0.fromArray( json.v0 ); + this.v1.fromArray( json.v1 ); + this.v2.fromArray( json.v2 ); - return this; + return this; - }; + }; - function SplineCurve( points /* array of Vector2 */ ) { + function SplineCurve( points /* array of Vector2 */ ) { - Curve.call( this ); + Curve.call( this ); - this.type = 'SplineCurve'; + this.type = 'SplineCurve'; - this.points = points || []; + this.points = points || []; - } + } - SplineCurve.prototype = Object.create( Curve.prototype ); - SplineCurve.prototype.constructor = SplineCurve; + SplineCurve.prototype = Object.create( Curve.prototype ); + SplineCurve.prototype.constructor = SplineCurve; - SplineCurve.prototype.isSplineCurve = true; + SplineCurve.prototype.isSplineCurve = true; - SplineCurve.prototype.getPoint = function ( t, optionalTarget ) { + SplineCurve.prototype.getPoint = function ( t, optionalTarget ) { - var point = optionalTarget || new Vector2(); + var point = optionalTarget || new Vector2(); - var points = this.points; - var p = ( points.length - 1 ) * t; + var points = this.points; + var p = ( points.length - 1 ) * t; - var intPoint = Math.floor( p ); - var weight = p - intPoint; + var intPoint = Math.floor( p ); + var weight = p - intPoint; - var p0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ]; - var p1 = points[ intPoint ]; - var p2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ]; - var p3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ]; + var p0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ]; + var p1 = points[ intPoint ]; + var p2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ]; + var p3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ]; - point.set( - CatmullRom( weight, p0.x, p1.x, p2.x, p3.x ), - CatmullRom( weight, p0.y, p1.y, p2.y, p3.y ) - ); + point.set( + CatmullRom( weight, p0.x, p1.x, p2.x, p3.x ), + CatmullRom( weight, p0.y, p1.y, p2.y, p3.y ) + ); - return point; + return point; - }; + }; - SplineCurve.prototype.copy = function ( source ) { + SplineCurve.prototype.copy = function ( source ) { - Curve.prototype.copy.call( this, source ); + Curve.prototype.copy.call( this, source ); - this.points = []; + this.points = []; - for ( var i = 0, l = source.points.length; i < l; i ++ ) { + for ( var i = 0, l = source.points.length; i < l; i ++ ) { - var point = source.points[ i ]; + var point = source.points[ i ]; - this.points.push( point.clone() ); + this.points.push( point.clone() ); - } + } - return this; + return this; - }; + }; - SplineCurve.prototype.toJSON = function () { + SplineCurve.prototype.toJSON = function () { - var data = Curve.prototype.toJSON.call( this ); + var data = Curve.prototype.toJSON.call( this ); - data.points = []; + data.points = []; - for ( var i = 0, l = this.points.length; i < l; i ++ ) { + for ( var i = 0, l = this.points.length; i < l; i ++ ) { - var point = this.points[ i ]; - data.points.push( point.toArray() ); + var point = this.points[ i ]; + data.points.push( point.toArray() ); - } + } - return data; + return data; - }; + }; - SplineCurve.prototype.fromJSON = function ( json ) { + SplineCurve.prototype.fromJSON = function ( json ) { - Curve.prototype.fromJSON.call( this, json ); + Curve.prototype.fromJSON.call( this, json ); - this.points = []; + this.points = []; - for ( var i = 0, l = json.points.length; i < l; i ++ ) { + for ( var i = 0, l = json.points.length; i < l; i ++ ) { - var point = json.points[ i ]; - this.points.push( new Vector2().fromArray( point ) ); + var point = json.points[ i ]; + this.points.push( new Vector2().fromArray( point ) ); - } + } - return this; + return this; - }; + }; - var Curves = /*#__PURE__*/Object.freeze({ - ArcCurve: ArcCurve, - CatmullRomCurve3: CatmullRomCurve3, - CubicBezierCurve: CubicBezierCurve, - CubicBezierCurve3: CubicBezierCurve3, - EllipseCurve: EllipseCurve, - LineCurve: LineCurve, - LineCurve3: LineCurve3, - QuadraticBezierCurve: QuadraticBezierCurve, - QuadraticBezierCurve3: QuadraticBezierCurve3, - SplineCurve: SplineCurve - }); + var Curves = /*#__PURE__*/Object.freeze({ + ArcCurve: ArcCurve, + CatmullRomCurve3: CatmullRomCurve3, + CubicBezierCurve: CubicBezierCurve, + CubicBezierCurve3: CubicBezierCurve3, + EllipseCurve: EllipseCurve, + LineCurve: LineCurve, + LineCurve3: LineCurve3, + QuadraticBezierCurve: QuadraticBezierCurve, + QuadraticBezierCurve3: QuadraticBezierCurve3, + SplineCurve: SplineCurve + }); - /** - * @author zz85 / http://www.lab4games.net/zz85/blog - * - **/ + /** + * @author zz85 / http://www.lab4games.net/zz85/blog + * + **/ - /************************************************************** - * Curved Path - a curve path is simply a array of connected - * curves, but retains the api of a curve - **************************************************************/ + /************************************************************** + * Curved Path - a curve path is simply a array of connected + * curves, but retains the api of a curve + **************************************************************/ - function CurvePath() { + function CurvePath() { - Curve.call( this ); + Curve.call( this ); - this.type = 'CurvePath'; + this.type = 'CurvePath'; - this.curves = []; - this.autoClose = false; // Automatically closes the path + this.curves = []; + this.autoClose = false; // Automatically closes the path - } + } - CurvePath.prototype = Object.assign( Object.create( Curve.prototype ), { + CurvePath.prototype = Object.assign( Object.create( Curve.prototype ), { - constructor: CurvePath, + constructor: CurvePath, - add: function ( curve ) { + add: function ( curve ) { - this.curves.push( curve ); + this.curves.push( curve ); - }, + }, - closePath: function () { + closePath: function () { - // Add a line curve if start and end of lines are not connected - var startPoint = this.curves[ 0 ].getPoint( 0 ); - var endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 ); + // Add a line curve if start and end of lines are not connected + var startPoint = this.curves[ 0 ].getPoint( 0 ); + var endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 ); - if ( ! startPoint.equals( endPoint ) ) { + if ( ! startPoint.equals( endPoint ) ) { - this.curves.push( new LineCurve( endPoint, startPoint ) ); + this.curves.push( new LineCurve( endPoint, startPoint ) ); - } + } - }, + }, - // To get accurate point with reference to - // entire path distance at time t, - // following has to be done: + // To get accurate point with reference to + // entire path distance at time t, + // following has to be done: - // 1. Length of each sub path have to be known - // 2. Locate and identify type of curve - // 3. Get t for the curve - // 4. Return curve.getPointAt(t') + // 1. Length of each sub path have to be known + // 2. Locate and identify type of curve + // 3. Get t for the curve + // 4. Return curve.getPointAt(t') - getPoint: function ( t ) { + getPoint: function ( t ) { - var d = t * this.getLength(); - var curveLengths = this.getCurveLengths(); - var i = 0; + var d = t * this.getLength(); + var curveLengths = this.getCurveLengths(); + var i = 0; - // To think about boundaries points. + // To think about boundaries points. - while ( i < curveLengths.length ) { + while ( i < curveLengths.length ) { - if ( curveLengths[ i ] >= d ) { + if ( curveLengths[ i ] >= d ) { - var diff = curveLengths[ i ] - d; - var curve = this.curves[ i ]; + var diff = curveLengths[ i ] - d; + var curve = this.curves[ i ]; - var segmentLength = curve.getLength(); - var u = segmentLength === 0 ? 0 : 1 - diff / segmentLength; + var segmentLength = curve.getLength(); + var u = segmentLength === 0 ? 0 : 1 - diff / segmentLength; - return curve.getPointAt( u ); + return curve.getPointAt( u ); - } + } - i ++; + i ++; - } + } - return null; + return null; - // loop where sum != 0, sum > d , sum+1 d , sum+1 1 && ! points[ points.length - 1 ].equals( points[ 0 ] ) ) { + if ( this.autoClose && points.length > 1 && ! points[ points.length - 1 ].equals( points[ 0 ] ) ) { - points.push( points[ 0 ] ); + points.push( points[ 0 ] ); - } + } - return points; + return points; - }, + }, - copy: function ( source ) { + copy: function ( source ) { - Curve.prototype.copy.call( this, source ); + Curve.prototype.copy.call( this, source ); - this.curves = []; + this.curves = []; - for ( var i = 0, l = source.curves.length; i < l; i ++ ) { + for ( var i = 0, l = source.curves.length; i < l; i ++ ) { - var curve = source.curves[ i ]; + var curve = source.curves[ i ]; - this.curves.push( curve.clone() ); + this.curves.push( curve.clone() ); - } + } - this.autoClose = source.autoClose; + this.autoClose = source.autoClose; - return this; + return this; - }, + }, - toJSON: function () { + toJSON: function () { - var data = Curve.prototype.toJSON.call( this ); + var data = Curve.prototype.toJSON.call( this ); - data.autoClose = this.autoClose; - data.curves = []; + data.autoClose = this.autoClose; + data.curves = []; - for ( var i = 0, l = this.curves.length; i < l; i ++ ) { + for ( var i = 0, l = this.curves.length; i < l; i ++ ) { - var curve = this.curves[ i ]; - data.curves.push( curve.toJSON() ); + var curve = this.curves[ i ]; + data.curves.push( curve.toJSON() ); - } + } - return data; + return data; - }, + }, - fromJSON: function ( json ) { + fromJSON: function ( json ) { - Curve.prototype.fromJSON.call( this, json ); + Curve.prototype.fromJSON.call( this, json ); - this.autoClose = json.autoClose; - this.curves = []; + this.autoClose = json.autoClose; + this.curves = []; - for ( var i = 0, l = json.curves.length; i < l; i ++ ) { + for ( var i = 0, l = json.curves.length; i < l; i ++ ) { - var curve = json.curves[ i ]; - this.curves.push( new Curves[ curve.type ]().fromJSON( curve ) ); + var curve = json.curves[ i ]; + this.curves.push( new Curves[ curve.type ]().fromJSON( curve ) ); - } + } - return this; + return this; - } + } - } ); + } ); - /** - * @author zz85 / http://www.lab4games.net/zz85/blog - * Creates free form 2d path using series of points, lines or curves. - **/ + /** + * @author zz85 / http://www.lab4games.net/zz85/blog + * Creates free form 2d path using series of points, lines or curves. + **/ - function Path( points ) { + function Path( points ) { - CurvePath.call( this ); + CurvePath.call( this ); - this.type = 'Path'; + this.type = 'Path'; - this.currentPoint = new Vector2(); + this.currentPoint = new Vector2(); - if ( points ) { + if ( points ) { - this.setFromPoints( points ); + this.setFromPoints( points ); - } + } - } + } - Path.prototype = Object.assign( Object.create( CurvePath.prototype ), { + Path.prototype = Object.assign( Object.create( CurvePath.prototype ), { - constructor: Path, + constructor: Path, - setFromPoints: function ( points ) { + setFromPoints: function ( points ) { - this.moveTo( points[ 0 ].x, points[ 0 ].y ); + this.moveTo( points[ 0 ].x, points[ 0 ].y ); - for ( var i = 1, l = points.length; i < l; i ++ ) { + for ( var i = 1, l = points.length; i < l; i ++ ) { - this.lineTo( points[ i ].x, points[ i ].y ); + this.lineTo( points[ i ].x, points[ i ].y ); - } + } - }, + }, - moveTo: function ( x, y ) { + moveTo: function ( x, y ) { - this.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying? + this.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying? - }, + }, - lineTo: function ( x, y ) { + lineTo: function ( x, y ) { - var curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) ); - this.curves.push( curve ); + var curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) ); + this.curves.push( curve ); - this.currentPoint.set( x, y ); + this.currentPoint.set( x, y ); - }, + }, - quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) { + quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) { - var curve = new QuadraticBezierCurve( - this.currentPoint.clone(), - new Vector2( aCPx, aCPy ), - new Vector2( aX, aY ) - ); + var curve = new QuadraticBezierCurve( + this.currentPoint.clone(), + new Vector2( aCPx, aCPy ), + new Vector2( aX, aY ) + ); - this.curves.push( curve ); + this.curves.push( curve ); - this.currentPoint.set( aX, aY ); + this.currentPoint.set( aX, aY ); - }, + }, - bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) { + bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) { - var curve = new CubicBezierCurve( - this.currentPoint.clone(), - new Vector2( aCP1x, aCP1y ), - new Vector2( aCP2x, aCP2y ), - new Vector2( aX, aY ) - ); + var curve = new CubicBezierCurve( + this.currentPoint.clone(), + new Vector2( aCP1x, aCP1y ), + new Vector2( aCP2x, aCP2y ), + new Vector2( aX, aY ) + ); - this.curves.push( curve ); + this.curves.push( curve ); - this.currentPoint.set( aX, aY ); + this.currentPoint.set( aX, aY ); - }, + }, - splineThru: function ( pts /*Array of Vector*/ ) { + splineThru: function ( pts /*Array of Vector*/ ) { - var npts = [ this.currentPoint.clone() ].concat( pts ); + var npts = [ this.currentPoint.clone() ].concat( pts ); - var curve = new SplineCurve( npts ); - this.curves.push( curve ); + var curve = new SplineCurve( npts ); + this.curves.push( curve ); - this.currentPoint.copy( pts[ pts.length - 1 ] ); + this.currentPoint.copy( pts[ pts.length - 1 ] ); - }, + }, - arc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { + arc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { - var x0 = this.currentPoint.x; - var y0 = this.currentPoint.y; + var x0 = this.currentPoint.x; + var y0 = this.currentPoint.y; - this.absarc( aX + x0, aY + y0, aRadius, - aStartAngle, aEndAngle, aClockwise ); + this.absarc( aX + x0, aY + y0, aRadius, + aStartAngle, aEndAngle, aClockwise ); - }, + }, - absarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { + absarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { - this.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise ); + this.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise ); - }, + }, - ellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { + ellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { - var x0 = this.currentPoint.x; - var y0 = this.currentPoint.y; + var x0 = this.currentPoint.x; + var y0 = this.currentPoint.y; - this.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ); + this.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ); - }, + }, - absellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { + absellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { - var curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ); + var curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ); - if ( this.curves.length > 0 ) { + if ( this.curves.length > 0 ) { - // if a previous curve is present, attempt to join - var firstPoint = curve.getPoint( 0 ); + // if a previous curve is present, attempt to join + var firstPoint = curve.getPoint( 0 ); - if ( ! firstPoint.equals( this.currentPoint ) ) { + if ( ! firstPoint.equals( this.currentPoint ) ) { - this.lineTo( firstPoint.x, firstPoint.y ); + this.lineTo( firstPoint.x, firstPoint.y ); - } + } - } + } - this.curves.push( curve ); + this.curves.push( curve ); - var lastPoint = curve.getPoint( 1 ); - this.currentPoint.copy( lastPoint ); + var lastPoint = curve.getPoint( 1 ); + this.currentPoint.copy( lastPoint ); - }, + }, - copy: function ( source ) { + copy: function ( source ) { - CurvePath.prototype.copy.call( this, source ); + CurvePath.prototype.copy.call( this, source ); - this.currentPoint.copy( source.currentPoint ); + this.currentPoint.copy( source.currentPoint ); - return this; + return this; - }, + }, - toJSON: function () { + toJSON: function () { - var data = CurvePath.prototype.toJSON.call( this ); + var data = CurvePath.prototype.toJSON.call( this ); - data.currentPoint = this.currentPoint.toArray(); + data.currentPoint = this.currentPoint.toArray(); - return data; + return data; - }, + }, - fromJSON: function ( json ) { + fromJSON: function ( json ) { - CurvePath.prototype.fromJSON.call( this, json ); + CurvePath.prototype.fromJSON.call( this, json ); - this.currentPoint.fromArray( json.currentPoint ); + this.currentPoint.fromArray( json.currentPoint ); - return this; + return this; - } + } - } ); + } ); - /** - * @author zz85 / http://www.lab4games.net/zz85/blog - * Defines a 2d shape plane using paths. - **/ + /** + * @author zz85 / http://www.lab4games.net/zz85/blog + * Defines a 2d shape plane using paths. + **/ - // STEP 1 Create a path. - // STEP 2 Turn path into shape. - // STEP 3 ExtrudeGeometry takes in Shape/Shapes - // STEP 3a - Extract points from each shape, turn to vertices - // STEP 3b - Triangulate each shape, add faces. + // STEP 1 Create a path. + // STEP 2 Turn path into shape. + // STEP 3 ExtrudeGeometry takes in Shape/Shapes + // STEP 3a - Extract points from each shape, turn to vertices + // STEP 3b - Triangulate each shape, add faces. - function Shape( points ) { + function Shape( points ) { - Path.call( this, points ); + Path.call( this, points ); - this.uuid = _Math.generateUUID(); + this.uuid = _Math.generateUUID(); - this.type = 'Shape'; + this.type = 'Shape'; - this.holes = []; + this.holes = []; - } + } - Shape.prototype = Object.assign( Object.create( Path.prototype ), { + Shape.prototype = Object.assign( Object.create( Path.prototype ), { - constructor: Shape, + constructor: Shape, - getPointsHoles: function ( divisions ) { + getPointsHoles: function ( divisions ) { - var holesPts = []; + var holesPts = []; - for ( var i = 0, l = this.holes.length; i < l; i ++ ) { + for ( var i = 0, l = this.holes.length; i < l; i ++ ) { - holesPts[ i ] = this.holes[ i ].getPoints( divisions ); + holesPts[ i ] = this.holes[ i ].getPoints( divisions ); - } + } - return holesPts; + return holesPts; - }, + }, - // get points of shape and holes (keypoints based on segments parameter) + // get points of shape and holes (keypoints based on segments parameter) - extractPoints: function ( divisions ) { + extractPoints: function ( divisions ) { - return { + return { - shape: this.getPoints( divisions ), - holes: this.getPointsHoles( divisions ) + shape: this.getPoints( divisions ), + holes: this.getPointsHoles( divisions ) - }; + }; - }, + }, - copy: function ( source ) { + copy: function ( source ) { - Path.prototype.copy.call( this, source ); + Path.prototype.copy.call( this, source ); - this.holes = []; + this.holes = []; - for ( var i = 0, l = source.holes.length; i < l; i ++ ) { + for ( var i = 0, l = source.holes.length; i < l; i ++ ) { - var hole = source.holes[ i ]; + var hole = source.holes[ i ]; - this.holes.push( hole.clone() ); + this.holes.push( hole.clone() ); - } + } - return this; + return this; - }, + }, - toJSON: function () { + toJSON: function () { - var data = Path.prototype.toJSON.call( this ); + var data = Path.prototype.toJSON.call( this ); - data.uuid = this.uuid; - data.holes = []; + data.uuid = this.uuid; + data.holes = []; - for ( var i = 0, l = this.holes.length; i < l; i ++ ) { + for ( var i = 0, l = this.holes.length; i < l; i ++ ) { - var hole = this.holes[ i ]; - data.holes.push( hole.toJSON() ); + var hole = this.holes[ i ]; + data.holes.push( hole.toJSON() ); - } + } - return data; + return data; - }, + }, - fromJSON: function ( json ) { + fromJSON: function ( json ) { - Path.prototype.fromJSON.call( this, json ); + Path.prototype.fromJSON.call( this, json ); - this.uuid = json.uuid; - this.holes = []; + this.uuid = json.uuid; + this.holes = []; - for ( var i = 0, l = json.holes.length; i < l; i ++ ) { + for ( var i = 0, l = json.holes.length; i < l; i ++ ) { - var hole = json.holes[ i ]; - this.holes.push( new Path().fromJSON( hole ) ); + var hole = json.holes[ i ]; + this.holes.push( new Path().fromJSON( hole ) ); - } + } - return this; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + */ - function Light( color, intensity ) { + function Light( color, intensity ) { - Object3D.call( this ); + Object3D.call( this ); - this.type = 'Light'; + this.type = 'Light'; - this.color = new Color( color ); - this.intensity = intensity !== undefined ? intensity : 1; + this.color = new Color( color ); + this.intensity = intensity !== undefined ? intensity : 1; - this.receiveShadow = undefined; + this.receiveShadow = undefined; - } + } - Light.prototype = Object.assign( Object.create( Object3D.prototype ), { + Light.prototype = Object.assign( Object.create( Object3D.prototype ), { - constructor: Light, + constructor: Light, - isLight: true, + isLight: true, - copy: function ( source ) { + copy: function ( source ) { - Object3D.prototype.copy.call( this, source ); + Object3D.prototype.copy.call( this, source ); - this.color.copy( source.color ); - this.intensity = source.intensity; + this.color.copy( source.color ); + this.intensity = source.intensity; - return this; + return this; - }, + }, - toJSON: function ( meta ) { + toJSON: function ( meta ) { - var data = Object3D.prototype.toJSON.call( this, meta ); + var data = Object3D.prototype.toJSON.call( this, meta ); - data.object.color = this.color.getHex(); - data.object.intensity = this.intensity; + data.object.color = this.color.getHex(); + data.object.intensity = this.intensity; - if ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex(); + if ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex(); - if ( this.distance !== undefined ) data.object.distance = this.distance; - if ( this.angle !== undefined ) data.object.angle = this.angle; - if ( this.decay !== undefined ) data.object.decay = this.decay; - if ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra; + if ( this.distance !== undefined ) data.object.distance = this.distance; + if ( this.angle !== undefined ) data.object.angle = this.angle; + if ( this.decay !== undefined ) data.object.decay = this.decay; + if ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra; - if ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON(); + if ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON(); - return data; + return data; - } + } - } ); + } ); - /** - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author alteredq / http://alteredqualia.com/ + */ - function HemisphereLight( skyColor, groundColor, intensity ) { + function HemisphereLight( skyColor, groundColor, intensity ) { - Light.call( this, skyColor, intensity ); + Light.call( this, skyColor, intensity ); - this.type = 'HemisphereLight'; + this.type = 'HemisphereLight'; - this.castShadow = undefined; + this.castShadow = undefined; - this.position.copy( Object3D.DefaultUp ); - this.updateMatrix(); + this.position.copy( Object3D.DefaultUp ); + this.updateMatrix(); - this.groundColor = new Color( groundColor ); + this.groundColor = new Color( groundColor ); - } + } - HemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), { + HemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), { - constructor: HemisphereLight, + constructor: HemisphereLight, - isHemisphereLight: true, + isHemisphereLight: true, - copy: function ( source ) { + copy: function ( source ) { - Light.prototype.copy.call( this, source ); + Light.prototype.copy.call( this, source ); - this.groundColor.copy( source.groundColor ); + this.groundColor.copy( source.groundColor ); - return this; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function LightShadow( camera ) { + function LightShadow( camera ) { - this.camera = camera; + this.camera = camera; - this.bias = 0; - this.radius = 1; + this.bias = 0; + this.radius = 1; - this.mapSize = new Vector2( 512, 512 ); + this.mapSize = new Vector2( 512, 512 ); - this.map = null; - this.matrix = new Matrix4(); + this.map = null; + this.matrix = new Matrix4(); - } + } - Object.assign( LightShadow.prototype, { + Object.assign( LightShadow.prototype, { - copy: function ( source ) { + copy: function ( source ) { - this.camera = source.camera.clone(); + this.camera = source.camera.clone(); - this.bias = source.bias; - this.radius = source.radius; + this.bias = source.bias; + this.radius = source.radius; - this.mapSize.copy( source.mapSize ); + this.mapSize.copy( source.mapSize ); - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - toJSON: function () { + toJSON: function () { - var object = {}; + var object = {}; - if ( this.bias !== 0 ) object.bias = this.bias; - if ( this.radius !== 1 ) object.radius = this.radius; - if ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray(); + if ( this.bias !== 0 ) object.bias = this.bias; + if ( this.radius !== 1 ) object.radius = this.radius; + if ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray(); - object.camera = this.camera.toJSON( false ).object; - delete object.camera.matrix; + object.camera = this.camera.toJSON( false ).object; + delete object.camera.matrix; - return object; + return object; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function SpotLightShadow() { + function SpotLightShadow() { - LightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) ); + LightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) ); - } + } - SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { + SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { - constructor: SpotLightShadow, + constructor: SpotLightShadow, - isSpotLightShadow: true, + isSpotLightShadow: true, - update: function ( light ) { + update: function ( light ) { - var camera = this.camera; + var camera = this.camera; - var fov = _Math.RAD2DEG * 2 * light.angle; - var aspect = this.mapSize.width / this.mapSize.height; - var far = light.distance || camera.far; + var fov = _Math.RAD2DEG * 2 * light.angle; + var aspect = this.mapSize.width / this.mapSize.height; + var far = light.distance || camera.far; - if ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) { + if ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) { - camera.fov = fov; - camera.aspect = aspect; - camera.far = far; - camera.updateProjectionMatrix(); + camera.fov = fov; + camera.aspect = aspect; + camera.far = far; + camera.updateProjectionMatrix(); - } + } - } + } - } ); + } ); - /** - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author alteredq / http://alteredqualia.com/ + */ - function SpotLight( color, intensity, distance, angle, penumbra, decay ) { + function SpotLight( color, intensity, distance, angle, penumbra, decay ) { - Light.call( this, color, intensity ); + Light.call( this, color, intensity ); - this.type = 'SpotLight'; + this.type = 'SpotLight'; - this.position.copy( Object3D.DefaultUp ); - this.updateMatrix(); + this.position.copy( Object3D.DefaultUp ); + this.updateMatrix(); - this.target = new Object3D(); + this.target = new Object3D(); - Object.defineProperty( this, 'power', { - get: function () { + Object.defineProperty( this, 'power', { + get: function () { - // intensity = power per solid angle. - // ref: equation (17) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf - return this.intensity * Math.PI; + // intensity = power per solid angle. + // ref: equation (17) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf + return this.intensity * Math.PI; - }, - set: function ( power ) { + }, + set: function ( power ) { - // intensity = power per solid angle. - // ref: equation (17) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf - this.intensity = power / Math.PI; + // intensity = power per solid angle. + // ref: equation (17) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf + this.intensity = power / Math.PI; - } - } ); + } + } ); - this.distance = ( distance !== undefined ) ? distance : 0; - this.angle = ( angle !== undefined ) ? angle : Math.PI / 3; - this.penumbra = ( penumbra !== undefined ) ? penumbra : 0; - this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. + this.distance = ( distance !== undefined ) ? distance : 0; + this.angle = ( angle !== undefined ) ? angle : Math.PI / 3; + this.penumbra = ( penumbra !== undefined ) ? penumbra : 0; + this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. - this.shadow = new SpotLightShadow(); + this.shadow = new SpotLightShadow(); - } + } - SpotLight.prototype = Object.assign( Object.create( Light.prototype ), { + SpotLight.prototype = Object.assign( Object.create( Light.prototype ), { - constructor: SpotLight, + constructor: SpotLight, - isSpotLight: true, + isSpotLight: true, - copy: function ( source ) { + copy: function ( source ) { - Light.prototype.copy.call( this, source ); + Light.prototype.copy.call( this, source ); - this.distance = source.distance; - this.angle = source.angle; - this.penumbra = source.penumbra; - this.decay = source.decay; + this.distance = source.distance; + this.angle = source.angle; + this.penumbra = source.penumbra; + this.decay = source.decay; - this.target = source.target.clone(); + this.target = source.target.clone(); - this.shadow = source.shadow.clone(); + this.shadow = source.shadow.clone(); - return this; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function PointLight( color, intensity, distance, decay ) { + function PointLight( color, intensity, distance, decay ) { - Light.call( this, color, intensity ); + Light.call( this, color, intensity ); - this.type = 'PointLight'; + this.type = 'PointLight'; - Object.defineProperty( this, 'power', { - get: function () { + Object.defineProperty( this, 'power', { + get: function () { - // intensity = power per solid angle. - // ref: equation (15) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf - return this.intensity * 4 * Math.PI; + // intensity = power per solid angle. + // ref: equation (15) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf + return this.intensity * 4 * Math.PI; - }, - set: function ( power ) { + }, + set: function ( power ) { - // intensity = power per solid angle. - // ref: equation (15) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf - this.intensity = power / ( 4 * Math.PI ); + // intensity = power per solid angle. + // ref: equation (15) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf + this.intensity = power / ( 4 * Math.PI ); - } - } ); + } + } ); - this.distance = ( distance !== undefined ) ? distance : 0; - this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. + this.distance = ( distance !== undefined ) ? distance : 0; + this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. - this.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) ); + this.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) ); - } + } - PointLight.prototype = Object.assign( Object.create( Light.prototype ), { + PointLight.prototype = Object.assign( Object.create( Light.prototype ), { - constructor: PointLight, + constructor: PointLight, - isPointLight: true, + isPointLight: true, - copy: function ( source ) { + copy: function ( source ) { - Light.prototype.copy.call( this, source ); + Light.prototype.copy.call( this, source ); - this.distance = source.distance; - this.decay = source.decay; + this.distance = source.distance; + this.decay = source.decay; - this.shadow = source.shadow.clone(); + this.shadow = source.shadow.clone(); - return this; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function DirectionalLightShadow( ) { + function DirectionalLightShadow( ) { - LightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) ); + LightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) ); - } + } - DirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { + DirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { - constructor: DirectionalLightShadow + constructor: DirectionalLightShadow - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + */ - function DirectionalLight( color, intensity ) { + function DirectionalLight( color, intensity ) { - Light.call( this, color, intensity ); + Light.call( this, color, intensity ); - this.type = 'DirectionalLight'; + this.type = 'DirectionalLight'; - this.position.copy( Object3D.DefaultUp ); - this.updateMatrix(); + this.position.copy( Object3D.DefaultUp ); + this.updateMatrix(); - this.target = new Object3D(); + this.target = new Object3D(); - this.shadow = new DirectionalLightShadow(); + this.shadow = new DirectionalLightShadow(); - } + } - DirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), { + DirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), { - constructor: DirectionalLight, + constructor: DirectionalLight, - isDirectionalLight: true, + isDirectionalLight: true, - copy: function ( source ) { + copy: function ( source ) { - Light.prototype.copy.call( this, source ); + Light.prototype.copy.call( this, source ); - this.target = source.target.clone(); + this.target = source.target.clone(); - this.shadow = source.shadow.clone(); + this.shadow = source.shadow.clone(); - return this; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function AmbientLight( color, intensity ) { + function AmbientLight( color, intensity ) { - Light.call( this, color, intensity ); + Light.call( this, color, intensity ); - this.type = 'AmbientLight'; + this.type = 'AmbientLight'; - this.castShadow = undefined; + this.castShadow = undefined; - } + } - AmbientLight.prototype = Object.assign( Object.create( Light.prototype ), { + AmbientLight.prototype = Object.assign( Object.create( Light.prototype ), { - constructor: AmbientLight, + constructor: AmbientLight, - isAmbientLight: true + isAmbientLight: true - } ); + } ); - /** - * @author abelnation / http://github.com/abelnation - */ + /** + * @author abelnation / http://github.com/abelnation + */ - function RectAreaLight( color, intensity, width, height ) { + function RectAreaLight( color, intensity, width, height ) { - Light.call( this, color, intensity ); + Light.call( this, color, intensity ); - this.type = 'RectAreaLight'; + this.type = 'RectAreaLight'; - this.width = ( width !== undefined ) ? width : 10; - this.height = ( height !== undefined ) ? height : 10; + this.width = ( width !== undefined ) ? width : 10; + this.height = ( height !== undefined ) ? height : 10; - } + } - RectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), { + RectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), { - constructor: RectAreaLight, + constructor: RectAreaLight, - isRectAreaLight: true, + isRectAreaLight: true, - copy: function ( source ) { + copy: function ( source ) { - Light.prototype.copy.call( this, source ); + Light.prototype.copy.call( this, source ); - this.width = source.width; - this.height = source.height; + this.width = source.width; + this.height = source.height; - return this; + return this; - }, + }, - toJSON: function ( meta ) { + toJSON: function ( meta ) { - var data = Light.prototype.toJSON.call( this, meta ); + var data = Light.prototype.toJSON.call( this, meta ); - data.object.width = this.width; - data.object.height = this.height; + data.object.width = this.width; + data.object.height = this.height; - return data; + return data; - } + } - } ); + } ); - /** - * @author tschw - * @author Ben Houston / http://clara.io/ - * @author David Sarno / http://lighthaus.us/ - */ + /** + * @author tschw + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + */ - var AnimationUtils = { + var AnimationUtils = { - // same as Array.prototype.slice, but also works on typed arrays - arraySlice: function ( array, from, to ) { + // same as Array.prototype.slice, but also works on typed arrays + arraySlice: function ( array, from, to ) { - if ( AnimationUtils.isTypedArray( array ) ) { + if ( AnimationUtils.isTypedArray( array ) ) { - // in ios9 array.subarray(from, undefined) will return empty array - // but array.subarray(from) or array.subarray(from, len) is correct - return new array.constructor( array.subarray( from, to !== undefined ? to : array.length ) ); + // in ios9 array.subarray(from, undefined) will return empty array + // but array.subarray(from) or array.subarray(from, len) is correct + return new array.constructor( array.subarray( from, to !== undefined ? to : array.length ) ); - } + } - return array.slice( from, to ); + return array.slice( from, to ); - }, + }, - // converts an array to a specific type - convertArray: function ( array, type, forceClone ) { + // converts an array to a specific type + convertArray: function ( array, type, forceClone ) { - if ( ! array || // let 'undefined' and 'null' pass - ! forceClone && array.constructor === type ) return array; + if ( ! array || // let 'undefined' and 'null' pass + ! forceClone && array.constructor === type ) return array; - if ( typeof type.BYTES_PER_ELEMENT === 'number' ) { + if ( typeof type.BYTES_PER_ELEMENT === 'number' ) { - return new type( array ); // create typed array + return new type( array ); // create typed array - } + } - return Array.prototype.slice.call( array ); // create Array + return Array.prototype.slice.call( array ); // create Array - }, + }, - isTypedArray: function ( object ) { + isTypedArray: function ( object ) { - return ArrayBuffer.isView( object ) && - ! ( object instanceof DataView ); + return ArrayBuffer.isView( object ) && + ! ( object instanceof DataView ); - }, + }, - // returns an array by which times and values can be sorted - getKeyframeOrder: function ( times ) { + // returns an array by which times and values can be sorted + getKeyframeOrder: function ( times ) { - function compareTime( i, j ) { + function compareTime( i, j ) { - return times[ i ] - times[ j ]; + return times[ i ] - times[ j ]; - } + } - var n = times.length; - var result = new Array( n ); - for ( var i = 0; i !== n; ++ i ) result[ i ] = i; + var n = times.length; + var result = new Array( n ); + for ( var i = 0; i !== n; ++ i ) result[ i ] = i; - result.sort( compareTime ); + result.sort( compareTime ); - return result; + return result; - }, + }, - // uses the array previously returned by 'getKeyframeOrder' to sort data - sortedArray: function ( values, stride, order ) { + // uses the array previously returned by 'getKeyframeOrder' to sort data + sortedArray: function ( values, stride, order ) { - var nValues = values.length; - var result = new values.constructor( nValues ); + var nValues = values.length; + var result = new values.constructor( nValues ); - for ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) { + for ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) { - var srcOffset = order[ i ] * stride; + var srcOffset = order[ i ] * stride; - for ( var j = 0; j !== stride; ++ j ) { + for ( var j = 0; j !== stride; ++ j ) { - result[ dstOffset ++ ] = values[ srcOffset + j ]; + result[ dstOffset ++ ] = values[ srcOffset + j ]; - } + } - } + } - return result; + return result; - }, + }, - // function for parsing AOS keyframe formats - flattenJSON: function ( jsonKeys, times, values, valuePropertyName ) { + // function for parsing AOS keyframe formats + flattenJSON: function ( jsonKeys, times, values, valuePropertyName ) { - var i = 1, key = jsonKeys[ 0 ]; + var i = 1, key = jsonKeys[ 0 ]; - while ( key !== undefined && key[ valuePropertyName ] === undefined ) { + while ( key !== undefined && key[ valuePropertyName ] === undefined ) { - key = jsonKeys[ i ++ ]; + key = jsonKeys[ i ++ ]; - } + } - if ( key === undefined ) return; // no data + if ( key === undefined ) return; // no data - var value = key[ valuePropertyName ]; - if ( value === undefined ) return; // no data + var value = key[ valuePropertyName ]; + if ( value === undefined ) return; // no data - if ( Array.isArray( value ) ) { + if ( Array.isArray( value ) ) { - do { + do { - value = key[ valuePropertyName ]; + value = key[ valuePropertyName ]; - if ( value !== undefined ) { + if ( value !== undefined ) { - times.push( key.time ); - values.push.apply( values, value ); // push all elements + times.push( key.time ); + values.push.apply( values, value ); // push all elements - } + } - key = jsonKeys[ i ++ ]; + key = jsonKeys[ i ++ ]; - } while ( key !== undefined ); + } while ( key !== undefined ); - } else if ( value.toArray !== undefined ) { + } else if ( value.toArray !== undefined ) { - // ...assume THREE.Math-ish + // ...assume THREE.Math-ish - do { + do { - value = key[ valuePropertyName ]; + value = key[ valuePropertyName ]; - if ( value !== undefined ) { + if ( value !== undefined ) { - times.push( key.time ); - value.toArray( values, values.length ); + times.push( key.time ); + value.toArray( values, values.length ); - } + } - key = jsonKeys[ i ++ ]; + key = jsonKeys[ i ++ ]; - } while ( key !== undefined ); + } while ( key !== undefined ); - } else { + } else { - // otherwise push as-is + // otherwise push as-is - do { + do { - value = key[ valuePropertyName ]; + value = key[ valuePropertyName ]; - if ( value !== undefined ) { + if ( value !== undefined ) { - times.push( key.time ); - values.push( value ); + times.push( key.time ); + values.push( value ); - } + } - key = jsonKeys[ i ++ ]; + key = jsonKeys[ i ++ ]; - } while ( key !== undefined ); + } while ( key !== undefined ); - } + } - } + } - }; + }; - /** - * Abstract base class of interpolants over parametric samples. - * - * The parameter domain is one dimensional, typically the time or a path - * along a curve defined by the data. - * - * The sample values can have any dimensionality and derived classes may - * apply special interpretations to the data. - * - * This class provides the interval seek in a Template Method, deferring - * the actual interpolation to derived classes. - * - * Time complexity is O(1) for linear access crossing at most two points - * and O(log N) for random access, where N is the number of positions. - * - * References: - * - * http://www.oodesign.com/template-method-pattern.html - * - * @author tschw - */ + /** + * Abstract base class of interpolants over parametric samples. + * + * The parameter domain is one dimensional, typically the time or a path + * along a curve defined by the data. + * + * The sample values can have any dimensionality and derived classes may + * apply special interpretations to the data. + * + * This class provides the interval seek in a Template Method, deferring + * the actual interpolation to derived classes. + * + * Time complexity is O(1) for linear access crossing at most two points + * and O(log N) for random access, where N is the number of positions. + * + * References: + * + * http://www.oodesign.com/template-method-pattern.html + * + * @author tschw + */ - function Interpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { + function Interpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { - this.parameterPositions = parameterPositions; - this._cachedIndex = 0; + this.parameterPositions = parameterPositions; + this._cachedIndex = 0; - this.resultBuffer = resultBuffer !== undefined ? - resultBuffer : new sampleValues.constructor( sampleSize ); - this.sampleValues = sampleValues; - this.valueSize = sampleSize; + this.resultBuffer = resultBuffer !== undefined ? + resultBuffer : new sampleValues.constructor( sampleSize ); + this.sampleValues = sampleValues; + this.valueSize = sampleSize; - } + } - Object.assign( Interpolant.prototype, { + Object.assign( Interpolant.prototype, { - evaluate: function ( t ) { + evaluate: function ( t ) { - var pp = this.parameterPositions, - i1 = this._cachedIndex, + var pp = this.parameterPositions, + i1 = this._cachedIndex, - t1 = pp[ i1 ], - t0 = pp[ i1 - 1 ]; + t1 = pp[ i1 ], + t0 = pp[ i1 - 1 ]; - validate_interval: { + validate_interval: { - seek: { + seek: { - var right; + var right; - linear_scan: { + linear_scan: { - //- See http://jsperf.com/comparison-to-undefined/3 - //- slower code: - //- - //- if ( t >= t1 || t1 === undefined ) { - forward_scan: if ( ! ( t < t1 ) ) { + //- See http://jsperf.com/comparison-to-undefined/3 + //- slower code: + //- + //- if ( t >= t1 || t1 === undefined ) { + forward_scan: if ( ! ( t < t1 ) ) { - for ( var giveUpAt = i1 + 2; ; ) { + for ( var giveUpAt = i1 + 2; ; ) { - if ( t1 === undefined ) { + if ( t1 === undefined ) { - if ( t < t0 ) break forward_scan; + if ( t < t0 ) break forward_scan; - // after end + // after end - i1 = pp.length; - this._cachedIndex = i1; - return this.afterEnd_( i1 - 1, t, t0 ); + i1 = pp.length; + this._cachedIndex = i1; + return this.afterEnd_( i1 - 1, t, t0 ); - } + } - if ( i1 === giveUpAt ) break; // this loop + if ( i1 === giveUpAt ) break; // this loop - t0 = t1; - t1 = pp[ ++ i1 ]; + t0 = t1; + t1 = pp[ ++ i1 ]; - if ( t < t1 ) { + if ( t < t1 ) { - // we have arrived at the sought interval - break seek; + // we have arrived at the sought interval + break seek; - } + } - } + } - // prepare binary search on the right side of the index - right = pp.length; - break linear_scan; + // prepare binary search on the right side of the index + right = pp.length; + break linear_scan; - } + } - //- slower code: - //- if ( t < t0 || t0 === undefined ) { - if ( ! ( t >= t0 ) ) { + //- slower code: + //- if ( t < t0 || t0 === undefined ) { + if ( ! ( t >= t0 ) ) { - // looping? + // looping? - var t1global = pp[ 1 ]; + var t1global = pp[ 1 ]; - if ( t < t1global ) { + if ( t < t1global ) { - i1 = 2; // + 1, using the scan for the details - t0 = t1global; + i1 = 2; // + 1, using the scan for the details + t0 = t1global; - } + } - // linear reverse scan + // linear reverse scan - for ( var giveUpAt = i1 - 2; ; ) { + for ( var giveUpAt = i1 - 2; ; ) { - if ( t0 === undefined ) { + if ( t0 === undefined ) { - // before start + // before start - this._cachedIndex = 0; - return this.beforeStart_( 0, t, t1 ); + this._cachedIndex = 0; + return this.beforeStart_( 0, t, t1 ); - } + } - if ( i1 === giveUpAt ) break; // this loop + if ( i1 === giveUpAt ) break; // this loop - t1 = t0; - t0 = pp[ -- i1 - 1 ]; + t1 = t0; + t0 = pp[ -- i1 - 1 ]; - if ( t >= t0 ) { + if ( t >= t0 ) { - // we have arrived at the sought interval - break seek; + // we have arrived at the sought interval + break seek; - } + } - } + } - // prepare binary search on the left side of the index - right = i1; - i1 = 0; - break linear_scan; + // prepare binary search on the left side of the index + right = i1; + i1 = 0; + break linear_scan; - } + } - // the interval is valid + // the interval is valid - break validate_interval; + break validate_interval; - } // linear scan + } // linear scan - // binary search + // binary search - while ( i1 < right ) { + while ( i1 < right ) { - var mid = ( i1 + right ) >>> 1; + var mid = ( i1 + right ) >>> 1; - if ( t < pp[ mid ] ) { + if ( t < pp[ mid ] ) { - right = mid; + right = mid; - } else { + } else { - i1 = mid + 1; + i1 = mid + 1; - } + } - } + } - t1 = pp[ i1 ]; - t0 = pp[ i1 - 1 ]; + t1 = pp[ i1 ]; + t0 = pp[ i1 - 1 ]; - // check boundary cases, again + // check boundary cases, again - if ( t0 === undefined ) { + if ( t0 === undefined ) { - this._cachedIndex = 0; - return this.beforeStart_( 0, t, t1 ); + this._cachedIndex = 0; + return this.beforeStart_( 0, t, t1 ); - } + } - if ( t1 === undefined ) { + if ( t1 === undefined ) { - i1 = pp.length; - this._cachedIndex = i1; - return this.afterEnd_( i1 - 1, t0, t ); + i1 = pp.length; + this._cachedIndex = i1; + return this.afterEnd_( i1 - 1, t0, t ); - } + } - } // seek + } // seek - this._cachedIndex = i1; + this._cachedIndex = i1; - this.intervalChanged_( i1, t0, t1 ); + this.intervalChanged_( i1, t0, t1 ); - } // validate_interval + } // validate_interval - return this.interpolate_( i1, t0, t, t1 ); + return this.interpolate_( i1, t0, t, t1 ); - }, + }, - settings: null, // optional, subclass-specific settings structure - // Note: The indirection allows central control of many interpolants. + settings: null, // optional, subclass-specific settings structure + // Note: The indirection allows central control of many interpolants. - // --- Protected interface + // --- Protected interface - DefaultSettings_: {}, + DefaultSettings_: {}, - getSettings_: function () { + getSettings_: function () { - return this.settings || this.DefaultSettings_; + return this.settings || this.DefaultSettings_; - }, + }, - copySampleValue_: function ( index ) { + copySampleValue_: function ( index ) { - // copies a sample value to the result buffer + // copies a sample value to the result buffer - var result = this.resultBuffer, - values = this.sampleValues, - stride = this.valueSize, - offset = index * stride; + var result = this.resultBuffer, + values = this.sampleValues, + stride = this.valueSize, + offset = index * stride; - for ( var i = 0; i !== stride; ++ i ) { + for ( var i = 0; i !== stride; ++ i ) { - result[ i ] = values[ offset + i ]; + result[ i ] = values[ offset + i ]; - } + } - return result; + return result; - }, + }, - // Template methods for derived classes: + // Template methods for derived classes: - interpolate_: function ( /* i1, t0, t, t1 */ ) { + interpolate_: function ( /* i1, t0, t, t1 */ ) { - throw new Error( 'call to abstract method' ); - // implementations shall return this.resultBuffer + throw new Error( 'call to abstract method' ); + // implementations shall return this.resultBuffer - }, + }, - intervalChanged_: function ( /* i1, t0, t1 */ ) { + intervalChanged_: function ( /* i1, t0, t1 */ ) { - // empty + // empty - } + } - } ); + } ); - //!\ DECLARE ALIAS AFTER assign prototype ! - Object.assign( Interpolant.prototype, { + //!\ DECLARE ALIAS AFTER assign prototype ! + Object.assign( Interpolant.prototype, { - //( 0, t, t0 ), returns this.resultBuffer - beforeStart_: Interpolant.prototype.copySampleValue_, + //( 0, t, t0 ), returns this.resultBuffer + beforeStart_: Interpolant.prototype.copySampleValue_, - //( N-1, tN-1, t ), returns this.resultBuffer - afterEnd_: Interpolant.prototype.copySampleValue_, + //( N-1, tN-1, t ), returns this.resultBuffer + afterEnd_: Interpolant.prototype.copySampleValue_, - } ); + } ); - /** - * Fast and simple cubic spline interpolant. - * - * It was derived from a Hermitian construction setting the first derivative - * at each sample position to the linear slope between neighboring positions - * over their parameter interval. - * - * @author tschw - */ + /** + * Fast and simple cubic spline interpolant. + * + * It was derived from a Hermitian construction setting the first derivative + * at each sample position to the linear slope between neighboring positions + * over their parameter interval. + * + * @author tschw + */ - function CubicInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { + function CubicInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { - Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); + Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); - this._weightPrev = - 0; - this._offsetPrev = - 0; - this._weightNext = - 0; - this._offsetNext = - 0; + this._weightPrev = - 0; + this._offsetPrev = - 0; + this._weightNext = - 0; + this._offsetNext = - 0; - } + } - CubicInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { + CubicInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { - constructor: CubicInterpolant, + constructor: CubicInterpolant, - DefaultSettings_: { + DefaultSettings_: { - endingStart: ZeroCurvatureEnding, - endingEnd: ZeroCurvatureEnding + endingStart: ZeroCurvatureEnding, + endingEnd: ZeroCurvatureEnding - }, + }, - intervalChanged_: function ( i1, t0, t1 ) { + intervalChanged_: function ( i1, t0, t1 ) { - var pp = this.parameterPositions, - iPrev = i1 - 2, - iNext = i1 + 1, + var pp = this.parameterPositions, + iPrev = i1 - 2, + iNext = i1 + 1, - tPrev = pp[ iPrev ], - tNext = pp[ iNext ]; + tPrev = pp[ iPrev ], + tNext = pp[ iNext ]; - if ( tPrev === undefined ) { + if ( tPrev === undefined ) { - switch ( this.getSettings_().endingStart ) { + switch ( this.getSettings_().endingStart ) { - case ZeroSlopeEnding: + case ZeroSlopeEnding: - // f'(t0) = 0 - iPrev = i1; - tPrev = 2 * t0 - t1; + // f'(t0) = 0 + iPrev = i1; + tPrev = 2 * t0 - t1; - break; + break; - case WrapAroundEnding: + case WrapAroundEnding: - // use the other end of the curve - iPrev = pp.length - 2; - tPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ]; + // use the other end of the curve + iPrev = pp.length - 2; + tPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ]; - break; + break; - default: // ZeroCurvatureEnding + default: // ZeroCurvatureEnding - // f''(t0) = 0 a.k.a. Natural Spline - iPrev = i1; - tPrev = t1; + // f''(t0) = 0 a.k.a. Natural Spline + iPrev = i1; + tPrev = t1; - } + } - } + } - if ( tNext === undefined ) { + if ( tNext === undefined ) { - switch ( this.getSettings_().endingEnd ) { + switch ( this.getSettings_().endingEnd ) { - case ZeroSlopeEnding: + case ZeroSlopeEnding: - // f'(tN) = 0 - iNext = i1; - tNext = 2 * t1 - t0; + // f'(tN) = 0 + iNext = i1; + tNext = 2 * t1 - t0; - break; + break; - case WrapAroundEnding: + case WrapAroundEnding: - // use the other end of the curve - iNext = 1; - tNext = t1 + pp[ 1 ] - pp[ 0 ]; + // use the other end of the curve + iNext = 1; + tNext = t1 + pp[ 1 ] - pp[ 0 ]; - break; + break; - default: // ZeroCurvatureEnding + default: // ZeroCurvatureEnding - // f''(tN) = 0, a.k.a. Natural Spline - iNext = i1 - 1; - tNext = t0; + // f''(tN) = 0, a.k.a. Natural Spline + iNext = i1 - 1; + tNext = t0; - } + } - } + } - var halfDt = ( t1 - t0 ) * 0.5, - stride = this.valueSize; + var halfDt = ( t1 - t0 ) * 0.5, + stride = this.valueSize; - this._weightPrev = halfDt / ( t0 - tPrev ); - this._weightNext = halfDt / ( tNext - t1 ); - this._offsetPrev = iPrev * stride; - this._offsetNext = iNext * stride; + this._weightPrev = halfDt / ( t0 - tPrev ); + this._weightNext = halfDt / ( tNext - t1 ); + this._offsetPrev = iPrev * stride; + this._offsetNext = iNext * stride; - }, + }, - interpolate_: function ( i1, t0, t, t1 ) { + interpolate_: function ( i1, t0, t, t1 ) { - var result = this.resultBuffer, - values = this.sampleValues, - stride = this.valueSize, + var result = this.resultBuffer, + values = this.sampleValues, + stride = this.valueSize, - o1 = i1 * stride, o0 = o1 - stride, - oP = this._offsetPrev, oN = this._offsetNext, - wP = this._weightPrev, wN = this._weightNext, + o1 = i1 * stride, o0 = o1 - stride, + oP = this._offsetPrev, oN = this._offsetNext, + wP = this._weightPrev, wN = this._weightNext, - p = ( t - t0 ) / ( t1 - t0 ), - pp = p * p, - ppp = pp * p; + p = ( t - t0 ) / ( t1 - t0 ), + pp = p * p, + ppp = pp * p; - // evaluate polynomials + // evaluate polynomials - var sP = - wP * ppp + 2 * wP * pp - wP * p; - var s0 = ( 1 + wP ) * ppp + ( - 1.5 - 2 * wP ) * pp + ( - 0.5 + wP ) * p + 1; - var s1 = ( - 1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p; - var sN = wN * ppp - wN * pp; + var sP = - wP * ppp + 2 * wP * pp - wP * p; + var s0 = ( 1 + wP ) * ppp + ( - 1.5 - 2 * wP ) * pp + ( - 0.5 + wP ) * p + 1; + var s1 = ( - 1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p; + var sN = wN * ppp - wN * pp; - // combine data linearly + // combine data linearly - for ( var i = 0; i !== stride; ++ i ) { + for ( var i = 0; i !== stride; ++ i ) { - result[ i ] = - sP * values[ oP + i ] + - s0 * values[ o0 + i ] + - s1 * values[ o1 + i ] + - sN * values[ oN + i ]; + result[ i ] = + sP * values[ oP + i ] + + s0 * values[ o0 + i ] + + s1 * values[ o1 + i ] + + sN * values[ oN + i ]; - } + } - return result; + return result; - } + } - } ); + } ); - /** - * @author tschw - */ + /** + * @author tschw + */ - function LinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { + function LinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { - Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); + Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); - } + } - LinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { + LinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { - constructor: LinearInterpolant, + constructor: LinearInterpolant, - interpolate_: function ( i1, t0, t, t1 ) { + interpolate_: function ( i1, t0, t, t1 ) { - var result = this.resultBuffer, - values = this.sampleValues, - stride = this.valueSize, + var result = this.resultBuffer, + values = this.sampleValues, + stride = this.valueSize, - offset1 = i1 * stride, - offset0 = offset1 - stride, + offset1 = i1 * stride, + offset0 = offset1 - stride, - weight1 = ( t - t0 ) / ( t1 - t0 ), - weight0 = 1 - weight1; + weight1 = ( t - t0 ) / ( t1 - t0 ), + weight0 = 1 - weight1; - for ( var i = 0; i !== stride; ++ i ) { + for ( var i = 0; i !== stride; ++ i ) { - result[ i ] = - values[ offset0 + i ] * weight0 + - values[ offset1 + i ] * weight1; + result[ i ] = + values[ offset0 + i ] * weight0 + + values[ offset1 + i ] * weight1; - } + } - return result; + return result; - } + } - } ); + } ); - /** - * - * Interpolant that evaluates to the sample value at the position preceeding - * the parameter. - * - * @author tschw - */ + /** + * + * Interpolant that evaluates to the sample value at the position preceeding + * the parameter. + * + * @author tschw + */ - function DiscreteInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { + function DiscreteInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { - Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); + Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); - } + } - DiscreteInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { + DiscreteInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { - constructor: DiscreteInterpolant, + constructor: DiscreteInterpolant, - interpolate_: function ( i1 /*, t0, t, t1 */ ) { + interpolate_: function ( i1 /*, t0, t, t1 */ ) { - return this.copySampleValue_( i1 - 1 ); + return this.copySampleValue_( i1 - 1 ); - } + } - } ); + } ); - /** - * - * A timed sequence of keyframes for a specific property. - * - * - * @author Ben Houston / http://clara.io/ - * @author David Sarno / http://lighthaus.us/ - * @author tschw - */ + /** + * + * A timed sequence of keyframes for a specific property. + * + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + * @author tschw + */ - function KeyframeTrack( name, times, values, interpolation ) { + function KeyframeTrack( name, times, values, interpolation ) { - if ( name === undefined ) throw new Error( 'THREE.KeyframeTrack: track name is undefined' ); - if ( times === undefined || times.length === 0 ) throw new Error( 'THREE.KeyframeTrack: no keyframes in track named ' + name ); + if ( name === undefined ) throw new Error( 'THREE.KeyframeTrack: track name is undefined' ); + if ( times === undefined || times.length === 0 ) throw new Error( 'THREE.KeyframeTrack: no keyframes in track named ' + name ); - this.name = name; + this.name = name; - this.times = AnimationUtils.convertArray( times, this.TimeBufferType ); - this.values = AnimationUtils.convertArray( values, this.ValueBufferType ); + this.times = AnimationUtils.convertArray( times, this.TimeBufferType ); + this.values = AnimationUtils.convertArray( values, this.ValueBufferType ); - this.setInterpolation( interpolation || this.DefaultInterpolation ); + this.setInterpolation( interpolation || this.DefaultInterpolation ); - } + } - // Static methods + // Static methods - Object.assign( KeyframeTrack, { + Object.assign( KeyframeTrack, { - // Serialization (in static context, because of constructor invocation - // and automatic invocation of .toJSON): + // Serialization (in static context, because of constructor invocation + // and automatic invocation of .toJSON): - toJSON: function ( track ) { + toJSON: function ( track ) { - var trackType = track.constructor; + var trackType = track.constructor; - var json; + var json; - // derived classes can define a static toJSON method - if ( trackType.toJSON !== undefined ) { + // derived classes can define a static toJSON method + if ( trackType.toJSON !== undefined ) { - json = trackType.toJSON( track ); + json = trackType.toJSON( track ); - } else { + } else { - // by default, we assume the data can be serialized as-is - json = { + // by default, we assume the data can be serialized as-is + json = { - 'name': track.name, - 'times': AnimationUtils.convertArray( track.times, Array ), - 'values': AnimationUtils.convertArray( track.values, Array ) + 'name': track.name, + 'times': AnimationUtils.convertArray( track.times, Array ), + 'values': AnimationUtils.convertArray( track.values, Array ) - }; + }; - var interpolation = track.getInterpolation(); + var interpolation = track.getInterpolation(); - if ( interpolation !== track.DefaultInterpolation ) { + if ( interpolation !== track.DefaultInterpolation ) { - json.interpolation = interpolation; + json.interpolation = interpolation; - } + } - } + } - json.type = track.ValueTypeName; // mandatory + json.type = track.ValueTypeName; // mandatory - return json; + return json; - } + } - } ); + } ); - Object.assign( KeyframeTrack.prototype, { + Object.assign( KeyframeTrack.prototype, { - constructor: KeyframeTrack, + constructor: KeyframeTrack, - TimeBufferType: Float32Array, + TimeBufferType: Float32Array, - ValueBufferType: Float32Array, + ValueBufferType: Float32Array, - DefaultInterpolation: InterpolateLinear, + DefaultInterpolation: InterpolateLinear, - InterpolantFactoryMethodDiscrete: function ( result ) { + InterpolantFactoryMethodDiscrete: function ( result ) { - return new DiscreteInterpolant( this.times, this.values, this.getValueSize(), result ); + return new DiscreteInterpolant( this.times, this.values, this.getValueSize(), result ); - }, + }, - InterpolantFactoryMethodLinear: function ( result ) { + InterpolantFactoryMethodLinear: function ( result ) { - return new LinearInterpolant( this.times, this.values, this.getValueSize(), result ); + return new LinearInterpolant( this.times, this.values, this.getValueSize(), result ); - }, + }, - InterpolantFactoryMethodSmooth: function ( result ) { + InterpolantFactoryMethodSmooth: function ( result ) { - return new CubicInterpolant( this.times, this.values, this.getValueSize(), result ); + return new CubicInterpolant( this.times, this.values, this.getValueSize(), result ); - }, + }, - setInterpolation: function ( interpolation ) { + setInterpolation: function ( interpolation ) { - var factoryMethod; + var factoryMethod; - switch ( interpolation ) { + switch ( interpolation ) { - case InterpolateDiscrete: + case InterpolateDiscrete: - factoryMethod = this.InterpolantFactoryMethodDiscrete; + factoryMethod = this.InterpolantFactoryMethodDiscrete; - break; + break; - case InterpolateLinear: + case InterpolateLinear: - factoryMethod = this.InterpolantFactoryMethodLinear; + factoryMethod = this.InterpolantFactoryMethodLinear; - break; + break; - case InterpolateSmooth: + case InterpolateSmooth: - factoryMethod = this.InterpolantFactoryMethodSmooth; + factoryMethod = this.InterpolantFactoryMethodSmooth; - break; + break; - } + } - if ( factoryMethod === undefined ) { + if ( factoryMethod === undefined ) { - var message = "unsupported interpolation for " + - this.ValueTypeName + " keyframe track named " + this.name; + var message = "unsupported interpolation for " + + this.ValueTypeName + " keyframe track named " + this.name; - if ( this.createInterpolant === undefined ) { + if ( this.createInterpolant === undefined ) { - // fall back to default, unless the default itself is messed up - if ( interpolation !== this.DefaultInterpolation ) { + // fall back to default, unless the default itself is messed up + if ( interpolation !== this.DefaultInterpolation ) { - this.setInterpolation( this.DefaultInterpolation ); + this.setInterpolation( this.DefaultInterpolation ); - } else { + } else { - throw new Error( message ); // fatal, in this case + throw new Error( message ); // fatal, in this case - } + } - } + } - console.warn( 'THREE.KeyframeTrack:', message ); - return this; + console.warn( 'THREE.KeyframeTrack:', message ); + return this; - } + } - this.createInterpolant = factoryMethod; + this.createInterpolant = factoryMethod; - return this; + return this; - }, + }, - getInterpolation: function () { + getInterpolation: function () { - switch ( this.createInterpolant ) { + switch ( this.createInterpolant ) { - case this.InterpolantFactoryMethodDiscrete: + case this.InterpolantFactoryMethodDiscrete: - return InterpolateDiscrete; + return InterpolateDiscrete; - case this.InterpolantFactoryMethodLinear: + case this.InterpolantFactoryMethodLinear: - return InterpolateLinear; + return InterpolateLinear; - case this.InterpolantFactoryMethodSmooth: + case this.InterpolantFactoryMethodSmooth: - return InterpolateSmooth; + return InterpolateSmooth; - } + } - }, + }, - getValueSize: function () { + getValueSize: function () { - return this.values.length / this.times.length; + return this.values.length / this.times.length; - }, + }, - // move all keyframes either forwards or backwards in time - shift: function ( timeOffset ) { + // move all keyframes either forwards or backwards in time + shift: function ( timeOffset ) { - if ( timeOffset !== 0.0 ) { + if ( timeOffset !== 0.0 ) { - var times = this.times; + var times = this.times; - for ( var i = 0, n = times.length; i !== n; ++ i ) { + for ( var i = 0, n = times.length; i !== n; ++ i ) { - times[ i ] += timeOffset; + times[ i ] += timeOffset; - } + } - } + } - return this; + return this; - }, + }, - // scale all keyframe times by a factor (useful for frame <-> seconds conversions) - scale: function ( timeScale ) { + // scale all keyframe times by a factor (useful for frame <-> seconds conversions) + scale: function ( timeScale ) { - if ( timeScale !== 1.0 ) { + if ( timeScale !== 1.0 ) { - var times = this.times; + var times = this.times; - for ( var i = 0, n = times.length; i !== n; ++ i ) { + for ( var i = 0, n = times.length; i !== n; ++ i ) { - times[ i ] *= timeScale; + times[ i ] *= timeScale; - } + } - } + } - return this; + return this; - }, + }, - // removes keyframes before and after animation without changing any values within the range [startTime, endTime]. - // IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values - trim: function ( startTime, endTime ) { + // removes keyframes before and after animation without changing any values within the range [startTime, endTime]. + // IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values + trim: function ( startTime, endTime ) { - var times = this.times, - nKeys = times.length, - from = 0, - to = nKeys - 1; + var times = this.times, + nKeys = times.length, + from = 0, + to = nKeys - 1; - while ( from !== nKeys && times[ from ] < startTime ) { + while ( from !== nKeys && times[ from ] < startTime ) { - ++ from; + ++ from; - } + } - while ( to !== - 1 && times[ to ] > endTime ) { + while ( to !== - 1 && times[ to ] > endTime ) { - -- to; + -- to; - } + } - ++ to; // inclusive -> exclusive bound + ++ to; // inclusive -> exclusive bound - if ( from !== 0 || to !== nKeys ) { + if ( from !== 0 || to !== nKeys ) { - // empty tracks are forbidden, so keep at least one keyframe - if ( from >= to ) to = Math.max( to, 1 ), from = to - 1; + // empty tracks are forbidden, so keep at least one keyframe + if ( from >= to ) to = Math.max( to, 1 ), from = to - 1; - var stride = this.getValueSize(); - this.times = AnimationUtils.arraySlice( times, from, to ); - this.values = AnimationUtils.arraySlice( this.values, from * stride, to * stride ); + var stride = this.getValueSize(); + this.times = AnimationUtils.arraySlice( times, from, to ); + this.values = AnimationUtils.arraySlice( this.values, from * stride, to * stride ); - } + } - return this; + return this; - }, + }, - // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable - validate: function () { + // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable + validate: function () { - var valid = true; + var valid = true; - var valueSize = this.getValueSize(); - if ( valueSize - Math.floor( valueSize ) !== 0 ) { + var valueSize = this.getValueSize(); + if ( valueSize - Math.floor( valueSize ) !== 0 ) { - console.error( 'THREE.KeyframeTrack: Invalid value size in track.', this ); - valid = false; + console.error( 'THREE.KeyframeTrack: Invalid value size in track.', this ); + valid = false; - } + } - var times = this.times, - values = this.values, + var times = this.times, + values = this.values, - nKeys = times.length; + nKeys = times.length; - if ( nKeys === 0 ) { + if ( nKeys === 0 ) { - console.error( 'THREE.KeyframeTrack: Track is empty.', this ); - valid = false; + console.error( 'THREE.KeyframeTrack: Track is empty.', this ); + valid = false; - } + } - var prevTime = null; + var prevTime = null; - for ( var i = 0; i !== nKeys; i ++ ) { + for ( var i = 0; i !== nKeys; i ++ ) { - var currTime = times[ i ]; + var currTime = times[ i ]; - if ( typeof currTime === 'number' && isNaN( currTime ) ) { + if ( typeof currTime === 'number' && isNaN( currTime ) ) { - console.error( 'THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime ); - valid = false; - break; + console.error( 'THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime ); + valid = false; + break; - } + } - if ( prevTime !== null && prevTime > currTime ) { + if ( prevTime !== null && prevTime > currTime ) { - console.error( 'THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime ); - valid = false; - break; + console.error( 'THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime ); + valid = false; + break; - } + } - prevTime = currTime; + prevTime = currTime; - } + } - if ( values !== undefined ) { + if ( values !== undefined ) { - if ( AnimationUtils.isTypedArray( values ) ) { + if ( AnimationUtils.isTypedArray( values ) ) { - for ( var i = 0, n = values.length; i !== n; ++ i ) { + for ( var i = 0, n = values.length; i !== n; ++ i ) { - var value = values[ i ]; + var value = values[ i ]; - if ( isNaN( value ) ) { + if ( isNaN( value ) ) { - console.error( 'THREE.KeyframeTrack: Value is not a valid number.', this, i, value ); - valid = false; - break; + console.error( 'THREE.KeyframeTrack: Value is not a valid number.', this, i, value ); + valid = false; + break; - } + } - } + } - } + } - } + } - return valid; + return valid; - }, + }, - // removes equivalent sequential keys as common in morph target sequences - // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0) - optimize: function () { + // removes equivalent sequential keys as common in morph target sequences + // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0) + optimize: function () { - var times = this.times, - values = this.values, - stride = this.getValueSize(), + var times = this.times, + values = this.values, + stride = this.getValueSize(), - smoothInterpolation = this.getInterpolation() === InterpolateSmooth, + smoothInterpolation = this.getInterpolation() === InterpolateSmooth, - writeIndex = 1, - lastIndex = times.length - 1; + writeIndex = 1, + lastIndex = times.length - 1; - for ( var i = 1; i < lastIndex; ++ i ) { + for ( var i = 1; i < lastIndex; ++ i ) { - var keep = false; + var keep = false; - var time = times[ i ]; - var timeNext = times[ i + 1 ]; + var time = times[ i ]; + var timeNext = times[ i + 1 ]; - // remove adjacent keyframes scheduled at the same time + // remove adjacent keyframes scheduled at the same time - if ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) { + if ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) { - if ( ! smoothInterpolation ) { + if ( ! smoothInterpolation ) { - // remove unnecessary keyframes same as their neighbors + // remove unnecessary keyframes same as their neighbors - var offset = i * stride, - offsetP = offset - stride, - offsetN = offset + stride; + var offset = i * stride, + offsetP = offset - stride, + offsetN = offset + stride; - for ( var j = 0; j !== stride; ++ j ) { + for ( var j = 0; j !== stride; ++ j ) { - var value = values[ offset + j ]; + var value = values[ offset + j ]; - if ( value !== values[ offsetP + j ] || - value !== values[ offsetN + j ] ) { + if ( value !== values[ offsetP + j ] || + value !== values[ offsetN + j ] ) { - keep = true; - break; + keep = true; + break; - } + } - } + } - } else { + } else { - keep = true; + keep = true; - } + } - } + } - // in-place compaction + // in-place compaction - if ( keep ) { + if ( keep ) { - if ( i !== writeIndex ) { + if ( i !== writeIndex ) { - times[ writeIndex ] = times[ i ]; + times[ writeIndex ] = times[ i ]; - var readOffset = i * stride, - writeOffset = writeIndex * stride; + var readOffset = i * stride, + writeOffset = writeIndex * stride; - for ( var j = 0; j !== stride; ++ j ) { + for ( var j = 0; j !== stride; ++ j ) { - values[ writeOffset + j ] = values[ readOffset + j ]; + values[ writeOffset + j ] = values[ readOffset + j ]; - } + } - } + } - ++ writeIndex; + ++ writeIndex; - } + } - } + } - // flush last keyframe (compaction looks ahead) + // flush last keyframe (compaction looks ahead) - if ( lastIndex > 0 ) { + if ( lastIndex > 0 ) { - times[ writeIndex ] = times[ lastIndex ]; + times[ writeIndex ] = times[ lastIndex ]; - for ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j ) { + for ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j ) { - values[ writeOffset + j ] = values[ readOffset + j ]; + values[ writeOffset + j ] = values[ readOffset + j ]; - } + } - ++ writeIndex; + ++ writeIndex; - } + } - if ( writeIndex !== times.length ) { + if ( writeIndex !== times.length ) { - this.times = AnimationUtils.arraySlice( times, 0, writeIndex ); - this.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride ); + this.times = AnimationUtils.arraySlice( times, 0, writeIndex ); + this.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride ); - } + } - return this; + return this; - } + } - } ); + } ); - /** - * - * A Track of Boolean keyframe values. - * - * - * @author Ben Houston / http://clara.io/ - * @author David Sarno / http://lighthaus.us/ - * @author tschw - */ + /** + * + * A Track of Boolean keyframe values. + * + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + * @author tschw + */ - function BooleanKeyframeTrack( name, times, values ) { + function BooleanKeyframeTrack( name, times, values ) { - KeyframeTrack.call( this, name, times, values ); + KeyframeTrack.call( this, name, times, values ); - } + } - BooleanKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { + BooleanKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { - constructor: BooleanKeyframeTrack, + constructor: BooleanKeyframeTrack, - ValueTypeName: 'bool', - ValueBufferType: Array, + ValueTypeName: 'bool', + ValueBufferType: Array, - DefaultInterpolation: InterpolateDiscrete, + DefaultInterpolation: InterpolateDiscrete, - InterpolantFactoryMethodLinear: undefined, - InterpolantFactoryMethodSmooth: undefined + InterpolantFactoryMethodLinear: undefined, + InterpolantFactoryMethodSmooth: undefined - // Note: Actually this track could have a optimized / compressed - // representation of a single value and a custom interpolant that - // computes "firstValue ^ isOdd( index )". + // Note: Actually this track could have a optimized / compressed + // representation of a single value and a custom interpolant that + // computes "firstValue ^ isOdd( index )". - } ); + } ); - /** - * - * A Track of keyframe values that represent color. - * - * - * @author Ben Houston / http://clara.io/ - * @author David Sarno / http://lighthaus.us/ - * @author tschw - */ + /** + * + * A Track of keyframe values that represent color. + * + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + * @author tschw + */ - function ColorKeyframeTrack( name, times, values, interpolation ) { + function ColorKeyframeTrack( name, times, values, interpolation ) { - KeyframeTrack.call( this, name, times, values, interpolation ); + KeyframeTrack.call( this, name, times, values, interpolation ); - } + } - ColorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { + ColorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { - constructor: ColorKeyframeTrack, + constructor: ColorKeyframeTrack, - ValueTypeName: 'color' + ValueTypeName: 'color' - // ValueBufferType is inherited + // ValueBufferType is inherited - // DefaultInterpolation is inherited + // DefaultInterpolation is inherited - // Note: Very basic implementation and nothing special yet. - // However, this is the place for color space parameterization. + // Note: Very basic implementation and nothing special yet. + // However, this is the place for color space parameterization. - } ); + } ); - /** - * - * A Track of numeric keyframe values. - * - * @author Ben Houston / http://clara.io/ - * @author David Sarno / http://lighthaus.us/ - * @author tschw - */ + /** + * + * A Track of numeric keyframe values. + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + * @author tschw + */ - function NumberKeyframeTrack( name, times, values, interpolation ) { + function NumberKeyframeTrack( name, times, values, interpolation ) { - KeyframeTrack.call( this, name, times, values, interpolation ); + KeyframeTrack.call( this, name, times, values, interpolation ); - } + } - NumberKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { + NumberKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { - constructor: NumberKeyframeTrack, + constructor: NumberKeyframeTrack, - ValueTypeName: 'number' + ValueTypeName: 'number' - // ValueBufferType is inherited + // ValueBufferType is inherited - // DefaultInterpolation is inherited + // DefaultInterpolation is inherited - } ); + } ); - /** - * Spherical linear unit quaternion interpolant. - * - * @author tschw - */ + /** + * Spherical linear unit quaternion interpolant. + * + * @author tschw + */ - function QuaternionLinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { + function QuaternionLinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { - Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); + Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); - } + } - QuaternionLinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { + QuaternionLinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), { - constructor: QuaternionLinearInterpolant, + constructor: QuaternionLinearInterpolant, - interpolate_: function ( i1, t0, t, t1 ) { + interpolate_: function ( i1, t0, t, t1 ) { - var result = this.resultBuffer, - values = this.sampleValues, - stride = this.valueSize, + var result = this.resultBuffer, + values = this.sampleValues, + stride = this.valueSize, - offset = i1 * stride, + offset = i1 * stride, - alpha = ( t - t0 ) / ( t1 - t0 ); + alpha = ( t - t0 ) / ( t1 - t0 ); - for ( var end = offset + stride; offset !== end; offset += 4 ) { + for ( var end = offset + stride; offset !== end; offset += 4 ) { - Quaternion.slerpFlat( result, 0, values, offset - stride, values, offset, alpha ); + Quaternion.slerpFlat( result, 0, values, offset - stride, values, offset, alpha ); - } + } - return result; + return result; - } + } - } ); + } ); - /** - * - * A Track of quaternion keyframe values. - * - * @author Ben Houston / http://clara.io/ - * @author David Sarno / http://lighthaus.us/ - * @author tschw - */ + /** + * + * A Track of quaternion keyframe values. + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + * @author tschw + */ - function QuaternionKeyframeTrack( name, times, values, interpolation ) { + function QuaternionKeyframeTrack( name, times, values, interpolation ) { - KeyframeTrack.call( this, name, times, values, interpolation ); + KeyframeTrack.call( this, name, times, values, interpolation ); - } + } - QuaternionKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { + QuaternionKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { - constructor: QuaternionKeyframeTrack, + constructor: QuaternionKeyframeTrack, - ValueTypeName: 'quaternion', + ValueTypeName: 'quaternion', - // ValueBufferType is inherited + // ValueBufferType is inherited - DefaultInterpolation: InterpolateLinear, + DefaultInterpolation: InterpolateLinear, - InterpolantFactoryMethodLinear: function ( result ) { + InterpolantFactoryMethodLinear: function ( result ) { - return new QuaternionLinearInterpolant( this.times, this.values, this.getValueSize(), result ); + return new QuaternionLinearInterpolant( this.times, this.values, this.getValueSize(), result ); - }, + }, - InterpolantFactoryMethodSmooth: undefined // not yet implemented + InterpolantFactoryMethodSmooth: undefined // not yet implemented - } ); + } ); - /** - * - * A Track that interpolates Strings - * - * - * @author Ben Houston / http://clara.io/ - * @author David Sarno / http://lighthaus.us/ - * @author tschw - */ + /** + * + * A Track that interpolates Strings + * + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + * @author tschw + */ - function StringKeyframeTrack( name, times, values, interpolation ) { + function StringKeyframeTrack( name, times, values, interpolation ) { - KeyframeTrack.call( this, name, times, values, interpolation ); + KeyframeTrack.call( this, name, times, values, interpolation ); - } + } - StringKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { + StringKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { - constructor: StringKeyframeTrack, + constructor: StringKeyframeTrack, - ValueTypeName: 'string', - ValueBufferType: Array, + ValueTypeName: 'string', + ValueBufferType: Array, - DefaultInterpolation: InterpolateDiscrete, + DefaultInterpolation: InterpolateDiscrete, - InterpolantFactoryMethodLinear: undefined, + InterpolantFactoryMethodLinear: undefined, - InterpolantFactoryMethodSmooth: undefined + InterpolantFactoryMethodSmooth: undefined - } ); + } ); - /** - * - * A Track of vectored keyframe values. - * - * - * @author Ben Houston / http://clara.io/ - * @author David Sarno / http://lighthaus.us/ - * @author tschw - */ + /** + * + * A Track of vectored keyframe values. + * + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + * @author tschw + */ - function VectorKeyframeTrack( name, times, values, interpolation ) { + function VectorKeyframeTrack( name, times, values, interpolation ) { - KeyframeTrack.call( this, name, times, values, interpolation ); + KeyframeTrack.call( this, name, times, values, interpolation ); - } + } - VectorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { + VectorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), { - constructor: VectorKeyframeTrack, + constructor: VectorKeyframeTrack, - ValueTypeName: 'vector' + ValueTypeName: 'vector' - // ValueBufferType is inherited + // ValueBufferType is inherited - // DefaultInterpolation is inherited + // DefaultInterpolation is inherited - } ); + } ); - /** - * - * Reusable set of Tracks that represent an animation. - * - * @author Ben Houston / http://clara.io/ - * @author David Sarno / http://lighthaus.us/ - */ + /** + * + * Reusable set of Tracks that represent an animation. + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + */ - function AnimationClip( name, duration, tracks ) { + function AnimationClip( name, duration, tracks ) { - this.name = name; - this.tracks = tracks; - this.duration = ( duration !== undefined ) ? duration : - 1; + this.name = name; + this.tracks = tracks; + this.duration = ( duration !== undefined ) ? duration : - 1; - this.uuid = _Math.generateUUID(); + this.uuid = _Math.generateUUID(); - // this means it should figure out its duration by scanning the tracks - if ( this.duration < 0 ) { + // this means it should figure out its duration by scanning the tracks + if ( this.duration < 0 ) { - this.resetDuration(); + this.resetDuration(); - } + } - } + } - function getTrackTypeForValueTypeName( typeName ) { + function getTrackTypeForValueTypeName( typeName ) { - switch ( typeName.toLowerCase() ) { + switch ( typeName.toLowerCase() ) { - case 'scalar': - case 'double': - case 'float': - case 'number': - case 'integer': + case 'scalar': + case 'double': + case 'float': + case 'number': + case 'integer': - return NumberKeyframeTrack; + return NumberKeyframeTrack; - case 'vector': - case 'vector2': - case 'vector3': - case 'vector4': + case 'vector': + case 'vector2': + case 'vector3': + case 'vector4': - return VectorKeyframeTrack; + return VectorKeyframeTrack; - case 'color': + case 'color': - return ColorKeyframeTrack; + return ColorKeyframeTrack; - case 'quaternion': + case 'quaternion': - return QuaternionKeyframeTrack; + return QuaternionKeyframeTrack; - case 'bool': - case 'boolean': + case 'bool': + case 'boolean': - return BooleanKeyframeTrack; + return BooleanKeyframeTrack; - case 'string': + case 'string': - return StringKeyframeTrack; + return StringKeyframeTrack; - } + } - throw new Error( 'THREE.KeyframeTrack: Unsupported typeName: ' + typeName ); + throw new Error( 'THREE.KeyframeTrack: Unsupported typeName: ' + typeName ); - } + } - function parseKeyframeTrack( json ) { + function parseKeyframeTrack( json ) { - if ( json.type === undefined ) { + if ( json.type === undefined ) { - throw new Error( 'THREE.KeyframeTrack: track type undefined, can not parse' ); + throw new Error( 'THREE.KeyframeTrack: track type undefined, can not parse' ); - } + } - var trackType = getTrackTypeForValueTypeName( json.type ); + var trackType = getTrackTypeForValueTypeName( json.type ); - if ( json.times === undefined ) { + if ( json.times === undefined ) { - var times = [], values = []; + var times = [], values = []; - AnimationUtils.flattenJSON( json.keys, times, values, 'value' ); + AnimationUtils.flattenJSON( json.keys, times, values, 'value' ); - json.times = times; - json.values = values; + json.times = times; + json.values = values; - } + } - // derived classes can define a static parse method - if ( trackType.parse !== undefined ) { + // derived classes can define a static parse method + if ( trackType.parse !== undefined ) { - return trackType.parse( json ); + return trackType.parse( json ); - } else { + } else { - // by default, we assume a constructor compatible with the base - return new trackType( json.name, json.times, json.values, json.interpolation ); + // by default, we assume a constructor compatible with the base + return new trackType( json.name, json.times, json.values, json.interpolation ); - } + } - } + } - Object.assign( AnimationClip, { + Object.assign( AnimationClip, { - parse: function ( json ) { + parse: function ( json ) { - var tracks = [], - jsonTracks = json.tracks, - frameTime = 1.0 / ( json.fps || 1.0 ); + var tracks = [], + jsonTracks = json.tracks, + frameTime = 1.0 / ( json.fps || 1.0 ); - for ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) { + for ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) { - tracks.push( parseKeyframeTrack( jsonTracks[ i ] ).scale( frameTime ) ); + tracks.push( parseKeyframeTrack( jsonTracks[ i ] ).scale( frameTime ) ); - } + } - return new AnimationClip( json.name, json.duration, tracks ); + return new AnimationClip( json.name, json.duration, tracks ); - }, + }, - toJSON: function ( clip ) { + toJSON: function ( clip ) { - var tracks = [], - clipTracks = clip.tracks; + var tracks = [], + clipTracks = clip.tracks; - var json = { + var json = { - 'name': clip.name, - 'duration': clip.duration, - 'tracks': tracks, - 'uuid': clip.uuid + 'name': clip.name, + 'duration': clip.duration, + 'tracks': tracks, + 'uuid': clip.uuid - }; + }; - for ( var i = 0, n = clipTracks.length; i !== n; ++ i ) { + for ( var i = 0, n = clipTracks.length; i !== n; ++ i ) { - tracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) ); + tracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) ); - } + } - return json; + return json; - }, + }, - CreateFromMorphTargetSequence: function ( name, morphTargetSequence, fps, noLoop ) { + CreateFromMorphTargetSequence: function ( name, morphTargetSequence, fps, noLoop ) { - var numMorphTargets = morphTargetSequence.length; - var tracks = []; + var numMorphTargets = morphTargetSequence.length; + var tracks = []; - for ( var i = 0; i < numMorphTargets; i ++ ) { + for ( var i = 0; i < numMorphTargets; i ++ ) { - var times = []; - var values = []; + var times = []; + var values = []; - times.push( - ( i + numMorphTargets - 1 ) % numMorphTargets, - i, - ( i + 1 ) % numMorphTargets ); + times.push( + ( i + numMorphTargets - 1 ) % numMorphTargets, + i, + ( i + 1 ) % numMorphTargets ); - values.push( 0, 1, 0 ); + values.push( 0, 1, 0 ); - var order = AnimationUtils.getKeyframeOrder( times ); - times = AnimationUtils.sortedArray( times, 1, order ); - values = AnimationUtils.sortedArray( values, 1, order ); + var order = AnimationUtils.getKeyframeOrder( times ); + times = AnimationUtils.sortedArray( times, 1, order ); + values = AnimationUtils.sortedArray( values, 1, order ); - // if there is a key at the first frame, duplicate it as the - // last frame as well for perfect loop. - if ( ! noLoop && times[ 0 ] === 0 ) { + // if there is a key at the first frame, duplicate it as the + // last frame as well for perfect loop. + if ( ! noLoop && times[ 0 ] === 0 ) { - times.push( numMorphTargets ); - values.push( values[ 0 ] ); + times.push( numMorphTargets ); + values.push( values[ 0 ] ); - } + } - tracks.push( - new NumberKeyframeTrack( - '.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']', - times, values - ).scale( 1.0 / fps ) ); + tracks.push( + new NumberKeyframeTrack( + '.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']', + times, values + ).scale( 1.0 / fps ) ); - } + } - return new AnimationClip( name, - 1, tracks ); + return new AnimationClip( name, - 1, tracks ); - }, + }, - findByName: function ( objectOrClipArray, name ) { + findByName: function ( objectOrClipArray, name ) { - var clipArray = objectOrClipArray; + var clipArray = objectOrClipArray; - if ( ! Array.isArray( objectOrClipArray ) ) { + if ( ! Array.isArray( objectOrClipArray ) ) { - var o = objectOrClipArray; - clipArray = o.geometry && o.geometry.animations || o.animations; + var o = objectOrClipArray; + clipArray = o.geometry && o.geometry.animations || o.animations; - } + } - for ( var i = 0; i < clipArray.length; i ++ ) { + for ( var i = 0; i < clipArray.length; i ++ ) { - if ( clipArray[ i ].name === name ) { + if ( clipArray[ i ].name === name ) { - return clipArray[ i ]; + return clipArray[ i ]; - } + } - } + } - return null; + return null; - }, + }, - CreateClipsFromMorphTargetSequences: function ( morphTargets, fps, noLoop ) { + CreateClipsFromMorphTargetSequences: function ( morphTargets, fps, noLoop ) { - var animationToMorphTargets = {}; + var animationToMorphTargets = {}; - // tested with https://regex101.com/ on trick sequences - // such flamingo_flyA_003, flamingo_run1_003, crdeath0059 - var pattern = /^([\w-]*?)([\d]+)$/; + // tested with https://regex101.com/ on trick sequences + // such flamingo_flyA_003, flamingo_run1_003, crdeath0059 + var pattern = /^([\w-]*?)([\d]+)$/; - // sort morph target names into animation groups based - // patterns like Walk_001, Walk_002, Run_001, Run_002 - for ( var i = 0, il = morphTargets.length; i < il; i ++ ) { + // sort morph target names into animation groups based + // patterns like Walk_001, Walk_002, Run_001, Run_002 + for ( var i = 0, il = morphTargets.length; i < il; i ++ ) { - var morphTarget = morphTargets[ i ]; - var parts = morphTarget.name.match( pattern ); + var morphTarget = morphTargets[ i ]; + var parts = morphTarget.name.match( pattern ); - if ( parts && parts.length > 1 ) { + if ( parts && parts.length > 1 ) { - var name = parts[ 1 ]; + var name = parts[ 1 ]; - var animationMorphTargets = animationToMorphTargets[ name ]; - if ( ! animationMorphTargets ) { + var animationMorphTargets = animationToMorphTargets[ name ]; + if ( ! animationMorphTargets ) { - animationToMorphTargets[ name ] = animationMorphTargets = []; + animationToMorphTargets[ name ] = animationMorphTargets = []; - } + } - animationMorphTargets.push( morphTarget ); + animationMorphTargets.push( morphTarget ); - } + } - } + } - var clips = []; + var clips = []; - for ( var name in animationToMorphTargets ) { + for ( var name in animationToMorphTargets ) { - clips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) ); + clips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) ); - } + } - return clips; + return clips; - }, + }, - // parse the animation.hierarchy format - parseAnimation: function ( animation, bones ) { + // parse the animation.hierarchy format + parseAnimation: function ( animation, bones ) { - if ( ! animation ) { + if ( ! animation ) { - console.error( 'THREE.AnimationClip: No animation in JSONLoader data.' ); - return null; + console.error( 'THREE.AnimationClip: No animation in JSONLoader data.' ); + return null; - } + } - var addNonemptyTrack = function ( trackType, trackName, animationKeys, propertyName, destTracks ) { + var addNonemptyTrack = function ( trackType, trackName, animationKeys, propertyName, destTracks ) { - // only return track if there are actually keys. - if ( animationKeys.length !== 0 ) { + // only return track if there are actually keys. + if ( animationKeys.length !== 0 ) { - var times = []; - var values = []; + var times = []; + var values = []; - AnimationUtils.flattenJSON( animationKeys, times, values, propertyName ); + AnimationUtils.flattenJSON( animationKeys, times, values, propertyName ); - // empty keys are filtered out, so check again - if ( times.length !== 0 ) { + // empty keys are filtered out, so check again + if ( times.length !== 0 ) { - destTracks.push( new trackType( trackName, times, values ) ); + destTracks.push( new trackType( trackName, times, values ) ); - } + } - } + } - }; + }; - var tracks = []; + var tracks = []; - var clipName = animation.name || 'default'; - // automatic length determination in AnimationClip. - var duration = animation.length || - 1; - var fps = animation.fps || 30; + var clipName = animation.name || 'default'; + // automatic length determination in AnimationClip. + var duration = animation.length || - 1; + var fps = animation.fps || 30; - var hierarchyTracks = animation.hierarchy || []; + var hierarchyTracks = animation.hierarchy || []; - for ( var h = 0; h < hierarchyTracks.length; h ++ ) { + for ( var h = 0; h < hierarchyTracks.length; h ++ ) { - var animationKeys = hierarchyTracks[ h ].keys; + var animationKeys = hierarchyTracks[ h ].keys; - // skip empty tracks - if ( ! animationKeys || animationKeys.length === 0 ) continue; + // skip empty tracks + if ( ! animationKeys || animationKeys.length === 0 ) continue; - // process morph targets - if ( animationKeys[ 0 ].morphTargets ) { + // process morph targets + if ( animationKeys[ 0 ].morphTargets ) { - // figure out all morph targets used in this track - var morphTargetNames = {}; + // figure out all morph targets used in this track + var morphTargetNames = {}; - for ( var k = 0; k < animationKeys.length; k ++ ) { + for ( var k = 0; k < animationKeys.length; k ++ ) { - if ( animationKeys[ k ].morphTargets ) { + if ( animationKeys[ k ].morphTargets ) { - for ( var m = 0; m < animationKeys[ k ].morphTargets.length; m ++ ) { + for ( var m = 0; m < animationKeys[ k ].morphTargets.length; m ++ ) { - morphTargetNames[ animationKeys[ k ].morphTargets[ m ] ] = - 1; + morphTargetNames[ animationKeys[ k ].morphTargets[ m ] ] = - 1; - } + } - } + } - } + } - // create a track for each morph target with all zero - // morphTargetInfluences except for the keys in which - // the morphTarget is named. - for ( var morphTargetName in morphTargetNames ) { + // create a track for each morph target with all zero + // morphTargetInfluences except for the keys in which + // the morphTarget is named. + for ( var morphTargetName in morphTargetNames ) { - var times = []; - var values = []; + var times = []; + var values = []; - for ( var m = 0; m !== animationKeys[ k ].morphTargets.length; ++ m ) { + for ( var m = 0; m !== animationKeys[ k ].morphTargets.length; ++ m ) { - var animationKey = animationKeys[ k ]; + var animationKey = animationKeys[ k ]; - times.push( animationKey.time ); - values.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 ); + times.push( animationKey.time ); + values.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 ); - } + } - tracks.push( new NumberKeyframeTrack( '.morphTargetInfluence[' + morphTargetName + ']', times, values ) ); + tracks.push( new NumberKeyframeTrack( '.morphTargetInfluence[' + morphTargetName + ']', times, values ) ); - } + } - duration = morphTargetNames.length * ( fps || 1.0 ); + duration = morphTargetNames.length * ( fps || 1.0 ); - } else { + } else { - // ...assume skeletal animation + // ...assume skeletal animation - var boneName = '.bones[' + bones[ h ].name + ']'; + var boneName = '.bones[' + bones[ h ].name + ']'; - addNonemptyTrack( - VectorKeyframeTrack, boneName + '.position', - animationKeys, 'pos', tracks ); + addNonemptyTrack( + VectorKeyframeTrack, boneName + '.position', + animationKeys, 'pos', tracks ); - addNonemptyTrack( - QuaternionKeyframeTrack, boneName + '.quaternion', - animationKeys, 'rot', tracks ); + addNonemptyTrack( + QuaternionKeyframeTrack, boneName + '.quaternion', + animationKeys, 'rot', tracks ); - addNonemptyTrack( - VectorKeyframeTrack, boneName + '.scale', - animationKeys, 'scl', tracks ); + addNonemptyTrack( + VectorKeyframeTrack, boneName + '.scale', + animationKeys, 'scl', tracks ); - } + } - } + } - if ( tracks.length === 0 ) { + if ( tracks.length === 0 ) { - return null; + return null; - } + } - var clip = new AnimationClip( clipName, duration, tracks ); + var clip = new AnimationClip( clipName, duration, tracks ); - return clip; + return clip; - } + } - } ); + } ); - Object.assign( AnimationClip.prototype, { + Object.assign( AnimationClip.prototype, { - resetDuration: function () { + resetDuration: function () { - var tracks = this.tracks, duration = 0; + var tracks = this.tracks, duration = 0; - for ( var i = 0, n = tracks.length; i !== n; ++ i ) { + for ( var i = 0, n = tracks.length; i !== n; ++ i ) { - var track = this.tracks[ i ]; + var track = this.tracks[ i ]; - duration = Math.max( duration, track.times[ track.times.length - 1 ] ); + duration = Math.max( duration, track.times[ track.times.length - 1 ] ); - } + } - this.duration = duration; + this.duration = duration; - return this; + return this; - }, + }, - trim: function () { + trim: function () { - for ( var i = 0; i < this.tracks.length; i ++ ) { + for ( var i = 0; i < this.tracks.length; i ++ ) { - this.tracks[ i ].trim( 0, this.duration ); + this.tracks[ i ].trim( 0, this.duration ); - } + } - return this; + return this; - }, + }, - validate: function () { + validate: function () { - var valid = true; + var valid = true; - for ( var i = 0; i < this.tracks.length; i ++ ) { + for ( var i = 0; i < this.tracks.length; i ++ ) { - valid = valid && this.tracks[ i ].validate(); + valid = valid && this.tracks[ i ].validate(); - } + } - return valid; + return valid; - }, + }, - optimize: function () { + optimize: function () { - for ( var i = 0; i < this.tracks.length; i ++ ) { + for ( var i = 0; i < this.tracks.length; i ++ ) { - this.tracks[ i ].optimize(); + this.tracks[ i ].optimize(); - } + } - return this; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function MaterialLoader( manager ) { + function MaterialLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - this.textures = {}; + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + this.textures = {}; - } + } - Object.assign( MaterialLoader.prototype, { + Object.assign( MaterialLoader.prototype, { - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - var scope = this; + var scope = this; - var loader = new FileLoader( scope.manager ); - loader.load( url, function ( text ) { + var loader = new FileLoader( scope.manager ); + loader.load( url, function ( text ) { - onLoad( scope.parse( JSON.parse( text ) ) ); + onLoad( scope.parse( JSON.parse( text ) ) ); - }, onProgress, onError ); + }, onProgress, onError ); - }, + }, - setTextures: function ( value ) { + setTextures: function ( value ) { - this.textures = value; + this.textures = value; - }, + }, - parse: function ( json ) { + parse: function ( json ) { - var textures = this.textures; + var textures = this.textures; - function getTexture( name ) { + function getTexture( name ) { - if ( textures[ name ] === undefined ) { + if ( textures[ name ] === undefined ) { - console.warn( 'THREE.MaterialLoader: Undefined texture', name ); + console.warn( 'THREE.MaterialLoader: Undefined texture', name ); - } + } - return textures[ name ]; + return textures[ name ]; - } + } - var material = new Materials[ json.type ](); + var material = new Materials[ json.type ](); - if ( json.uuid !== undefined ) material.uuid = json.uuid; - if ( json.name !== undefined ) material.name = json.name; - if ( json.color !== undefined ) material.color.setHex( json.color ); - if ( json.roughness !== undefined ) material.roughness = json.roughness; - if ( json.metalness !== undefined ) material.metalness = json.metalness; - if ( json.emissive !== undefined ) material.emissive.setHex( json.emissive ); - if ( json.specular !== undefined ) material.specular.setHex( json.specular ); - if ( json.shininess !== undefined ) material.shininess = json.shininess; - if ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat; - if ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness; - if ( json.uniforms !== undefined ) material.uniforms = json.uniforms; - if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader; - if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader; - if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors; - if ( json.fog !== undefined ) material.fog = json.fog; - if ( json.flatShading !== undefined ) material.flatShading = json.flatShading; - if ( json.blending !== undefined ) material.blending = json.blending; - if ( json.side !== undefined ) material.side = json.side; - if ( json.opacity !== undefined ) material.opacity = json.opacity; - if ( json.transparent !== undefined ) material.transparent = json.transparent; - if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest; - if ( json.depthTest !== undefined ) material.depthTest = json.depthTest; - if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite; - if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite; - if ( json.wireframe !== undefined ) material.wireframe = json.wireframe; - if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth; - if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap; - if ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin; + if ( json.uuid !== undefined ) material.uuid = json.uuid; + if ( json.name !== undefined ) material.name = json.name; + if ( json.color !== undefined ) material.color.setHex( json.color ); + if ( json.roughness !== undefined ) material.roughness = json.roughness; + if ( json.metalness !== undefined ) material.metalness = json.metalness; + if ( json.emissive !== undefined ) material.emissive.setHex( json.emissive ); + if ( json.specular !== undefined ) material.specular.setHex( json.specular ); + if ( json.shininess !== undefined ) material.shininess = json.shininess; + if ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat; + if ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness; + if ( json.uniforms !== undefined ) material.uniforms = json.uniforms; + if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader; + if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader; + if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors; + if ( json.fog !== undefined ) material.fog = json.fog; + if ( json.flatShading !== undefined ) material.flatShading = json.flatShading; + if ( json.blending !== undefined ) material.blending = json.blending; + if ( json.side !== undefined ) material.side = json.side; + if ( json.opacity !== undefined ) material.opacity = json.opacity; + if ( json.transparent !== undefined ) material.transparent = json.transparent; + if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest; + if ( json.depthTest !== undefined ) material.depthTest = json.depthTest; + if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite; + if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite; + if ( json.wireframe !== undefined ) material.wireframe = json.wireframe; + if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth; + if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap; + if ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin; - if ( json.rotation !== undefined ) material.rotation = json.rotation; + if ( json.rotation !== undefined ) material.rotation = json.rotation; - if ( json.linewidth !== 1 ) material.linewidth = json.linewidth; - if ( json.dashSize !== undefined ) material.dashSize = json.dashSize; - if ( json.gapSize !== undefined ) material.gapSize = json.gapSize; - if ( json.scale !== undefined ) material.scale = json.scale; + if ( json.linewidth !== 1 ) material.linewidth = json.linewidth; + if ( json.dashSize !== undefined ) material.dashSize = json.dashSize; + if ( json.gapSize !== undefined ) material.gapSize = json.gapSize; + if ( json.scale !== undefined ) material.scale = json.scale; - if ( json.polygonOffset !== undefined ) material.polygonOffset = json.polygonOffset; - if ( json.polygonOffsetFactor !== undefined ) material.polygonOffsetFactor = json.polygonOffsetFactor; - if ( json.polygonOffsetUnits !== undefined ) material.polygonOffsetUnits = json.polygonOffsetUnits; + if ( json.polygonOffset !== undefined ) material.polygonOffset = json.polygonOffset; + if ( json.polygonOffsetFactor !== undefined ) material.polygonOffsetFactor = json.polygonOffsetFactor; + if ( json.polygonOffsetUnits !== undefined ) material.polygonOffsetUnits = json.polygonOffsetUnits; - if ( json.skinning !== undefined ) material.skinning = json.skinning; - if ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets; - if ( json.dithering !== undefined ) material.dithering = json.dithering; + if ( json.skinning !== undefined ) material.skinning = json.skinning; + if ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets; + if ( json.dithering !== undefined ) material.dithering = json.dithering; - if ( json.visible !== undefined ) material.visible = json.visible; - if ( json.userData !== undefined ) material.userData = json.userData; + if ( json.visible !== undefined ) material.visible = json.visible; + if ( json.userData !== undefined ) material.userData = json.userData; - // Deprecated + // Deprecated - if ( json.shading !== undefined ) material.flatShading = json.shading === 1; // THREE.FlatShading + if ( json.shading !== undefined ) material.flatShading = json.shading === 1; // THREE.FlatShading - // for PointsMaterial + // for PointsMaterial - if ( json.size !== undefined ) material.size = json.size; - if ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation; + if ( json.size !== undefined ) material.size = json.size; + if ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation; - // maps + // maps - if ( json.map !== undefined ) material.map = getTexture( json.map ); + if ( json.map !== undefined ) material.map = getTexture( json.map ); - if ( json.alphaMap !== undefined ) { + if ( json.alphaMap !== undefined ) { - material.alphaMap = getTexture( json.alphaMap ); - material.transparent = true; + material.alphaMap = getTexture( json.alphaMap ); + material.transparent = true; - } + } - if ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap ); - if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale; + if ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap ); + if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale; - if ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap ); - if ( json.normalMapType !== undefined ) material.normalMapType = json.normalMapType; - if ( json.normalScale !== undefined ) { + if ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap ); + if ( json.normalMapType !== undefined ) material.normalMapType = json.normalMapType; + if ( json.normalScale !== undefined ) { - var normalScale = json.normalScale; + var normalScale = json.normalScale; - if ( Array.isArray( normalScale ) === false ) { + if ( Array.isArray( normalScale ) === false ) { - // Blender exporter used to export a scalar. See #7459 + // Blender exporter used to export a scalar. See #7459 - normalScale = [ normalScale, normalScale ]; + normalScale = [ normalScale, normalScale ]; - } + } - material.normalScale = new Vector2().fromArray( normalScale ); + material.normalScale = new Vector2().fromArray( normalScale ); - } + } - if ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap ); - if ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale; - if ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias; + if ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap ); + if ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale; + if ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias; - if ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap ); - if ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap ); + if ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap ); + if ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap ); - if ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap ); - if ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity; + if ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap ); + if ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity; - if ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap ); + if ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap ); - if ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap ); + if ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap ); - if ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity; + if ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity; - if ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap ); - if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity; + if ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap ); + if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity; - if ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap ); - if ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity; + if ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap ); + if ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity; - if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap ); + if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap ); - return material; + return material; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function BufferGeometryLoader( manager ) { + function BufferGeometryLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - } + } - Object.assign( BufferGeometryLoader.prototype, { + Object.assign( BufferGeometryLoader.prototype, { - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - var scope = this; + var scope = this; - var loader = new FileLoader( scope.manager ); - loader.load( url, function ( text ) { + var loader = new FileLoader( scope.manager ); + loader.load( url, function ( text ) { - onLoad( scope.parse( JSON.parse( text ) ) ); + onLoad( scope.parse( JSON.parse( text ) ) ); - }, onProgress, onError ); + }, onProgress, onError ); - }, + }, - parse: function ( json ) { + parse: function ( json ) { - var geometry = new BufferGeometry(); + var geometry = new BufferGeometry(); - var index = json.data.index; + var index = json.data.index; - if ( index !== undefined ) { + if ( index !== undefined ) { - var typedArray = new TYPED_ARRAYS[ index.type ]( index.array ); - geometry.setIndex( new BufferAttribute( typedArray, 1 ) ); + var typedArray = new TYPED_ARRAYS[ index.type ]( index.array ); + geometry.setIndex( new BufferAttribute( typedArray, 1 ) ); - } + } - var attributes = json.data.attributes; + var attributes = json.data.attributes; - for ( var key in attributes ) { + for ( var key in attributes ) { - var attribute = attributes[ key ]; - var typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array ); + var attribute = attributes[ key ]; + var typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array ); - geometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) ); + geometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) ); - } + } - var groups = json.data.groups || json.data.drawcalls || json.data.offsets; + var groups = json.data.groups || json.data.drawcalls || json.data.offsets; - if ( groups !== undefined ) { + if ( groups !== undefined ) { - for ( var i = 0, n = groups.length; i !== n; ++ i ) { + for ( var i = 0, n = groups.length; i !== n; ++ i ) { - var group = groups[ i ]; + var group = groups[ i ]; - geometry.addGroup( group.start, group.count, group.materialIndex ); + geometry.addGroup( group.start, group.count, group.materialIndex ); - } + } - } + } - var boundingSphere = json.data.boundingSphere; + var boundingSphere = json.data.boundingSphere; - if ( boundingSphere !== undefined ) { + if ( boundingSphere !== undefined ) { - var center = new Vector3(); + var center = new Vector3(); - if ( boundingSphere.center !== undefined ) { + if ( boundingSphere.center !== undefined ) { - center.fromArray( boundingSphere.center ); + center.fromArray( boundingSphere.center ); - } + } - geometry.boundingSphere = new Sphere( center, boundingSphere.radius ); + geometry.boundingSphere = new Sphere( center, boundingSphere.radius ); - } + } - return geometry; + return geometry; - } + } - } ); + } ); - var TYPED_ARRAYS = { - Int8Array: Int8Array, - Uint8Array: Uint8Array, - // Workaround for IE11 pre KB2929437. See #11440 - Uint8ClampedArray: typeof Uint8ClampedArray !== 'undefined' ? Uint8ClampedArray : Uint8Array, - Int16Array: Int16Array, - Uint16Array: Uint16Array, - Int32Array: Int32Array, - Uint32Array: Uint32Array, - Float32Array: Float32Array, - Float64Array: Float64Array - }; + var TYPED_ARRAYS = { + Int8Array: Int8Array, + Uint8Array: Uint8Array, + // Workaround for IE11 pre KB2929437. See #11440 + Uint8ClampedArray: typeof Uint8ClampedArray !== 'undefined' ? Uint8ClampedArray : Uint8Array, + Int16Array: Int16Array, + Uint16Array: Uint16Array, + Int32Array: Int32Array, + Uint32Array: Uint32Array, + Float32Array: Float32Array, + Float64Array: Float64Array + }; - /** - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author alteredq / http://alteredqualia.com/ + */ - function Loader() {} + function Loader() {} - Loader.Handlers = { + Loader.Handlers = { - handlers: [], + handlers: [], - add: function ( regex, loader ) { + add: function ( regex, loader ) { - this.handlers.push( regex, loader ); + this.handlers.push( regex, loader ); - }, + }, - get: function ( file ) { + get: function ( file ) { - var handlers = this.handlers; + var handlers = this.handlers; - for ( var i = 0, l = handlers.length; i < l; i += 2 ) { + for ( var i = 0, l = handlers.length; i < l; i += 2 ) { - var regex = handlers[ i ]; - var loader = handlers[ i + 1 ]; + var regex = handlers[ i ]; + var loader = handlers[ i + 1 ]; - if ( regex.test( file ) ) { + if ( regex.test( file ) ) { - return loader; + return loader; - } + } - } + } - return null; + return null; - } + } - }; + }; - Object.assign( Loader.prototype, { + Object.assign( Loader.prototype, { - crossOrigin: 'anonymous', + crossOrigin: 'anonymous', - onLoadStart: function () {}, + onLoadStart: function () {}, - onLoadProgress: function () {}, + onLoadProgress: function () {}, - onLoadComplete: function () {}, + onLoadComplete: function () {}, - initMaterials: function ( materials, texturePath, crossOrigin ) { + initMaterials: function ( materials, texturePath, crossOrigin ) { - var array = []; + var array = []; - for ( var i = 0; i < materials.length; ++ i ) { + for ( var i = 0; i < materials.length; ++ i ) { - array[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin ); + array[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin ); - } + } - return array; + return array; - }, + }, - createMaterial: ( function () { + createMaterial: ( function () { - var BlendingMode = { - NoBlending: NoBlending, - NormalBlending: NormalBlending, - AdditiveBlending: AdditiveBlending, - SubtractiveBlending: SubtractiveBlending, - MultiplyBlending: MultiplyBlending, - CustomBlending: CustomBlending - }; + var BlendingMode = { + NoBlending: NoBlending, + NormalBlending: NormalBlending, + AdditiveBlending: AdditiveBlending, + SubtractiveBlending: SubtractiveBlending, + MultiplyBlending: MultiplyBlending, + CustomBlending: CustomBlending + }; - var color = new Color(); - var textureLoader = new TextureLoader(); - var materialLoader = new MaterialLoader(); + var color = new Color(); + var textureLoader = new TextureLoader(); + var materialLoader = new MaterialLoader(); - return function createMaterial( m, texturePath, crossOrigin ) { + return function createMaterial( m, texturePath, crossOrigin ) { - // convert from old material format + // convert from old material format - var textures = {}; + var textures = {}; - function loadTexture( path, repeat, offset, wrap, anisotropy ) { + function loadTexture( path, repeat, offset, wrap, anisotropy ) { - var fullPath = texturePath + path; - var loader = Loader.Handlers.get( fullPath ); + var fullPath = texturePath + path; + var loader = Loader.Handlers.get( fullPath ); - var texture; + var texture; - if ( loader !== null ) { + if ( loader !== null ) { - texture = loader.load( fullPath ); + texture = loader.load( fullPath ); - } else { + } else { - textureLoader.setCrossOrigin( crossOrigin ); - texture = textureLoader.load( fullPath ); + textureLoader.setCrossOrigin( crossOrigin ); + texture = textureLoader.load( fullPath ); - } + } - if ( repeat !== undefined ) { + if ( repeat !== undefined ) { - texture.repeat.fromArray( repeat ); + texture.repeat.fromArray( repeat ); - if ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping; - if ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping; + if ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping; + if ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping; - } + } - if ( offset !== undefined ) { + if ( offset !== undefined ) { - texture.offset.fromArray( offset ); + texture.offset.fromArray( offset ); - } + } - if ( wrap !== undefined ) { + if ( wrap !== undefined ) { - if ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping; - if ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping; + if ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping; + if ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping; - if ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping; - if ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping; + if ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping; + if ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping; - } + } - if ( anisotropy !== undefined ) { + if ( anisotropy !== undefined ) { - texture.anisotropy = anisotropy; + texture.anisotropy = anisotropy; - } + } - var uuid = _Math.generateUUID(); + var uuid = _Math.generateUUID(); - textures[ uuid ] = texture; + textures[ uuid ] = texture; - return uuid; + return uuid; - } - - // - - var json = { - uuid: _Math.generateUUID(), - type: 'MeshLambertMaterial' - }; - - for ( var name in m ) { - - var value = m[ name ]; - - switch ( name ) { - - case 'DbgColor': - case 'DbgIndex': - case 'opticalDensity': - case 'illumination': - break; - case 'DbgName': - json.name = value; - break; - case 'blending': - json.blending = BlendingMode[ value ]; - break; - case 'colorAmbient': - case 'mapAmbient': - console.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' ); - break; - case 'colorDiffuse': - json.color = color.fromArray( value ).getHex(); - break; - case 'colorSpecular': - json.specular = color.fromArray( value ).getHex(); - break; - case 'colorEmissive': - json.emissive = color.fromArray( value ).getHex(); - break; - case 'specularCoef': - json.shininess = value; - break; - case 'shading': - if ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial'; - if ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial'; - if ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial'; - break; - case 'mapDiffuse': - json.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy ); - break; - case 'mapDiffuseRepeat': - case 'mapDiffuseOffset': - case 'mapDiffuseWrap': - case 'mapDiffuseAnisotropy': - break; - case 'mapEmissive': - json.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy ); - break; - case 'mapEmissiveRepeat': - case 'mapEmissiveOffset': - case 'mapEmissiveWrap': - case 'mapEmissiveAnisotropy': - break; - case 'mapLight': - json.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy ); - break; - case 'mapLightRepeat': - case 'mapLightOffset': - case 'mapLightWrap': - case 'mapLightAnisotropy': - break; - case 'mapAO': - json.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy ); - break; - case 'mapAORepeat': - case 'mapAOOffset': - case 'mapAOWrap': - case 'mapAOAnisotropy': - break; - case 'mapBump': - json.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy ); - break; - case 'mapBumpScale': - json.bumpScale = value; - break; - case 'mapBumpRepeat': - case 'mapBumpOffset': - case 'mapBumpWrap': - case 'mapBumpAnisotropy': - break; - case 'mapNormal': - json.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy ); - break; - case 'mapNormalFactor': - json.normalScale = value; - break; - case 'mapNormalRepeat': - case 'mapNormalOffset': - case 'mapNormalWrap': - case 'mapNormalAnisotropy': - break; - case 'mapSpecular': - json.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy ); - break; - case 'mapSpecularRepeat': - case 'mapSpecularOffset': - case 'mapSpecularWrap': - case 'mapSpecularAnisotropy': - break; - case 'mapMetalness': - json.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy ); - break; - case 'mapMetalnessRepeat': - case 'mapMetalnessOffset': - case 'mapMetalnessWrap': - case 'mapMetalnessAnisotropy': - break; - case 'mapRoughness': - json.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy ); - break; - case 'mapRoughnessRepeat': - case 'mapRoughnessOffset': - case 'mapRoughnessWrap': - case 'mapRoughnessAnisotropy': - break; - case 'mapAlpha': - json.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy ); - break; - case 'mapAlphaRepeat': - case 'mapAlphaOffset': - case 'mapAlphaWrap': - case 'mapAlphaAnisotropy': - break; - case 'flipSided': - json.side = BackSide; - break; - case 'doubleSided': - json.side = DoubleSide; - break; - case 'transparency': - console.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' ); - json.opacity = value; - break; - case 'depthTest': - case 'depthWrite': - case 'colorWrite': - case 'opacity': - case 'reflectivity': - case 'transparent': - case 'visible': - case 'wireframe': - json[ name ] = value; - break; - case 'vertexColors': - if ( value === true ) json.vertexColors = VertexColors; - if ( value === 'face' ) json.vertexColors = FaceColors; - break; - default: - console.error( 'THREE.Loader.createMaterial: Unsupported', name, value ); - break; - - } - - } - - if ( json.type === 'MeshBasicMaterial' ) delete json.emissive; - if ( json.type !== 'MeshPhongMaterial' ) delete json.specular; - - if ( json.opacity < 1 ) json.transparent = true; - - materialLoader.setTextures( textures ); - - return materialLoader.parse( json ); + } + + // + + var json = { + uuid: _Math.generateUUID(), + type: 'MeshLambertMaterial' + }; + + for ( var name in m ) { + + var value = m[ name ]; + + switch ( name ) { + + case 'DbgColor': + case 'DbgIndex': + case 'opticalDensity': + case 'illumination': + break; + case 'DbgName': + json.name = value; + break; + case 'blending': + json.blending = BlendingMode[ value ]; + break; + case 'colorAmbient': + case 'mapAmbient': + console.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' ); + break; + case 'colorDiffuse': + json.color = color.fromArray( value ).getHex(); + break; + case 'colorSpecular': + json.specular = color.fromArray( value ).getHex(); + break; + case 'colorEmissive': + json.emissive = color.fromArray( value ).getHex(); + break; + case 'specularCoef': + json.shininess = value; + break; + case 'shading': + if ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial'; + if ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial'; + if ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial'; + break; + case 'mapDiffuse': + json.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy ); + break; + case 'mapDiffuseRepeat': + case 'mapDiffuseOffset': + case 'mapDiffuseWrap': + case 'mapDiffuseAnisotropy': + break; + case 'mapEmissive': + json.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy ); + break; + case 'mapEmissiveRepeat': + case 'mapEmissiveOffset': + case 'mapEmissiveWrap': + case 'mapEmissiveAnisotropy': + break; + case 'mapLight': + json.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy ); + break; + case 'mapLightRepeat': + case 'mapLightOffset': + case 'mapLightWrap': + case 'mapLightAnisotropy': + break; + case 'mapAO': + json.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy ); + break; + case 'mapAORepeat': + case 'mapAOOffset': + case 'mapAOWrap': + case 'mapAOAnisotropy': + break; + case 'mapBump': + json.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy ); + break; + case 'mapBumpScale': + json.bumpScale = value; + break; + case 'mapBumpRepeat': + case 'mapBumpOffset': + case 'mapBumpWrap': + case 'mapBumpAnisotropy': + break; + case 'mapNormal': + json.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy ); + break; + case 'mapNormalFactor': + json.normalScale = value; + break; + case 'mapNormalRepeat': + case 'mapNormalOffset': + case 'mapNormalWrap': + case 'mapNormalAnisotropy': + break; + case 'mapSpecular': + json.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy ); + break; + case 'mapSpecularRepeat': + case 'mapSpecularOffset': + case 'mapSpecularWrap': + case 'mapSpecularAnisotropy': + break; + case 'mapMetalness': + json.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy ); + break; + case 'mapMetalnessRepeat': + case 'mapMetalnessOffset': + case 'mapMetalnessWrap': + case 'mapMetalnessAnisotropy': + break; + case 'mapRoughness': + json.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy ); + break; + case 'mapRoughnessRepeat': + case 'mapRoughnessOffset': + case 'mapRoughnessWrap': + case 'mapRoughnessAnisotropy': + break; + case 'mapAlpha': + json.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy ); + break; + case 'mapAlphaRepeat': + case 'mapAlphaOffset': + case 'mapAlphaWrap': + case 'mapAlphaAnisotropy': + break; + case 'flipSided': + json.side = BackSide; + break; + case 'doubleSided': + json.side = DoubleSide; + break; + case 'transparency': + console.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' ); + json.opacity = value; + break; + case 'depthTest': + case 'depthWrite': + case 'colorWrite': + case 'opacity': + case 'reflectivity': + case 'transparent': + case 'visible': + case 'wireframe': + json[ name ] = value; + break; + case 'vertexColors': + if ( value === true ) json.vertexColors = VertexColors; + if ( value === 'face' ) json.vertexColors = FaceColors; + break; + default: + console.error( 'THREE.Loader.createMaterial: Unsupported', name, value ); + break; + + } + + } + + if ( json.type === 'MeshBasicMaterial' ) delete json.emissive; + if ( json.type !== 'MeshPhongMaterial' ) delete json.specular; + + if ( json.opacity < 1 ) json.transparent = true; + + materialLoader.setTextures( textures ); + + return materialLoader.parse( json ); - }; + }; - } )() + } )() - } ); + } ); - /** - * @author Don McCurdy / https://www.donmccurdy.com - */ + /** + * @author Don McCurdy / https://www.donmccurdy.com + */ - var LoaderUtils = { + var LoaderUtils = { - decodeText: function ( array ) { + decodeText: function ( array ) { - if ( typeof TextDecoder !== 'undefined' ) { + if ( typeof TextDecoder !== 'undefined' ) { - return new TextDecoder().decode( array ); + return new TextDecoder().decode( array ); - } + } - // Avoid the String.fromCharCode.apply(null, array) shortcut, which - // throws a "maximum call stack size exceeded" error for large arrays. + // Avoid the String.fromCharCode.apply(null, array) shortcut, which + // throws a "maximum call stack size exceeded" error for large arrays. - var s = ''; + var s = ''; - for ( var i = 0, il = array.length; i < il; i ++ ) { + for ( var i = 0, il = array.length; i < il; i ++ ) { - // Implicitly assumes little-endian. - s += String.fromCharCode( array[ i ] ); + // Implicitly assumes little-endian. + s += String.fromCharCode( array[ i ] ); - } + } - // Merges multi-byte utf-8 characters. - return decodeURIComponent( escape( s ) ); + // Merges multi-byte utf-8 characters. + return decodeURIComponent( escape( s ) ); - }, + }, - extractUrlBase: function ( url ) { + extractUrlBase: function ( url ) { - var index = url.lastIndexOf( '/' ); + var index = url.lastIndexOf( '/' ); - if ( index === - 1 ) return './'; + if ( index === - 1 ) return './'; - return url.substr( 0, index + 1 ); + return url.substr( 0, index + 1 ); - } + } - }; + }; - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + */ - function JSONLoader( manager ) { + function JSONLoader( manager ) { - if ( typeof manager === 'boolean' ) { + if ( typeof manager === 'boolean' ) { - console.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' ); - manager = undefined; + console.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' ); + manager = undefined; - } + } - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - this.withCredentials = false; + this.withCredentials = false; - } + } - Object.assign( JSONLoader.prototype, { + Object.assign( JSONLoader.prototype, { - crossOrigin: 'anonymous', + crossOrigin: 'anonymous', - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - var scope = this; + var scope = this; - var texturePath = this.texturePath && ( typeof this.texturePath === 'string' ) ? this.texturePath : LoaderUtils.extractUrlBase( url ); + var texturePath = this.texturePath && ( typeof this.texturePath === 'string' ) ? this.texturePath : LoaderUtils.extractUrlBase( url ); - var loader = new FileLoader( this.manager ); - loader.setWithCredentials( this.withCredentials ); - loader.load( url, function ( text ) { + var loader = new FileLoader( this.manager ); + loader.setWithCredentials( this.withCredentials ); + loader.load( url, function ( text ) { - var json = JSON.parse( text ); - var metadata = json.metadata; + var json = JSON.parse( text ); + var metadata = json.metadata; - if ( metadata !== undefined ) { + if ( metadata !== undefined ) { - var type = metadata.type; + var type = metadata.type; - if ( type !== undefined ) { + if ( type !== undefined ) { - if ( type.toLowerCase() === 'object' ) { + if ( type.toLowerCase() === 'object' ) { - console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' ); - return; + console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' ); + return; - } + } - } + } - } + } - var object = scope.parse( json, texturePath ); - onLoad( object.geometry, object.materials ); + var object = scope.parse( json, texturePath ); + onLoad( object.geometry, object.materials ); - }, onProgress, onError ); + }, onProgress, onError ); - }, + }, - setCrossOrigin: function ( value ) { + setCrossOrigin: function ( value ) { - this.crossOrigin = value; - return this; + this.crossOrigin = value; + return this; - }, + }, - setTexturePath: function ( value ) { + setTexturePath: function ( value ) { - this.texturePath = value; - return this; + this.texturePath = value; + return this; - }, + }, - parse: ( function () { + parse: ( function () { - function parseModel( json, geometry ) { + function parseModel( json, geometry ) { - function isBitSet( value, position ) { + function isBitSet( value, position ) { - return value & ( 1 << position ); + return value & ( 1 << position ); - } + } - var i, j, fi, + var i, j, fi, - offset, zLength, + offset, zLength, - colorIndex, normalIndex, uvIndex, materialIndex, + colorIndex, normalIndex, uvIndex, materialIndex, - type, - isQuad, - hasMaterial, - hasFaceVertexUv, - hasFaceNormal, hasFaceVertexNormal, - hasFaceColor, hasFaceVertexColor, + type, + isQuad, + hasMaterial, + hasFaceVertexUv, + hasFaceNormal, hasFaceVertexNormal, + hasFaceColor, hasFaceVertexColor, - vertex, face, faceA, faceB, hex, normal, + vertex, face, faceA, faceB, hex, normal, - uvLayer, uv, u, v, + uvLayer, uv, u, v, - faces = json.faces, - vertices = json.vertices, - normals = json.normals, - colors = json.colors, + faces = json.faces, + vertices = json.vertices, + normals = json.normals, + colors = json.colors, - scale = json.scale, + scale = json.scale, - nUvLayers = 0; + nUvLayers = 0; - if ( json.uvs !== undefined ) { + if ( json.uvs !== undefined ) { - // disregard empty arrays + // disregard empty arrays - for ( i = 0; i < json.uvs.length; i ++ ) { + for ( i = 0; i < json.uvs.length; i ++ ) { - if ( json.uvs[ i ].length ) nUvLayers ++; + if ( json.uvs[ i ].length ) nUvLayers ++; - } + } - for ( i = 0; i < nUvLayers; i ++ ) { + for ( i = 0; i < nUvLayers; i ++ ) { - geometry.faceVertexUvs[ i ] = []; + geometry.faceVertexUvs[ i ] = []; - } + } - } + } - offset = 0; - zLength = vertices.length; + offset = 0; + zLength = vertices.length; - while ( offset < zLength ) { + while ( offset < zLength ) { - vertex = new Vector3(); + vertex = new Vector3(); - vertex.x = vertices[ offset ++ ] * scale; - vertex.y = vertices[ offset ++ ] * scale; - vertex.z = vertices[ offset ++ ] * scale; + vertex.x = vertices[ offset ++ ] * scale; + vertex.y = vertices[ offset ++ ] * scale; + vertex.z = vertices[ offset ++ ] * scale; - geometry.vertices.push( vertex ); + geometry.vertices.push( vertex ); - } + } - offset = 0; - zLength = faces.length; + offset = 0; + zLength = faces.length; - while ( offset < zLength ) { + while ( offset < zLength ) { - type = faces[ offset ++ ]; + type = faces[ offset ++ ]; - isQuad = isBitSet( type, 0 ); - hasMaterial = isBitSet( type, 1 ); - hasFaceVertexUv = isBitSet( type, 3 ); - hasFaceNormal = isBitSet( type, 4 ); - hasFaceVertexNormal = isBitSet( type, 5 ); - hasFaceColor = isBitSet( type, 6 ); - hasFaceVertexColor = isBitSet( type, 7 ); + isQuad = isBitSet( type, 0 ); + hasMaterial = isBitSet( type, 1 ); + hasFaceVertexUv = isBitSet( type, 3 ); + hasFaceNormal = isBitSet( type, 4 ); + hasFaceVertexNormal = isBitSet( type, 5 ); + hasFaceColor = isBitSet( type, 6 ); + hasFaceVertexColor = isBitSet( type, 7 ); - // console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor); + // console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor); - if ( isQuad ) { + if ( isQuad ) { - faceA = new Face3(); - faceA.a = faces[ offset ]; - faceA.b = faces[ offset + 1 ]; - faceA.c = faces[ offset + 3 ]; + faceA = new Face3(); + faceA.a = faces[ offset ]; + faceA.b = faces[ offset + 1 ]; + faceA.c = faces[ offset + 3 ]; - faceB = new Face3(); - faceB.a = faces[ offset + 1 ]; - faceB.b = faces[ offset + 2 ]; - faceB.c = faces[ offset + 3 ]; + faceB = new Face3(); + faceB.a = faces[ offset + 1 ]; + faceB.b = faces[ offset + 2 ]; + faceB.c = faces[ offset + 3 ]; - offset += 4; + offset += 4; - if ( hasMaterial ) { + if ( hasMaterial ) { - materialIndex = faces[ offset ++ ]; - faceA.materialIndex = materialIndex; - faceB.materialIndex = materialIndex; + materialIndex = faces[ offset ++ ]; + faceA.materialIndex = materialIndex; + faceB.materialIndex = materialIndex; - } + } - // to get face <=> uv index correspondence + // to get face <=> uv index correspondence - fi = geometry.faces.length; + fi = geometry.faces.length; - if ( hasFaceVertexUv ) { + if ( hasFaceVertexUv ) { - for ( i = 0; i < nUvLayers; i ++ ) { + for ( i = 0; i < nUvLayers; i ++ ) { - uvLayer = json.uvs[ i ]; + uvLayer = json.uvs[ i ]; - geometry.faceVertexUvs[ i ][ fi ] = []; - geometry.faceVertexUvs[ i ][ fi + 1 ] = []; + geometry.faceVertexUvs[ i ][ fi ] = []; + geometry.faceVertexUvs[ i ][ fi + 1 ] = []; - for ( j = 0; j < 4; j ++ ) { + for ( j = 0; j < 4; j ++ ) { - uvIndex = faces[ offset ++ ]; + uvIndex = faces[ offset ++ ]; - u = uvLayer[ uvIndex * 2 ]; - v = uvLayer[ uvIndex * 2 + 1 ]; + u = uvLayer[ uvIndex * 2 ]; + v = uvLayer[ uvIndex * 2 + 1 ]; - uv = new Vector2( u, v ); + uv = new Vector2( u, v ); - if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv ); - if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv ); + if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv ); + if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv ); - } + } - } + } - } + } - if ( hasFaceNormal ) { + if ( hasFaceNormal ) { - normalIndex = faces[ offset ++ ] * 3; + normalIndex = faces[ offset ++ ] * 3; - faceA.normal.set( - normals[ normalIndex ++ ], - normals[ normalIndex ++ ], - normals[ normalIndex ] - ); + faceA.normal.set( + normals[ normalIndex ++ ], + normals[ normalIndex ++ ], + normals[ normalIndex ] + ); - faceB.normal.copy( faceA.normal ); + faceB.normal.copy( faceA.normal ); - } + } - if ( hasFaceVertexNormal ) { + if ( hasFaceVertexNormal ) { - for ( i = 0; i < 4; i ++ ) { + for ( i = 0; i < 4; i ++ ) { - normalIndex = faces[ offset ++ ] * 3; + normalIndex = faces[ offset ++ ] * 3; - normal = new Vector3( - normals[ normalIndex ++ ], - normals[ normalIndex ++ ], - normals[ normalIndex ] - ); + normal = new Vector3( + normals[ normalIndex ++ ], + normals[ normalIndex ++ ], + normals[ normalIndex ] + ); - if ( i !== 2 ) faceA.vertexNormals.push( normal ); - if ( i !== 0 ) faceB.vertexNormals.push( normal ); + if ( i !== 2 ) faceA.vertexNormals.push( normal ); + if ( i !== 0 ) faceB.vertexNormals.push( normal ); - } + } - } + } - if ( hasFaceColor ) { + if ( hasFaceColor ) { - colorIndex = faces[ offset ++ ]; - hex = colors[ colorIndex ]; + colorIndex = faces[ offset ++ ]; + hex = colors[ colorIndex ]; - faceA.color.setHex( hex ); - faceB.color.setHex( hex ); + faceA.color.setHex( hex ); + faceB.color.setHex( hex ); - } + } - if ( hasFaceVertexColor ) { + if ( hasFaceVertexColor ) { - for ( i = 0; i < 4; i ++ ) { + for ( i = 0; i < 4; i ++ ) { - colorIndex = faces[ offset ++ ]; - hex = colors[ colorIndex ]; + colorIndex = faces[ offset ++ ]; + hex = colors[ colorIndex ]; - if ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) ); - if ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) ); + if ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) ); + if ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) ); - } + } - } + } - geometry.faces.push( faceA ); - geometry.faces.push( faceB ); + geometry.faces.push( faceA ); + geometry.faces.push( faceB ); - } else { + } else { - face = new Face3(); - face.a = faces[ offset ++ ]; - face.b = faces[ offset ++ ]; - face.c = faces[ offset ++ ]; + face = new Face3(); + face.a = faces[ offset ++ ]; + face.b = faces[ offset ++ ]; + face.c = faces[ offset ++ ]; - if ( hasMaterial ) { + if ( hasMaterial ) { - materialIndex = faces[ offset ++ ]; - face.materialIndex = materialIndex; + materialIndex = faces[ offset ++ ]; + face.materialIndex = materialIndex; - } + } - // to get face <=> uv index correspondence + // to get face <=> uv index correspondence - fi = geometry.faces.length; + fi = geometry.faces.length; - if ( hasFaceVertexUv ) { + if ( hasFaceVertexUv ) { - for ( i = 0; i < nUvLayers; i ++ ) { + for ( i = 0; i < nUvLayers; i ++ ) { - uvLayer = json.uvs[ i ]; + uvLayer = json.uvs[ i ]; - geometry.faceVertexUvs[ i ][ fi ] = []; + geometry.faceVertexUvs[ i ][ fi ] = []; - for ( j = 0; j < 3; j ++ ) { + for ( j = 0; j < 3; j ++ ) { - uvIndex = faces[ offset ++ ]; + uvIndex = faces[ offset ++ ]; - u = uvLayer[ uvIndex * 2 ]; - v = uvLayer[ uvIndex * 2 + 1 ]; + u = uvLayer[ uvIndex * 2 ]; + v = uvLayer[ uvIndex * 2 + 1 ]; - uv = new Vector2( u, v ); + uv = new Vector2( u, v ); - geometry.faceVertexUvs[ i ][ fi ].push( uv ); + geometry.faceVertexUvs[ i ][ fi ].push( uv ); - } + } - } + } - } + } - if ( hasFaceNormal ) { + if ( hasFaceNormal ) { - normalIndex = faces[ offset ++ ] * 3; + normalIndex = faces[ offset ++ ] * 3; - face.normal.set( - normals[ normalIndex ++ ], - normals[ normalIndex ++ ], - normals[ normalIndex ] - ); + face.normal.set( + normals[ normalIndex ++ ], + normals[ normalIndex ++ ], + normals[ normalIndex ] + ); - } + } - if ( hasFaceVertexNormal ) { + if ( hasFaceVertexNormal ) { - for ( i = 0; i < 3; i ++ ) { + for ( i = 0; i < 3; i ++ ) { - normalIndex = faces[ offset ++ ] * 3; + normalIndex = faces[ offset ++ ] * 3; - normal = new Vector3( - normals[ normalIndex ++ ], - normals[ normalIndex ++ ], - normals[ normalIndex ] - ); + normal = new Vector3( + normals[ normalIndex ++ ], + normals[ normalIndex ++ ], + normals[ normalIndex ] + ); - face.vertexNormals.push( normal ); + face.vertexNormals.push( normal ); - } + } - } + } - if ( hasFaceColor ) { + if ( hasFaceColor ) { - colorIndex = faces[ offset ++ ]; - face.color.setHex( colors[ colorIndex ] ); + colorIndex = faces[ offset ++ ]; + face.color.setHex( colors[ colorIndex ] ); - } + } - if ( hasFaceVertexColor ) { + if ( hasFaceVertexColor ) { - for ( i = 0; i < 3; i ++ ) { + for ( i = 0; i < 3; i ++ ) { - colorIndex = faces[ offset ++ ]; - face.vertexColors.push( new Color( colors[ colorIndex ] ) ); + colorIndex = faces[ offset ++ ]; + face.vertexColors.push( new Color( colors[ colorIndex ] ) ); - } + } - } + } - geometry.faces.push( face ); + geometry.faces.push( face ); - } + } - } + } - } + } - function parseSkin( json, geometry ) { + function parseSkin( json, geometry ) { - var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2; + var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2; - if ( json.skinWeights ) { + if ( json.skinWeights ) { - for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) { + for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) { - var x = json.skinWeights[ i ]; - var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0; - var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0; - var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0; + var x = json.skinWeights[ i ]; + var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0; + var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0; + var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0; - geometry.skinWeights.push( new Vector4( x, y, z, w ) ); + geometry.skinWeights.push( new Vector4( x, y, z, w ) ); - } + } - } + } - if ( json.skinIndices ) { + if ( json.skinIndices ) { - for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) { + for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) { - var a = json.skinIndices[ i ]; - var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0; - var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0; - var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0; + var a = json.skinIndices[ i ]; + var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0; + var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0; + var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0; - geometry.skinIndices.push( new Vector4( a, b, c, d ) ); + geometry.skinIndices.push( new Vector4( a, b, c, d ) ); - } + } - } + } - geometry.bones = json.bones; + geometry.bones = json.bones; - if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) { + if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) { - console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + - geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' ); + console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + + geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' ); - } + } - } + } - function parseMorphing( json, geometry ) { + function parseMorphing( json, geometry ) { - var scale = json.scale; + var scale = json.scale; - if ( json.morphTargets !== undefined ) { + if ( json.morphTargets !== undefined ) { - for ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) { + for ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) { - geometry.morphTargets[ i ] = {}; - geometry.morphTargets[ i ].name = json.morphTargets[ i ].name; - geometry.morphTargets[ i ].vertices = []; + geometry.morphTargets[ i ] = {}; + geometry.morphTargets[ i ].name = json.morphTargets[ i ].name; + geometry.morphTargets[ i ].vertices = []; - var dstVertices = geometry.morphTargets[ i ].vertices; - var srcVertices = json.morphTargets[ i ].vertices; + var dstVertices = geometry.morphTargets[ i ].vertices; + var srcVertices = json.morphTargets[ i ].vertices; - for ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) { + for ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) { - var vertex = new Vector3(); - vertex.x = srcVertices[ v ] * scale; - vertex.y = srcVertices[ v + 1 ] * scale; - vertex.z = srcVertices[ v + 2 ] * scale; + var vertex = new Vector3(); + vertex.x = srcVertices[ v ] * scale; + vertex.y = srcVertices[ v + 1 ] * scale; + vertex.z = srcVertices[ v + 2 ] * scale; - dstVertices.push( vertex ); + dstVertices.push( vertex ); - } + } - } + } - } + } - if ( json.morphColors !== undefined && json.morphColors.length > 0 ) { + if ( json.morphColors !== undefined && json.morphColors.length > 0 ) { - console.warn( 'THREE.JSONLoader: "morphColors" no longer supported. Using them as face colors.' ); + console.warn( 'THREE.JSONLoader: "morphColors" no longer supported. Using them as face colors.' ); - var faces = geometry.faces; - var morphColors = json.morphColors[ 0 ].colors; + var faces = geometry.faces; + var morphColors = json.morphColors[ 0 ].colors; - for ( var i = 0, l = faces.length; i < l; i ++ ) { + for ( var i = 0, l = faces.length; i < l; i ++ ) { - faces[ i ].color.fromArray( morphColors, i * 3 ); + faces[ i ].color.fromArray( morphColors, i * 3 ); - } + } - } + } - } + } - function parseAnimations( json, geometry ) { + function parseAnimations( json, geometry ) { - var outputAnimations = []; + var outputAnimations = []; - // parse old style Bone/Hierarchy animations - var animations = []; + // parse old style Bone/Hierarchy animations + var animations = []; - if ( json.animation !== undefined ) { + if ( json.animation !== undefined ) { - animations.push( json.animation ); + animations.push( json.animation ); - } + } - if ( json.animations !== undefined ) { + if ( json.animations !== undefined ) { - if ( json.animations.length ) { + if ( json.animations.length ) { - animations = animations.concat( json.animations ); + animations = animations.concat( json.animations ); - } else { + } else { - animations.push( json.animations ); + animations.push( json.animations ); - } + } - } + } - for ( var i = 0; i < animations.length; i ++ ) { + for ( var i = 0; i < animations.length; i ++ ) { - var clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones ); - if ( clip ) outputAnimations.push( clip ); + var clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones ); + if ( clip ) outputAnimations.push( clip ); - } + } - // parse implicit morph animations - if ( geometry.morphTargets ) { + // parse implicit morph animations + if ( geometry.morphTargets ) { - // TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary. - var morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 ); - outputAnimations = outputAnimations.concat( morphAnimationClips ); + // TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary. + var morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 ); + outputAnimations = outputAnimations.concat( morphAnimationClips ); - } + } - if ( outputAnimations.length > 0 ) geometry.animations = outputAnimations; + if ( outputAnimations.length > 0 ) geometry.animations = outputAnimations; - } + } - return function parse( json, texturePath ) { + return function parse( json, texturePath ) { - if ( json.data !== undefined ) { + if ( json.data !== undefined ) { - // Geometry 4.0 spec - json = json.data; + // Geometry 4.0 spec + json = json.data; - } + } - if ( json.scale !== undefined ) { + if ( json.scale !== undefined ) { - json.scale = 1.0 / json.scale; + json.scale = 1.0 / json.scale; - } else { + } else { - json.scale = 1.0; + json.scale = 1.0; - } + } - var geometry = new Geometry(); + var geometry = new Geometry(); - parseModel( json, geometry ); - parseSkin( json, geometry ); - parseMorphing( json, geometry ); - parseAnimations( json, geometry ); + parseModel( json, geometry ); + parseSkin( json, geometry ); + parseMorphing( json, geometry ); + parseAnimations( json, geometry ); - geometry.computeFaceNormals(); - geometry.computeBoundingSphere(); + geometry.computeFaceNormals(); + geometry.computeBoundingSphere(); - if ( json.materials === undefined || json.materials.length === 0 ) { + if ( json.materials === undefined || json.materials.length === 0 ) { - return { geometry: geometry }; + return { geometry: geometry }; - } else { + } else { - var materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin ); + var materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin ); - return { geometry: geometry, materials: materials }; + return { geometry: geometry, materials: materials }; - } + } - }; + }; - } )() + } )() - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function ObjectLoader( manager ) { + function ObjectLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - this.texturePath = ''; + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + this.texturePath = ''; - } + } - Object.assign( ObjectLoader.prototype, { + Object.assign( ObjectLoader.prototype, { - crossOrigin: 'anonymous', + crossOrigin: 'anonymous', - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - if ( this.texturePath === '' ) { + if ( this.texturePath === '' ) { - this.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 ); + this.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 ); - } + } - var scope = this; + var scope = this; - var loader = new FileLoader( scope.manager ); - loader.load( url, function ( text ) { + var loader = new FileLoader( scope.manager ); + loader.load( url, function ( text ) { - var json = null; + var json = null; - try { + try { - json = JSON.parse( text ); + json = JSON.parse( text ); - } catch ( error ) { + } catch ( error ) { - if ( onError !== undefined ) onError( error ); + if ( onError !== undefined ) onError( error ); - console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message ); + console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message ); - return; + return; - } + } - var metadata = json.metadata; + var metadata = json.metadata; - if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) { + if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) { - console.error( 'THREE.ObjectLoader: Can\'t load ' + url + '. Use THREE.JSONLoader instead.' ); - return; + console.error( 'THREE.ObjectLoader: Can\'t load ' + url + '. Use THREE.JSONLoader instead.' ); + return; - } + } - scope.parse( json, onLoad ); + scope.parse( json, onLoad ); - }, onProgress, onError ); + }, onProgress, onError ); - }, + }, - setTexturePath: function ( value ) { + setTexturePath: function ( value ) { - this.texturePath = value; - return this; + this.texturePath = value; + return this; - }, + }, - setCrossOrigin: function ( value ) { + setCrossOrigin: function ( value ) { - this.crossOrigin = value; - return this; + this.crossOrigin = value; + return this; - }, + }, - parse: function ( json, onLoad ) { + parse: function ( json, onLoad ) { - var shapes = this.parseShape( json.shapes ); - var geometries = this.parseGeometries( json.geometries, shapes ); + var shapes = this.parseShape( json.shapes ); + var geometries = this.parseGeometries( json.geometries, shapes ); - var images = this.parseImages( json.images, function () { + var images = this.parseImages( json.images, function () { - if ( onLoad !== undefined ) onLoad( object ); + if ( onLoad !== undefined ) onLoad( object ); - } ); + } ); - var textures = this.parseTextures( json.textures, images ); - var materials = this.parseMaterials( json.materials, textures ); + var textures = this.parseTextures( json.textures, images ); + var materials = this.parseMaterials( json.materials, textures ); - var object = this.parseObject( json.object, geometries, materials ); + var object = this.parseObject( json.object, geometries, materials ); - if ( json.animations ) { + if ( json.animations ) { - object.animations = this.parseAnimations( json.animations ); + object.animations = this.parseAnimations( json.animations ); - } + } - if ( json.images === undefined || json.images.length === 0 ) { + if ( json.images === undefined || json.images.length === 0 ) { - if ( onLoad !== undefined ) onLoad( object ); + if ( onLoad !== undefined ) onLoad( object ); - } + } - return object; + return object; - }, + }, - parseShape: function ( json ) { + parseShape: function ( json ) { - var shapes = {}; + var shapes = {}; - if ( json !== undefined ) { + if ( json !== undefined ) { - for ( var i = 0, l = json.length; i < l; i ++ ) { + for ( var i = 0, l = json.length; i < l; i ++ ) { - var shape = new Shape().fromJSON( json[ i ] ); + var shape = new Shape().fromJSON( json[ i ] ); - shapes[ shape.uuid ] = shape; + shapes[ shape.uuid ] = shape; - } + } - } + } - return shapes; + return shapes; - }, + }, - parseGeometries: function ( json, shapes ) { + parseGeometries: function ( json, shapes ) { - var geometries = {}; + var geometries = {}; - if ( json !== undefined ) { + if ( json !== undefined ) { - var geometryLoader = new JSONLoader(); - var bufferGeometryLoader = new BufferGeometryLoader(); + var geometryLoader = new JSONLoader(); + var bufferGeometryLoader = new BufferGeometryLoader(); - for ( var i = 0, l = json.length; i < l; i ++ ) { + for ( var i = 0, l = json.length; i < l; i ++ ) { - var geometry; - var data = json[ i ]; + var geometry; + var data = json[ i ]; - switch ( data.type ) { + switch ( data.type ) { - case 'PlaneGeometry': - case 'PlaneBufferGeometry': + case 'PlaneGeometry': + case 'PlaneBufferGeometry': - geometry = new Geometries[ data.type ]( - data.width, - data.height, - data.widthSegments, - data.heightSegments - ); + geometry = new Geometries[ data.type ]( + data.width, + data.height, + data.widthSegments, + data.heightSegments + ); - break; + break; - case 'BoxGeometry': - case 'BoxBufferGeometry': - case 'CubeGeometry': // backwards compatible + case 'BoxGeometry': + case 'BoxBufferGeometry': + case 'CubeGeometry': // backwards compatible - geometry = new Geometries[ data.type ]( - data.width, - data.height, - data.depth, - data.widthSegments, - data.heightSegments, - data.depthSegments - ); + geometry = new Geometries[ data.type ]( + data.width, + data.height, + data.depth, + data.widthSegments, + data.heightSegments, + data.depthSegments + ); - break; + break; - case 'CircleGeometry': - case 'CircleBufferGeometry': + case 'CircleGeometry': + case 'CircleBufferGeometry': - geometry = new Geometries[ data.type ]( - data.radius, - data.segments, - data.thetaStart, - data.thetaLength - ); + geometry = new Geometries[ data.type ]( + data.radius, + data.segments, + data.thetaStart, + data.thetaLength + ); - break; + break; - case 'CylinderGeometry': - case 'CylinderBufferGeometry': + case 'CylinderGeometry': + case 'CylinderBufferGeometry': - geometry = new Geometries[ data.type ]( - data.radiusTop, - data.radiusBottom, - data.height, - data.radialSegments, - data.heightSegments, - data.openEnded, - data.thetaStart, - data.thetaLength - ); + geometry = new Geometries[ data.type ]( + data.radiusTop, + data.radiusBottom, + data.height, + data.radialSegments, + data.heightSegments, + data.openEnded, + data.thetaStart, + data.thetaLength + ); - break; + break; - case 'ConeGeometry': - case 'ConeBufferGeometry': + case 'ConeGeometry': + case 'ConeBufferGeometry': - geometry = new Geometries[ data.type ]( - data.radius, - data.height, - data.radialSegments, - data.heightSegments, - data.openEnded, - data.thetaStart, - data.thetaLength - ); + geometry = new Geometries[ data.type ]( + data.radius, + data.height, + data.radialSegments, + data.heightSegments, + data.openEnded, + data.thetaStart, + data.thetaLength + ); - break; + break; - case 'SphereGeometry': - case 'SphereBufferGeometry': + case 'SphereGeometry': + case 'SphereBufferGeometry': - geometry = new Geometries[ data.type ]( - data.radius, - data.widthSegments, - data.heightSegments, - data.phiStart, - data.phiLength, - data.thetaStart, - data.thetaLength - ); + geometry = new Geometries[ data.type ]( + data.radius, + data.widthSegments, + data.heightSegments, + data.phiStart, + data.phiLength, + data.thetaStart, + data.thetaLength + ); - break; + break; - case 'DodecahedronGeometry': - case 'DodecahedronBufferGeometry': - case 'IcosahedronGeometry': - case 'IcosahedronBufferGeometry': - case 'OctahedronGeometry': - case 'OctahedronBufferGeometry': - case 'TetrahedronGeometry': - case 'TetrahedronBufferGeometry': + case 'DodecahedronGeometry': + case 'DodecahedronBufferGeometry': + case 'IcosahedronGeometry': + case 'IcosahedronBufferGeometry': + case 'OctahedronGeometry': + case 'OctahedronBufferGeometry': + case 'TetrahedronGeometry': + case 'TetrahedronBufferGeometry': - geometry = new Geometries[ data.type ]( - data.radius, - data.detail - ); + geometry = new Geometries[ data.type ]( + data.radius, + data.detail + ); - break; + break; - case 'RingGeometry': - case 'RingBufferGeometry': + case 'RingGeometry': + case 'RingBufferGeometry': - geometry = new Geometries[ data.type ]( - data.innerRadius, - data.outerRadius, - data.thetaSegments, - data.phiSegments, - data.thetaStart, - data.thetaLength - ); + geometry = new Geometries[ data.type ]( + data.innerRadius, + data.outerRadius, + data.thetaSegments, + data.phiSegments, + data.thetaStart, + data.thetaLength + ); - break; + break; - case 'TorusGeometry': - case 'TorusBufferGeometry': + case 'TorusGeometry': + case 'TorusBufferGeometry': - geometry = new Geometries[ data.type ]( - data.radius, - data.tube, - data.radialSegments, - data.tubularSegments, - data.arc - ); + geometry = new Geometries[ data.type ]( + data.radius, + data.tube, + data.radialSegments, + data.tubularSegments, + data.arc + ); - break; + break; - case 'TorusKnotGeometry': - case 'TorusKnotBufferGeometry': + case 'TorusKnotGeometry': + case 'TorusKnotBufferGeometry': - geometry = new Geometries[ data.type ]( - data.radius, - data.tube, - data.tubularSegments, - data.radialSegments, - data.p, - data.q - ); + geometry = new Geometries[ data.type ]( + data.radius, + data.tube, + data.tubularSegments, + data.radialSegments, + data.p, + data.q + ); - break; + break; - case 'LatheGeometry': - case 'LatheBufferGeometry': + case 'LatheGeometry': + case 'LatheBufferGeometry': - geometry = new Geometries[ data.type ]( - data.points, - data.segments, - data.phiStart, - data.phiLength - ); + geometry = new Geometries[ data.type ]( + data.points, + data.segments, + data.phiStart, + data.phiLength + ); - break; + break; - case 'PolyhedronGeometry': - case 'PolyhedronBufferGeometry': + case 'PolyhedronGeometry': + case 'PolyhedronBufferGeometry': - geometry = new Geometries[ data.type ]( - data.vertices, - data.indices, - data.radius, - data.details - ); + geometry = new Geometries[ data.type ]( + data.vertices, + data.indices, + data.radius, + data.details + ); - break; + break; - case 'ShapeGeometry': - case 'ShapeBufferGeometry': + case 'ShapeGeometry': + case 'ShapeBufferGeometry': - var geometryShapes = []; + var geometryShapes = []; - for ( var j = 0, jl = data.shapes.length; j < jl; j ++ ) { + for ( var j = 0, jl = data.shapes.length; j < jl; j ++ ) { - var shape = shapes[ data.shapes[ j ] ]; + var shape = shapes[ data.shapes[ j ] ]; - geometryShapes.push( shape ); + geometryShapes.push( shape ); - } + } - geometry = new Geometries[ data.type ]( - geometryShapes, - data.curveSegments - ); + geometry = new Geometries[ data.type ]( + geometryShapes, + data.curveSegments + ); - break; + break; - case 'ExtrudeGeometry': - case 'ExtrudeBufferGeometry': + case 'ExtrudeGeometry': + case 'ExtrudeBufferGeometry': - var geometryShapes = []; + var geometryShapes = []; - for ( var j = 0, jl = data.shapes.length; j < jl; j ++ ) { + for ( var j = 0, jl = data.shapes.length; j < jl; j ++ ) { - var shape = shapes[ data.shapes[ j ] ]; + var shape = shapes[ data.shapes[ j ] ]; - geometryShapes.push( shape ); + geometryShapes.push( shape ); - } + } - var extrudePath = data.options.extrudePath; + var extrudePath = data.options.extrudePath; - if ( extrudePath !== undefined ) { + if ( extrudePath !== undefined ) { - data.options.extrudePath = new Curves[ extrudePath.type ]().fromJSON( extrudePath ); + data.options.extrudePath = new Curves[ extrudePath.type ]().fromJSON( extrudePath ); - } + } - geometry = new Geometries[ data.type ]( - geometryShapes, - data.options - ); + geometry = new Geometries[ data.type ]( + geometryShapes, + data.options + ); - break; + break; - case 'BufferGeometry': + case 'BufferGeometry': - geometry = bufferGeometryLoader.parse( data ); + geometry = bufferGeometryLoader.parse( data ); - break; + break; - case 'Geometry': + case 'Geometry': - geometry = geometryLoader.parse( data, this.texturePath ).geometry; + geometry = geometryLoader.parse( data, this.texturePath ).geometry; - break; + break; - default: + default: - console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' ); + console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' ); - continue; + continue; - } + } - geometry.uuid = data.uuid; + geometry.uuid = data.uuid; - if ( data.name !== undefined ) geometry.name = data.name; - if ( geometry.isBufferGeometry === true && data.userData !== undefined ) geometry.userData = data.userData; + if ( data.name !== undefined ) geometry.name = data.name; + if ( geometry.isBufferGeometry === true && data.userData !== undefined ) geometry.userData = data.userData; - geometries[ data.uuid ] = geometry; + geometries[ data.uuid ] = geometry; - } + } - } + } - return geometries; + return geometries; - }, + }, - parseMaterials: function ( json, textures ) { + parseMaterials: function ( json, textures ) { - var materials = {}; + var materials = {}; - if ( json !== undefined ) { + if ( json !== undefined ) { - var loader = new MaterialLoader(); - loader.setTextures( textures ); + var loader = new MaterialLoader(); + loader.setTextures( textures ); - for ( var i = 0, l = json.length; i < l; i ++ ) { + for ( var i = 0, l = json.length; i < l; i ++ ) { - var data = json[ i ]; + var data = json[ i ]; - if ( data.type === 'MultiMaterial' ) { + if ( data.type === 'MultiMaterial' ) { - // Deprecated + // Deprecated - var array = []; + var array = []; - for ( var j = 0; j < data.materials.length; j ++ ) { + for ( var j = 0; j < data.materials.length; j ++ ) { - array.push( loader.parse( data.materials[ j ] ) ); + array.push( loader.parse( data.materials[ j ] ) ); - } + } - materials[ data.uuid ] = array; + materials[ data.uuid ] = array; - } else { + } else { - materials[ data.uuid ] = loader.parse( data ); + materials[ data.uuid ] = loader.parse( data ); - } + } - } + } - } + } - return materials; + return materials; - }, + }, - parseAnimations: function ( json ) { + parseAnimations: function ( json ) { - var animations = []; + var animations = []; - for ( var i = 0; i < json.length; i ++ ) { + for ( var i = 0; i < json.length; i ++ ) { - var data = json[ i ]; + var data = json[ i ]; - var clip = AnimationClip.parse( data ); + var clip = AnimationClip.parse( data ); - if ( data.uuid !== undefined ) clip.uuid = data.uuid; + if ( data.uuid !== undefined ) clip.uuid = data.uuid; - animations.push( clip ); + animations.push( clip ); - } + } - return animations; + return animations; - }, + }, - parseImages: function ( json, onLoad ) { + parseImages: function ( json, onLoad ) { - var scope = this; - var images = {}; + var scope = this; + var images = {}; - function loadImage( url ) { + function loadImage( url ) { - scope.manager.itemStart( url ); + scope.manager.itemStart( url ); - return loader.load( url, function () { + return loader.load( url, function () { - scope.manager.itemEnd( url ); + scope.manager.itemEnd( url ); - }, undefined, function () { + }, undefined, function () { - scope.manager.itemEnd( url ); - scope.manager.itemError( url ); + scope.manager.itemEnd( url ); + scope.manager.itemError( url ); - } ); + } ); - } + } - if ( json !== undefined && json.length > 0 ) { + if ( json !== undefined && json.length > 0 ) { - var manager = new LoadingManager( onLoad ); + var manager = new LoadingManager( onLoad ); - var loader = new ImageLoader( manager ); - loader.setCrossOrigin( this.crossOrigin ); + var loader = new ImageLoader( manager ); + loader.setCrossOrigin( this.crossOrigin ); - for ( var i = 0, il = json.length; i < il; i ++ ) { + for ( var i = 0, il = json.length; i < il; i ++ ) { - var image = json[ i ]; - var url = image.url; + var image = json[ i ]; + var url = image.url; - if ( Array.isArray( url ) ) { + if ( Array.isArray( url ) ) { - // load array of images e.g CubeTexture + // load array of images e.g CubeTexture - images[ image.uuid ] = []; + images[ image.uuid ] = []; - for ( var j = 0, jl = url.length; j < jl; j ++ ) { + for ( var j = 0, jl = url.length; j < jl; j ++ ) { - var currentUrl = url[ j ]; + var currentUrl = url[ j ]; - var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( currentUrl ) ? currentUrl : scope.texturePath + currentUrl; + var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( currentUrl ) ? currentUrl : scope.texturePath + currentUrl; - images[ image.uuid ].push( loadImage( path ) ); + images[ image.uuid ].push( loadImage( path ) ); - } + } - } else { + } else { - // load single image + // load single image - var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url; + var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url; - images[ image.uuid ] = loadImage( path ); + images[ image.uuid ] = loadImage( path ); - } + } - } + } - } + } - return images; + return images; - }, + }, - parseTextures: function ( json, images ) { + parseTextures: function ( json, images ) { - function parseConstant( value, type ) { + function parseConstant( value, type ) { - if ( typeof value === 'number' ) return value; + if ( typeof value === 'number' ) return value; - console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value ); + console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value ); - return type[ value ]; + return type[ value ]; - } + } - var textures = {}; + var textures = {}; - if ( json !== undefined ) { + if ( json !== undefined ) { - for ( var i = 0, l = json.length; i < l; i ++ ) { + for ( var i = 0, l = json.length; i < l; i ++ ) { - var data = json[ i ]; + var data = json[ i ]; - if ( data.image === undefined ) { + if ( data.image === undefined ) { - console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid ); + console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid ); - } + } - if ( images[ data.image ] === undefined ) { + if ( images[ data.image ] === undefined ) { - console.warn( 'THREE.ObjectLoader: Undefined image', data.image ); + console.warn( 'THREE.ObjectLoader: Undefined image', data.image ); - } + } - var texture; + var texture; - if ( Array.isArray( images[ data.image ] ) ) { + if ( Array.isArray( images[ data.image ] ) ) { - texture = new CubeTexture( images[ data.image ] ); + texture = new CubeTexture( images[ data.image ] ); - } else { + } else { - texture = new Texture( images[ data.image ] ); + texture = new Texture( images[ data.image ] ); - } + } - texture.needsUpdate = true; + texture.needsUpdate = true; - texture.uuid = data.uuid; + texture.uuid = data.uuid; - if ( data.name !== undefined ) texture.name = data.name; + if ( data.name !== undefined ) texture.name = data.name; - if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING ); + if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING ); - if ( data.offset !== undefined ) texture.offset.fromArray( data.offset ); - if ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat ); - if ( data.center !== undefined ) texture.center.fromArray( data.center ); - if ( data.rotation !== undefined ) texture.rotation = data.rotation; + if ( data.offset !== undefined ) texture.offset.fromArray( data.offset ); + if ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat ); + if ( data.center !== undefined ) texture.center.fromArray( data.center ); + if ( data.rotation !== undefined ) texture.rotation = data.rotation; - if ( data.wrap !== undefined ) { + if ( data.wrap !== undefined ) { - texture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING ); - texture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING ); + texture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING ); + texture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING ); - } + } - if ( data.format !== undefined ) texture.format = data.format; + if ( data.format !== undefined ) texture.format = data.format; - if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER ); - if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER ); - if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy; + if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER ); + if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER ); + if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy; - if ( data.flipY !== undefined ) texture.flipY = data.flipY; + if ( data.flipY !== undefined ) texture.flipY = data.flipY; - textures[ data.uuid ] = texture; + textures[ data.uuid ] = texture; - } + } - } + } - return textures; + return textures; - }, + }, - parseObject: function ( data, geometries, materials ) { + parseObject: function ( data, geometries, materials ) { - var object; + var object; - function getGeometry( name ) { + function getGeometry( name ) { - if ( geometries[ name ] === undefined ) { + if ( geometries[ name ] === undefined ) { - console.warn( 'THREE.ObjectLoader: Undefined geometry', name ); + console.warn( 'THREE.ObjectLoader: Undefined geometry', name ); - } + } - return geometries[ name ]; + return geometries[ name ]; - } + } - function getMaterial( name ) { + function getMaterial( name ) { - if ( name === undefined ) return undefined; + if ( name === undefined ) return undefined; - if ( Array.isArray( name ) ) { + if ( Array.isArray( name ) ) { - var array = []; + var array = []; - for ( var i = 0, l = name.length; i < l; i ++ ) { + for ( var i = 0, l = name.length; i < l; i ++ ) { - var uuid = name[ i ]; + var uuid = name[ i ]; - if ( materials[ uuid ] === undefined ) { + if ( materials[ uuid ] === undefined ) { - console.warn( 'THREE.ObjectLoader: Undefined material', uuid ); + console.warn( 'THREE.ObjectLoader: Undefined material', uuid ); - } + } - array.push( materials[ uuid ] ); + array.push( materials[ uuid ] ); - } + } - return array; + return array; - } + } - if ( materials[ name ] === undefined ) { + if ( materials[ name ] === undefined ) { - console.warn( 'THREE.ObjectLoader: Undefined material', name ); + console.warn( 'THREE.ObjectLoader: Undefined material', name ); - } + } - return materials[ name ]; + return materials[ name ]; - } + } - switch ( data.type ) { + switch ( data.type ) { - case 'Scene': + case 'Scene': - object = new Scene(); + object = new Scene(); - if ( data.background !== undefined ) { + if ( data.background !== undefined ) { - if ( Number.isInteger( data.background ) ) { + if ( Number.isInteger( data.background ) ) { - object.background = new Color( data.background ); + object.background = new Color( data.background ); - } + } - } + } - if ( data.fog !== undefined ) { + if ( data.fog !== undefined ) { - if ( data.fog.type === 'Fog' ) { + if ( data.fog.type === 'Fog' ) { - object.fog = new Fog( data.fog.color, data.fog.near, data.fog.far ); + object.fog = new Fog( data.fog.color, data.fog.near, data.fog.far ); - } else if ( data.fog.type === 'FogExp2' ) { + } else if ( data.fog.type === 'FogExp2' ) { - object.fog = new FogExp2( data.fog.color, data.fog.density ); + object.fog = new FogExp2( data.fog.color, data.fog.density ); - } + } - } + } - break; + break; - case 'PerspectiveCamera': + case 'PerspectiveCamera': - object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far ); + object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far ); - if ( data.focus !== undefined ) object.focus = data.focus; - if ( data.zoom !== undefined ) object.zoom = data.zoom; - if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge; - if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset; - if ( data.view !== undefined ) object.view = Object.assign( {}, data.view ); + if ( data.focus !== undefined ) object.focus = data.focus; + if ( data.zoom !== undefined ) object.zoom = data.zoom; + if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge; + if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset; + if ( data.view !== undefined ) object.view = Object.assign( {}, data.view ); - break; + break; - case 'OrthographicCamera': + case 'OrthographicCamera': - object = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far ); + object = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far ); - if ( data.zoom !== undefined ) object.zoom = data.zoom; - if ( data.view !== undefined ) object.view = Object.assign( {}, data.view ); + if ( data.zoom !== undefined ) object.zoom = data.zoom; + if ( data.view !== undefined ) object.view = Object.assign( {}, data.view ); - break; + break; - case 'AmbientLight': + case 'AmbientLight': - object = new AmbientLight( data.color, data.intensity ); + object = new AmbientLight( data.color, data.intensity ); - break; + break; - case 'DirectionalLight': + case 'DirectionalLight': - object = new DirectionalLight( data.color, data.intensity ); + object = new DirectionalLight( data.color, data.intensity ); - break; + break; - case 'PointLight': + case 'PointLight': - object = new PointLight( data.color, data.intensity, data.distance, data.decay ); + object = new PointLight( data.color, data.intensity, data.distance, data.decay ); - break; + break; - case 'RectAreaLight': + case 'RectAreaLight': - object = new RectAreaLight( data.color, data.intensity, data.width, data.height ); + object = new RectAreaLight( data.color, data.intensity, data.width, data.height ); - break; + break; - case 'SpotLight': + case 'SpotLight': - object = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay ); + object = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay ); - break; + break; - case 'HemisphereLight': + case 'HemisphereLight': - object = new HemisphereLight( data.color, data.groundColor, data.intensity ); + object = new HemisphereLight( data.color, data.groundColor, data.intensity ); - break; + break; - case 'SkinnedMesh': + case 'SkinnedMesh': - console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.' ); + console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.' ); - case 'Mesh': + case 'Mesh': - var geometry = getGeometry( data.geometry ); - var material = getMaterial( data.material ); + var geometry = getGeometry( data.geometry ); + var material = getMaterial( data.material ); - if ( geometry.bones && geometry.bones.length > 0 ) { + if ( geometry.bones && geometry.bones.length > 0 ) { - object = new SkinnedMesh( geometry, material ); + object = new SkinnedMesh( geometry, material ); - } else { + } else { - object = new Mesh( geometry, material ); + object = new Mesh( geometry, material ); - } + } - break; + break; - case 'LOD': + case 'LOD': - object = new LOD(); + object = new LOD(); - break; + break; - case 'Line': + case 'Line': - object = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode ); + object = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode ); - break; + break; - case 'LineLoop': + case 'LineLoop': - object = new LineLoop( getGeometry( data.geometry ), getMaterial( data.material ) ); + object = new LineLoop( getGeometry( data.geometry ), getMaterial( data.material ) ); - break; + break; - case 'LineSegments': + case 'LineSegments': - object = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) ); + object = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) ); - break; + break; - case 'PointCloud': - case 'Points': + case 'PointCloud': + case 'Points': - object = new Points( getGeometry( data.geometry ), getMaterial( data.material ) ); + object = new Points( getGeometry( data.geometry ), getMaterial( data.material ) ); - break; + break; - case 'Sprite': + case 'Sprite': - object = new Sprite( getMaterial( data.material ) ); + object = new Sprite( getMaterial( data.material ) ); - break; + break; - case 'Group': + case 'Group': - object = new Group(); + object = new Group(); - break; + break; - default: + default: - object = new Object3D(); + object = new Object3D(); - } + } - object.uuid = data.uuid; + object.uuid = data.uuid; - if ( data.name !== undefined ) object.name = data.name; + if ( data.name !== undefined ) object.name = data.name; - if ( data.matrix !== undefined ) { + if ( data.matrix !== undefined ) { - object.matrix.fromArray( data.matrix ); + object.matrix.fromArray( data.matrix ); - if ( data.matrixAutoUpdate !== undefined ) object.matrixAutoUpdate = data.matrixAutoUpdate; - if ( object.matrixAutoUpdate ) object.matrix.decompose( object.position, object.quaternion, object.scale ); + if ( data.matrixAutoUpdate !== undefined ) object.matrixAutoUpdate = data.matrixAutoUpdate; + if ( object.matrixAutoUpdate ) object.matrix.decompose( object.position, object.quaternion, object.scale ); - } else { + } else { - if ( data.position !== undefined ) object.position.fromArray( data.position ); - if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation ); - if ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion ); - if ( data.scale !== undefined ) object.scale.fromArray( data.scale ); + if ( data.position !== undefined ) object.position.fromArray( data.position ); + if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation ); + if ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion ); + if ( data.scale !== undefined ) object.scale.fromArray( data.scale ); - } + } - if ( data.castShadow !== undefined ) object.castShadow = data.castShadow; - if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow; + if ( data.castShadow !== undefined ) object.castShadow = data.castShadow; + if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow; - if ( data.shadow ) { + if ( data.shadow ) { - if ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias; - if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius; - if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize ); - if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera ); + if ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias; + if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius; + if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize ); + if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera ); - } + } - if ( data.visible !== undefined ) object.visible = data.visible; - if ( data.frustumCulled !== undefined ) object.frustumCulled = data.frustumCulled; - if ( data.renderOrder !== undefined ) object.renderOrder = data.renderOrder; - if ( data.userData !== undefined ) object.userData = data.userData; - if ( data.layers !== undefined ) object.layers.mask = data.layers; + if ( data.visible !== undefined ) object.visible = data.visible; + if ( data.frustumCulled !== undefined ) object.frustumCulled = data.frustumCulled; + if ( data.renderOrder !== undefined ) object.renderOrder = data.renderOrder; + if ( data.userData !== undefined ) object.userData = data.userData; + if ( data.layers !== undefined ) object.layers.mask = data.layers; - if ( data.children !== undefined ) { + if ( data.children !== undefined ) { - var children = data.children; + var children = data.children; - for ( var i = 0; i < children.length; i ++ ) { + for ( var i = 0; i < children.length; i ++ ) { - object.add( this.parseObject( children[ i ], geometries, materials ) ); + object.add( this.parseObject( children[ i ], geometries, materials ) ); - } + } - } + } - if ( data.type === 'LOD' ) { + if ( data.type === 'LOD' ) { - var levels = data.levels; + var levels = data.levels; - for ( var l = 0; l < levels.length; l ++ ) { + for ( var l = 0; l < levels.length; l ++ ) { - var level = levels[ l ]; - var child = object.getObjectByProperty( 'uuid', level.object ); + var level = levels[ l ]; + var child = object.getObjectByProperty( 'uuid', level.object ); - if ( child !== undefined ) { + if ( child !== undefined ) { - object.addLevel( child, level.distance ); + object.addLevel( child, level.distance ); - } + } - } + } - } + } - return object; + return object; - } + } - } ); + } ); - var TEXTURE_MAPPING = { - UVMapping: UVMapping, - CubeReflectionMapping: CubeReflectionMapping, - CubeRefractionMapping: CubeRefractionMapping, - EquirectangularReflectionMapping: EquirectangularReflectionMapping, - EquirectangularRefractionMapping: EquirectangularRefractionMapping, - SphericalReflectionMapping: SphericalReflectionMapping, - CubeUVReflectionMapping: CubeUVReflectionMapping, - CubeUVRefractionMapping: CubeUVRefractionMapping - }; + var TEXTURE_MAPPING = { + UVMapping: UVMapping, + CubeReflectionMapping: CubeReflectionMapping, + CubeRefractionMapping: CubeRefractionMapping, + EquirectangularReflectionMapping: EquirectangularReflectionMapping, + EquirectangularRefractionMapping: EquirectangularRefractionMapping, + SphericalReflectionMapping: SphericalReflectionMapping, + CubeUVReflectionMapping: CubeUVReflectionMapping, + CubeUVRefractionMapping: CubeUVRefractionMapping + }; - var TEXTURE_WRAPPING = { - RepeatWrapping: RepeatWrapping, - ClampToEdgeWrapping: ClampToEdgeWrapping, - MirroredRepeatWrapping: MirroredRepeatWrapping - }; + var TEXTURE_WRAPPING = { + RepeatWrapping: RepeatWrapping, + ClampToEdgeWrapping: ClampToEdgeWrapping, + MirroredRepeatWrapping: MirroredRepeatWrapping + }; - var TEXTURE_FILTER = { - NearestFilter: NearestFilter, - NearestMipMapNearestFilter: NearestMipMapNearestFilter, - NearestMipMapLinearFilter: NearestMipMapLinearFilter, - LinearFilter: LinearFilter, - LinearMipMapNearestFilter: LinearMipMapNearestFilter, - LinearMipMapLinearFilter: LinearMipMapLinearFilter - }; + var TEXTURE_FILTER = { + NearestFilter: NearestFilter, + NearestMipMapNearestFilter: NearestMipMapNearestFilter, + NearestMipMapLinearFilter: NearestMipMapLinearFilter, + LinearFilter: LinearFilter, + LinearMipMapNearestFilter: LinearMipMapNearestFilter, + LinearMipMapLinearFilter: LinearMipMapLinearFilter + }; - /** - * @author thespite / http://clicktorelease.com/ - */ + /** + * @author thespite / http://clicktorelease.com/ + */ - function ImageBitmapLoader( manager ) { + function ImageBitmapLoader( manager ) { - if ( typeof createImageBitmap === 'undefined' ) { + if ( typeof createImageBitmap === 'undefined' ) { - console.warn( 'THREE.ImageBitmapLoader: createImageBitmap() not supported.' ); + console.warn( 'THREE.ImageBitmapLoader: createImageBitmap() not supported.' ); - } + } - if ( typeof fetch === 'undefined' ) { + if ( typeof fetch === 'undefined' ) { - console.warn( 'THREE.ImageBitmapLoader: fetch() not supported.' ); + console.warn( 'THREE.ImageBitmapLoader: fetch() not supported.' ); - } + } - this.manager = manager !== undefined ? manager : DefaultLoadingManager; - this.options = undefined; + this.manager = manager !== undefined ? manager : DefaultLoadingManager; + this.options = undefined; - } + } - ImageBitmapLoader.prototype = { + ImageBitmapLoader.prototype = { - constructor: ImageBitmapLoader, + constructor: ImageBitmapLoader, - setOptions: function setOptions( options ) { + setOptions: function setOptions( options ) { - this.options = options; + this.options = options; - return this; + return this; - }, + }, - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - if ( url === undefined ) url = ''; + if ( url === undefined ) url = ''; - if ( this.path !== undefined ) url = this.path + url; + if ( this.path !== undefined ) url = this.path + url; - url = this.manager.resolveURL( url ); + url = this.manager.resolveURL( url ); - var scope = this; + var scope = this; - var cached = Cache.get( url ); + var cached = Cache.get( url ); - if ( cached !== undefined ) { + if ( cached !== undefined ) { - scope.manager.itemStart( url ); + scope.manager.itemStart( url ); - setTimeout( function () { + setTimeout( function () { - if ( onLoad ) onLoad( cached ); + if ( onLoad ) onLoad( cached ); - scope.manager.itemEnd( url ); + scope.manager.itemEnd( url ); - }, 0 ); + }, 0 ); - return cached; + return cached; - } + } - fetch( url ).then( function ( res ) { + fetch( url ).then( function ( res ) { - return res.blob(); + return res.blob(); - } ).then( function ( blob ) { + } ).then( function ( blob ) { - return createImageBitmap( blob, scope.options ); + return createImageBitmap( blob, scope.options ); - } ).then( function ( imageBitmap ) { + } ).then( function ( imageBitmap ) { - Cache.add( url, imageBitmap ); + Cache.add( url, imageBitmap ); - if ( onLoad ) onLoad( imageBitmap ); + if ( onLoad ) onLoad( imageBitmap ); - scope.manager.itemEnd( url ); + scope.manager.itemEnd( url ); - } ).catch( function ( e ) { + } ).catch( function ( e ) { - if ( onError ) onError( e ); + if ( onError ) onError( e ); - scope.manager.itemEnd( url ); - scope.manager.itemError( url ); + scope.manager.itemEnd( url ); + scope.manager.itemError( url ); - } ); + } ); - }, + }, - setCrossOrigin: function ( /* value */ ) { + setCrossOrigin: function ( /* value */ ) { - return this; + return this; - }, + }, - setPath: function ( value ) { + setPath: function ( value ) { - this.path = value; - return this; + this.path = value; + return this; - } + } - }; + }; - /** - * @author zz85 / http://www.lab4games.net/zz85/blog - * minimal class for proxing functions to Path. Replaces old "extractSubpaths()" - **/ + /** + * @author zz85 / http://www.lab4games.net/zz85/blog + * minimal class for proxing functions to Path. Replaces old "extractSubpaths()" + **/ - function ShapePath() { + function ShapePath() { - this.type = 'ShapePath'; + this.type = 'ShapePath'; - this.color = new Color(); + this.color = new Color(); - this.subPaths = []; - this.currentPath = null; + this.subPaths = []; + this.currentPath = null; - } + } - Object.assign( ShapePath.prototype, { + Object.assign( ShapePath.prototype, { - moveTo: function ( x, y ) { + moveTo: function ( x, y ) { - this.currentPath = new Path(); - this.subPaths.push( this.currentPath ); - this.currentPath.moveTo( x, y ); + this.currentPath = new Path(); + this.subPaths.push( this.currentPath ); + this.currentPath.moveTo( x, y ); - }, + }, - lineTo: function ( x, y ) { + lineTo: function ( x, y ) { - this.currentPath.lineTo( x, y ); + this.currentPath.lineTo( x, y ); - }, + }, - quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) { + quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) { - this.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY ); + this.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY ); - }, + }, - bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) { + bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) { - this.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ); + this.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ); - }, + }, - splineThru: function ( pts ) { + splineThru: function ( pts ) { - this.currentPath.splineThru( pts ); + this.currentPath.splineThru( pts ); - }, + }, - toShapes: function ( isCCW, noHoles ) { + toShapes: function ( isCCW, noHoles ) { - function toShapesNoHoles( inSubpaths ) { + function toShapesNoHoles( inSubpaths ) { - var shapes = []; + var shapes = []; - for ( var i = 0, l = inSubpaths.length; i < l; i ++ ) { + for ( var i = 0, l = inSubpaths.length; i < l; i ++ ) { - var tmpPath = inSubpaths[ i ]; + var tmpPath = inSubpaths[ i ]; - var tmpShape = new Shape(); - tmpShape.curves = tmpPath.curves; + var tmpShape = new Shape(); + tmpShape.curves = tmpPath.curves; - shapes.push( tmpShape ); + shapes.push( tmpShape ); - } + } - return shapes; + return shapes; - } + } - function isPointInsidePolygon( inPt, inPolygon ) { + function isPointInsidePolygon( inPt, inPolygon ) { - var polyLen = inPolygon.length; + var polyLen = inPolygon.length; - // inPt on polygon contour => immediate success or - // toggling of inside/outside at every single! intersection point of an edge - // with the horizontal line through inPt, left of inPt - // not counting lowerY endpoints of edges and whole edges on that line - var inside = false; - for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) { + // inPt on polygon contour => immediate success or + // toggling of inside/outside at every single! intersection point of an edge + // with the horizontal line through inPt, left of inPt + // not counting lowerY endpoints of edges and whole edges on that line + var inside = false; + for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) { - var edgeLowPt = inPolygon[ p ]; - var edgeHighPt = inPolygon[ q ]; + var edgeLowPt = inPolygon[ p ]; + var edgeHighPt = inPolygon[ q ]; - var edgeDx = edgeHighPt.x - edgeLowPt.x; - var edgeDy = edgeHighPt.y - edgeLowPt.y; + var edgeDx = edgeHighPt.x - edgeLowPt.x; + var edgeDy = edgeHighPt.y - edgeLowPt.y; - if ( Math.abs( edgeDy ) > Number.EPSILON ) { + if ( Math.abs( edgeDy ) > Number.EPSILON ) { - // not parallel - if ( edgeDy < 0 ) { + // not parallel + if ( edgeDy < 0 ) { - edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx; - edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy; + edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx; + edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy; - } - if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue; + } + if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue; - if ( inPt.y === edgeLowPt.y ) { + if ( inPt.y === edgeLowPt.y ) { - if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ? - // continue; // no intersection or edgeLowPt => doesn't count !!! + if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ? + // continue; // no intersection or edgeLowPt => doesn't count !!! - } else { + } else { - var perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y ); - if ( perpEdge === 0 ) return true; // inPt is on contour ? - if ( perpEdge < 0 ) continue; - inside = ! inside; // true intersection left of inPt + var perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y ); + if ( perpEdge === 0 ) return true; // inPt is on contour ? + if ( perpEdge < 0 ) continue; + inside = ! inside; // true intersection left of inPt - } + } - } else { + } else { - // parallel or collinear - if ( inPt.y !== edgeLowPt.y ) continue; // parallel - // edge lies on the same horizontal line as inPt - if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) || - ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour ! - // continue; + // parallel or collinear + if ( inPt.y !== edgeLowPt.y ) continue; // parallel + // edge lies on the same horizontal line as inPt + if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) || + ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour ! + // continue; - } + } - } + } - return inside; + return inside; - } + } - var isClockWise = ShapeUtils.isClockWise; + var isClockWise = ShapeUtils.isClockWise; - var subPaths = this.subPaths; - if ( subPaths.length === 0 ) return []; + var subPaths = this.subPaths; + if ( subPaths.length === 0 ) return []; - if ( noHoles === true ) return toShapesNoHoles( subPaths ); + if ( noHoles === true ) return toShapesNoHoles( subPaths ); - var solid, tmpPath, tmpShape, shapes = []; + var solid, tmpPath, tmpShape, shapes = []; - if ( subPaths.length === 1 ) { + if ( subPaths.length === 1 ) { - tmpPath = subPaths[ 0 ]; - tmpShape = new Shape(); - tmpShape.curves = tmpPath.curves; - shapes.push( tmpShape ); - return shapes; + tmpPath = subPaths[ 0 ]; + tmpShape = new Shape(); + tmpShape.curves = tmpPath.curves; + shapes.push( tmpShape ); + return shapes; - } + } - var holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() ); - holesFirst = isCCW ? ! holesFirst : holesFirst; + var holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() ); + holesFirst = isCCW ? ! holesFirst : holesFirst; - // console.log("Holes first", holesFirst); + // console.log("Holes first", holesFirst); - var betterShapeHoles = []; - var newShapes = []; - var newShapeHoles = []; - var mainIdx = 0; - var tmpPoints; + var betterShapeHoles = []; + var newShapes = []; + var newShapeHoles = []; + var mainIdx = 0; + var tmpPoints; - newShapes[ mainIdx ] = undefined; - newShapeHoles[ mainIdx ] = []; + newShapes[ mainIdx ] = undefined; + newShapeHoles[ mainIdx ] = []; - for ( var i = 0, l = subPaths.length; i < l; i ++ ) { + for ( var i = 0, l = subPaths.length; i < l; i ++ ) { - tmpPath = subPaths[ i ]; - tmpPoints = tmpPath.getPoints(); - solid = isClockWise( tmpPoints ); - solid = isCCW ? ! solid : solid; + tmpPath = subPaths[ i ]; + tmpPoints = tmpPath.getPoints(); + solid = isClockWise( tmpPoints ); + solid = isCCW ? ! solid : solid; - if ( solid ) { + if ( solid ) { - if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++; + if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++; - newShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints }; - newShapes[ mainIdx ].s.curves = tmpPath.curves; + newShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints }; + newShapes[ mainIdx ].s.curves = tmpPath.curves; - if ( holesFirst ) mainIdx ++; - newShapeHoles[ mainIdx ] = []; + if ( holesFirst ) mainIdx ++; + newShapeHoles[ mainIdx ] = []; - //console.log('cw', i); + //console.log('cw', i); - } else { + } else { - newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } ); + newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } ); - //console.log('ccw', i); + //console.log('ccw', i); - } + } - } + } - // only Holes? -> probably all Shapes with wrong orientation - if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths ); + // only Holes? -> probably all Shapes with wrong orientation + if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths ); - if ( newShapes.length > 1 ) { + if ( newShapes.length > 1 ) { - var ambiguous = false; - var toChange = []; + var ambiguous = false; + var toChange = []; - for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { + for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { - betterShapeHoles[ sIdx ] = []; + betterShapeHoles[ sIdx ] = []; - } + } - for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { + for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { - var sho = newShapeHoles[ sIdx ]; + var sho = newShapeHoles[ sIdx ]; - for ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) { + for ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) { - var ho = sho[ hIdx ]; - var hole_unassigned = true; + var ho = sho[ hIdx ]; + var hole_unassigned = true; - for ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) { + for ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) { - if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) { + if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) { - if ( sIdx !== s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } ); - if ( hole_unassigned ) { + if ( sIdx !== s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } ); + if ( hole_unassigned ) { - hole_unassigned = false; - betterShapeHoles[ s2Idx ].push( ho ); + hole_unassigned = false; + betterShapeHoles[ s2Idx ].push( ho ); - } else { + } else { - ambiguous = true; + ambiguous = true; - } + } - } + } - } - if ( hole_unassigned ) { + } + if ( hole_unassigned ) { - betterShapeHoles[ sIdx ].push( ho ); + betterShapeHoles[ sIdx ].push( ho ); - } + } - } + } - } - // console.log("ambiguous: ", ambiguous); - if ( toChange.length > 0 ) { + } + // console.log("ambiguous: ", ambiguous); + if ( toChange.length > 0 ) { - // console.log("to change: ", toChange); - if ( ! ambiguous ) newShapeHoles = betterShapeHoles; + // console.log("to change: ", toChange); + if ( ! ambiguous ) newShapeHoles = betterShapeHoles; - } + } - } + } - var tmpHoles; + var tmpHoles; - for ( var i = 0, il = newShapes.length; i < il; i ++ ) { + for ( var i = 0, il = newShapes.length; i < il; i ++ ) { - tmpShape = newShapes[ i ].s; - shapes.push( tmpShape ); - tmpHoles = newShapeHoles[ i ]; + tmpShape = newShapes[ i ].s; + shapes.push( tmpShape ); + tmpHoles = newShapeHoles[ i ]; - for ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) { + for ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) { - tmpShape.holes.push( tmpHoles[ j ].h ); + tmpShape.holes.push( tmpHoles[ j ].h ); - } + } - } + } - //console.log("shape", shapes); + //console.log("shape", shapes); - return shapes; + return shapes; - } + } - } ); + } ); - /** - * @author zz85 / http://www.lab4games.net/zz85/blog - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author zz85 / http://www.lab4games.net/zz85/blog + * @author mrdoob / http://mrdoob.com/ + */ - function Font( data ) { + function Font( data ) { - this.type = 'Font'; + this.type = 'Font'; - this.data = data; + this.data = data; - } + } - Object.assign( Font.prototype, { + Object.assign( Font.prototype, { - isFont: true, + isFont: true, - generateShapes: function ( text, size ) { + generateShapes: function ( text, size ) { - if ( size === undefined ) size = 100; + if ( size === undefined ) size = 100; - var shapes = []; - var paths = createPaths( text, size, this.data ); + var shapes = []; + var paths = createPaths( text, size, this.data ); - for ( var p = 0, pl = paths.length; p < pl; p ++ ) { + for ( var p = 0, pl = paths.length; p < pl; p ++ ) { - Array.prototype.push.apply( shapes, paths[ p ].toShapes() ); + Array.prototype.push.apply( shapes, paths[ p ].toShapes() ); - } + } - return shapes; + return shapes; - } + } - } ); + } ); - function createPaths( text, size, data ) { + function createPaths( text, size, data ) { - var chars = Array.from ? Array.from( text ) : String( text ).split( '' ); // see #13988 - var scale = size / data.resolution; - var line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale; + var chars = Array.from ? Array.from( text ) : String( text ).split( '' ); // see #13988 + var scale = size / data.resolution; + var line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale; - var paths = []; + var paths = []; - var offsetX = 0, offsetY = 0; + var offsetX = 0, offsetY = 0; - for ( var i = 0; i < chars.length; i ++ ) { + for ( var i = 0; i < chars.length; i ++ ) { - var char = chars[ i ]; + var char = chars[ i ]; - if ( char === '\n' ) { + if ( char === '\n' ) { - offsetX = 0; - offsetY -= line_height; + offsetX = 0; + offsetY -= line_height; - } else { + } else { - var ret = createPath( char, scale, offsetX, offsetY, data ); - offsetX += ret.offsetX; - paths.push( ret.path ); + var ret = createPath( char, scale, offsetX, offsetY, data ); + offsetX += ret.offsetX; + paths.push( ret.path ); - } + } - } + } - return paths; + return paths; - } + } - function createPath( char, scale, offsetX, offsetY, data ) { + function createPath( char, scale, offsetX, offsetY, data ) { - var glyph = data.glyphs[ char ] || data.glyphs[ '?' ]; + var glyph = data.glyphs[ char ] || data.glyphs[ '?' ]; - if ( ! glyph ) return; + if ( ! glyph ) return; - var path = new ShapePath(); + var path = new ShapePath(); - var x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2; + var x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2; - if ( glyph.o ) { + if ( glyph.o ) { - var outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) ); + var outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) ); - for ( var i = 0, l = outline.length; i < l; ) { + for ( var i = 0, l = outline.length; i < l; ) { - var action = outline[ i ++ ]; + var action = outline[ i ++ ]; - switch ( action ) { + switch ( action ) { - case 'm': // moveTo + case 'm': // moveTo - x = outline[ i ++ ] * scale + offsetX; - y = outline[ i ++ ] * scale + offsetY; + x = outline[ i ++ ] * scale + offsetX; + y = outline[ i ++ ] * scale + offsetY; - path.moveTo( x, y ); + path.moveTo( x, y ); - break; + break; - case 'l': // lineTo + case 'l': // lineTo - x = outline[ i ++ ] * scale + offsetX; - y = outline[ i ++ ] * scale + offsetY; + x = outline[ i ++ ] * scale + offsetX; + y = outline[ i ++ ] * scale + offsetY; - path.lineTo( x, y ); + path.lineTo( x, y ); - break; + break; - case 'q': // quadraticCurveTo + case 'q': // quadraticCurveTo - cpx = outline[ i ++ ] * scale + offsetX; - cpy = outline[ i ++ ] * scale + offsetY; - cpx1 = outline[ i ++ ] * scale + offsetX; - cpy1 = outline[ i ++ ] * scale + offsetY; + cpx = outline[ i ++ ] * scale + offsetX; + cpy = outline[ i ++ ] * scale + offsetY; + cpx1 = outline[ i ++ ] * scale + offsetX; + cpy1 = outline[ i ++ ] * scale + offsetY; - path.quadraticCurveTo( cpx1, cpy1, cpx, cpy ); + path.quadraticCurveTo( cpx1, cpy1, cpx, cpy ); - break; + break; - case 'b': // bezierCurveTo + case 'b': // bezierCurveTo - cpx = outline[ i ++ ] * scale + offsetX; - cpy = outline[ i ++ ] * scale + offsetY; - cpx1 = outline[ i ++ ] * scale + offsetX; - cpy1 = outline[ i ++ ] * scale + offsetY; - cpx2 = outline[ i ++ ] * scale + offsetX; - cpy2 = outline[ i ++ ] * scale + offsetY; + cpx = outline[ i ++ ] * scale + offsetX; + cpy = outline[ i ++ ] * scale + offsetY; + cpx1 = outline[ i ++ ] * scale + offsetX; + cpy1 = outline[ i ++ ] * scale + offsetY; + cpx2 = outline[ i ++ ] * scale + offsetX; + cpy2 = outline[ i ++ ] * scale + offsetY; - path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy ); + path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy ); - break; + break; - } + } - } + } - } + } - return { offsetX: glyph.ha * scale, path: path }; + return { offsetX: glyph.ha * scale, path: path }; - } + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function FontLoader( manager ) { + function FontLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - } + } - Object.assign( FontLoader.prototype, { + Object.assign( FontLoader.prototype, { - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - var scope = this; + var scope = this; - var loader = new FileLoader( this.manager ); - loader.setPath( this.path ); - loader.load( url, function ( text ) { + var loader = new FileLoader( this.manager ); + loader.setPath( this.path ); + loader.load( url, function ( text ) { - var json; + var json; - try { + try { - json = JSON.parse( text ); + json = JSON.parse( text ); - } catch ( e ) { + } catch ( e ) { - console.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' ); - json = JSON.parse( text.substring( 65, text.length - 2 ) ); + console.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' ); + json = JSON.parse( text.substring( 65, text.length - 2 ) ); - } + } - var font = scope.parse( json ); + var font = scope.parse( json ); - if ( onLoad ) onLoad( font ); + if ( onLoad ) onLoad( font ); - }, onProgress, onError ); + }, onProgress, onError ); - }, + }, - parse: function ( json ) { + parse: function ( json ) { - return new Font( json ); + return new Font( json ); - }, + }, - setPath: function ( value ) { + setPath: function ( value ) { - this.path = value; - return this; + this.path = value; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - var context; + var context; - var AudioContext = { + var AudioContext = { - getContext: function () { + getContext: function () { - if ( context === undefined ) { + if ( context === undefined ) { - context = new ( window.AudioContext || window.webkitAudioContext )(); + context = new ( window.AudioContext || window.webkitAudioContext )(); - } + } - return context; + return context; - }, + }, - setContext: function ( value ) { + setContext: function ( value ) { - context = value; + context = value; - } + } - }; + }; - /** - * @author Reece Aaron Lecrivain / http://reecenotes.com/ - */ + /** + * @author Reece Aaron Lecrivain / http://reecenotes.com/ + */ - function AudioLoader( manager ) { + function AudioLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - } + } - Object.assign( AudioLoader.prototype, { + Object.assign( AudioLoader.prototype, { - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - var loader = new FileLoader( this.manager ); - loader.setResponseType( 'arraybuffer' ); - loader.load( url, function ( buffer ) { + var loader = new FileLoader( this.manager ); + loader.setResponseType( 'arraybuffer' ); + loader.load( url, function ( buffer ) { - // Create a copy of the buffer. The `decodeAudioData` method - // detaches the buffer when complete, preventing reuse. - var bufferCopy = buffer.slice( 0 ); + // Create a copy of the buffer. The `decodeAudioData` method + // detaches the buffer when complete, preventing reuse. + var bufferCopy = buffer.slice( 0 ); - var context = AudioContext.getContext(); - context.decodeAudioData( bufferCopy, function ( audioBuffer ) { + var context = AudioContext.getContext(); + context.decodeAudioData( bufferCopy, function ( audioBuffer ) { - onLoad( audioBuffer ); + onLoad( audioBuffer ); - } ); + } ); - }, onProgress, onError ); + }, onProgress, onError ); - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function StereoCamera() { + function StereoCamera() { - this.type = 'StereoCamera'; + this.type = 'StereoCamera'; - this.aspect = 1; + this.aspect = 1; - this.eyeSep = 0.064; + this.eyeSep = 0.064; - this.cameraL = new PerspectiveCamera(); - this.cameraL.layers.enable( 1 ); - this.cameraL.matrixAutoUpdate = false; + this.cameraL = new PerspectiveCamera(); + this.cameraL.layers.enable( 1 ); + this.cameraL.matrixAutoUpdate = false; - this.cameraR = new PerspectiveCamera(); - this.cameraR.layers.enable( 2 ); - this.cameraR.matrixAutoUpdate = false; + this.cameraR = new PerspectiveCamera(); + this.cameraR.layers.enable( 2 ); + this.cameraR.matrixAutoUpdate = false; - } + } - Object.assign( StereoCamera.prototype, { + Object.assign( StereoCamera.prototype, { - update: ( function () { + update: ( function () { - var instance, focus, fov, aspect, near, far, zoom, eyeSep; + var instance, focus, fov, aspect, near, far, zoom, eyeSep; - var eyeRight = new Matrix4(); - var eyeLeft = new Matrix4(); + var eyeRight = new Matrix4(); + var eyeLeft = new Matrix4(); - return function update( camera ) { + return function update( camera ) { - var needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov || - aspect !== camera.aspect * this.aspect || near !== camera.near || - far !== camera.far || zoom !== camera.zoom || eyeSep !== this.eyeSep; + var needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov || + aspect !== camera.aspect * this.aspect || near !== camera.near || + far !== camera.far || zoom !== camera.zoom || eyeSep !== this.eyeSep; - if ( needsUpdate ) { + if ( needsUpdate ) { - instance = this; - focus = camera.focus; - fov = camera.fov; - aspect = camera.aspect * this.aspect; - near = camera.near; - far = camera.far; - zoom = camera.zoom; + instance = this; + focus = camera.focus; + fov = camera.fov; + aspect = camera.aspect * this.aspect; + near = camera.near; + far = camera.far; + zoom = camera.zoom; - // Off-axis stereoscopic effect based on - // http://paulbourke.net/stereographics/stereorender/ + // Off-axis stereoscopic effect based on + // http://paulbourke.net/stereographics/stereorender/ - var projectionMatrix = camera.projectionMatrix.clone(); - eyeSep = this.eyeSep / 2; - var eyeSepOnProjection = eyeSep * near / focus; - var ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom; - var xmin, xmax; + var projectionMatrix = camera.projectionMatrix.clone(); + eyeSep = this.eyeSep / 2; + var eyeSepOnProjection = eyeSep * near / focus; + var ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom; + var xmin, xmax; - // translate xOffset + // translate xOffset - eyeLeft.elements[ 12 ] = - eyeSep; - eyeRight.elements[ 12 ] = eyeSep; + eyeLeft.elements[ 12 ] = - eyeSep; + eyeRight.elements[ 12 ] = eyeSep; - // for left eye + // for left eye - xmin = - ymax * aspect + eyeSepOnProjection; - xmax = ymax * aspect + eyeSepOnProjection; + xmin = - ymax * aspect + eyeSepOnProjection; + xmax = ymax * aspect + eyeSepOnProjection; - projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin ); - projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin ); + projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin ); + projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin ); - this.cameraL.projectionMatrix.copy( projectionMatrix ); + this.cameraL.projectionMatrix.copy( projectionMatrix ); - // for right eye + // for right eye - xmin = - ymax * aspect - eyeSepOnProjection; - xmax = ymax * aspect - eyeSepOnProjection; + xmin = - ymax * aspect - eyeSepOnProjection; + xmax = ymax * aspect - eyeSepOnProjection; - projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin ); - projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin ); + projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin ); + projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin ); - this.cameraR.projectionMatrix.copy( projectionMatrix ); + this.cameraR.projectionMatrix.copy( projectionMatrix ); - } + } - this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft ); - this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight ); + this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft ); + this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight ); - }; + }; - } )() + } )() - } ); + } ); - /** - * Camera for rendering cube maps - * - renders scene into axis-aligned cube - * - * @author alteredq / http://alteredqualia.com/ - */ + /** + * Camera for rendering cube maps + * - renders scene into axis-aligned cube + * + * @author alteredq / http://alteredqualia.com/ + */ - function CubeCamera( near, far, cubeResolution ) { + function CubeCamera( near, far, cubeResolution ) { - Object3D.call( this ); + Object3D.call( this ); - this.type = 'CubeCamera'; + this.type = 'CubeCamera'; - var fov = 90, aspect = 1; + var fov = 90, aspect = 1; - var cameraPX = new PerspectiveCamera( fov, aspect, near, far ); - cameraPX.up.set( 0, - 1, 0 ); - cameraPX.lookAt( new Vector3( 1, 0, 0 ) ); - this.add( cameraPX ); + var cameraPX = new PerspectiveCamera( fov, aspect, near, far ); + cameraPX.up.set( 0, - 1, 0 ); + cameraPX.lookAt( new Vector3( 1, 0, 0 ) ); + this.add( cameraPX ); - var cameraNX = new PerspectiveCamera( fov, aspect, near, far ); - cameraNX.up.set( 0, - 1, 0 ); - cameraNX.lookAt( new Vector3( - 1, 0, 0 ) ); - this.add( cameraNX ); + var cameraNX = new PerspectiveCamera( fov, aspect, near, far ); + cameraNX.up.set( 0, - 1, 0 ); + cameraNX.lookAt( new Vector3( - 1, 0, 0 ) ); + this.add( cameraNX ); - var cameraPY = new PerspectiveCamera( fov, aspect, near, far ); - cameraPY.up.set( 0, 0, 1 ); - cameraPY.lookAt( new Vector3( 0, 1, 0 ) ); - this.add( cameraPY ); + var cameraPY = new PerspectiveCamera( fov, aspect, near, far ); + cameraPY.up.set( 0, 0, 1 ); + cameraPY.lookAt( new Vector3( 0, 1, 0 ) ); + this.add( cameraPY ); - var cameraNY = new PerspectiveCamera( fov, aspect, near, far ); - cameraNY.up.set( 0, 0, - 1 ); - cameraNY.lookAt( new Vector3( 0, - 1, 0 ) ); - this.add( cameraNY ); + var cameraNY = new PerspectiveCamera( fov, aspect, near, far ); + cameraNY.up.set( 0, 0, - 1 ); + cameraNY.lookAt( new Vector3( 0, - 1, 0 ) ); + this.add( cameraNY ); - var cameraPZ = new PerspectiveCamera( fov, aspect, near, far ); - cameraPZ.up.set( 0, - 1, 0 ); - cameraPZ.lookAt( new Vector3( 0, 0, 1 ) ); - this.add( cameraPZ ); + var cameraPZ = new PerspectiveCamera( fov, aspect, near, far ); + cameraPZ.up.set( 0, - 1, 0 ); + cameraPZ.lookAt( new Vector3( 0, 0, 1 ) ); + this.add( cameraPZ ); - var cameraNZ = new PerspectiveCamera( fov, aspect, near, far ); - cameraNZ.up.set( 0, - 1, 0 ); - cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) ); - this.add( cameraNZ ); + var cameraNZ = new PerspectiveCamera( fov, aspect, near, far ); + cameraNZ.up.set( 0, - 1, 0 ); + cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) ); + this.add( cameraNZ ); - var options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter }; + var options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter }; - this.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options ); - this.renderTarget.texture.name = "CubeCamera"; + this.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options ); + this.renderTarget.texture.name = "CubeCamera"; - this.update = function ( renderer, scene ) { + this.update = function ( renderer, scene ) { - if ( this.parent === null ) this.updateMatrixWorld(); + if ( this.parent === null ) this.updateMatrixWorld(); - var renderTarget = this.renderTarget; - var generateMipmaps = renderTarget.texture.generateMipmaps; + var renderTarget = this.renderTarget; + var generateMipmaps = renderTarget.texture.generateMipmaps; - renderTarget.texture.generateMipmaps = false; + renderTarget.texture.generateMipmaps = false; - renderTarget.activeCubeFace = 0; - renderer.render( scene, cameraPX, renderTarget ); + renderTarget.activeCubeFace = 0; + renderer.render( scene, cameraPX, renderTarget ); - renderTarget.activeCubeFace = 1; - renderer.render( scene, cameraNX, renderTarget ); + renderTarget.activeCubeFace = 1; + renderer.render( scene, cameraNX, renderTarget ); - renderTarget.activeCubeFace = 2; - renderer.render( scene, cameraPY, renderTarget ); + renderTarget.activeCubeFace = 2; + renderer.render( scene, cameraPY, renderTarget ); - renderTarget.activeCubeFace = 3; - renderer.render( scene, cameraNY, renderTarget ); + renderTarget.activeCubeFace = 3; + renderer.render( scene, cameraNY, renderTarget ); - renderTarget.activeCubeFace = 4; - renderer.render( scene, cameraPZ, renderTarget ); + renderTarget.activeCubeFace = 4; + renderer.render( scene, cameraPZ, renderTarget ); - renderTarget.texture.generateMipmaps = generateMipmaps; + renderTarget.texture.generateMipmaps = generateMipmaps; - renderTarget.activeCubeFace = 5; - renderer.render( scene, cameraNZ, renderTarget ); + renderTarget.activeCubeFace = 5; + renderer.render( scene, cameraNZ, renderTarget ); - renderer.setRenderTarget( null ); + renderer.setRenderTarget( null ); - }; + }; - this.clear = function ( renderer, color, depth, stencil ) { + this.clear = function ( renderer, color, depth, stencil ) { - var renderTarget = this.renderTarget; + var renderTarget = this.renderTarget; - for ( var i = 0; i < 6; i ++ ) { + for ( var i = 0; i < 6; i ++ ) { - renderTarget.activeCubeFace = i; - renderer.setRenderTarget( renderTarget ); + renderTarget.activeCubeFace = i; + renderer.setRenderTarget( renderTarget ); - renderer.clear( color, depth, stencil ); + renderer.clear( color, depth, stencil ); - } + } - renderer.setRenderTarget( null ); + renderer.setRenderTarget( null ); - }; + }; - } + } - CubeCamera.prototype = Object.create( Object3D.prototype ); - CubeCamera.prototype.constructor = CubeCamera; + CubeCamera.prototype = Object.create( Object3D.prototype ); + CubeCamera.prototype.constructor = CubeCamera; - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function AudioListener() { + function AudioListener() { - Object3D.call( this ); + Object3D.call( this ); - this.type = 'AudioListener'; + this.type = 'AudioListener'; - this.context = AudioContext.getContext(); + this.context = AudioContext.getContext(); - this.gain = this.context.createGain(); - this.gain.connect( this.context.destination ); + this.gain = this.context.createGain(); + this.gain.connect( this.context.destination ); - this.filter = null; + this.filter = null; - } + } - AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), { + AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), { - constructor: AudioListener, + constructor: AudioListener, - getInput: function () { + getInput: function () { - return this.gain; + return this.gain; - }, + }, - removeFilter: function ( ) { + removeFilter: function ( ) { - if ( this.filter !== null ) { + if ( this.filter !== null ) { - this.gain.disconnect( this.filter ); - this.filter.disconnect( this.context.destination ); - this.gain.connect( this.context.destination ); - this.filter = null; + this.gain.disconnect( this.filter ); + this.filter.disconnect( this.context.destination ); + this.gain.connect( this.context.destination ); + this.filter = null; - } + } - return this; + return this; - }, + }, - getFilter: function () { + getFilter: function () { - return this.filter; + return this.filter; - }, + }, - setFilter: function ( value ) { + setFilter: function ( value ) { - if ( this.filter !== null ) { + if ( this.filter !== null ) { - this.gain.disconnect( this.filter ); - this.filter.disconnect( this.context.destination ); + this.gain.disconnect( this.filter ); + this.filter.disconnect( this.context.destination ); - } else { + } else { - this.gain.disconnect( this.context.destination ); + this.gain.disconnect( this.context.destination ); - } + } - this.filter = value; - this.gain.connect( this.filter ); - this.filter.connect( this.context.destination ); + this.filter = value; + this.gain.connect( this.filter ); + this.filter.connect( this.context.destination ); - return this; + return this; - }, + }, - getMasterVolume: function () { + getMasterVolume: function () { - return this.gain.gain.value; + return this.gain.gain.value; - }, + }, - setMasterVolume: function ( value ) { + setMasterVolume: function ( value ) { - this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 ); + this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 ); - return this; + return this; - }, + }, - updateMatrixWorld: ( function () { + updateMatrixWorld: ( function () { - var position = new Vector3(); - var quaternion = new Quaternion(); - var scale = new Vector3(); + var position = new Vector3(); + var quaternion = new Quaternion(); + var scale = new Vector3(); - var orientation = new Vector3(); + var orientation = new Vector3(); - return function updateMatrixWorld( force ) { + return function updateMatrixWorld( force ) { - Object3D.prototype.updateMatrixWorld.call( this, force ); + Object3D.prototype.updateMatrixWorld.call( this, force ); - var listener = this.context.listener; - var up = this.up; + var listener = this.context.listener; + var up = this.up; - this.matrixWorld.decompose( position, quaternion, scale ); + this.matrixWorld.decompose( position, quaternion, scale ); - orientation.set( 0, 0, - 1 ).applyQuaternion( quaternion ); + orientation.set( 0, 0, - 1 ).applyQuaternion( quaternion ); - if ( listener.positionX ) { + if ( listener.positionX ) { - listener.positionX.setValueAtTime( position.x, this.context.currentTime ); - listener.positionY.setValueAtTime( position.y, this.context.currentTime ); - listener.positionZ.setValueAtTime( position.z, this.context.currentTime ); - listener.forwardX.setValueAtTime( orientation.x, this.context.currentTime ); - listener.forwardY.setValueAtTime( orientation.y, this.context.currentTime ); - listener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime ); - listener.upX.setValueAtTime( up.x, this.context.currentTime ); - listener.upY.setValueAtTime( up.y, this.context.currentTime ); - listener.upZ.setValueAtTime( up.z, this.context.currentTime ); + listener.positionX.setValueAtTime( position.x, this.context.currentTime ); + listener.positionY.setValueAtTime( position.y, this.context.currentTime ); + listener.positionZ.setValueAtTime( position.z, this.context.currentTime ); + listener.forwardX.setValueAtTime( orientation.x, this.context.currentTime ); + listener.forwardY.setValueAtTime( orientation.y, this.context.currentTime ); + listener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime ); + listener.upX.setValueAtTime( up.x, this.context.currentTime ); + listener.upY.setValueAtTime( up.y, this.context.currentTime ); + listener.upZ.setValueAtTime( up.z, this.context.currentTime ); - } else { + } else { - listener.setPosition( position.x, position.y, position.z ); - listener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z ); + listener.setPosition( position.x, position.y, position.z ); + listener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z ); - } + } - }; + }; - } )() + } )() - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author Reece Aaron Lecrivain / http://reecenotes.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author Reece Aaron Lecrivain / http://reecenotes.com/ + */ - function Audio( listener ) { + function Audio( listener ) { - Object3D.call( this ); + Object3D.call( this ); - this.type = 'Audio'; + this.type = 'Audio'; - this.context = listener.context; + this.context = listener.context; - this.gain = this.context.createGain(); - this.gain.connect( listener.getInput() ); + this.gain = this.context.createGain(); + this.gain.connect( listener.getInput() ); - this.autoplay = false; + this.autoplay = false; - this.buffer = null; - this.loop = false; - this.startTime = 0; - this.offset = 0; - this.playbackRate = 1; - this.isPlaying = false; - this.hasPlaybackControl = true; - this.sourceType = 'empty'; + this.buffer = null; + this.loop = false; + this.startTime = 0; + this.offset = 0; + this.playbackRate = 1; + this.isPlaying = false; + this.hasPlaybackControl = true; + this.sourceType = 'empty'; - this.filters = []; + this.filters = []; - } + } - Audio.prototype = Object.assign( Object.create( Object3D.prototype ), { + Audio.prototype = Object.assign( Object.create( Object3D.prototype ), { - constructor: Audio, + constructor: Audio, - getOutput: function () { + getOutput: function () { - return this.gain; + return this.gain; - }, + }, - setNodeSource: function ( audioNode ) { + setNodeSource: function ( audioNode ) { - this.hasPlaybackControl = false; - this.sourceType = 'audioNode'; - this.source = audioNode; - this.connect(); + this.hasPlaybackControl = false; + this.sourceType = 'audioNode'; + this.source = audioNode; + this.connect(); - return this; + return this; - }, + }, - setMediaElementSource: function ( mediaElement ) { + setMediaElementSource: function ( mediaElement ) { - this.hasPlaybackControl = false; - this.sourceType = 'mediaNode'; - this.source = this.context.createMediaElementSource( mediaElement ); - this.connect(); + this.hasPlaybackControl = false; + this.sourceType = 'mediaNode'; + this.source = this.context.createMediaElementSource( mediaElement ); + this.connect(); - return this; + return this; - }, + }, - setBuffer: function ( audioBuffer ) { + setBuffer: function ( audioBuffer ) { - this.buffer = audioBuffer; - this.sourceType = 'buffer'; + this.buffer = audioBuffer; + this.sourceType = 'buffer'; - if ( this.autoplay ) this.play(); + if ( this.autoplay ) this.play(); - return this; + return this; - }, + }, - play: function () { + play: function () { - if ( this.isPlaying === true ) { + if ( this.isPlaying === true ) { - console.warn( 'THREE.Audio: Audio is already playing.' ); - return; + console.warn( 'THREE.Audio: Audio is already playing.' ); + return; - } + } - if ( this.hasPlaybackControl === false ) { + if ( this.hasPlaybackControl === false ) { - console.warn( 'THREE.Audio: this Audio has no playback control.' ); - return; + console.warn( 'THREE.Audio: this Audio has no playback control.' ); + return; - } + } - var source = this.context.createBufferSource(); + var source = this.context.createBufferSource(); - source.buffer = this.buffer; - source.loop = this.loop; - source.onended = this.onEnded.bind( this ); - source.playbackRate.setValueAtTime( this.playbackRate, this.startTime ); - this.startTime = this.context.currentTime; - source.start( this.startTime, this.offset ); + source.buffer = this.buffer; + source.loop = this.loop; + source.onended = this.onEnded.bind( this ); + source.playbackRate.setValueAtTime( this.playbackRate, this.startTime ); + this.startTime = this.context.currentTime; + source.start( this.startTime, this.offset ); - this.isPlaying = true; + this.isPlaying = true; - this.source = source; + this.source = source; - return this.connect(); + return this.connect(); - }, + }, - pause: function () { + pause: function () { - if ( this.hasPlaybackControl === false ) { + if ( this.hasPlaybackControl === false ) { - console.warn( 'THREE.Audio: this Audio has no playback control.' ); - return; + console.warn( 'THREE.Audio: this Audio has no playback control.' ); + return; - } + } - if ( this.isPlaying === true ) { + if ( this.isPlaying === true ) { - this.source.stop(); - this.source.onended = null; - this.offset += ( this.context.currentTime - this.startTime ) * this.playbackRate; - this.isPlaying = false; + this.source.stop(); + this.source.onended = null; + this.offset += ( this.context.currentTime - this.startTime ) * this.playbackRate; + this.isPlaying = false; - } + } - return this; + return this; - }, + }, - stop: function () { + stop: function () { - if ( this.hasPlaybackControl === false ) { + if ( this.hasPlaybackControl === false ) { - console.warn( 'THREE.Audio: this Audio has no playback control.' ); - return; + console.warn( 'THREE.Audio: this Audio has no playback control.' ); + return; - } + } - this.source.stop(); - this.source.onended = null; - this.offset = 0; - this.isPlaying = false; + this.source.stop(); + this.source.onended = null; + this.offset = 0; + this.isPlaying = false; - return this; + return this; - }, + }, - connect: function () { + connect: function () { - if ( this.filters.length > 0 ) { + if ( this.filters.length > 0 ) { - this.source.connect( this.filters[ 0 ] ); + this.source.connect( this.filters[ 0 ] ); - for ( var i = 1, l = this.filters.length; i < l; i ++ ) { + for ( var i = 1, l = this.filters.length; i < l; i ++ ) { - this.filters[ i - 1 ].connect( this.filters[ i ] ); + this.filters[ i - 1 ].connect( this.filters[ i ] ); - } + } - this.filters[ this.filters.length - 1 ].connect( this.getOutput() ); + this.filters[ this.filters.length - 1 ].connect( this.getOutput() ); - } else { + } else { - this.source.connect( this.getOutput() ); + this.source.connect( this.getOutput() ); - } + } - return this; + return this; - }, + }, - disconnect: function () { + disconnect: function () { - if ( this.filters.length > 0 ) { + if ( this.filters.length > 0 ) { - this.source.disconnect( this.filters[ 0 ] ); + this.source.disconnect( this.filters[ 0 ] ); - for ( var i = 1, l = this.filters.length; i < l; i ++ ) { + for ( var i = 1, l = this.filters.length; i < l; i ++ ) { - this.filters[ i - 1 ].disconnect( this.filters[ i ] ); + this.filters[ i - 1 ].disconnect( this.filters[ i ] ); - } + } - this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() ); + this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() ); - } else { + } else { - this.source.disconnect( this.getOutput() ); + this.source.disconnect( this.getOutput() ); - } + } - return this; + return this; - }, + }, - getFilters: function () { + getFilters: function () { - return this.filters; + return this.filters; - }, + }, - setFilters: function ( value ) { + setFilters: function ( value ) { - if ( ! value ) value = []; + if ( ! value ) value = []; - if ( this.isPlaying === true ) { + if ( this.isPlaying === true ) { - this.disconnect(); - this.filters = value; - this.connect(); + this.disconnect(); + this.filters = value; + this.connect(); - } else { + } else { - this.filters = value; + this.filters = value; - } + } - return this; + return this; - }, + }, - getFilter: function () { + getFilter: function () { - return this.getFilters()[ 0 ]; + return this.getFilters()[ 0 ]; - }, + }, - setFilter: function ( filter ) { + setFilter: function ( filter ) { - return this.setFilters( filter ? [ filter ] : [] ); + return this.setFilters( filter ? [ filter ] : [] ); - }, + }, - setPlaybackRate: function ( value ) { + setPlaybackRate: function ( value ) { - if ( this.hasPlaybackControl === false ) { + if ( this.hasPlaybackControl === false ) { - console.warn( 'THREE.Audio: this Audio has no playback control.' ); - return; + console.warn( 'THREE.Audio: this Audio has no playback control.' ); + return; - } + } - this.playbackRate = value; + this.playbackRate = value; - if ( this.isPlaying === true ) { + if ( this.isPlaying === true ) { - this.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime ); + this.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime ); - } + } - return this; + return this; - }, + }, - getPlaybackRate: function () { + getPlaybackRate: function () { - return this.playbackRate; + return this.playbackRate; - }, + }, - onEnded: function () { + onEnded: function () { - this.isPlaying = false; + this.isPlaying = false; - }, + }, - getLoop: function () { + getLoop: function () { - if ( this.hasPlaybackControl === false ) { + if ( this.hasPlaybackControl === false ) { - console.warn( 'THREE.Audio: this Audio has no playback control.' ); - return false; + console.warn( 'THREE.Audio: this Audio has no playback control.' ); + return false; - } + } - return this.loop; + return this.loop; - }, + }, - setLoop: function ( value ) { + setLoop: function ( value ) { - if ( this.hasPlaybackControl === false ) { + if ( this.hasPlaybackControl === false ) { - console.warn( 'THREE.Audio: this Audio has no playback control.' ); - return; + console.warn( 'THREE.Audio: this Audio has no playback control.' ); + return; - } + } - this.loop = value; + this.loop = value; - if ( this.isPlaying === true ) { + if ( this.isPlaying === true ) { - this.source.loop = this.loop; + this.source.loop = this.loop; - } + } - return this; + return this; - }, + }, - getVolume: function () { + getVolume: function () { - return this.gain.gain.value; + return this.gain.gain.value; - }, + }, - setVolume: function ( value ) { + setVolume: function ( value ) { - this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 ); + this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 ); - return this; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function PositionalAudio( listener ) { + function PositionalAudio( listener ) { - Audio.call( this, listener ); + Audio.call( this, listener ); - this.panner = this.context.createPanner(); - this.panner.connect( this.gain ); + this.panner = this.context.createPanner(); + this.panner.connect( this.gain ); - } + } - PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), { + PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), { - constructor: PositionalAudio, + constructor: PositionalAudio, - getOutput: function () { + getOutput: function () { - return this.panner; + return this.panner; - }, + }, - getRefDistance: function () { + getRefDistance: function () { - return this.panner.refDistance; + return this.panner.refDistance; - }, + }, - setRefDistance: function ( value ) { + setRefDistance: function ( value ) { - this.panner.refDistance = value; + this.panner.refDistance = value; - return this; + return this; - }, + }, - getRolloffFactor: function () { + getRolloffFactor: function () { - return this.panner.rolloffFactor; + return this.panner.rolloffFactor; - }, + }, - setRolloffFactor: function ( value ) { + setRolloffFactor: function ( value ) { - this.panner.rolloffFactor = value; + this.panner.rolloffFactor = value; - return this; + return this; - }, + }, - getDistanceModel: function () { + getDistanceModel: function () { - return this.panner.distanceModel; + return this.panner.distanceModel; - }, + }, - setDistanceModel: function ( value ) { + setDistanceModel: function ( value ) { - this.panner.distanceModel = value; + this.panner.distanceModel = value; - return this; + return this; - }, + }, - getMaxDistance: function () { + getMaxDistance: function () { - return this.panner.maxDistance; + return this.panner.maxDistance; - }, + }, - setMaxDistance: function ( value ) { + setMaxDistance: function ( value ) { - this.panner.maxDistance = value; + this.panner.maxDistance = value; - return this; + return this; - }, + }, - setDirectionalCone: function ( coneInnerAngle, coneOuterAngle, coneOuterGain ) { + setDirectionalCone: function ( coneInnerAngle, coneOuterAngle, coneOuterGain ) { - this.panner.coneInnerAngle = coneInnerAngle; - this.panner.coneOuterAngle = coneOuterAngle; - this.panner.coneOuterGain = coneOuterGain; + this.panner.coneInnerAngle = coneInnerAngle; + this.panner.coneOuterAngle = coneOuterAngle; + this.panner.coneOuterGain = coneOuterGain; - return this; + return this; - }, + }, - updateMatrixWorld: ( function () { + updateMatrixWorld: ( function () { - var position = new Vector3(); - var quaternion = new Quaternion(); - var scale = new Vector3(); + var position = new Vector3(); + var quaternion = new Quaternion(); + var scale = new Vector3(); - var orientation = new Vector3(); + var orientation = new Vector3(); - return function updateMatrixWorld( force ) { + return function updateMatrixWorld( force ) { - Object3D.prototype.updateMatrixWorld.call( this, force ); + Object3D.prototype.updateMatrixWorld.call( this, force ); - var panner = this.panner; - this.matrixWorld.decompose( position, quaternion, scale ); + var panner = this.panner; + this.matrixWorld.decompose( position, quaternion, scale ); - orientation.set( 0, 0, 1 ).applyQuaternion( quaternion ); + orientation.set( 0, 0, 1 ).applyQuaternion( quaternion ); - panner.setPosition( position.x, position.y, position.z ); - panner.setOrientation( orientation.x, orientation.y, orientation.z ); + panner.setPosition( position.x, position.y, position.z ); + panner.setOrientation( orientation.x, orientation.y, orientation.z ); - }; + }; - } )() + } )() - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function AudioAnalyser( audio, fftSize ) { + function AudioAnalyser( audio, fftSize ) { - this.analyser = audio.context.createAnalyser(); - this.analyser.fftSize = fftSize !== undefined ? fftSize : 2048; + this.analyser = audio.context.createAnalyser(); + this.analyser.fftSize = fftSize !== undefined ? fftSize : 2048; - this.data = new Uint8Array( this.analyser.frequencyBinCount ); + this.data = new Uint8Array( this.analyser.frequencyBinCount ); - audio.getOutput().connect( this.analyser ); + audio.getOutput().connect( this.analyser ); - } + } - Object.assign( AudioAnalyser.prototype, { + Object.assign( AudioAnalyser.prototype, { - getFrequencyData: function () { + getFrequencyData: function () { - this.analyser.getByteFrequencyData( this.data ); + this.analyser.getByteFrequencyData( this.data ); - return this.data; + return this.data; - }, + }, - getAverageFrequency: function () { + getAverageFrequency: function () { - var value = 0, data = this.getFrequencyData(); + var value = 0, data = this.getFrequencyData(); - for ( var i = 0; i < data.length; i ++ ) { + for ( var i = 0; i < data.length; i ++ ) { - value += data[ i ]; + value += data[ i ]; - } + } - return value / data.length; + return value / data.length; - } + } - } ); + } ); - /** - * - * Buffered scene graph property that allows weighted accumulation. - * - * - * @author Ben Houston / http://clara.io/ - * @author David Sarno / http://lighthaus.us/ - * @author tschw - */ + /** + * + * Buffered scene graph property that allows weighted accumulation. + * + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + * @author tschw + */ - function PropertyMixer( binding, typeName, valueSize ) { + function PropertyMixer( binding, typeName, valueSize ) { - this.binding = binding; - this.valueSize = valueSize; + this.binding = binding; + this.valueSize = valueSize; - var bufferType = Float64Array, - mixFunction; + var bufferType = Float64Array, + mixFunction; - switch ( typeName ) { + switch ( typeName ) { - case 'quaternion': - mixFunction = this._slerp; - break; + case 'quaternion': + mixFunction = this._slerp; + break; - case 'string': - case 'bool': - bufferType = Array; - mixFunction = this._select; - break; + case 'string': + case 'bool': + bufferType = Array; + mixFunction = this._select; + break; - default: - mixFunction = this._lerp; + default: + mixFunction = this._lerp; - } + } - this.buffer = new bufferType( valueSize * 4 ); - // layout: [ incoming | accu0 | accu1 | orig ] - // - // interpolators can use .buffer as their .result - // the data then goes to 'incoming' - // - // 'accu0' and 'accu1' are used frame-interleaved for - // the cumulative result and are compared to detect - // changes - // - // 'orig' stores the original state of the property + this.buffer = new bufferType( valueSize * 4 ); + // layout: [ incoming | accu0 | accu1 | orig ] + // + // interpolators can use .buffer as their .result + // the data then goes to 'incoming' + // + // 'accu0' and 'accu1' are used frame-interleaved for + // the cumulative result and are compared to detect + // changes + // + // 'orig' stores the original state of the property - this._mixBufferRegion = mixFunction; + this._mixBufferRegion = mixFunction; - this.cumulativeWeight = 0; + this.cumulativeWeight = 0; - this.useCount = 0; - this.referenceCount = 0; + this.useCount = 0; + this.referenceCount = 0; - } + } - Object.assign( PropertyMixer.prototype, { + Object.assign( PropertyMixer.prototype, { - // accumulate data in the 'incoming' region into 'accu' - accumulate: function ( accuIndex, weight ) { + // accumulate data in the 'incoming' region into 'accu' + accumulate: function ( accuIndex, weight ) { - // note: happily accumulating nothing when weight = 0, the caller knows - // the weight and shouldn't have made the call in the first place + // note: happily accumulating nothing when weight = 0, the caller knows + // the weight and shouldn't have made the call in the first place - var buffer = this.buffer, - stride = this.valueSize, - offset = accuIndex * stride + stride, + var buffer = this.buffer, + stride = this.valueSize, + offset = accuIndex * stride + stride, - currentWeight = this.cumulativeWeight; + currentWeight = this.cumulativeWeight; - if ( currentWeight === 0 ) { + if ( currentWeight === 0 ) { - // accuN := incoming * weight + // accuN := incoming * weight - for ( var i = 0; i !== stride; ++ i ) { + for ( var i = 0; i !== stride; ++ i ) { - buffer[ offset + i ] = buffer[ i ]; + buffer[ offset + i ] = buffer[ i ]; - } + } - currentWeight = weight; + currentWeight = weight; - } else { + } else { - // accuN := accuN + incoming * weight + // accuN := accuN + incoming * weight - currentWeight += weight; - var mix = weight / currentWeight; - this._mixBufferRegion( buffer, offset, 0, mix, stride ); + currentWeight += weight; + var mix = weight / currentWeight; + this._mixBufferRegion( buffer, offset, 0, mix, stride ); - } + } - this.cumulativeWeight = currentWeight; + this.cumulativeWeight = currentWeight; - }, + }, - // apply the state of 'accu' to the binding when accus differ - apply: function ( accuIndex ) { + // apply the state of 'accu' to the binding when accus differ + apply: function ( accuIndex ) { - var stride = this.valueSize, - buffer = this.buffer, - offset = accuIndex * stride + stride, + var stride = this.valueSize, + buffer = this.buffer, + offset = accuIndex * stride + stride, - weight = this.cumulativeWeight, + weight = this.cumulativeWeight, - binding = this.binding; + binding = this.binding; - this.cumulativeWeight = 0; + this.cumulativeWeight = 0; - if ( weight < 1 ) { + if ( weight < 1 ) { - // accuN := accuN + original * ( 1 - cumulativeWeight ) + // accuN := accuN + original * ( 1 - cumulativeWeight ) - var originalValueOffset = stride * 3; + var originalValueOffset = stride * 3; - this._mixBufferRegion( - buffer, offset, originalValueOffset, 1 - weight, stride ); + this._mixBufferRegion( + buffer, offset, originalValueOffset, 1 - weight, stride ); - } + } - for ( var i = stride, e = stride + stride; i !== e; ++ i ) { + for ( var i = stride, e = stride + stride; i !== e; ++ i ) { - if ( buffer[ i ] !== buffer[ i + stride ] ) { + if ( buffer[ i ] !== buffer[ i + stride ] ) { - // value has changed -> update scene graph + // value has changed -> update scene graph - binding.setValue( buffer, offset ); - break; + binding.setValue( buffer, offset ); + break; - } + } - } + } - }, + }, - // remember the state of the bound property and copy it to both accus - saveOriginalState: function () { + // remember the state of the bound property and copy it to both accus + saveOriginalState: function () { - var binding = this.binding; + var binding = this.binding; - var buffer = this.buffer, - stride = this.valueSize, + var buffer = this.buffer, + stride = this.valueSize, - originalValueOffset = stride * 3; + originalValueOffset = stride * 3; - binding.getValue( buffer, originalValueOffset ); + binding.getValue( buffer, originalValueOffset ); - // accu[0..1] := orig -- initially detect changes against the original - for ( var i = stride, e = originalValueOffset; i !== e; ++ i ) { + // accu[0..1] := orig -- initially detect changes against the original + for ( var i = stride, e = originalValueOffset; i !== e; ++ i ) { - buffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ]; + buffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ]; - } + } - this.cumulativeWeight = 0; + this.cumulativeWeight = 0; - }, + }, - // apply the state previously taken via 'saveOriginalState' to the binding - restoreOriginalState: function () { + // apply the state previously taken via 'saveOriginalState' to the binding + restoreOriginalState: function () { - var originalValueOffset = this.valueSize * 3; - this.binding.setValue( this.buffer, originalValueOffset ); + var originalValueOffset = this.valueSize * 3; + this.binding.setValue( this.buffer, originalValueOffset ); - }, + }, - // mix functions + // mix functions - _select: function ( buffer, dstOffset, srcOffset, t, stride ) { + _select: function ( buffer, dstOffset, srcOffset, t, stride ) { - if ( t >= 0.5 ) { + if ( t >= 0.5 ) { - for ( var i = 0; i !== stride; ++ i ) { + for ( var i = 0; i !== stride; ++ i ) { - buffer[ dstOffset + i ] = buffer[ srcOffset + i ]; + buffer[ dstOffset + i ] = buffer[ srcOffset + i ]; - } + } - } + } - }, + }, - _slerp: function ( buffer, dstOffset, srcOffset, t ) { + _slerp: function ( buffer, dstOffset, srcOffset, t ) { - Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t ); + Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t ); - }, + }, - _lerp: function ( buffer, dstOffset, srcOffset, t, stride ) { + _lerp: function ( buffer, dstOffset, srcOffset, t, stride ) { - var s = 1 - t; + var s = 1 - t; - for ( var i = 0; i !== stride; ++ i ) { + for ( var i = 0; i !== stride; ++ i ) { - var j = dstOffset + i; + var j = dstOffset + i; - buffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t; + buffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t; - } + } - } + } - } ); + } ); - /** - * - * A reference to a real property in the scene graph. - * - * - * @author Ben Houston / http://clara.io/ - * @author David Sarno / http://lighthaus.us/ - * @author tschw - */ + /** + * + * A reference to a real property in the scene graph. + * + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + * @author tschw + */ - // Characters [].:/ are reserved for track binding syntax. - var RESERVED_CHARS_RE = '\\[\\]\\.:\\/'; + // Characters [].:/ are reserved for track binding syntax. + var RESERVED_CHARS_RE = '\\[\\]\\.:\\/'; - function Composite( targetGroup, path, optionalParsedPath ) { + function Composite( targetGroup, path, optionalParsedPath ) { - var parsedPath = optionalParsedPath || PropertyBinding.parseTrackName( path ); + var parsedPath = optionalParsedPath || PropertyBinding.parseTrackName( path ); - this._targetGroup = targetGroup; - this._bindings = targetGroup.subscribe_( path, parsedPath ); + this._targetGroup = targetGroup; + this._bindings = targetGroup.subscribe_( path, parsedPath ); - } + } - Object.assign( Composite.prototype, { + Object.assign( Composite.prototype, { - getValue: function ( array, offset ) { + getValue: function ( array, offset ) { - this.bind(); // bind all binding + this.bind(); // bind all binding - var firstValidIndex = this._targetGroup.nCachedObjects_, - binding = this._bindings[ firstValidIndex ]; + var firstValidIndex = this._targetGroup.nCachedObjects_, + binding = this._bindings[ firstValidIndex ]; - // and only call .getValue on the first - if ( binding !== undefined ) binding.getValue( array, offset ); + // and only call .getValue on the first + if ( binding !== undefined ) binding.getValue( array, offset ); - }, + }, - setValue: function ( array, offset ) { + setValue: function ( array, offset ) { - var bindings = this._bindings; + var bindings = this._bindings; - for ( var i = this._targetGroup.nCachedObjects_, - n = bindings.length; i !== n; ++ i ) { + for ( var i = this._targetGroup.nCachedObjects_, + n = bindings.length; i !== n; ++ i ) { - bindings[ i ].setValue( array, offset ); + bindings[ i ].setValue( array, offset ); - } + } - }, + }, - bind: function () { + bind: function () { - var bindings = this._bindings; + var bindings = this._bindings; - for ( var i = this._targetGroup.nCachedObjects_, - n = bindings.length; i !== n; ++ i ) { + for ( var i = this._targetGroup.nCachedObjects_, + n = bindings.length; i !== n; ++ i ) { - bindings[ i ].bind(); + bindings[ i ].bind(); - } + } - }, + }, - unbind: function () { + unbind: function () { - var bindings = this._bindings; + var bindings = this._bindings; - for ( var i = this._targetGroup.nCachedObjects_, - n = bindings.length; i !== n; ++ i ) { + for ( var i = this._targetGroup.nCachedObjects_, + n = bindings.length; i !== n; ++ i ) { - bindings[ i ].unbind(); + bindings[ i ].unbind(); - } + } - } + } - } ); + } ); - function PropertyBinding( rootNode, path, parsedPath ) { + function PropertyBinding( rootNode, path, parsedPath ) { - this.path = path; - this.parsedPath = parsedPath || PropertyBinding.parseTrackName( path ); + this.path = path; + this.parsedPath = parsedPath || PropertyBinding.parseTrackName( path ); - this.node = PropertyBinding.findNode( rootNode, this.parsedPath.nodeName ) || rootNode; + this.node = PropertyBinding.findNode( rootNode, this.parsedPath.nodeName ) || rootNode; - this.rootNode = rootNode; + this.rootNode = rootNode; - } + } - Object.assign( PropertyBinding, { + Object.assign( PropertyBinding, { - Composite: Composite, + Composite: Composite, - create: function ( root, path, parsedPath ) { + create: function ( root, path, parsedPath ) { - if ( ! ( root && root.isAnimationObjectGroup ) ) { + if ( ! ( root && root.isAnimationObjectGroup ) ) { - return new PropertyBinding( root, path, parsedPath ); + return new PropertyBinding( root, path, parsedPath ); - } else { + } else { - return new PropertyBinding.Composite( root, path, parsedPath ); + return new PropertyBinding.Composite( root, path, parsedPath ); - } + } - }, + }, - /** - * Replaces spaces with underscores and removes unsupported characters from - * node names, to ensure compatibility with parseTrackName(). - * - * @param {string} name Node name to be sanitized. - * @return {string} - */ - sanitizeNodeName: ( function () { + /** + * Replaces spaces with underscores and removes unsupported characters from + * node names, to ensure compatibility with parseTrackName(). + * + * @param {string} name Node name to be sanitized. + * @return {string} + */ + sanitizeNodeName: ( function () { - var reservedRe = new RegExp( '[' + RESERVED_CHARS_RE + ']', 'g' ); + var reservedRe = new RegExp( '[' + RESERVED_CHARS_RE + ']', 'g' ); - return function sanitizeNodeName( name ) { + return function sanitizeNodeName( name ) { - return name.replace( /\s/g, '_' ).replace( reservedRe, '' ); + return name.replace( /\s/g, '_' ).replace( reservedRe, '' ); - }; + }; - }() ), + }() ), - parseTrackName: function () { + parseTrackName: function () { - // Attempts to allow node names from any language. ES5's `\w` regexp matches - // only latin characters, and the unicode \p{L} is not yet supported. So - // instead, we exclude reserved characters and match everything else. - var wordChar = '[^' + RESERVED_CHARS_RE + ']'; - var wordCharOrDot = '[^' + RESERVED_CHARS_RE.replace( '\\.', '' ) + ']'; + // Attempts to allow node names from any language. ES5's `\w` regexp matches + // only latin characters, and the unicode \p{L} is not yet supported. So + // instead, we exclude reserved characters and match everything else. + var wordChar = '[^' + RESERVED_CHARS_RE + ']'; + var wordCharOrDot = '[^' + RESERVED_CHARS_RE.replace( '\\.', '' ) + ']'; - // Parent directories, delimited by '/' or ':'. Currently unused, but must - // be matched to parse the rest of the track name. - var directoryRe = /((?:WC+[\/:])*)/.source.replace( 'WC', wordChar ); + // Parent directories, delimited by '/' or ':'. Currently unused, but must + // be matched to parse the rest of the track name. + var directoryRe = /((?:WC+[\/:])*)/.source.replace( 'WC', wordChar ); - // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. - var nodeRe = /(WCOD+)?/.source.replace( 'WCOD', wordCharOrDot ); + // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'. + var nodeRe = /(WCOD+)?/.source.replace( 'WCOD', wordCharOrDot ); - // Object on target node, and accessor. May not contain reserved - // characters. Accessor may contain any character except closing bracket. - var objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace( 'WC', wordChar ); + // Object on target node, and accessor. May not contain reserved + // characters. Accessor may contain any character except closing bracket. + var objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace( 'WC', wordChar ); - // Property and accessor. May not contain reserved characters. Accessor may - // contain any non-bracket characters. - var propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace( 'WC', wordChar ); + // Property and accessor. May not contain reserved characters. Accessor may + // contain any non-bracket characters. + var propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace( 'WC', wordChar ); - var trackRe = new RegExp( '' - + '^' - + directoryRe - + nodeRe - + objectRe - + propertyRe - + '$' - ); + var trackRe = new RegExp( '' + + '^' + + directoryRe + + nodeRe + + objectRe + + propertyRe + + '$' + ); - var supportedObjectNames = [ 'material', 'materials', 'bones' ]; + var supportedObjectNames = [ 'material', 'materials', 'bones' ]; - return function parseTrackName( trackName ) { + return function parseTrackName( trackName ) { - var matches = trackRe.exec( trackName ); + var matches = trackRe.exec( trackName ); - if ( ! matches ) { + if ( ! matches ) { - throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName ); + throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName ); - } + } - var results = { - // directoryName: matches[ 1 ], // (tschw) currently unused - nodeName: matches[ 2 ], - objectName: matches[ 3 ], - objectIndex: matches[ 4 ], - propertyName: matches[ 5 ], // required - propertyIndex: matches[ 6 ] - }; + var results = { + // directoryName: matches[ 1 ], // (tschw) currently unused + nodeName: matches[ 2 ], + objectName: matches[ 3 ], + objectIndex: matches[ 4 ], + propertyName: matches[ 5 ], // required + propertyIndex: matches[ 6 ] + }; - var lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' ); + var lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' ); - if ( lastDot !== undefined && lastDot !== - 1 ) { + if ( lastDot !== undefined && lastDot !== - 1 ) { - var objectName = results.nodeName.substring( lastDot + 1 ); + var objectName = results.nodeName.substring( lastDot + 1 ); - // Object names must be checked against a whitelist. Otherwise, there - // is no way to parse 'foo.bar.baz': 'baz' must be a property, but - // 'bar' could be the objectName, or part of a nodeName (which can - // include '.' characters). - if ( supportedObjectNames.indexOf( objectName ) !== - 1 ) { + // Object names must be checked against a whitelist. Otherwise, there + // is no way to parse 'foo.bar.baz': 'baz' must be a property, but + // 'bar' could be the objectName, or part of a nodeName (which can + // include '.' characters). + if ( supportedObjectNames.indexOf( objectName ) !== - 1 ) { - results.nodeName = results.nodeName.substring( 0, lastDot ); - results.objectName = objectName; + results.nodeName = results.nodeName.substring( 0, lastDot ); + results.objectName = objectName; - } + } - } + } - if ( results.propertyName === null || results.propertyName.length === 0 ) { + if ( results.propertyName === null || results.propertyName.length === 0 ) { - throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName ); + throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName ); - } + } - return results; + return results; - }; + }; - }(), + }(), - findNode: function ( root, nodeName ) { + findNode: function ( root, nodeName ) { - if ( ! nodeName || nodeName === "" || nodeName === "root" || nodeName === "." || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) { + if ( ! nodeName || nodeName === "" || nodeName === "root" || nodeName === "." || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) { - return root; + return root; - } + } - // search into skeleton bones. - if ( root.skeleton ) { + // search into skeleton bones. + if ( root.skeleton ) { - var bone = root.skeleton.getBoneByName( nodeName ); + var bone = root.skeleton.getBoneByName( nodeName ); - if ( bone !== undefined ) { + if ( bone !== undefined ) { - return bone; + return bone; - } + } - } + } - // search into node subtree. - if ( root.children ) { + // search into node subtree. + if ( root.children ) { - var searchNodeSubtree = function ( children ) { + var searchNodeSubtree = function ( children ) { - for ( var i = 0; i < children.length; i ++ ) { + for ( var i = 0; i < children.length; i ++ ) { - var childNode = children[ i ]; + var childNode = children[ i ]; - if ( childNode.name === nodeName || childNode.uuid === nodeName ) { + if ( childNode.name === nodeName || childNode.uuid === nodeName ) { - return childNode; + return childNode; - } + } - var result = searchNodeSubtree( childNode.children ); + var result = searchNodeSubtree( childNode.children ); - if ( result ) return result; + if ( result ) return result; - } + } - return null; + return null; - }; + }; - var subTreeNode = searchNodeSubtree( root.children ); + var subTreeNode = searchNodeSubtree( root.children ); - if ( subTreeNode ) { + if ( subTreeNode ) { - return subTreeNode; + return subTreeNode; - } + } - } + } - return null; + return null; - } + } - } ); + } ); - Object.assign( PropertyBinding.prototype, { // prototype, continued + Object.assign( PropertyBinding.prototype, { // prototype, continued - // these are used to "bind" a nonexistent property - _getValue_unavailable: function () {}, - _setValue_unavailable: function () {}, + // these are used to "bind" a nonexistent property + _getValue_unavailable: function () {}, + _setValue_unavailable: function () {}, - BindingType: { - Direct: 0, - EntireArray: 1, - ArrayElement: 2, - HasFromToArray: 3 - }, + BindingType: { + Direct: 0, + EntireArray: 1, + ArrayElement: 2, + HasFromToArray: 3 + }, - Versioning: { - None: 0, - NeedsUpdate: 1, - MatrixWorldNeedsUpdate: 2 - }, + Versioning: { + None: 0, + NeedsUpdate: 1, + MatrixWorldNeedsUpdate: 2 + }, - GetterByBindingType: [ + GetterByBindingType: [ - function getValue_direct( buffer, offset ) { + function getValue_direct( buffer, offset ) { - buffer[ offset ] = this.node[ this.propertyName ]; + buffer[ offset ] = this.node[ this.propertyName ]; - }, + }, - function getValue_array( buffer, offset ) { + function getValue_array( buffer, offset ) { - var source = this.resolvedProperty; + var source = this.resolvedProperty; - for ( var i = 0, n = source.length; i !== n; ++ i ) { + for ( var i = 0, n = source.length; i !== n; ++ i ) { - buffer[ offset ++ ] = source[ i ]; + buffer[ offset ++ ] = source[ i ]; - } + } - }, + }, - function getValue_arrayElement( buffer, offset ) { + function getValue_arrayElement( buffer, offset ) { - buffer[ offset ] = this.resolvedProperty[ this.propertyIndex ]; + buffer[ offset ] = this.resolvedProperty[ this.propertyIndex ]; - }, + }, - function getValue_toArray( buffer, offset ) { + function getValue_toArray( buffer, offset ) { - this.resolvedProperty.toArray( buffer, offset ); + this.resolvedProperty.toArray( buffer, offset ); - } + } - ], + ], - SetterByBindingTypeAndVersioning: [ + SetterByBindingTypeAndVersioning: [ - [ - // Direct + [ + // Direct - function setValue_direct( buffer, offset ) { + function setValue_direct( buffer, offset ) { - this.targetObject[ this.propertyName ] = buffer[ offset ]; + this.targetObject[ this.propertyName ] = buffer[ offset ]; - }, + }, - function setValue_direct_setNeedsUpdate( buffer, offset ) { + function setValue_direct_setNeedsUpdate( buffer, offset ) { - this.targetObject[ this.propertyName ] = buffer[ offset ]; - this.targetObject.needsUpdate = true; + this.targetObject[ this.propertyName ] = buffer[ offset ]; + this.targetObject.needsUpdate = true; - }, + }, - function setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) { + function setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) { - this.targetObject[ this.propertyName ] = buffer[ offset ]; - this.targetObject.matrixWorldNeedsUpdate = true; + this.targetObject[ this.propertyName ] = buffer[ offset ]; + this.targetObject.matrixWorldNeedsUpdate = true; - } + } - ], [ + ], [ - // EntireArray + // EntireArray - function setValue_array( buffer, offset ) { + function setValue_array( buffer, offset ) { - var dest = this.resolvedProperty; + var dest = this.resolvedProperty; - for ( var i = 0, n = dest.length; i !== n; ++ i ) { + for ( var i = 0, n = dest.length; i !== n; ++ i ) { - dest[ i ] = buffer[ offset ++ ]; + dest[ i ] = buffer[ offset ++ ]; - } + } - }, + }, - function setValue_array_setNeedsUpdate( buffer, offset ) { + function setValue_array_setNeedsUpdate( buffer, offset ) { - var dest = this.resolvedProperty; + var dest = this.resolvedProperty; - for ( var i = 0, n = dest.length; i !== n; ++ i ) { + for ( var i = 0, n = dest.length; i !== n; ++ i ) { - dest[ i ] = buffer[ offset ++ ]; + dest[ i ] = buffer[ offset ++ ]; - } + } - this.targetObject.needsUpdate = true; + this.targetObject.needsUpdate = true; - }, + }, - function setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) { + function setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) { - var dest = this.resolvedProperty; + var dest = this.resolvedProperty; - for ( var i = 0, n = dest.length; i !== n; ++ i ) { + for ( var i = 0, n = dest.length; i !== n; ++ i ) { - dest[ i ] = buffer[ offset ++ ]; + dest[ i ] = buffer[ offset ++ ]; - } + } - this.targetObject.matrixWorldNeedsUpdate = true; + this.targetObject.matrixWorldNeedsUpdate = true; - } + } - ], [ + ], [ - // ArrayElement + // ArrayElement - function setValue_arrayElement( buffer, offset ) { + function setValue_arrayElement( buffer, offset ) { - this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ]; + this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ]; - }, + }, - function setValue_arrayElement_setNeedsUpdate( buffer, offset ) { + function setValue_arrayElement_setNeedsUpdate( buffer, offset ) { - this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ]; - this.targetObject.needsUpdate = true; + this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ]; + this.targetObject.needsUpdate = true; - }, + }, - function setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) { + function setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) { - this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ]; - this.targetObject.matrixWorldNeedsUpdate = true; + this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ]; + this.targetObject.matrixWorldNeedsUpdate = true; - } + } - ], [ + ], [ - // HasToFromArray + // HasToFromArray - function setValue_fromArray( buffer, offset ) { + function setValue_fromArray( buffer, offset ) { - this.resolvedProperty.fromArray( buffer, offset ); + this.resolvedProperty.fromArray( buffer, offset ); - }, + }, - function setValue_fromArray_setNeedsUpdate( buffer, offset ) { + function setValue_fromArray_setNeedsUpdate( buffer, offset ) { - this.resolvedProperty.fromArray( buffer, offset ); - this.targetObject.needsUpdate = true; + this.resolvedProperty.fromArray( buffer, offset ); + this.targetObject.needsUpdate = true; - }, + }, - function setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) { + function setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) { - this.resolvedProperty.fromArray( buffer, offset ); - this.targetObject.matrixWorldNeedsUpdate = true; + this.resolvedProperty.fromArray( buffer, offset ); + this.targetObject.matrixWorldNeedsUpdate = true; - } + } - ] + ] - ], + ], - getValue: function getValue_unbound( targetArray, offset ) { + getValue: function getValue_unbound( targetArray, offset ) { - this.bind(); - this.getValue( targetArray, offset ); + this.bind(); + this.getValue( targetArray, offset ); - // Note: This class uses a State pattern on a per-method basis: - // 'bind' sets 'this.getValue' / 'setValue' and shadows the - // prototype version of these methods with one that represents - // the bound state. When the property is not found, the methods - // become no-ops. + // Note: This class uses a State pattern on a per-method basis: + // 'bind' sets 'this.getValue' / 'setValue' and shadows the + // prototype version of these methods with one that represents + // the bound state. When the property is not found, the methods + // become no-ops. - }, + }, - setValue: function getValue_unbound( sourceArray, offset ) { + setValue: function getValue_unbound( sourceArray, offset ) { - this.bind(); - this.setValue( sourceArray, offset ); + this.bind(); + this.setValue( sourceArray, offset ); - }, + }, - // create getter / setter pair for a property in the scene graph - bind: function () { + // create getter / setter pair for a property in the scene graph + bind: function () { - var targetObject = this.node, - parsedPath = this.parsedPath, + var targetObject = this.node, + parsedPath = this.parsedPath, - objectName = parsedPath.objectName, - propertyName = parsedPath.propertyName, - propertyIndex = parsedPath.propertyIndex; + objectName = parsedPath.objectName, + propertyName = parsedPath.propertyName, + propertyIndex = parsedPath.propertyIndex; - if ( ! targetObject ) { + if ( ! targetObject ) { - targetObject = PropertyBinding.findNode( this.rootNode, parsedPath.nodeName ) || this.rootNode; + targetObject = PropertyBinding.findNode( this.rootNode, parsedPath.nodeName ) || this.rootNode; - this.node = targetObject; + this.node = targetObject; - } + } - // set fail state so we can just 'return' on error - this.getValue = this._getValue_unavailable; - this.setValue = this._setValue_unavailable; + // set fail state so we can just 'return' on error + this.getValue = this._getValue_unavailable; + this.setValue = this._setValue_unavailable; - // ensure there is a value node - if ( ! targetObject ) { + // ensure there is a value node + if ( ! targetObject ) { - console.error( 'THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.' ); - return; + console.error( 'THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.' ); + return; - } + } - if ( objectName ) { + if ( objectName ) { - var objectIndex = parsedPath.objectIndex; + var objectIndex = parsedPath.objectIndex; - // special cases were we need to reach deeper into the hierarchy to get the face materials.... - switch ( objectName ) { + // special cases were we need to reach deeper into the hierarchy to get the face materials.... + switch ( objectName ) { - case 'materials': + case 'materials': - if ( ! targetObject.material ) { + if ( ! targetObject.material ) { - console.error( 'THREE.PropertyBinding: Can not bind to material as node does not have a material.', this ); - return; + console.error( 'THREE.PropertyBinding: Can not bind to material as node does not have a material.', this ); + return; - } + } - if ( ! targetObject.material.materials ) { + if ( ! targetObject.material.materials ) { - console.error( 'THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this ); - return; + console.error( 'THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this ); + return; - } + } - targetObject = targetObject.material.materials; + targetObject = targetObject.material.materials; - break; + break; - case 'bones': + case 'bones': - if ( ! targetObject.skeleton ) { + if ( ! targetObject.skeleton ) { - console.error( 'THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this ); - return; + console.error( 'THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this ); + return; - } + } - // potential future optimization: skip this if propertyIndex is already an integer - // and convert the integer string to a true integer. + // potential future optimization: skip this if propertyIndex is already an integer + // and convert the integer string to a true integer. - targetObject = targetObject.skeleton.bones; + targetObject = targetObject.skeleton.bones; - // support resolving morphTarget names into indices. - for ( var i = 0; i < targetObject.length; i ++ ) { + // support resolving morphTarget names into indices. + for ( var i = 0; i < targetObject.length; i ++ ) { - if ( targetObject[ i ].name === objectIndex ) { + if ( targetObject[ i ].name === objectIndex ) { - objectIndex = i; - break; + objectIndex = i; + break; - } + } - } + } - break; + break; - default: + default: - if ( targetObject[ objectName ] === undefined ) { + if ( targetObject[ objectName ] === undefined ) { - console.error( 'THREE.PropertyBinding: Can not bind to objectName of node undefined.', this ); - return; + console.error( 'THREE.PropertyBinding: Can not bind to objectName of node undefined.', this ); + return; - } + } - targetObject = targetObject[ objectName ]; + targetObject = targetObject[ objectName ]; - } + } - if ( objectIndex !== undefined ) { + if ( objectIndex !== undefined ) { - if ( targetObject[ objectIndex ] === undefined ) { + if ( targetObject[ objectIndex ] === undefined ) { - console.error( 'THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject ); - return; + console.error( 'THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject ); + return; - } + } - targetObject = targetObject[ objectIndex ]; + targetObject = targetObject[ objectIndex ]; - } + } - } + } - // resolve property - var nodeProperty = targetObject[ propertyName ]; + // resolve property + var nodeProperty = targetObject[ propertyName ]; - if ( nodeProperty === undefined ) { + if ( nodeProperty === undefined ) { - var nodeName = parsedPath.nodeName; + var nodeName = parsedPath.nodeName; - console.error( 'THREE.PropertyBinding: Trying to update property for track: ' + nodeName + - '.' + propertyName + ' but it wasn\'t found.', targetObject ); - return; + console.error( 'THREE.PropertyBinding: Trying to update property for track: ' + nodeName + + '.' + propertyName + ' but it wasn\'t found.', targetObject ); + return; - } + } - // determine versioning scheme - var versioning = this.Versioning.None; + // determine versioning scheme + var versioning = this.Versioning.None; - if ( targetObject.needsUpdate !== undefined ) { // material + if ( targetObject.needsUpdate !== undefined ) { // material - versioning = this.Versioning.NeedsUpdate; - this.targetObject = targetObject; + versioning = this.Versioning.NeedsUpdate; + this.targetObject = targetObject; - } else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform + } else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform - versioning = this.Versioning.MatrixWorldNeedsUpdate; - this.targetObject = targetObject; + versioning = this.Versioning.MatrixWorldNeedsUpdate; + this.targetObject = targetObject; - } + } - // determine how the property gets bound - var bindingType = this.BindingType.Direct; + // determine how the property gets bound + var bindingType = this.BindingType.Direct; - if ( propertyIndex !== undefined ) { + if ( propertyIndex !== undefined ) { - // access a sub element of the property array (only primitives are supported right now) + // access a sub element of the property array (only primitives are supported right now) - if ( propertyName === "morphTargetInfluences" ) { + if ( propertyName === "morphTargetInfluences" ) { - // potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer. + // potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer. - // support resolving morphTarget names into indices. - if ( ! targetObject.geometry ) { + // support resolving morphTarget names into indices. + if ( ! targetObject.geometry ) { - console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this ); - return; + console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this ); + return; - } + } - if ( targetObject.geometry.isBufferGeometry ) { + if ( targetObject.geometry.isBufferGeometry ) { - if ( ! targetObject.geometry.morphAttributes ) { + if ( ! targetObject.geometry.morphAttributes ) { - console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this ); - return; + console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this ); + return; - } + } - for ( var i = 0; i < this.node.geometry.morphAttributes.position.length; i ++ ) { + for ( var i = 0; i < this.node.geometry.morphAttributes.position.length; i ++ ) { - if ( targetObject.geometry.morphAttributes.position[ i ].name === propertyIndex ) { + if ( targetObject.geometry.morphAttributes.position[ i ].name === propertyIndex ) { - propertyIndex = i; - break; + propertyIndex = i; + break; - } + } - } + } - } else { + } else { - if ( ! targetObject.geometry.morphTargets ) { + if ( ! targetObject.geometry.morphTargets ) { - console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphTargets.', this ); - return; + console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphTargets.', this ); + return; - } + } - for ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) { + for ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) { - if ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) { + if ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) { - propertyIndex = i; - break; + propertyIndex = i; + break; - } + } - } + } - } + } - } + } - bindingType = this.BindingType.ArrayElement; + bindingType = this.BindingType.ArrayElement; - this.resolvedProperty = nodeProperty; - this.propertyIndex = propertyIndex; + this.resolvedProperty = nodeProperty; + this.propertyIndex = propertyIndex; - } else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) { + } else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) { - // must use copy for Object3D.Euler/Quaternion + // must use copy for Object3D.Euler/Quaternion - bindingType = this.BindingType.HasFromToArray; + bindingType = this.BindingType.HasFromToArray; - this.resolvedProperty = nodeProperty; + this.resolvedProperty = nodeProperty; - } else if ( Array.isArray( nodeProperty ) ) { + } else if ( Array.isArray( nodeProperty ) ) { - bindingType = this.BindingType.EntireArray; + bindingType = this.BindingType.EntireArray; - this.resolvedProperty = nodeProperty; + this.resolvedProperty = nodeProperty; - } else { + } else { - this.propertyName = propertyName; + this.propertyName = propertyName; - } + } - // select getter / setter - this.getValue = this.GetterByBindingType[ bindingType ]; - this.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ]; + // select getter / setter + this.getValue = this.GetterByBindingType[ bindingType ]; + this.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ]; - }, + }, - unbind: function () { + unbind: function () { - this.node = null; + this.node = null; - // back to the prototype version of getValue / setValue - // note: avoiding to mutate the shape of 'this' via 'delete' - this.getValue = this._getValue_unbound; - this.setValue = this._setValue_unbound; + // back to the prototype version of getValue / setValue + // note: avoiding to mutate the shape of 'this' via 'delete' + this.getValue = this._getValue_unbound; + this.setValue = this._setValue_unbound; - } + } - } ); + } ); - //!\ DECLARE ALIAS AFTER assign prototype ! - Object.assign( PropertyBinding.prototype, { + //!\ DECLARE ALIAS AFTER assign prototype ! + Object.assign( PropertyBinding.prototype, { - // initial state of these methods that calls 'bind' - _getValue_unbound: PropertyBinding.prototype.getValue, - _setValue_unbound: PropertyBinding.prototype.setValue, + // initial state of these methods that calls 'bind' + _getValue_unbound: PropertyBinding.prototype.getValue, + _setValue_unbound: PropertyBinding.prototype.setValue, - } ); + } ); - /** - * - * A group of objects that receives a shared animation state. - * - * Usage: - * - * - Add objects you would otherwise pass as 'root' to the - * constructor or the .clipAction method of AnimationMixer. - * - * - Instead pass this object as 'root'. - * - * - You can also add and remove objects later when the mixer - * is running. - * - * Note: - * - * Objects of this class appear as one object to the mixer, - * so cache control of the individual objects must be done - * on the group. - * - * Limitation: - * - * - The animated properties must be compatible among the - * all objects in the group. - * - * - A single property can either be controlled through a - * target group or directly, but not both. - * - * @author tschw - */ + /** + * + * A group of objects that receives a shared animation state. + * + * Usage: + * + * - Add objects you would otherwise pass as 'root' to the + * constructor or the .clipAction method of AnimationMixer. + * + * - Instead pass this object as 'root'. + * + * - You can also add and remove objects later when the mixer + * is running. + * + * Note: + * + * Objects of this class appear as one object to the mixer, + * so cache control of the individual objects must be done + * on the group. + * + * Limitation: + * + * - The animated properties must be compatible among the + * all objects in the group. + * + * - A single property can either be controlled through a + * target group or directly, but not both. + * + * @author tschw + */ - function AnimationObjectGroup() { + function AnimationObjectGroup() { - this.uuid = _Math.generateUUID(); + this.uuid = _Math.generateUUID(); - // cached objects followed by the active ones - this._objects = Array.prototype.slice.call( arguments ); + // cached objects followed by the active ones + this._objects = Array.prototype.slice.call( arguments ); - this.nCachedObjects_ = 0; // threshold - // note: read by PropertyBinding.Composite + this.nCachedObjects_ = 0; // threshold + // note: read by PropertyBinding.Composite - var indices = {}; - this._indicesByUUID = indices; // for bookkeeping + var indices = {}; + this._indicesByUUID = indices; // for bookkeeping - for ( var i = 0, n = arguments.length; i !== n; ++ i ) { + for ( var i = 0, n = arguments.length; i !== n; ++ i ) { - indices[ arguments[ i ].uuid ] = i; + indices[ arguments[ i ].uuid ] = i; - } + } - this._paths = []; // inside: string - this._parsedPaths = []; // inside: { we don't care, here } - this._bindings = []; // inside: Array< PropertyBinding > - this._bindingsIndicesByPath = {}; // inside: indices in these arrays + this._paths = []; // inside: string + this._parsedPaths = []; // inside: { we don't care, here } + this._bindings = []; // inside: Array< PropertyBinding > + this._bindingsIndicesByPath = {}; // inside: indices in these arrays - var scope = this; + var scope = this; - this.stats = { + this.stats = { - objects: { - get total() { + objects: { + get total() { - return scope._objects.length; + return scope._objects.length; - }, - get inUse() { + }, + get inUse() { - return this.total - scope.nCachedObjects_; + return this.total - scope.nCachedObjects_; - } - }, - get bindingsPerObject() { + } + }, + get bindingsPerObject() { - return scope._bindings.length; + return scope._bindings.length; - } + } - }; + }; - } + } - Object.assign( AnimationObjectGroup.prototype, { + Object.assign( AnimationObjectGroup.prototype, { - isAnimationObjectGroup: true, + isAnimationObjectGroup: true, - add: function () { + add: function () { - var objects = this._objects, - nObjects = objects.length, - nCachedObjects = this.nCachedObjects_, - indicesByUUID = this._indicesByUUID, - paths = this._paths, - parsedPaths = this._parsedPaths, - bindings = this._bindings, - nBindings = bindings.length, - knownObject = undefined; + var objects = this._objects, + nObjects = objects.length, + nCachedObjects = this.nCachedObjects_, + indicesByUUID = this._indicesByUUID, + paths = this._paths, + parsedPaths = this._parsedPaths, + bindings = this._bindings, + nBindings = bindings.length, + knownObject = undefined; - for ( var i = 0, n = arguments.length; i !== n; ++ i ) { + for ( var i = 0, n = arguments.length; i !== n; ++ i ) { - var object = arguments[ i ], - uuid = object.uuid, - index = indicesByUUID[ uuid ]; + var object = arguments[ i ], + uuid = object.uuid, + index = indicesByUUID[ uuid ]; - if ( index === undefined ) { + if ( index === undefined ) { - // unknown object -> add it to the ACTIVE region + // unknown object -> add it to the ACTIVE region - index = nObjects ++; - indicesByUUID[ uuid ] = index; - objects.push( object ); + index = nObjects ++; + indicesByUUID[ uuid ] = index; + objects.push( object ); - // accounting is done, now do the same for all bindings + // accounting is done, now do the same for all bindings - for ( var j = 0, m = nBindings; j !== m; ++ j ) { + for ( var j = 0, m = nBindings; j !== m; ++ j ) { - bindings[ j ].push( new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ) ); + bindings[ j ].push( new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ) ); - } + } - } else if ( index < nCachedObjects ) { + } else if ( index < nCachedObjects ) { - knownObject = objects[ index ]; + knownObject = objects[ index ]; - // move existing object to the ACTIVE region + // move existing object to the ACTIVE region - var firstActiveIndex = -- nCachedObjects, - lastCachedObject = objects[ firstActiveIndex ]; + var firstActiveIndex = -- nCachedObjects, + lastCachedObject = objects[ firstActiveIndex ]; - indicesByUUID[ lastCachedObject.uuid ] = index; - objects[ index ] = lastCachedObject; + indicesByUUID[ lastCachedObject.uuid ] = index; + objects[ index ] = lastCachedObject; - indicesByUUID[ uuid ] = firstActiveIndex; - objects[ firstActiveIndex ] = object; + indicesByUUID[ uuid ] = firstActiveIndex; + objects[ firstActiveIndex ] = object; - // accounting is done, now do the same for all bindings + // accounting is done, now do the same for all bindings - for ( var j = 0, m = nBindings; j !== m; ++ j ) { + for ( var j = 0, m = nBindings; j !== m; ++ j ) { - var bindingsForPath = bindings[ j ], - lastCached = bindingsForPath[ firstActiveIndex ], - binding = bindingsForPath[ index ]; + var bindingsForPath = bindings[ j ], + lastCached = bindingsForPath[ firstActiveIndex ], + binding = bindingsForPath[ index ]; - bindingsForPath[ index ] = lastCached; + bindingsForPath[ index ] = lastCached; - if ( binding === undefined ) { + if ( binding === undefined ) { - // since we do not bother to create new bindings - // for objects that are cached, the binding may - // or may not exist + // since we do not bother to create new bindings + // for objects that are cached, the binding may + // or may not exist - binding = new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ); + binding = new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ); - } + } - bindingsForPath[ firstActiveIndex ] = binding; + bindingsForPath[ firstActiveIndex ] = binding; - } + } - } else if ( objects[ index ] !== knownObject ) { + } else if ( objects[ index ] !== knownObject ) { - console.error( 'THREE.AnimationObjectGroup: Different objects with the same UUID ' + - 'detected. Clean the caches or recreate your infrastructure when reloading scenes.' ); + console.error( 'THREE.AnimationObjectGroup: Different objects with the same UUID ' + + 'detected. Clean the caches or recreate your infrastructure when reloading scenes.' ); - } // else the object is already where we want it to be + } // else the object is already where we want it to be - } // for arguments + } // for arguments - this.nCachedObjects_ = nCachedObjects; + this.nCachedObjects_ = nCachedObjects; - }, + }, - remove: function () { + remove: function () { - var objects = this._objects, - nCachedObjects = this.nCachedObjects_, - indicesByUUID = this._indicesByUUID, - bindings = this._bindings, - nBindings = bindings.length; + var objects = this._objects, + nCachedObjects = this.nCachedObjects_, + indicesByUUID = this._indicesByUUID, + bindings = this._bindings, + nBindings = bindings.length; - for ( var i = 0, n = arguments.length; i !== n; ++ i ) { + for ( var i = 0, n = arguments.length; i !== n; ++ i ) { - var object = arguments[ i ], - uuid = object.uuid, - index = indicesByUUID[ uuid ]; + var object = arguments[ i ], + uuid = object.uuid, + index = indicesByUUID[ uuid ]; - if ( index !== undefined && index >= nCachedObjects ) { + if ( index !== undefined && index >= nCachedObjects ) { - // move existing object into the CACHED region + // move existing object into the CACHED region - var lastCachedIndex = nCachedObjects ++, - firstActiveObject = objects[ lastCachedIndex ]; + var lastCachedIndex = nCachedObjects ++, + firstActiveObject = objects[ lastCachedIndex ]; - indicesByUUID[ firstActiveObject.uuid ] = index; - objects[ index ] = firstActiveObject; + indicesByUUID[ firstActiveObject.uuid ] = index; + objects[ index ] = firstActiveObject; - indicesByUUID[ uuid ] = lastCachedIndex; - objects[ lastCachedIndex ] = object; + indicesByUUID[ uuid ] = lastCachedIndex; + objects[ lastCachedIndex ] = object; - // accounting is done, now do the same for all bindings + // accounting is done, now do the same for all bindings - for ( var j = 0, m = nBindings; j !== m; ++ j ) { + for ( var j = 0, m = nBindings; j !== m; ++ j ) { - var bindingsForPath = bindings[ j ], - firstActive = bindingsForPath[ lastCachedIndex ], - binding = bindingsForPath[ index ]; + var bindingsForPath = bindings[ j ], + firstActive = bindingsForPath[ lastCachedIndex ], + binding = bindingsForPath[ index ]; - bindingsForPath[ index ] = firstActive; - bindingsForPath[ lastCachedIndex ] = binding; + bindingsForPath[ index ] = firstActive; + bindingsForPath[ lastCachedIndex ] = binding; - } + } - } + } - } // for arguments + } // for arguments - this.nCachedObjects_ = nCachedObjects; + this.nCachedObjects_ = nCachedObjects; - }, + }, - // remove & forget - uncache: function () { + // remove & forget + uncache: function () { - var objects = this._objects, - nObjects = objects.length, - nCachedObjects = this.nCachedObjects_, - indicesByUUID = this._indicesByUUID, - bindings = this._bindings, - nBindings = bindings.length; + var objects = this._objects, + nObjects = objects.length, + nCachedObjects = this.nCachedObjects_, + indicesByUUID = this._indicesByUUID, + bindings = this._bindings, + nBindings = bindings.length; - for ( var i = 0, n = arguments.length; i !== n; ++ i ) { + for ( var i = 0, n = arguments.length; i !== n; ++ i ) { - var object = arguments[ i ], - uuid = object.uuid, - index = indicesByUUID[ uuid ]; + var object = arguments[ i ], + uuid = object.uuid, + index = indicesByUUID[ uuid ]; - if ( index !== undefined ) { + if ( index !== undefined ) { - delete indicesByUUID[ uuid ]; + delete indicesByUUID[ uuid ]; - if ( index < nCachedObjects ) { + if ( index < nCachedObjects ) { - // object is cached, shrink the CACHED region + // object is cached, shrink the CACHED region - var firstActiveIndex = -- nCachedObjects, - lastCachedObject = objects[ firstActiveIndex ], - lastIndex = -- nObjects, - lastObject = objects[ lastIndex ]; + var firstActiveIndex = -- nCachedObjects, + lastCachedObject = objects[ firstActiveIndex ], + lastIndex = -- nObjects, + lastObject = objects[ lastIndex ]; - // last cached object takes this object's place - indicesByUUID[ lastCachedObject.uuid ] = index; - objects[ index ] = lastCachedObject; + // last cached object takes this object's place + indicesByUUID[ lastCachedObject.uuid ] = index; + objects[ index ] = lastCachedObject; - // last object goes to the activated slot and pop - indicesByUUID[ lastObject.uuid ] = firstActiveIndex; - objects[ firstActiveIndex ] = lastObject; - objects.pop(); + // last object goes to the activated slot and pop + indicesByUUID[ lastObject.uuid ] = firstActiveIndex; + objects[ firstActiveIndex ] = lastObject; + objects.pop(); - // accounting is done, now do the same for all bindings + // accounting is done, now do the same for all bindings - for ( var j = 0, m = nBindings; j !== m; ++ j ) { + for ( var j = 0, m = nBindings; j !== m; ++ j ) { - var bindingsForPath = bindings[ j ], - lastCached = bindingsForPath[ firstActiveIndex ], - last = bindingsForPath[ lastIndex ]; + var bindingsForPath = bindings[ j ], + lastCached = bindingsForPath[ firstActiveIndex ], + last = bindingsForPath[ lastIndex ]; - bindingsForPath[ index ] = lastCached; - bindingsForPath[ firstActiveIndex ] = last; - bindingsForPath.pop(); + bindingsForPath[ index ] = lastCached; + bindingsForPath[ firstActiveIndex ] = last; + bindingsForPath.pop(); - } + } - } else { + } else { - // object is active, just swap with the last and pop + // object is active, just swap with the last and pop - var lastIndex = -- nObjects, - lastObject = objects[ lastIndex ]; + var lastIndex = -- nObjects, + lastObject = objects[ lastIndex ]; - indicesByUUID[ lastObject.uuid ] = index; - objects[ index ] = lastObject; - objects.pop(); + indicesByUUID[ lastObject.uuid ] = index; + objects[ index ] = lastObject; + objects.pop(); - // accounting is done, now do the same for all bindings + // accounting is done, now do the same for all bindings - for ( var j = 0, m = nBindings; j !== m; ++ j ) { + for ( var j = 0, m = nBindings; j !== m; ++ j ) { - var bindingsForPath = bindings[ j ]; + var bindingsForPath = bindings[ j ]; - bindingsForPath[ index ] = bindingsForPath[ lastIndex ]; - bindingsForPath.pop(); + bindingsForPath[ index ] = bindingsForPath[ lastIndex ]; + bindingsForPath.pop(); - } + } - } // cached or active + } // cached or active - } // if object is known + } // if object is known - } // for arguments + } // for arguments - this.nCachedObjects_ = nCachedObjects; + this.nCachedObjects_ = nCachedObjects; - }, + }, - // Internal interface used by befriended PropertyBinding.Composite: + // Internal interface used by befriended PropertyBinding.Composite: - subscribe_: function ( path, parsedPath ) { + subscribe_: function ( path, parsedPath ) { - // returns an array of bindings for the given path that is changed - // according to the contained objects in the group + // returns an array of bindings for the given path that is changed + // according to the contained objects in the group - var indicesByPath = this._bindingsIndicesByPath, - index = indicesByPath[ path ], - bindings = this._bindings; + var indicesByPath = this._bindingsIndicesByPath, + index = indicesByPath[ path ], + bindings = this._bindings; - if ( index !== undefined ) return bindings[ index ]; + if ( index !== undefined ) return bindings[ index ]; - var paths = this._paths, - parsedPaths = this._parsedPaths, - objects = this._objects, - nObjects = objects.length, - nCachedObjects = this.nCachedObjects_, - bindingsForPath = new Array( nObjects ); + var paths = this._paths, + parsedPaths = this._parsedPaths, + objects = this._objects, + nObjects = objects.length, + nCachedObjects = this.nCachedObjects_, + bindingsForPath = new Array( nObjects ); - index = bindings.length; + index = bindings.length; - indicesByPath[ path ] = index; + indicesByPath[ path ] = index; - paths.push( path ); - parsedPaths.push( parsedPath ); - bindings.push( bindingsForPath ); + paths.push( path ); + parsedPaths.push( parsedPath ); + bindings.push( bindingsForPath ); - for ( var i = nCachedObjects, n = objects.length; i !== n; ++ i ) { + for ( var i = nCachedObjects, n = objects.length; i !== n; ++ i ) { - var object = objects[ i ]; - bindingsForPath[ i ] = new PropertyBinding( object, path, parsedPath ); + var object = objects[ i ]; + bindingsForPath[ i ] = new PropertyBinding( object, path, parsedPath ); - } + } - return bindingsForPath; + return bindingsForPath; - }, + }, - unsubscribe_: function ( path ) { + unsubscribe_: function ( path ) { - // tells the group to forget about a property path and no longer - // update the array previously obtained with 'subscribe_' + // tells the group to forget about a property path and no longer + // update the array previously obtained with 'subscribe_' - var indicesByPath = this._bindingsIndicesByPath, - index = indicesByPath[ path ]; + var indicesByPath = this._bindingsIndicesByPath, + index = indicesByPath[ path ]; - if ( index !== undefined ) { + if ( index !== undefined ) { - var paths = this._paths, - parsedPaths = this._parsedPaths, - bindings = this._bindings, - lastBindingsIndex = bindings.length - 1, - lastBindings = bindings[ lastBindingsIndex ], - lastBindingsPath = path[ lastBindingsIndex ]; + var paths = this._paths, + parsedPaths = this._parsedPaths, + bindings = this._bindings, + lastBindingsIndex = bindings.length - 1, + lastBindings = bindings[ lastBindingsIndex ], + lastBindingsPath = path[ lastBindingsIndex ]; - indicesByPath[ lastBindingsPath ] = index; + indicesByPath[ lastBindingsPath ] = index; - bindings[ index ] = lastBindings; - bindings.pop(); + bindings[ index ] = lastBindings; + bindings.pop(); - parsedPaths[ index ] = parsedPaths[ lastBindingsIndex ]; - parsedPaths.pop(); + parsedPaths[ index ] = parsedPaths[ lastBindingsIndex ]; + parsedPaths.pop(); - paths[ index ] = paths[ lastBindingsIndex ]; - paths.pop(); + paths[ index ] = paths[ lastBindingsIndex ]; + paths.pop(); - } + } - } + } - } ); + } ); - /** - * - * Action provided by AnimationMixer for scheduling clip playback on specific - * objects. - * - * @author Ben Houston / http://clara.io/ - * @author David Sarno / http://lighthaus.us/ - * @author tschw - * - */ + /** + * + * Action provided by AnimationMixer for scheduling clip playback on specific + * objects. + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + * @author tschw + * + */ - function AnimationAction( mixer, clip, localRoot ) { + function AnimationAction( mixer, clip, localRoot ) { - this._mixer = mixer; - this._clip = clip; - this._localRoot = localRoot || null; + this._mixer = mixer; + this._clip = clip; + this._localRoot = localRoot || null; - var tracks = clip.tracks, - nTracks = tracks.length, - interpolants = new Array( nTracks ); + var tracks = clip.tracks, + nTracks = tracks.length, + interpolants = new Array( nTracks ); - var interpolantSettings = { - endingStart: ZeroCurvatureEnding, - endingEnd: ZeroCurvatureEnding - }; + var interpolantSettings = { + endingStart: ZeroCurvatureEnding, + endingEnd: ZeroCurvatureEnding + }; - for ( var i = 0; i !== nTracks; ++ i ) { + for ( var i = 0; i !== nTracks; ++ i ) { - var interpolant = tracks[ i ].createInterpolant( null ); - interpolants[ i ] = interpolant; - interpolant.settings = interpolantSettings; + var interpolant = tracks[ i ].createInterpolant( null ); + interpolants[ i ] = interpolant; + interpolant.settings = interpolantSettings; - } + } - this._interpolantSettings = interpolantSettings; + this._interpolantSettings = interpolantSettings; - this._interpolants = interpolants; // bound by the mixer + this._interpolants = interpolants; // bound by the mixer - // inside: PropertyMixer (managed by the mixer) - this._propertyBindings = new Array( nTracks ); + // inside: PropertyMixer (managed by the mixer) + this._propertyBindings = new Array( nTracks ); - this._cacheIndex = null; // for the memory manager - this._byClipCacheIndex = null; // for the memory manager + this._cacheIndex = null; // for the memory manager + this._byClipCacheIndex = null; // for the memory manager - this._timeScaleInterpolant = null; - this._weightInterpolant = null; + this._timeScaleInterpolant = null; + this._weightInterpolant = null; - this.loop = LoopRepeat; - this._loopCount = - 1; + this.loop = LoopRepeat; + this._loopCount = - 1; - // global mixer time when the action is to be started - // it's set back to 'null' upon start of the action - this._startTime = null; + // global mixer time when the action is to be started + // it's set back to 'null' upon start of the action + this._startTime = null; - // scaled local time of the action - // gets clamped or wrapped to 0..clip.duration according to loop - this.time = 0; + // scaled local time of the action + // gets clamped or wrapped to 0..clip.duration according to loop + this.time = 0; - this.timeScale = 1; - this._effectiveTimeScale = 1; + this.timeScale = 1; + this._effectiveTimeScale = 1; - this.weight = 1; - this._effectiveWeight = 1; + this.weight = 1; + this._effectiveWeight = 1; - this.repetitions = Infinity; // no. of repetitions when looping + this.repetitions = Infinity; // no. of repetitions when looping - this.paused = false; // true -> zero effective time scale - this.enabled = true; // false -> zero effective weight + this.paused = false; // true -> zero effective time scale + this.enabled = true; // false -> zero effective weight - this.clampWhenFinished = false; // keep feeding the last frame? + this.clampWhenFinished = false; // keep feeding the last frame? - this.zeroSlopeAtStart = true; // for smooth interpolation w/o separate - this.zeroSlopeAtEnd = true; // clips for start, loop and end + this.zeroSlopeAtStart = true; // for smooth interpolation w/o separate + this.zeroSlopeAtEnd = true; // clips for start, loop and end - } + } - Object.assign( AnimationAction.prototype, { + Object.assign( AnimationAction.prototype, { - // State & Scheduling + // State & Scheduling - play: function () { + play: function () { - this._mixer._activateAction( this ); + this._mixer._activateAction( this ); - return this; + return this; - }, + }, - stop: function () { + stop: function () { - this._mixer._deactivateAction( this ); + this._mixer._deactivateAction( this ); - return this.reset(); + return this.reset(); - }, + }, - reset: function () { + reset: function () { - this.paused = false; - this.enabled = true; + this.paused = false; + this.enabled = true; - this.time = 0; // restart clip - this._loopCount = - 1; // forget previous loops - this._startTime = null; // forget scheduling + this.time = 0; // restart clip + this._loopCount = - 1; // forget previous loops + this._startTime = null; // forget scheduling - return this.stopFading().stopWarping(); + return this.stopFading().stopWarping(); - }, + }, - isRunning: function () { + isRunning: function () { - return this.enabled && ! this.paused && this.timeScale !== 0 && - this._startTime === null && this._mixer._isActiveAction( this ); + return this.enabled && ! this.paused && this.timeScale !== 0 && + this._startTime === null && this._mixer._isActiveAction( this ); - }, + }, - // return true when play has been called - isScheduled: function () { + // return true when play has been called + isScheduled: function () { - return this._mixer._isActiveAction( this ); + return this._mixer._isActiveAction( this ); - }, + }, - startAt: function ( time ) { + startAt: function ( time ) { - this._startTime = time; + this._startTime = time; - return this; + return this; - }, + }, - setLoop: function ( mode, repetitions ) { + setLoop: function ( mode, repetitions ) { - this.loop = mode; - this.repetitions = repetitions; + this.loop = mode; + this.repetitions = repetitions; - return this; + return this; - }, + }, - // Weight + // Weight - // set the weight stopping any scheduled fading - // although .enabled = false yields an effective weight of zero, this - // method does *not* change .enabled, because it would be confusing - setEffectiveWeight: function ( weight ) { + // set the weight stopping any scheduled fading + // although .enabled = false yields an effective weight of zero, this + // method does *not* change .enabled, because it would be confusing + setEffectiveWeight: function ( weight ) { - this.weight = weight; + this.weight = weight; - // note: same logic as when updated at runtime - this._effectiveWeight = this.enabled ? weight : 0; + // note: same logic as when updated at runtime + this._effectiveWeight = this.enabled ? weight : 0; - return this.stopFading(); + return this.stopFading(); - }, + }, - // return the weight considering fading and .enabled - getEffectiveWeight: function () { + // return the weight considering fading and .enabled + getEffectiveWeight: function () { - return this._effectiveWeight; + return this._effectiveWeight; - }, + }, - fadeIn: function ( duration ) { + fadeIn: function ( duration ) { - return this._scheduleFading( duration, 0, 1 ); + return this._scheduleFading( duration, 0, 1 ); - }, + }, - fadeOut: function ( duration ) { + fadeOut: function ( duration ) { - return this._scheduleFading( duration, 1, 0 ); + return this._scheduleFading( duration, 1, 0 ); - }, + }, - crossFadeFrom: function ( fadeOutAction, duration, warp ) { + crossFadeFrom: function ( fadeOutAction, duration, warp ) { - fadeOutAction.fadeOut( duration ); - this.fadeIn( duration ); + fadeOutAction.fadeOut( duration ); + this.fadeIn( duration ); - if ( warp ) { + if ( warp ) { - var fadeInDuration = this._clip.duration, - fadeOutDuration = fadeOutAction._clip.duration, + var fadeInDuration = this._clip.duration, + fadeOutDuration = fadeOutAction._clip.duration, - startEndRatio = fadeOutDuration / fadeInDuration, - endStartRatio = fadeInDuration / fadeOutDuration; + startEndRatio = fadeOutDuration / fadeInDuration, + endStartRatio = fadeInDuration / fadeOutDuration; - fadeOutAction.warp( 1.0, startEndRatio, duration ); - this.warp( endStartRatio, 1.0, duration ); + fadeOutAction.warp( 1.0, startEndRatio, duration ); + this.warp( endStartRatio, 1.0, duration ); - } + } - return this; + return this; - }, + }, - crossFadeTo: function ( fadeInAction, duration, warp ) { + crossFadeTo: function ( fadeInAction, duration, warp ) { - return fadeInAction.crossFadeFrom( this, duration, warp ); + return fadeInAction.crossFadeFrom( this, duration, warp ); - }, + }, - stopFading: function () { + stopFading: function () { - var weightInterpolant = this._weightInterpolant; + var weightInterpolant = this._weightInterpolant; - if ( weightInterpolant !== null ) { + if ( weightInterpolant !== null ) { - this._weightInterpolant = null; - this._mixer._takeBackControlInterpolant( weightInterpolant ); + this._weightInterpolant = null; + this._mixer._takeBackControlInterpolant( weightInterpolant ); - } + } - return this; + return this; - }, + }, - // Time Scale Control + // Time Scale Control - // set the time scale stopping any scheduled warping - // although .paused = true yields an effective time scale of zero, this - // method does *not* change .paused, because it would be confusing - setEffectiveTimeScale: function ( timeScale ) { + // set the time scale stopping any scheduled warping + // although .paused = true yields an effective time scale of zero, this + // method does *not* change .paused, because it would be confusing + setEffectiveTimeScale: function ( timeScale ) { - this.timeScale = timeScale; - this._effectiveTimeScale = this.paused ? 0 : timeScale; + this.timeScale = timeScale; + this._effectiveTimeScale = this.paused ? 0 : timeScale; - return this.stopWarping(); + return this.stopWarping(); - }, + }, - // return the time scale considering warping and .paused - getEffectiveTimeScale: function () { + // return the time scale considering warping and .paused + getEffectiveTimeScale: function () { - return this._effectiveTimeScale; + return this._effectiveTimeScale; - }, + }, - setDuration: function ( duration ) { + setDuration: function ( duration ) { - this.timeScale = this._clip.duration / duration; + this.timeScale = this._clip.duration / duration; - return this.stopWarping(); + return this.stopWarping(); - }, + }, - syncWith: function ( action ) { + syncWith: function ( action ) { - this.time = action.time; - this.timeScale = action.timeScale; + this.time = action.time; + this.timeScale = action.timeScale; - return this.stopWarping(); + return this.stopWarping(); - }, + }, - halt: function ( duration ) { + halt: function ( duration ) { - return this.warp( this._effectiveTimeScale, 0, duration ); + return this.warp( this._effectiveTimeScale, 0, duration ); - }, + }, - warp: function ( startTimeScale, endTimeScale, duration ) { + warp: function ( startTimeScale, endTimeScale, duration ) { - var mixer = this._mixer, now = mixer.time, - interpolant = this._timeScaleInterpolant, + var mixer = this._mixer, now = mixer.time, + interpolant = this._timeScaleInterpolant, - timeScale = this.timeScale; + timeScale = this.timeScale; - if ( interpolant === null ) { + if ( interpolant === null ) { - interpolant = mixer._lendControlInterpolant(); - this._timeScaleInterpolant = interpolant; + interpolant = mixer._lendControlInterpolant(); + this._timeScaleInterpolant = interpolant; - } + } - var times = interpolant.parameterPositions, - values = interpolant.sampleValues; + var times = interpolant.parameterPositions, + values = interpolant.sampleValues; - times[ 0 ] = now; - times[ 1 ] = now + duration; + times[ 0 ] = now; + times[ 1 ] = now + duration; - values[ 0 ] = startTimeScale / timeScale; - values[ 1 ] = endTimeScale / timeScale; + values[ 0 ] = startTimeScale / timeScale; + values[ 1 ] = endTimeScale / timeScale; - return this; + return this; - }, + }, - stopWarping: function () { + stopWarping: function () { - var timeScaleInterpolant = this._timeScaleInterpolant; + var timeScaleInterpolant = this._timeScaleInterpolant; - if ( timeScaleInterpolant !== null ) { + if ( timeScaleInterpolant !== null ) { - this._timeScaleInterpolant = null; - this._mixer._takeBackControlInterpolant( timeScaleInterpolant ); + this._timeScaleInterpolant = null; + this._mixer._takeBackControlInterpolant( timeScaleInterpolant ); - } + } - return this; + return this; - }, + }, - // Object Accessors + // Object Accessors - getMixer: function () { + getMixer: function () { - return this._mixer; + return this._mixer; - }, + }, - getClip: function () { + getClip: function () { - return this._clip; + return this._clip; - }, + }, - getRoot: function () { + getRoot: function () { - return this._localRoot || this._mixer._root; + return this._localRoot || this._mixer._root; - }, + }, - // Interna + // Interna - _update: function ( time, deltaTime, timeDirection, accuIndex ) { + _update: function ( time, deltaTime, timeDirection, accuIndex ) { - // called by the mixer + // called by the mixer - if ( ! this.enabled ) { + if ( ! this.enabled ) { - // call ._updateWeight() to update ._effectiveWeight + // call ._updateWeight() to update ._effectiveWeight - this._updateWeight( time ); - return; + this._updateWeight( time ); + return; - } + } - var startTime = this._startTime; + var startTime = this._startTime; - if ( startTime !== null ) { + if ( startTime !== null ) { - // check for scheduled start of action + // check for scheduled start of action - var timeRunning = ( time - startTime ) * timeDirection; - if ( timeRunning < 0 || timeDirection === 0 ) { + var timeRunning = ( time - startTime ) * timeDirection; + if ( timeRunning < 0 || timeDirection === 0 ) { - return; // yet to come / don't decide when delta = 0 + return; // yet to come / don't decide when delta = 0 - } + } - // start + // start - this._startTime = null; // unschedule - deltaTime = timeDirection * timeRunning; + this._startTime = null; // unschedule + deltaTime = timeDirection * timeRunning; - } + } - // apply time scale and advance time + // apply time scale and advance time - deltaTime *= this._updateTimeScale( time ); - var clipTime = this._updateTime( deltaTime ); + deltaTime *= this._updateTimeScale( time ); + var clipTime = this._updateTime( deltaTime ); - // note: _updateTime may disable the action resulting in - // an effective weight of 0 + // note: _updateTime may disable the action resulting in + // an effective weight of 0 - var weight = this._updateWeight( time ); + var weight = this._updateWeight( time ); - if ( weight > 0 ) { + if ( weight > 0 ) { - var interpolants = this._interpolants; - var propertyMixers = this._propertyBindings; + var interpolants = this._interpolants; + var propertyMixers = this._propertyBindings; - for ( var j = 0, m = interpolants.length; j !== m; ++ j ) { + for ( var j = 0, m = interpolants.length; j !== m; ++ j ) { - interpolants[ j ].evaluate( clipTime ); - propertyMixers[ j ].accumulate( accuIndex, weight ); + interpolants[ j ].evaluate( clipTime ); + propertyMixers[ j ].accumulate( accuIndex, weight ); - } + } - } + } - }, + }, - _updateWeight: function ( time ) { + _updateWeight: function ( time ) { - var weight = 0; + var weight = 0; - if ( this.enabled ) { + if ( this.enabled ) { - weight = this.weight; - var interpolant = this._weightInterpolant; + weight = this.weight; + var interpolant = this._weightInterpolant; - if ( interpolant !== null ) { + if ( interpolant !== null ) { - var interpolantValue = interpolant.evaluate( time )[ 0 ]; + var interpolantValue = interpolant.evaluate( time )[ 0 ]; - weight *= interpolantValue; + weight *= interpolantValue; - if ( time > interpolant.parameterPositions[ 1 ] ) { + if ( time > interpolant.parameterPositions[ 1 ] ) { - this.stopFading(); + this.stopFading(); - if ( interpolantValue === 0 ) { + if ( interpolantValue === 0 ) { - // faded out, disable - this.enabled = false; + // faded out, disable + this.enabled = false; - } + } - } + } - } + } - } + } - this._effectiveWeight = weight; - return weight; + this._effectiveWeight = weight; + return weight; - }, + }, - _updateTimeScale: function ( time ) { + _updateTimeScale: function ( time ) { - var timeScale = 0; + var timeScale = 0; - if ( ! this.paused ) { + if ( ! this.paused ) { - timeScale = this.timeScale; + timeScale = this.timeScale; - var interpolant = this._timeScaleInterpolant; + var interpolant = this._timeScaleInterpolant; - if ( interpolant !== null ) { + if ( interpolant !== null ) { - var interpolantValue = interpolant.evaluate( time )[ 0 ]; + var interpolantValue = interpolant.evaluate( time )[ 0 ]; - timeScale *= interpolantValue; + timeScale *= interpolantValue; - if ( time > interpolant.parameterPositions[ 1 ] ) { + if ( time > interpolant.parameterPositions[ 1 ] ) { - this.stopWarping(); + this.stopWarping(); - if ( timeScale === 0 ) { + if ( timeScale === 0 ) { - // motion has halted, pause - this.paused = true; + // motion has halted, pause + this.paused = true; - } else { + } else { - // warp done - apply final time scale - this.timeScale = timeScale; + // warp done - apply final time scale + this.timeScale = timeScale; - } + } - } + } - } + } - } + } - this._effectiveTimeScale = timeScale; - return timeScale; + this._effectiveTimeScale = timeScale; + return timeScale; - }, + }, - _updateTime: function ( deltaTime ) { + _updateTime: function ( deltaTime ) { - var time = this.time + deltaTime; - var duration = this._clip.duration; - var loop = this.loop; - var loopCount = this._loopCount; + var time = this.time + deltaTime; + var duration = this._clip.duration; + var loop = this.loop; + var loopCount = this._loopCount; - var pingPong = ( loop === LoopPingPong ); + var pingPong = ( loop === LoopPingPong ); - if ( deltaTime === 0 ) { + if ( deltaTime === 0 ) { - if ( loopCount === - 1 ) return time; + if ( loopCount === - 1 ) return time; - return ( pingPong && ( loopCount & 1 ) === 1 ) ? duration - time : time; + return ( pingPong && ( loopCount & 1 ) === 1 ) ? duration - time : time; - } + } - if ( loop === LoopOnce ) { + if ( loop === LoopOnce ) { - if ( loopCount === - 1 ) { + if ( loopCount === - 1 ) { - // just started + // just started - this._loopCount = 0; - this._setEndings( true, true, false ); + this._loopCount = 0; + this._setEndings( true, true, false ); - } + } - handle_stop: { + handle_stop: { - if ( time >= duration ) { + if ( time >= duration ) { - time = duration; + time = duration; - } else if ( time < 0 ) { + } else if ( time < 0 ) { - time = 0; + time = 0; - } else break handle_stop; + } else break handle_stop; - if ( this.clampWhenFinished ) this.paused = true; - else this.enabled = false; + if ( this.clampWhenFinished ) this.paused = true; + else this.enabled = false; - this._mixer.dispatchEvent( { - type: 'finished', action: this, - direction: deltaTime < 0 ? - 1 : 1 - } ); + this._mixer.dispatchEvent( { + type: 'finished', action: this, + direction: deltaTime < 0 ? - 1 : 1 + } ); - } + } - } else { // repetitive Repeat or PingPong + } else { // repetitive Repeat or PingPong - if ( loopCount === - 1 ) { + if ( loopCount === - 1 ) { - // just started + // just started - if ( deltaTime >= 0 ) { + if ( deltaTime >= 0 ) { - loopCount = 0; + loopCount = 0; - this._setEndings( true, this.repetitions === 0, pingPong ); + this._setEndings( true, this.repetitions === 0, pingPong ); - } else { + } else { - // when looping in reverse direction, the initial - // transition through zero counts as a repetition, - // so leave loopCount at -1 + // when looping in reverse direction, the initial + // transition through zero counts as a repetition, + // so leave loopCount at -1 - this._setEndings( this.repetitions === 0, true, pingPong ); + this._setEndings( this.repetitions === 0, true, pingPong ); - } + } - } + } - if ( time >= duration || time < 0 ) { + if ( time >= duration || time < 0 ) { - // wrap around + // wrap around - var loopDelta = Math.floor( time / duration ); // signed - time -= duration * loopDelta; + var loopDelta = Math.floor( time / duration ); // signed + time -= duration * loopDelta; - loopCount += Math.abs( loopDelta ); + loopCount += Math.abs( loopDelta ); - var pending = this.repetitions - loopCount; + var pending = this.repetitions - loopCount; - if ( pending <= 0 ) { + if ( pending <= 0 ) { - // have to stop (switch state, clamp time, fire event) + // have to stop (switch state, clamp time, fire event) - if ( this.clampWhenFinished ) this.paused = true; - else this.enabled = false; + if ( this.clampWhenFinished ) this.paused = true; + else this.enabled = false; - time = deltaTime > 0 ? duration : 0; + time = deltaTime > 0 ? duration : 0; - this._mixer.dispatchEvent( { - type: 'finished', action: this, - direction: deltaTime > 0 ? 1 : - 1 - } ); + this._mixer.dispatchEvent( { + type: 'finished', action: this, + direction: deltaTime > 0 ? 1 : - 1 + } ); - } else { + } else { - // keep running + // keep running - if ( pending === 1 ) { + if ( pending === 1 ) { - // entering the last round + // entering the last round - var atStart = deltaTime < 0; - this._setEndings( atStart, ! atStart, pingPong ); + var atStart = deltaTime < 0; + this._setEndings( atStart, ! atStart, pingPong ); - } else { + } else { - this._setEndings( false, false, pingPong ); + this._setEndings( false, false, pingPong ); - } + } - this._loopCount = loopCount; + this._loopCount = loopCount; - this._mixer.dispatchEvent( { - type: 'loop', action: this, loopDelta: loopDelta - } ); + this._mixer.dispatchEvent( { + type: 'loop', action: this, loopDelta: loopDelta + } ); - } + } - } + } - if ( pingPong && ( loopCount & 1 ) === 1 ) { + if ( pingPong && ( loopCount & 1 ) === 1 ) { - // invert time for the "pong round" + // invert time for the "pong round" - this.time = time; - return duration - time; + this.time = time; + return duration - time; - } + } - } + } - this.time = time; - return time; + this.time = time; + return time; - }, + }, - _setEndings: function ( atStart, atEnd, pingPong ) { + _setEndings: function ( atStart, atEnd, pingPong ) { - var settings = this._interpolantSettings; + var settings = this._interpolantSettings; - if ( pingPong ) { + if ( pingPong ) { - settings.endingStart = ZeroSlopeEnding; - settings.endingEnd = ZeroSlopeEnding; + settings.endingStart = ZeroSlopeEnding; + settings.endingEnd = ZeroSlopeEnding; - } else { + } else { - // assuming for LoopOnce atStart == atEnd == true + // assuming for LoopOnce atStart == atEnd == true - if ( atStart ) { + if ( atStart ) { - settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding; + settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding; - } else { + } else { - settings.endingStart = WrapAroundEnding; + settings.endingStart = WrapAroundEnding; - } + } - if ( atEnd ) { + if ( atEnd ) { - settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding; + settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding; - } else { + } else { - settings.endingEnd = WrapAroundEnding; + settings.endingEnd = WrapAroundEnding; - } + } - } + } - }, + }, - _scheduleFading: function ( duration, weightNow, weightThen ) { + _scheduleFading: function ( duration, weightNow, weightThen ) { - var mixer = this._mixer, now = mixer.time, - interpolant = this._weightInterpolant; + var mixer = this._mixer, now = mixer.time, + interpolant = this._weightInterpolant; - if ( interpolant === null ) { + if ( interpolant === null ) { - interpolant = mixer._lendControlInterpolant(); - this._weightInterpolant = interpolant; + interpolant = mixer._lendControlInterpolant(); + this._weightInterpolant = interpolant; - } + } - var times = interpolant.parameterPositions, - values = interpolant.sampleValues; + var times = interpolant.parameterPositions, + values = interpolant.sampleValues; - times[ 0 ] = now; values[ 0 ] = weightNow; - times[ 1 ] = now + duration; values[ 1 ] = weightThen; + times[ 0 ] = now; values[ 0 ] = weightNow; + times[ 1 ] = now + duration; values[ 1 ] = weightThen; - return this; + return this; - } + } - } ); + } ); - /** - * - * Player for AnimationClips. - * - * - * @author Ben Houston / http://clara.io/ - * @author David Sarno / http://lighthaus.us/ - * @author tschw - */ + /** + * + * Player for AnimationClips. + * + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + * @author tschw + */ - function AnimationMixer( root ) { + function AnimationMixer( root ) { - this._root = root; - this._initMemoryManager(); - this._accuIndex = 0; + this._root = root; + this._initMemoryManager(); + this._accuIndex = 0; - this.time = 0; + this.time = 0; - this.timeScale = 1.0; + this.timeScale = 1.0; - } + } - AnimationMixer.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { + AnimationMixer.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - constructor: AnimationMixer, + constructor: AnimationMixer, - _bindAction: function ( action, prototypeAction ) { + _bindAction: function ( action, prototypeAction ) { - var root = action._localRoot || this._root, - tracks = action._clip.tracks, - nTracks = tracks.length, - bindings = action._propertyBindings, - interpolants = action._interpolants, - rootUuid = root.uuid, - bindingsByRoot = this._bindingsByRootAndName, - bindingsByName = bindingsByRoot[ rootUuid ]; + var root = action._localRoot || this._root, + tracks = action._clip.tracks, + nTracks = tracks.length, + bindings = action._propertyBindings, + interpolants = action._interpolants, + rootUuid = root.uuid, + bindingsByRoot = this._bindingsByRootAndName, + bindingsByName = bindingsByRoot[ rootUuid ]; - if ( bindingsByName === undefined ) { + if ( bindingsByName === undefined ) { - bindingsByName = {}; - bindingsByRoot[ rootUuid ] = bindingsByName; + bindingsByName = {}; + bindingsByRoot[ rootUuid ] = bindingsByName; - } + } - for ( var i = 0; i !== nTracks; ++ i ) { + for ( var i = 0; i !== nTracks; ++ i ) { - var track = tracks[ i ], - trackName = track.name, - binding = bindingsByName[ trackName ]; + var track = tracks[ i ], + trackName = track.name, + binding = bindingsByName[ trackName ]; - if ( binding !== undefined ) { + if ( binding !== undefined ) { - bindings[ i ] = binding; + bindings[ i ] = binding; - } else { + } else { - binding = bindings[ i ]; + binding = bindings[ i ]; - if ( binding !== undefined ) { + if ( binding !== undefined ) { - // existing binding, make sure the cache knows + // existing binding, make sure the cache knows - if ( binding._cacheIndex === null ) { + if ( binding._cacheIndex === null ) { - ++ binding.referenceCount; - this._addInactiveBinding( binding, rootUuid, trackName ); + ++ binding.referenceCount; + this._addInactiveBinding( binding, rootUuid, trackName ); - } + } - continue; + continue; - } + } - var path = prototypeAction && prototypeAction. - _propertyBindings[ i ].binding.parsedPath; + var path = prototypeAction && prototypeAction. + _propertyBindings[ i ].binding.parsedPath; - binding = new PropertyMixer( - PropertyBinding.create( root, trackName, path ), - track.ValueTypeName, track.getValueSize() ); + binding = new PropertyMixer( + PropertyBinding.create( root, trackName, path ), + track.ValueTypeName, track.getValueSize() ); - ++ binding.referenceCount; - this._addInactiveBinding( binding, rootUuid, trackName ); + ++ binding.referenceCount; + this._addInactiveBinding( binding, rootUuid, trackName ); - bindings[ i ] = binding; + bindings[ i ] = binding; - } + } - interpolants[ i ].resultBuffer = binding.buffer; + interpolants[ i ].resultBuffer = binding.buffer; - } + } - }, + }, - _activateAction: function ( action ) { + _activateAction: function ( action ) { - if ( ! this._isActiveAction( action ) ) { + if ( ! this._isActiveAction( action ) ) { - if ( action._cacheIndex === null ) { + if ( action._cacheIndex === null ) { - // this action has been forgotten by the cache, but the user - // appears to be still using it -> rebind + // this action has been forgotten by the cache, but the user + // appears to be still using it -> rebind - var rootUuid = ( action._localRoot || this._root ).uuid, - clipUuid = action._clip.uuid, - actionsForClip = this._actionsByClip[ clipUuid ]; + var rootUuid = ( action._localRoot || this._root ).uuid, + clipUuid = action._clip.uuid, + actionsForClip = this._actionsByClip[ clipUuid ]; - this._bindAction( action, - actionsForClip && actionsForClip.knownActions[ 0 ] ); + this._bindAction( action, + actionsForClip && actionsForClip.knownActions[ 0 ] ); - this._addInactiveAction( action, clipUuid, rootUuid ); + this._addInactiveAction( action, clipUuid, rootUuid ); - } + } - var bindings = action._propertyBindings; + var bindings = action._propertyBindings; - // increment reference counts / sort out state - for ( var i = 0, n = bindings.length; i !== n; ++ i ) { + // increment reference counts / sort out state + for ( var i = 0, n = bindings.length; i !== n; ++ i ) { - var binding = bindings[ i ]; + var binding = bindings[ i ]; - if ( binding.useCount ++ === 0 ) { + if ( binding.useCount ++ === 0 ) { - this._lendBinding( binding ); - binding.saveOriginalState(); + this._lendBinding( binding ); + binding.saveOriginalState(); - } + } - } + } - this._lendAction( action ); + this._lendAction( action ); - } + } - }, + }, - _deactivateAction: function ( action ) { + _deactivateAction: function ( action ) { - if ( this._isActiveAction( action ) ) { + if ( this._isActiveAction( action ) ) { - var bindings = action._propertyBindings; + var bindings = action._propertyBindings; - // decrement reference counts / sort out state - for ( var i = 0, n = bindings.length; i !== n; ++ i ) { + // decrement reference counts / sort out state + for ( var i = 0, n = bindings.length; i !== n; ++ i ) { - var binding = bindings[ i ]; + var binding = bindings[ i ]; - if ( -- binding.useCount === 0 ) { + if ( -- binding.useCount === 0 ) { - binding.restoreOriginalState(); - this._takeBackBinding( binding ); + binding.restoreOriginalState(); + this._takeBackBinding( binding ); - } + } - } + } - this._takeBackAction( action ); + this._takeBackAction( action ); - } + } - }, + }, - // Memory manager + // Memory manager - _initMemoryManager: function () { + _initMemoryManager: function () { - this._actions = []; // 'nActiveActions' followed by inactive ones - this._nActiveActions = 0; + this._actions = []; // 'nActiveActions' followed by inactive ones + this._nActiveActions = 0; - this._actionsByClip = {}; - // inside: - // { - // knownActions: Array< AnimationAction > - used as prototypes - // actionByRoot: AnimationAction - lookup - // } + this._actionsByClip = {}; + // inside: + // { + // knownActions: Array< AnimationAction > - used as prototypes + // actionByRoot: AnimationAction - lookup + // } - this._bindings = []; // 'nActiveBindings' followed by inactive ones - this._nActiveBindings = 0; + this._bindings = []; // 'nActiveBindings' followed by inactive ones + this._nActiveBindings = 0; - this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer > + this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer > - this._controlInterpolants = []; // same game as above - this._nActiveControlInterpolants = 0; + this._controlInterpolants = []; // same game as above + this._nActiveControlInterpolants = 0; - var scope = this; + var scope = this; - this.stats = { + this.stats = { - actions: { - get total() { + actions: { + get total() { - return scope._actions.length; + return scope._actions.length; - }, - get inUse() { + }, + get inUse() { - return scope._nActiveActions; + return scope._nActiveActions; - } - }, - bindings: { - get total() { + } + }, + bindings: { + get total() { - return scope._bindings.length; + return scope._bindings.length; - }, - get inUse() { + }, + get inUse() { - return scope._nActiveBindings; + return scope._nActiveBindings; - } - }, - controlInterpolants: { - get total() { + } + }, + controlInterpolants: { + get total() { - return scope._controlInterpolants.length; + return scope._controlInterpolants.length; - }, - get inUse() { + }, + get inUse() { - return scope._nActiveControlInterpolants; + return scope._nActiveControlInterpolants; - } - } + } + } - }; + }; - }, + }, - // Memory management for AnimationAction objects + // Memory management for AnimationAction objects - _isActiveAction: function ( action ) { + _isActiveAction: function ( action ) { - var index = action._cacheIndex; - return index !== null && index < this._nActiveActions; + var index = action._cacheIndex; + return index !== null && index < this._nActiveActions; - }, + }, - _addInactiveAction: function ( action, clipUuid, rootUuid ) { + _addInactiveAction: function ( action, clipUuid, rootUuid ) { - var actions = this._actions, - actionsByClip = this._actionsByClip, - actionsForClip = actionsByClip[ clipUuid ]; + var actions = this._actions, + actionsByClip = this._actionsByClip, + actionsForClip = actionsByClip[ clipUuid ]; - if ( actionsForClip === undefined ) { + if ( actionsForClip === undefined ) { - actionsForClip = { + actionsForClip = { - knownActions: [ action ], - actionByRoot: {} + knownActions: [ action ], + actionByRoot: {} - }; + }; - action._byClipCacheIndex = 0; + action._byClipCacheIndex = 0; - actionsByClip[ clipUuid ] = actionsForClip; + actionsByClip[ clipUuid ] = actionsForClip; - } else { + } else { - var knownActions = actionsForClip.knownActions; + var knownActions = actionsForClip.knownActions; - action._byClipCacheIndex = knownActions.length; - knownActions.push( action ); + action._byClipCacheIndex = knownActions.length; + knownActions.push( action ); - } + } - action._cacheIndex = actions.length; - actions.push( action ); + action._cacheIndex = actions.length; + actions.push( action ); - actionsForClip.actionByRoot[ rootUuid ] = action; + actionsForClip.actionByRoot[ rootUuid ] = action; - }, + }, - _removeInactiveAction: function ( action ) { + _removeInactiveAction: function ( action ) { - var actions = this._actions, - lastInactiveAction = actions[ actions.length - 1 ], - cacheIndex = action._cacheIndex; + var actions = this._actions, + lastInactiveAction = actions[ actions.length - 1 ], + cacheIndex = action._cacheIndex; - lastInactiveAction._cacheIndex = cacheIndex; - actions[ cacheIndex ] = lastInactiveAction; - actions.pop(); + lastInactiveAction._cacheIndex = cacheIndex; + actions[ cacheIndex ] = lastInactiveAction; + actions.pop(); - action._cacheIndex = null; + action._cacheIndex = null; - var clipUuid = action._clip.uuid, - actionsByClip = this._actionsByClip, - actionsForClip = actionsByClip[ clipUuid ], - knownActionsForClip = actionsForClip.knownActions, + var clipUuid = action._clip.uuid, + actionsByClip = this._actionsByClip, + actionsForClip = actionsByClip[ clipUuid ], + knownActionsForClip = actionsForClip.knownActions, - lastKnownAction = - knownActionsForClip[ knownActionsForClip.length - 1 ], + lastKnownAction = + knownActionsForClip[ knownActionsForClip.length - 1 ], - byClipCacheIndex = action._byClipCacheIndex; + byClipCacheIndex = action._byClipCacheIndex; - lastKnownAction._byClipCacheIndex = byClipCacheIndex; - knownActionsForClip[ byClipCacheIndex ] = lastKnownAction; - knownActionsForClip.pop(); + lastKnownAction._byClipCacheIndex = byClipCacheIndex; + knownActionsForClip[ byClipCacheIndex ] = lastKnownAction; + knownActionsForClip.pop(); - action._byClipCacheIndex = null; + action._byClipCacheIndex = null; - var actionByRoot = actionsForClip.actionByRoot, - rootUuid = ( action._localRoot || this._root ).uuid; + var actionByRoot = actionsForClip.actionByRoot, + rootUuid = ( action._localRoot || this._root ).uuid; - delete actionByRoot[ rootUuid ]; + delete actionByRoot[ rootUuid ]; - if ( knownActionsForClip.length === 0 ) { + if ( knownActionsForClip.length === 0 ) { - delete actionsByClip[ clipUuid ]; + delete actionsByClip[ clipUuid ]; - } + } - this._removeInactiveBindingsForAction( action ); + this._removeInactiveBindingsForAction( action ); - }, + }, - _removeInactiveBindingsForAction: function ( action ) { + _removeInactiveBindingsForAction: function ( action ) { - var bindings = action._propertyBindings; - for ( var i = 0, n = bindings.length; i !== n; ++ i ) { + var bindings = action._propertyBindings; + for ( var i = 0, n = bindings.length; i !== n; ++ i ) { - var binding = bindings[ i ]; + var binding = bindings[ i ]; - if ( -- binding.referenceCount === 0 ) { + if ( -- binding.referenceCount === 0 ) { - this._removeInactiveBinding( binding ); + this._removeInactiveBinding( binding ); - } + } - } + } - }, + }, - _lendAction: function ( action ) { + _lendAction: function ( action ) { - // [ active actions | inactive actions ] - // [ active actions >| inactive actions ] - // s a - // <-swap-> - // a s + // [ active actions | inactive actions ] + // [ active actions >| inactive actions ] + // s a + // <-swap-> + // a s - var actions = this._actions, - prevIndex = action._cacheIndex, + var actions = this._actions, + prevIndex = action._cacheIndex, - lastActiveIndex = this._nActiveActions ++, + lastActiveIndex = this._nActiveActions ++, - firstInactiveAction = actions[ lastActiveIndex ]; + firstInactiveAction = actions[ lastActiveIndex ]; - action._cacheIndex = lastActiveIndex; - actions[ lastActiveIndex ] = action; + action._cacheIndex = lastActiveIndex; + actions[ lastActiveIndex ] = action; - firstInactiveAction._cacheIndex = prevIndex; - actions[ prevIndex ] = firstInactiveAction; + firstInactiveAction._cacheIndex = prevIndex; + actions[ prevIndex ] = firstInactiveAction; - }, + }, - _takeBackAction: function ( action ) { + _takeBackAction: function ( action ) { - // [ active actions | inactive actions ] - // [ active actions |< inactive actions ] - // a s - // <-swap-> - // s a + // [ active actions | inactive actions ] + // [ active actions |< inactive actions ] + // a s + // <-swap-> + // s a - var actions = this._actions, - prevIndex = action._cacheIndex, + var actions = this._actions, + prevIndex = action._cacheIndex, - firstInactiveIndex = -- this._nActiveActions, + firstInactiveIndex = -- this._nActiveActions, - lastActiveAction = actions[ firstInactiveIndex ]; + lastActiveAction = actions[ firstInactiveIndex ]; - action._cacheIndex = firstInactiveIndex; - actions[ firstInactiveIndex ] = action; + action._cacheIndex = firstInactiveIndex; + actions[ firstInactiveIndex ] = action; - lastActiveAction._cacheIndex = prevIndex; - actions[ prevIndex ] = lastActiveAction; + lastActiveAction._cacheIndex = prevIndex; + actions[ prevIndex ] = lastActiveAction; - }, + }, - // Memory management for PropertyMixer objects + // Memory management for PropertyMixer objects - _addInactiveBinding: function ( binding, rootUuid, trackName ) { + _addInactiveBinding: function ( binding, rootUuid, trackName ) { - var bindingsByRoot = this._bindingsByRootAndName, - bindingByName = bindingsByRoot[ rootUuid ], + var bindingsByRoot = this._bindingsByRootAndName, + bindingByName = bindingsByRoot[ rootUuid ], - bindings = this._bindings; + bindings = this._bindings; - if ( bindingByName === undefined ) { + if ( bindingByName === undefined ) { - bindingByName = {}; - bindingsByRoot[ rootUuid ] = bindingByName; + bindingByName = {}; + bindingsByRoot[ rootUuid ] = bindingByName; - } + } - bindingByName[ trackName ] = binding; + bindingByName[ trackName ] = binding; - binding._cacheIndex = bindings.length; - bindings.push( binding ); + binding._cacheIndex = bindings.length; + bindings.push( binding ); - }, + }, - _removeInactiveBinding: function ( binding ) { + _removeInactiveBinding: function ( binding ) { - var bindings = this._bindings, - propBinding = binding.binding, - rootUuid = propBinding.rootNode.uuid, - trackName = propBinding.path, - bindingsByRoot = this._bindingsByRootAndName, - bindingByName = bindingsByRoot[ rootUuid ], + var bindings = this._bindings, + propBinding = binding.binding, + rootUuid = propBinding.rootNode.uuid, + trackName = propBinding.path, + bindingsByRoot = this._bindingsByRootAndName, + bindingByName = bindingsByRoot[ rootUuid ], - lastInactiveBinding = bindings[ bindings.length - 1 ], - cacheIndex = binding._cacheIndex; + lastInactiveBinding = bindings[ bindings.length - 1 ], + cacheIndex = binding._cacheIndex; - lastInactiveBinding._cacheIndex = cacheIndex; - bindings[ cacheIndex ] = lastInactiveBinding; - bindings.pop(); + lastInactiveBinding._cacheIndex = cacheIndex; + bindings[ cacheIndex ] = lastInactiveBinding; + bindings.pop(); - delete bindingByName[ trackName ]; + delete bindingByName[ trackName ]; - remove_empty_map: { + remove_empty_map: { - for ( var _ in bindingByName ) break remove_empty_map; // eslint-disable-line no-unused-vars + for ( var _ in bindingByName ) break remove_empty_map; // eslint-disable-line no-unused-vars - delete bindingsByRoot[ rootUuid ]; + delete bindingsByRoot[ rootUuid ]; - } + } - }, + }, - _lendBinding: function ( binding ) { + _lendBinding: function ( binding ) { - var bindings = this._bindings, - prevIndex = binding._cacheIndex, + var bindings = this._bindings, + prevIndex = binding._cacheIndex, - lastActiveIndex = this._nActiveBindings ++, + lastActiveIndex = this._nActiveBindings ++, - firstInactiveBinding = bindings[ lastActiveIndex ]; + firstInactiveBinding = bindings[ lastActiveIndex ]; - binding._cacheIndex = lastActiveIndex; - bindings[ lastActiveIndex ] = binding; + binding._cacheIndex = lastActiveIndex; + bindings[ lastActiveIndex ] = binding; - firstInactiveBinding._cacheIndex = prevIndex; - bindings[ prevIndex ] = firstInactiveBinding; + firstInactiveBinding._cacheIndex = prevIndex; + bindings[ prevIndex ] = firstInactiveBinding; - }, + }, - _takeBackBinding: function ( binding ) { + _takeBackBinding: function ( binding ) { - var bindings = this._bindings, - prevIndex = binding._cacheIndex, + var bindings = this._bindings, + prevIndex = binding._cacheIndex, - firstInactiveIndex = -- this._nActiveBindings, + firstInactiveIndex = -- this._nActiveBindings, - lastActiveBinding = bindings[ firstInactiveIndex ]; + lastActiveBinding = bindings[ firstInactiveIndex ]; - binding._cacheIndex = firstInactiveIndex; - bindings[ firstInactiveIndex ] = binding; + binding._cacheIndex = firstInactiveIndex; + bindings[ firstInactiveIndex ] = binding; - lastActiveBinding._cacheIndex = prevIndex; - bindings[ prevIndex ] = lastActiveBinding; + lastActiveBinding._cacheIndex = prevIndex; + bindings[ prevIndex ] = lastActiveBinding; - }, + }, - // Memory management of Interpolants for weight and time scale + // Memory management of Interpolants for weight and time scale - _lendControlInterpolant: function () { + _lendControlInterpolant: function () { - var interpolants = this._controlInterpolants, - lastActiveIndex = this._nActiveControlInterpolants ++, - interpolant = interpolants[ lastActiveIndex ]; + var interpolants = this._controlInterpolants, + lastActiveIndex = this._nActiveControlInterpolants ++, + interpolant = interpolants[ lastActiveIndex ]; - if ( interpolant === undefined ) { + if ( interpolant === undefined ) { - interpolant = new LinearInterpolant( - new Float32Array( 2 ), new Float32Array( 2 ), - 1, this._controlInterpolantsResultBuffer ); + interpolant = new LinearInterpolant( + new Float32Array( 2 ), new Float32Array( 2 ), + 1, this._controlInterpolantsResultBuffer ); - interpolant.__cacheIndex = lastActiveIndex; - interpolants[ lastActiveIndex ] = interpolant; + interpolant.__cacheIndex = lastActiveIndex; + interpolants[ lastActiveIndex ] = interpolant; - } + } - return interpolant; + return interpolant; - }, + }, - _takeBackControlInterpolant: function ( interpolant ) { + _takeBackControlInterpolant: function ( interpolant ) { - var interpolants = this._controlInterpolants, - prevIndex = interpolant.__cacheIndex, + var interpolants = this._controlInterpolants, + prevIndex = interpolant.__cacheIndex, - firstInactiveIndex = -- this._nActiveControlInterpolants, + firstInactiveIndex = -- this._nActiveControlInterpolants, - lastActiveInterpolant = interpolants[ firstInactiveIndex ]; + lastActiveInterpolant = interpolants[ firstInactiveIndex ]; - interpolant.__cacheIndex = firstInactiveIndex; - interpolants[ firstInactiveIndex ] = interpolant; + interpolant.__cacheIndex = firstInactiveIndex; + interpolants[ firstInactiveIndex ] = interpolant; - lastActiveInterpolant.__cacheIndex = prevIndex; - interpolants[ prevIndex ] = lastActiveInterpolant; + lastActiveInterpolant.__cacheIndex = prevIndex; + interpolants[ prevIndex ] = lastActiveInterpolant; - }, + }, - _controlInterpolantsResultBuffer: new Float32Array( 1 ), + _controlInterpolantsResultBuffer: new Float32Array( 1 ), - // return an action for a clip optionally using a custom root target - // object (this method allocates a lot of dynamic memory in case a - // previously unknown clip/root combination is specified) - clipAction: function ( clip, optionalRoot ) { + // return an action for a clip optionally using a custom root target + // object (this method allocates a lot of dynamic memory in case a + // previously unknown clip/root combination is specified) + clipAction: function ( clip, optionalRoot ) { - var root = optionalRoot || this._root, - rootUuid = root.uuid, + var root = optionalRoot || this._root, + rootUuid = root.uuid, - clipObject = typeof clip === 'string' ? - AnimationClip.findByName( root, clip ) : clip, + clipObject = typeof clip === 'string' ? + AnimationClip.findByName( root, clip ) : clip, - clipUuid = clipObject !== null ? clipObject.uuid : clip, + clipUuid = clipObject !== null ? clipObject.uuid : clip, - actionsForClip = this._actionsByClip[ clipUuid ], - prototypeAction = null; + actionsForClip = this._actionsByClip[ clipUuid ], + prototypeAction = null; - if ( actionsForClip !== undefined ) { + if ( actionsForClip !== undefined ) { - var existingAction = - actionsForClip.actionByRoot[ rootUuid ]; + var existingAction = + actionsForClip.actionByRoot[ rootUuid ]; - if ( existingAction !== undefined ) { + if ( existingAction !== undefined ) { - return existingAction; + return existingAction; - } + } - // we know the clip, so we don't have to parse all - // the bindings again but can just copy - prototypeAction = actionsForClip.knownActions[ 0 ]; + // we know the clip, so we don't have to parse all + // the bindings again but can just copy + prototypeAction = actionsForClip.knownActions[ 0 ]; - // also, take the clip from the prototype action - if ( clipObject === null ) - clipObject = prototypeAction._clip; + // also, take the clip from the prototype action + if ( clipObject === null ) + clipObject = prototypeAction._clip; - } + } - // clip must be known when specified via string - if ( clipObject === null ) return null; + // clip must be known when specified via string + if ( clipObject === null ) return null; - // allocate all resources required to run it - var newAction = new AnimationAction( this, clipObject, optionalRoot ); + // allocate all resources required to run it + var newAction = new AnimationAction( this, clipObject, optionalRoot ); - this._bindAction( newAction, prototypeAction ); + this._bindAction( newAction, prototypeAction ); - // and make the action known to the memory manager - this._addInactiveAction( newAction, clipUuid, rootUuid ); + // and make the action known to the memory manager + this._addInactiveAction( newAction, clipUuid, rootUuid ); - return newAction; + return newAction; - }, + }, - // get an existing action - existingAction: function ( clip, optionalRoot ) { + // get an existing action + existingAction: function ( clip, optionalRoot ) { - var root = optionalRoot || this._root, - rootUuid = root.uuid, + var root = optionalRoot || this._root, + rootUuid = root.uuid, - clipObject = typeof clip === 'string' ? - AnimationClip.findByName( root, clip ) : clip, + clipObject = typeof clip === 'string' ? + AnimationClip.findByName( root, clip ) : clip, - clipUuid = clipObject ? clipObject.uuid : clip, + clipUuid = clipObject ? clipObject.uuid : clip, - actionsForClip = this._actionsByClip[ clipUuid ]; + actionsForClip = this._actionsByClip[ clipUuid ]; - if ( actionsForClip !== undefined ) { + if ( actionsForClip !== undefined ) { - return actionsForClip.actionByRoot[ rootUuid ] || null; + return actionsForClip.actionByRoot[ rootUuid ] || null; - } + } - return null; + return null; - }, + }, - // deactivates all previously scheduled actions - stopAllAction: function () { + // deactivates all previously scheduled actions + stopAllAction: function () { - var actions = this._actions, - nActions = this._nActiveActions, - bindings = this._bindings, - nBindings = this._nActiveBindings; + var actions = this._actions, + nActions = this._nActiveActions, + bindings = this._bindings, + nBindings = this._nActiveBindings; - this._nActiveActions = 0; - this._nActiveBindings = 0; + this._nActiveActions = 0; + this._nActiveBindings = 0; - for ( var i = 0; i !== nActions; ++ i ) { + for ( var i = 0; i !== nActions; ++ i ) { - actions[ i ].reset(); + actions[ i ].reset(); - } + } - for ( var i = 0; i !== nBindings; ++ i ) { + for ( var i = 0; i !== nBindings; ++ i ) { - bindings[ i ].useCount = 0; + bindings[ i ].useCount = 0; - } + } - return this; + return this; - }, + }, - // advance the time and update apply the animation - update: function ( deltaTime ) { + // advance the time and update apply the animation + update: function ( deltaTime ) { - deltaTime *= this.timeScale; + deltaTime *= this.timeScale; - var actions = this._actions, - nActions = this._nActiveActions, + var actions = this._actions, + nActions = this._nActiveActions, - time = this.time += deltaTime, - timeDirection = Math.sign( deltaTime ), + time = this.time += deltaTime, + timeDirection = Math.sign( deltaTime ), - accuIndex = this._accuIndex ^= 1; + accuIndex = this._accuIndex ^= 1; - // run active actions + // run active actions - for ( var i = 0; i !== nActions; ++ i ) { + for ( var i = 0; i !== nActions; ++ i ) { - var action = actions[ i ]; + var action = actions[ i ]; - action._update( time, deltaTime, timeDirection, accuIndex ); + action._update( time, deltaTime, timeDirection, accuIndex ); - } + } - // update scene graph + // update scene graph - var bindings = this._bindings, - nBindings = this._nActiveBindings; + var bindings = this._bindings, + nBindings = this._nActiveBindings; - for ( var i = 0; i !== nBindings; ++ i ) { + for ( var i = 0; i !== nBindings; ++ i ) { - bindings[ i ].apply( accuIndex ); + bindings[ i ].apply( accuIndex ); - } + } - return this; + return this; - }, + }, - // return this mixer's root target object - getRoot: function () { + // return this mixer's root target object + getRoot: function () { - return this._root; + return this._root; - }, + }, - // free all resources specific to a particular clip - uncacheClip: function ( clip ) { + // free all resources specific to a particular clip + uncacheClip: function ( clip ) { - var actions = this._actions, - clipUuid = clip.uuid, - actionsByClip = this._actionsByClip, - actionsForClip = actionsByClip[ clipUuid ]; + var actions = this._actions, + clipUuid = clip.uuid, + actionsByClip = this._actionsByClip, + actionsForClip = actionsByClip[ clipUuid ]; - if ( actionsForClip !== undefined ) { + if ( actionsForClip !== undefined ) { - // note: just calling _removeInactiveAction would mess up the - // iteration state and also require updating the state we can - // just throw away + // note: just calling _removeInactiveAction would mess up the + // iteration state and also require updating the state we can + // just throw away - var actionsToRemove = actionsForClip.knownActions; + var actionsToRemove = actionsForClip.knownActions; - for ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) { + for ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) { - var action = actionsToRemove[ i ]; + var action = actionsToRemove[ i ]; - this._deactivateAction( action ); + this._deactivateAction( action ); - var cacheIndex = action._cacheIndex, - lastInactiveAction = actions[ actions.length - 1 ]; + var cacheIndex = action._cacheIndex, + lastInactiveAction = actions[ actions.length - 1 ]; - action._cacheIndex = null; - action._byClipCacheIndex = null; + action._cacheIndex = null; + action._byClipCacheIndex = null; - lastInactiveAction._cacheIndex = cacheIndex; - actions[ cacheIndex ] = lastInactiveAction; - actions.pop(); + lastInactiveAction._cacheIndex = cacheIndex; + actions[ cacheIndex ] = lastInactiveAction; + actions.pop(); - this._removeInactiveBindingsForAction( action ); + this._removeInactiveBindingsForAction( action ); - } + } - delete actionsByClip[ clipUuid ]; + delete actionsByClip[ clipUuid ]; - } + } - }, + }, - // free all resources specific to a particular root target object - uncacheRoot: function ( root ) { + // free all resources specific to a particular root target object + uncacheRoot: function ( root ) { - var rootUuid = root.uuid, - actionsByClip = this._actionsByClip; + var rootUuid = root.uuid, + actionsByClip = this._actionsByClip; - for ( var clipUuid in actionsByClip ) { + for ( var clipUuid in actionsByClip ) { - var actionByRoot = actionsByClip[ clipUuid ].actionByRoot, - action = actionByRoot[ rootUuid ]; + var actionByRoot = actionsByClip[ clipUuid ].actionByRoot, + action = actionByRoot[ rootUuid ]; - if ( action !== undefined ) { + if ( action !== undefined ) { - this._deactivateAction( action ); - this._removeInactiveAction( action ); + this._deactivateAction( action ); + this._removeInactiveAction( action ); - } + } - } + } - var bindingsByRoot = this._bindingsByRootAndName, - bindingByName = bindingsByRoot[ rootUuid ]; + var bindingsByRoot = this._bindingsByRootAndName, + bindingByName = bindingsByRoot[ rootUuid ]; - if ( bindingByName !== undefined ) { + if ( bindingByName !== undefined ) { - for ( var trackName in bindingByName ) { + for ( var trackName in bindingByName ) { - var binding = bindingByName[ trackName ]; - binding.restoreOriginalState(); - this._removeInactiveBinding( binding ); + var binding = bindingByName[ trackName ]; + binding.restoreOriginalState(); + this._removeInactiveBinding( binding ); - } + } - } + } - }, + }, - // remove a targeted clip from the cache - uncacheAction: function ( clip, optionalRoot ) { + // remove a targeted clip from the cache + uncacheAction: function ( clip, optionalRoot ) { - var action = this.existingAction( clip, optionalRoot ); + var action = this.existingAction( clip, optionalRoot ); - if ( action !== null ) { + if ( action !== null ) { - this._deactivateAction( action ); - this._removeInactiveAction( action ); + this._deactivateAction( action ); + this._removeInactiveAction( action ); - } + } - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function Uniform( value ) { + function Uniform( value ) { - if ( typeof value === 'string' ) { + if ( typeof value === 'string' ) { - console.warn( 'THREE.Uniform: Type parameter is no longer needed.' ); - value = arguments[ 1 ]; + console.warn( 'THREE.Uniform: Type parameter is no longer needed.' ); + value = arguments[ 1 ]; - } + } - this.value = value; + this.value = value; - } + } - Uniform.prototype.clone = function () { + Uniform.prototype.clone = function () { - return new Uniform( this.value.clone === undefined ? this.value : this.value.clone() ); + return new Uniform( this.value.clone === undefined ? this.value : this.value.clone() ); - }; + }; - /** - * @author benaadams / https://twitter.com/ben_a_adams - */ + /** + * @author benaadams / https://twitter.com/ben_a_adams + */ - function InstancedBufferGeometry() { + function InstancedBufferGeometry() { - BufferGeometry.call( this ); + BufferGeometry.call( this ); - this.type = 'InstancedBufferGeometry'; - this.maxInstancedCount = undefined; + this.type = 'InstancedBufferGeometry'; + this.maxInstancedCount = undefined; - } + } - InstancedBufferGeometry.prototype = Object.assign( Object.create( BufferGeometry.prototype ), { + InstancedBufferGeometry.prototype = Object.assign( Object.create( BufferGeometry.prototype ), { - constructor: InstancedBufferGeometry, + constructor: InstancedBufferGeometry, - isInstancedBufferGeometry: true, + isInstancedBufferGeometry: true, - copy: function ( source ) { + copy: function ( source ) { - BufferGeometry.prototype.copy.call( this, source ); + BufferGeometry.prototype.copy.call( this, source ); - this.maxInstancedCount = source.maxInstancedCount; + this.maxInstancedCount = source.maxInstancedCount; - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - } + } - } ); + } ); - /** - * @author benaadams / https://twitter.com/ben_a_adams - */ + /** + * @author benaadams / https://twitter.com/ben_a_adams + */ - function InstancedInterleavedBuffer( array, stride, meshPerAttribute ) { + function InstancedInterleavedBuffer( array, stride, meshPerAttribute ) { - InterleavedBuffer.call( this, array, stride ); + InterleavedBuffer.call( this, array, stride ); - this.meshPerAttribute = meshPerAttribute || 1; + this.meshPerAttribute = meshPerAttribute || 1; - } + } - InstancedInterleavedBuffer.prototype = Object.assign( Object.create( InterleavedBuffer.prototype ), { + InstancedInterleavedBuffer.prototype = Object.assign( Object.create( InterleavedBuffer.prototype ), { - constructor: InstancedInterleavedBuffer, + constructor: InstancedInterleavedBuffer, - isInstancedInterleavedBuffer: true, + isInstancedInterleavedBuffer: true, - copy: function ( source ) { + copy: function ( source ) { - InterleavedBuffer.prototype.copy.call( this, source ); + InterleavedBuffer.prototype.copy.call( this, source ); - this.meshPerAttribute = source.meshPerAttribute; + this.meshPerAttribute = source.meshPerAttribute; - return this; + return this; - } + } - } ); + } ); - /** - * @author benaadams / https://twitter.com/ben_a_adams - */ + /** + * @author benaadams / https://twitter.com/ben_a_adams + */ - function InstancedBufferAttribute( array, itemSize, meshPerAttribute ) { + function InstancedBufferAttribute( array, itemSize, meshPerAttribute ) { - BufferAttribute.call( this, array, itemSize ); + BufferAttribute.call( this, array, itemSize ); - this.meshPerAttribute = meshPerAttribute || 1; + this.meshPerAttribute = meshPerAttribute || 1; - } + } - InstancedBufferAttribute.prototype = Object.assign( Object.create( BufferAttribute.prototype ), { + InstancedBufferAttribute.prototype = Object.assign( Object.create( BufferAttribute.prototype ), { - constructor: InstancedBufferAttribute, + constructor: InstancedBufferAttribute, - isInstancedBufferAttribute: true, + isInstancedBufferAttribute: true, - copy: function ( source ) { + copy: function ( source ) { - BufferAttribute.prototype.copy.call( this, source ); + BufferAttribute.prototype.copy.call( this, source ); - this.meshPerAttribute = source.meshPerAttribute; + this.meshPerAttribute = source.meshPerAttribute; - return this; + return this; - } + } - } ); + } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author bhouston / http://clara.io/ - * @author stephomi / http://stephaneginier.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author bhouston / http://clara.io/ + * @author stephomi / http://stephaneginier.com/ + */ - function Raycaster( origin, direction, near, far ) { + function Raycaster( origin, direction, near, far ) { - this.ray = new Ray( origin, direction ); - // direction is assumed to be normalized (for accurate distance calculations) + this.ray = new Ray( origin, direction ); + // direction is assumed to be normalized (for accurate distance calculations) - this.near = near || 0; - this.far = far || Infinity; + this.near = near || 0; + this.far = far || Infinity; - this.params = { - Mesh: {}, - Line: {}, - LOD: {}, - Points: { threshold: 1 }, - Sprite: {} - }; + this.params = { + Mesh: {}, + Line: {}, + LOD: {}, + Points: { threshold: 1 }, + Sprite: {} + }; - Object.defineProperties( this.params, { - PointCloud: { - get: function () { + Object.defineProperties( this.params, { + PointCloud: { + get: function () { - console.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' ); - return this.Points; + console.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' ); + return this.Points; - } - } - } ); + } + } + } ); - } + } - function ascSort( a, b ) { + function ascSort( a, b ) { - return a.distance - b.distance; + return a.distance - b.distance; - } + } - function intersectObject( object, raycaster, intersects, recursive ) { + function intersectObject( object, raycaster, intersects, recursive ) { - if ( object.visible === false ) return; + if ( object.visible === false ) return; - object.raycast( raycaster, intersects ); + object.raycast( raycaster, intersects ); - if ( recursive === true ) { + if ( recursive === true ) { - var children = object.children; + var children = object.children; - for ( var i = 0, l = children.length; i < l; i ++ ) { + for ( var i = 0, l = children.length; i < l; i ++ ) { - intersectObject( children[ i ], raycaster, intersects, true ); + intersectObject( children[ i ], raycaster, intersects, true ); - } + } - } + } - } + } - Object.assign( Raycaster.prototype, { + Object.assign( Raycaster.prototype, { - linePrecision: 1, + linePrecision: 1, - set: function ( origin, direction ) { + set: function ( origin, direction ) { - // direction is assumed to be normalized (for accurate distance calculations) + // direction is assumed to be normalized (for accurate distance calculations) - this.ray.set( origin, direction ); + this.ray.set( origin, direction ); - }, + }, - setFromCamera: function ( coords, camera ) { + setFromCamera: function ( coords, camera ) { - if ( ( camera && camera.isPerspectiveCamera ) ) { + if ( ( camera && camera.isPerspectiveCamera ) ) { - this.ray.origin.setFromMatrixPosition( camera.matrixWorld ); - this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize(); + this.ray.origin.setFromMatrixPosition( camera.matrixWorld ); + this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize(); - } else if ( ( camera && camera.isOrthographicCamera ) ) { + } else if ( ( camera && camera.isOrthographicCamera ) ) { - this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera - this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld ); + this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera + this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld ); - } else { + } else { - console.error( 'THREE.Raycaster: Unsupported camera type.' ); + console.error( 'THREE.Raycaster: Unsupported camera type.' ); - } + } - }, + }, - intersectObject: function ( object, recursive, optionalTarget ) { + intersectObject: function ( object, recursive, optionalTarget ) { - var intersects = optionalTarget || []; + var intersects = optionalTarget || []; - intersectObject( object, this, intersects, recursive ); + intersectObject( object, this, intersects, recursive ); - intersects.sort( ascSort ); + intersects.sort( ascSort ); - return intersects; + return intersects; - }, + }, - intersectObjects: function ( objects, recursive, optionalTarget ) { + intersectObjects: function ( objects, recursive, optionalTarget ) { - var intersects = optionalTarget || []; + var intersects = optionalTarget || []; - if ( Array.isArray( objects ) === false ) { + if ( Array.isArray( objects ) === false ) { - console.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' ); - return intersects; + console.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' ); + return intersects; - } + } - for ( var i = 0, l = objects.length; i < l; i ++ ) { + for ( var i = 0, l = objects.length; i < l; i ++ ) { - intersectObject( objects[ i ], this, intersects, recursive ); + intersectObject( objects[ i ], this, intersects, recursive ); - } + } - intersects.sort( ascSort ); + intersects.sort( ascSort ); - return intersects; + return intersects; - } + } - } ); + } ); - /** - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author alteredq / http://alteredqualia.com/ + */ - function Clock( autoStart ) { + function Clock( autoStart ) { - this.autoStart = ( autoStart !== undefined ) ? autoStart : true; + this.autoStart = ( autoStart !== undefined ) ? autoStart : true; - this.startTime = 0; - this.oldTime = 0; - this.elapsedTime = 0; + this.startTime = 0; + this.oldTime = 0; + this.elapsedTime = 0; - this.running = false; + this.running = false; - } + } - Object.assign( Clock.prototype, { + Object.assign( Clock.prototype, { - start: function () { + start: function () { - this.startTime = ( typeof performance === 'undefined' ? Date : performance ).now(); // see #10732 + this.startTime = ( typeof performance === 'undefined' ? Date : performance ).now(); // see #10732 - this.oldTime = this.startTime; - this.elapsedTime = 0; - this.running = true; + this.oldTime = this.startTime; + this.elapsedTime = 0; + this.running = true; - }, + }, - stop: function () { + stop: function () { - this.getElapsedTime(); - this.running = false; - this.autoStart = false; + this.getElapsedTime(); + this.running = false; + this.autoStart = false; - }, + }, - getElapsedTime: function () { + getElapsedTime: function () { - this.getDelta(); - return this.elapsedTime; + this.getDelta(); + return this.elapsedTime; - }, + }, - getDelta: function () { + getDelta: function () { - var diff = 0; + var diff = 0; - if ( this.autoStart && ! this.running ) { + if ( this.autoStart && ! this.running ) { - this.start(); - return 0; + this.start(); + return 0; - } + } - if ( this.running ) { + if ( this.running ) { - var newTime = ( typeof performance === 'undefined' ? Date : performance ).now(); + var newTime = ( typeof performance === 'undefined' ? Date : performance ).now(); - diff = ( newTime - this.oldTime ) / 1000; - this.oldTime = newTime; + diff = ( newTime - this.oldTime ) / 1000; + this.oldTime = newTime; - this.elapsedTime += diff; + this.elapsedTime += diff; - } + } - return diff; + return diff; - } + } - } ); + } ); - /** - * @author bhouston / http://clara.io - * @author WestLangley / http://github.com/WestLangley - * - * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system - * - * The poles (phi) are at the positive and negative y axis. - * The equator starts at positive z. - */ + /** + * @author bhouston / http://clara.io + * @author WestLangley / http://github.com/WestLangley + * + * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system + * + * The poles (phi) are at the positive and negative y axis. + * The equator starts at positive z. + */ - function Spherical( radius, phi, theta ) { + function Spherical( radius, phi, theta ) { - this.radius = ( radius !== undefined ) ? radius : 1.0; - this.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole - this.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere + this.radius = ( radius !== undefined ) ? radius : 1.0; + this.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole + this.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere - return this; + return this; - } + } - Object.assign( Spherical.prototype, { + Object.assign( Spherical.prototype, { - set: function ( radius, phi, theta ) { + set: function ( radius, phi, theta ) { - this.radius = radius; - this.phi = phi; - this.theta = theta; + this.radius = radius; + this.phi = phi; + this.theta = theta; - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( other ) { + copy: function ( other ) { - this.radius = other.radius; - this.phi = other.phi; - this.theta = other.theta; + this.radius = other.radius; + this.phi = other.phi; + this.theta = other.theta; - return this; + return this; - }, + }, - // restrict phi to be betwee EPS and PI-EPS - makeSafe: function () { + // restrict phi to be betwee EPS and PI-EPS + makeSafe: function () { - var EPS = 0.000001; - this.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) ); + var EPS = 0.000001; + this.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) ); - return this; + return this; - }, + }, - setFromVector3: function ( vec3 ) { + setFromVector3: function ( vec3 ) { - this.radius = vec3.length(); + this.radius = vec3.length(); - if ( this.radius === 0 ) { + if ( this.radius === 0 ) { - this.theta = 0; - this.phi = 0; + this.theta = 0; + this.phi = 0; - } else { + } else { - this.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis - this.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle + this.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis + this.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle - } + } - return this; + return this; - } + } - } ); + } ); - /** - * @author Mugen87 / https://github.com/Mugen87 - * - * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system - * - */ + /** + * @author Mugen87 / https://github.com/Mugen87 + * + * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system + * + */ - function Cylindrical( radius, theta, y ) { + function Cylindrical( radius, theta, y ) { - this.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane - this.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis - this.y = ( y !== undefined ) ? y : 0; // height above the x-z plane + this.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane + this.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis + this.y = ( y !== undefined ) ? y : 0; // height above the x-z plane - return this; + return this; - } + } - Object.assign( Cylindrical.prototype, { + Object.assign( Cylindrical.prototype, { - set: function ( radius, theta, y ) { + set: function ( radius, theta, y ) { - this.radius = radius; - this.theta = theta; - this.y = y; + this.radius = radius; + this.theta = theta; + this.y = y; - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( other ) { + copy: function ( other ) { - this.radius = other.radius; - this.theta = other.theta; - this.y = other.y; + this.radius = other.radius; + this.theta = other.theta; + this.y = other.y; - return this; + return this; - }, + }, - setFromVector3: function ( vec3 ) { + setFromVector3: function ( vec3 ) { - this.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z ); - this.theta = Math.atan2( vec3.x, vec3.z ); - this.y = vec3.y; + this.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z ); + this.theta = Math.atan2( vec3.x, vec3.z ); + this.y = vec3.y; - return this; + return this; - } + } - } ); + } ); - /** - * @author bhouston / http://clara.io - */ + /** + * @author bhouston / http://clara.io + */ - function Box2( min, max ) { + function Box2( min, max ) { - this.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity ); - this.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity ); + this.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity ); + this.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity ); - } + } - Object.assign( Box2.prototype, { + Object.assign( Box2.prototype, { - set: function ( min, max ) { + set: function ( min, max ) { - this.min.copy( min ); - this.max.copy( max ); + this.min.copy( min ); + this.max.copy( max ); - return this; + return this; - }, + }, - setFromPoints: function ( points ) { + setFromPoints: function ( points ) { - this.makeEmpty(); + this.makeEmpty(); - for ( var i = 0, il = points.length; i < il; i ++ ) { + for ( var i = 0, il = points.length; i < il; i ++ ) { - this.expandByPoint( points[ i ] ); + this.expandByPoint( points[ i ] ); - } + } - return this; + return this; - }, + }, - setFromCenterAndSize: function () { + setFromCenterAndSize: function () { - var v1 = new Vector2(); + var v1 = new Vector2(); - return function setFromCenterAndSize( center, size ) { + return function setFromCenterAndSize( center, size ) { - var halfSize = v1.copy( size ).multiplyScalar( 0.5 ); - this.min.copy( center ).sub( halfSize ); - this.max.copy( center ).add( halfSize ); + var halfSize = v1.copy( size ).multiplyScalar( 0.5 ); + this.min.copy( center ).sub( halfSize ); + this.max.copy( center ).add( halfSize ); - return this; + return this; - }; + }; - }(), + }(), - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( box ) { + copy: function ( box ) { - this.min.copy( box.min ); - this.max.copy( box.max ); + this.min.copy( box.min ); + this.max.copy( box.max ); - return this; + return this; - }, + }, - makeEmpty: function () { + makeEmpty: function () { - this.min.x = this.min.y = + Infinity; - this.max.x = this.max.y = - Infinity; + this.min.x = this.min.y = + Infinity; + this.max.x = this.max.y = - Infinity; - return this; + return this; - }, + }, - isEmpty: function () { + isEmpty: function () { - // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes + // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes - return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ); + return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ); - }, + }, - getCenter: function ( target ) { + getCenter: function ( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Box2: .getCenter() target is now required' ); - target = new Vector2(); + console.warn( 'THREE.Box2: .getCenter() target is now required' ); + target = new Vector2(); - } + } - return this.isEmpty() ? target.set( 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); + return this.isEmpty() ? target.set( 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); - }, + }, - getSize: function ( target ) { + getSize: function ( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Box2: .getSize() target is now required' ); - target = new Vector2(); + console.warn( 'THREE.Box2: .getSize() target is now required' ); + target = new Vector2(); - } + } - return this.isEmpty() ? target.set( 0, 0 ) : target.subVectors( this.max, this.min ); + return this.isEmpty() ? target.set( 0, 0 ) : target.subVectors( this.max, this.min ); - }, + }, - expandByPoint: function ( point ) { + expandByPoint: function ( point ) { - this.min.min( point ); - this.max.max( point ); + this.min.min( point ); + this.max.max( point ); - return this; + return this; - }, + }, - expandByVector: function ( vector ) { + expandByVector: function ( vector ) { - this.min.sub( vector ); - this.max.add( vector ); + this.min.sub( vector ); + this.max.add( vector ); - return this; + return this; - }, + }, - expandByScalar: function ( scalar ) { + expandByScalar: function ( scalar ) { - this.min.addScalar( - scalar ); - this.max.addScalar( scalar ); + this.min.addScalar( - scalar ); + this.max.addScalar( scalar ); - return this; + return this; - }, + }, - containsPoint: function ( point ) { + containsPoint: function ( point ) { - return point.x < this.min.x || point.x > this.max.x || - point.y < this.min.y || point.y > this.max.y ? false : true; + return point.x < this.min.x || point.x > this.max.x || + point.y < this.min.y || point.y > this.max.y ? false : true; - }, + }, - containsBox: function ( box ) { + containsBox: function ( box ) { - return this.min.x <= box.min.x && box.max.x <= this.max.x && - this.min.y <= box.min.y && box.max.y <= this.max.y; + return this.min.x <= box.min.x && box.max.x <= this.max.x && + this.min.y <= box.min.y && box.max.y <= this.max.y; - }, + }, - getParameter: function ( point, target ) { + getParameter: function ( point, target ) { - // This can potentially have a divide by zero if the box - // has a size dimension of 0. + // This can potentially have a divide by zero if the box + // has a size dimension of 0. - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Box2: .getParameter() target is now required' ); - target = new Vector2(); + console.warn( 'THREE.Box2: .getParameter() target is now required' ); + target = new Vector2(); - } + } - return target.set( - ( point.x - this.min.x ) / ( this.max.x - this.min.x ), - ( point.y - this.min.y ) / ( this.max.y - this.min.y ) - ); + return target.set( + ( point.x - this.min.x ) / ( this.max.x - this.min.x ), + ( point.y - this.min.y ) / ( this.max.y - this.min.y ) + ); - }, + }, - intersectsBox: function ( box ) { + intersectsBox: function ( box ) { - // using 4 splitting planes to rule out intersections + // using 4 splitting planes to rule out intersections - return box.max.x < this.min.x || box.min.x > this.max.x || - box.max.y < this.min.y || box.min.y > this.max.y ? false : true; + return box.max.x < this.min.x || box.min.x > this.max.x || + box.max.y < this.min.y || box.min.y > this.max.y ? false : true; - }, + }, - clampPoint: function ( point, target ) { + clampPoint: function ( point, target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Box2: .clampPoint() target is now required' ); - target = new Vector2(); + console.warn( 'THREE.Box2: .clampPoint() target is now required' ); + target = new Vector2(); - } + } - return target.copy( point ).clamp( this.min, this.max ); + return target.copy( point ).clamp( this.min, this.max ); - }, + }, - distanceToPoint: function () { + distanceToPoint: function () { - var v1 = new Vector2(); + var v1 = new Vector2(); - return function distanceToPoint( point ) { + return function distanceToPoint( point ) { - var clampedPoint = v1.copy( point ).clamp( this.min, this.max ); - return clampedPoint.sub( point ).length(); + var clampedPoint = v1.copy( point ).clamp( this.min, this.max ); + return clampedPoint.sub( point ).length(); - }; + }; - }(), + }(), - intersect: function ( box ) { + intersect: function ( box ) { - this.min.max( box.min ); - this.max.min( box.max ); + this.min.max( box.min ); + this.max.min( box.max ); - return this; + return this; - }, + }, - union: function ( box ) { + union: function ( box ) { - this.min.min( box.min ); - this.max.max( box.max ); + this.min.min( box.min ); + this.max.max( box.max ); - return this; + return this; - }, + }, - translate: function ( offset ) { + translate: function ( offset ) { - this.min.add( offset ); - this.max.add( offset ); + this.min.add( offset ); + this.max.add( offset ); - return this; + return this; - }, + }, - equals: function ( box ) { + equals: function ( box ) { - return box.min.equals( this.min ) && box.max.equals( this.max ); + return box.min.equals( this.min ) && box.max.equals( this.max ); - } + } - } ); + } ); - /** - * @author bhouston / http://clara.io - */ + /** + * @author bhouston / http://clara.io + */ - function Line3( start, end ) { + function Line3( start, end ) { - this.start = ( start !== undefined ) ? start : new Vector3(); - this.end = ( end !== undefined ) ? end : new Vector3(); + this.start = ( start !== undefined ) ? start : new Vector3(); + this.end = ( end !== undefined ) ? end : new Vector3(); - } + } - Object.assign( Line3.prototype, { + Object.assign( Line3.prototype, { - set: function ( start, end ) { + set: function ( start, end ) { - this.start.copy( start ); - this.end.copy( end ); + this.start.copy( start ); + this.end.copy( end ); - return this; + return this; - }, + }, - clone: function () { + clone: function () { - return new this.constructor().copy( this ); + return new this.constructor().copy( this ); - }, + }, - copy: function ( line ) { + copy: function ( line ) { - this.start.copy( line.start ); - this.end.copy( line.end ); + this.start.copy( line.start ); + this.end.copy( line.end ); - return this; + return this; - }, + }, - getCenter: function ( target ) { + getCenter: function ( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Line3: .getCenter() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Line3: .getCenter() target is now required' ); + target = new Vector3(); - } + } - return target.addVectors( this.start, this.end ).multiplyScalar( 0.5 ); + return target.addVectors( this.start, this.end ).multiplyScalar( 0.5 ); - }, + }, - delta: function ( target ) { + delta: function ( target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Line3: .delta() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Line3: .delta() target is now required' ); + target = new Vector3(); - } + } - return target.subVectors( this.end, this.start ); + return target.subVectors( this.end, this.start ); - }, + }, - distanceSq: function () { + distanceSq: function () { - return this.start.distanceToSquared( this.end ); + return this.start.distanceToSquared( this.end ); - }, + }, - distance: function () { + distance: function () { - return this.start.distanceTo( this.end ); + return this.start.distanceTo( this.end ); - }, + }, - at: function ( t, target ) { + at: function ( t, target ) { - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Line3: .at() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Line3: .at() target is now required' ); + target = new Vector3(); - } + } - return this.delta( target ).multiplyScalar( t ).add( this.start ); + return this.delta( target ).multiplyScalar( t ).add( this.start ); - }, + }, - closestPointToPointParameter: function () { + closestPointToPointParameter: function () { - var startP = new Vector3(); - var startEnd = new Vector3(); + var startP = new Vector3(); + var startEnd = new Vector3(); - return function closestPointToPointParameter( point, clampToLine ) { + return function closestPointToPointParameter( point, clampToLine ) { - startP.subVectors( point, this.start ); - startEnd.subVectors( this.end, this.start ); + startP.subVectors( point, this.start ); + startEnd.subVectors( this.end, this.start ); - var startEnd2 = startEnd.dot( startEnd ); - var startEnd_startP = startEnd.dot( startP ); + var startEnd2 = startEnd.dot( startEnd ); + var startEnd_startP = startEnd.dot( startP ); - var t = startEnd_startP / startEnd2; + var t = startEnd_startP / startEnd2; - if ( clampToLine ) { + if ( clampToLine ) { - t = _Math.clamp( t, 0, 1 ); + t = _Math.clamp( t, 0, 1 ); - } + } - return t; + return t; - }; + }; - }(), + }(), - closestPointToPoint: function ( point, clampToLine, target ) { + closestPointToPoint: function ( point, clampToLine, target ) { - var t = this.closestPointToPointParameter( point, clampToLine ); + var t = this.closestPointToPointParameter( point, clampToLine ); - if ( target === undefined ) { + if ( target === undefined ) { - console.warn( 'THREE.Line3: .closestPointToPoint() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Line3: .closestPointToPoint() target is now required' ); + target = new Vector3(); - } + } - return this.delta( target ).multiplyScalar( t ).add( this.start ); + return this.delta( target ).multiplyScalar( t ).add( this.start ); - }, + }, - applyMatrix4: function ( matrix ) { + applyMatrix4: function ( matrix ) { - this.start.applyMatrix4( matrix ); - this.end.applyMatrix4( matrix ); + this.start.applyMatrix4( matrix ); + this.end.applyMatrix4( matrix ); - return this; + return this; - }, + }, - equals: function ( line ) { + equals: function ( line ) { - return line.start.equals( this.start ) && line.end.equals( this.end ); + return line.start.equals( this.start ) && line.end.equals( this.end ); - } + } - } ); + } ); - /** - * @author alteredq / http://alteredqualia.com/ - */ + /** + * @author alteredq / http://alteredqualia.com/ + */ - function ImmediateRenderObject( material ) { + function ImmediateRenderObject( material ) { - Object3D.call( this ); + Object3D.call( this ); - this.material = material; - this.render = function ( /* renderCallback */ ) {}; + this.material = material; + this.render = function ( /* renderCallback */ ) {}; - } + } - ImmediateRenderObject.prototype = Object.create( Object3D.prototype ); - ImmediateRenderObject.prototype.constructor = ImmediateRenderObject; + ImmediateRenderObject.prototype = Object.create( Object3D.prototype ); + ImmediateRenderObject.prototype.constructor = ImmediateRenderObject; - ImmediateRenderObject.prototype.isImmediateRenderObject = true; + ImmediateRenderObject.prototype.isImmediateRenderObject = true; - /** - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author WestLangley / http://github.com/WestLangley + */ - function VertexNormalsHelper( object, size, hex, linewidth ) { + function VertexNormalsHelper( object, size, hex, linewidth ) { - this.object = object; + this.object = object; - this.size = ( size !== undefined ) ? size : 1; + this.size = ( size !== undefined ) ? size : 1; - var color = ( hex !== undefined ) ? hex : 0xff0000; + var color = ( hex !== undefined ) ? hex : 0xff0000; - var width = ( linewidth !== undefined ) ? linewidth : 1; + var width = ( linewidth !== undefined ) ? linewidth : 1; - // + // - var nNormals = 0; + var nNormals = 0; - var objGeometry = this.object.geometry; + var objGeometry = this.object.geometry; - if ( objGeometry && objGeometry.isGeometry ) { + if ( objGeometry && objGeometry.isGeometry ) { - nNormals = objGeometry.faces.length * 3; + nNormals = objGeometry.faces.length * 3; - } else if ( objGeometry && objGeometry.isBufferGeometry ) { + } else if ( objGeometry && objGeometry.isBufferGeometry ) { - nNormals = objGeometry.attributes.normal.count; + nNormals = objGeometry.attributes.normal.count; - } + } - // + // - var geometry = new BufferGeometry(); + var geometry = new BufferGeometry(); - var positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 ); + var positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 ); - geometry.addAttribute( 'position', positions ); + geometry.addAttribute( 'position', positions ); - LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) ); + LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) ); - // + // - this.matrixAutoUpdate = false; + this.matrixAutoUpdate = false; - this.update(); + this.update(); - } + } - VertexNormalsHelper.prototype = Object.create( LineSegments.prototype ); - VertexNormalsHelper.prototype.constructor = VertexNormalsHelper; + VertexNormalsHelper.prototype = Object.create( LineSegments.prototype ); + VertexNormalsHelper.prototype.constructor = VertexNormalsHelper; - VertexNormalsHelper.prototype.update = ( function () { + VertexNormalsHelper.prototype.update = ( function () { - var v1 = new Vector3(); - var v2 = new Vector3(); - var normalMatrix = new Matrix3(); + var v1 = new Vector3(); + var v2 = new Vector3(); + var normalMatrix = new Matrix3(); - return function update() { + return function update() { - var keys = [ 'a', 'b', 'c' ]; + var keys = [ 'a', 'b', 'c' ]; - this.object.updateMatrixWorld( true ); + this.object.updateMatrixWorld( true ); - normalMatrix.getNormalMatrix( this.object.matrixWorld ); + normalMatrix.getNormalMatrix( this.object.matrixWorld ); - var matrixWorld = this.object.matrixWorld; + var matrixWorld = this.object.matrixWorld; - var position = this.geometry.attributes.position; + var position = this.geometry.attributes.position; - // + // - var objGeometry = this.object.geometry; + var objGeometry = this.object.geometry; - if ( objGeometry && objGeometry.isGeometry ) { + if ( objGeometry && objGeometry.isGeometry ) { - var vertices = objGeometry.vertices; + var vertices = objGeometry.vertices; - var faces = objGeometry.faces; + var faces = objGeometry.faces; - var idx = 0; + var idx = 0; - for ( var i = 0, l = faces.length; i < l; i ++ ) { + for ( var i = 0, l = faces.length; i < l; i ++ ) { - var face = faces[ i ]; + var face = faces[ i ]; - for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { + for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { - var vertex = vertices[ face[ keys[ j ] ] ]; + var vertex = vertices[ face[ keys[ j ] ] ]; - var normal = face.vertexNormals[ j ]; + var normal = face.vertexNormals[ j ]; - v1.copy( vertex ).applyMatrix4( matrixWorld ); + v1.copy( vertex ).applyMatrix4( matrixWorld ); - v2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 ); + v2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 ); - position.setXYZ( idx, v1.x, v1.y, v1.z ); + position.setXYZ( idx, v1.x, v1.y, v1.z ); - idx = idx + 1; + idx = idx + 1; - position.setXYZ( idx, v2.x, v2.y, v2.z ); + position.setXYZ( idx, v2.x, v2.y, v2.z ); - idx = idx + 1; + idx = idx + 1; - } + } - } + } - } else if ( objGeometry && objGeometry.isBufferGeometry ) { + } else if ( objGeometry && objGeometry.isBufferGeometry ) { - var objPos = objGeometry.attributes.position; + var objPos = objGeometry.attributes.position; - var objNorm = objGeometry.attributes.normal; + var objNorm = objGeometry.attributes.normal; - var idx = 0; + var idx = 0; - // for simplicity, ignore index and drawcalls, and render every normal + // for simplicity, ignore index and drawcalls, and render every normal - for ( var j = 0, jl = objPos.count; j < jl; j ++ ) { + for ( var j = 0, jl = objPos.count; j < jl; j ++ ) { - v1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld ); + v1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld ); - v2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) ); + v2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) ); - v2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 ); + v2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 ); - position.setXYZ( idx, v1.x, v1.y, v1.z ); + position.setXYZ( idx, v1.x, v1.y, v1.z ); - idx = idx + 1; + idx = idx + 1; - position.setXYZ( idx, v2.x, v2.y, v2.z ); + position.setXYZ( idx, v2.x, v2.y, v2.z ); - idx = idx + 1; + idx = idx + 1; - } + } - } + } - position.needsUpdate = true; + position.needsUpdate = true; - }; + }; - }() ); + }() ); - /** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley - */ + /** + * @author alteredq / http://alteredqualia.com/ + * @author mrdoob / http://mrdoob.com/ + * @author WestLangley / http://github.com/WestLangley + */ - function SpotLightHelper( light, color ) { + function SpotLightHelper( light, color ) { - Object3D.call( this ); + Object3D.call( this ); - this.light = light; - this.light.updateMatrixWorld(); + this.light = light; + this.light.updateMatrixWorld(); - this.matrix = light.matrixWorld; - this.matrixAutoUpdate = false; + this.matrix = light.matrixWorld; + this.matrixAutoUpdate = false; - this.color = color; + this.color = color; - var geometry = new BufferGeometry(); + var geometry = new BufferGeometry(); - var positions = [ - 0, 0, 0, 0, 0, 1, - 0, 0, 0, 1, 0, 1, - 0, 0, 0, - 1, 0, 1, - 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, - 1, 1 - ]; + var positions = [ + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 1, + 0, 0, 0, - 1, 0, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, - 1, 1 + ]; - for ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) { + for ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) { - var p1 = ( i / l ) * Math.PI * 2; - var p2 = ( j / l ) * Math.PI * 2; + var p1 = ( i / l ) * Math.PI * 2; + var p2 = ( j / l ) * Math.PI * 2; - positions.push( - Math.cos( p1 ), Math.sin( p1 ), 1, - Math.cos( p2 ), Math.sin( p2 ), 1 - ); + positions.push( + Math.cos( p1 ), Math.sin( p1 ), 1, + Math.cos( p2 ), Math.sin( p2 ), 1 + ); - } + } - geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); + geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); - var material = new LineBasicMaterial( { fog: false } ); + var material = new LineBasicMaterial( { fog: false } ); - this.cone = new LineSegments( geometry, material ); - this.add( this.cone ); + this.cone = new LineSegments( geometry, material ); + this.add( this.cone ); - this.update(); + this.update(); - } + } - SpotLightHelper.prototype = Object.create( Object3D.prototype ); - SpotLightHelper.prototype.constructor = SpotLightHelper; + SpotLightHelper.prototype = Object.create( Object3D.prototype ); + SpotLightHelper.prototype.constructor = SpotLightHelper; - SpotLightHelper.prototype.dispose = function () { + SpotLightHelper.prototype.dispose = function () { - this.cone.geometry.dispose(); - this.cone.material.dispose(); + this.cone.geometry.dispose(); + this.cone.material.dispose(); - }; + }; - SpotLightHelper.prototype.update = function () { + SpotLightHelper.prototype.update = function () { - var vector = new Vector3(); - var vector2 = new Vector3(); + var vector = new Vector3(); + var vector2 = new Vector3(); - return function update() { + return function update() { - this.light.updateMatrixWorld(); + this.light.updateMatrixWorld(); - var coneLength = this.light.distance ? this.light.distance : 1000; - var coneWidth = coneLength * Math.tan( this.light.angle ); + var coneLength = this.light.distance ? this.light.distance : 1000; + var coneWidth = coneLength * Math.tan( this.light.angle ); - this.cone.scale.set( coneWidth, coneWidth, coneLength ); + this.cone.scale.set( coneWidth, coneWidth, coneLength ); - vector.setFromMatrixPosition( this.light.matrixWorld ); - vector2.setFromMatrixPosition( this.light.target.matrixWorld ); + vector.setFromMatrixPosition( this.light.matrixWorld ); + vector2.setFromMatrixPosition( this.light.target.matrixWorld ); - this.cone.lookAt( vector2.sub( vector ) ); + this.cone.lookAt( vector2.sub( vector ) ); - if ( this.color !== undefined ) { + if ( this.color !== undefined ) { - this.cone.material.color.set( this.color ); + this.cone.material.color.set( this.color ); - } else { + } else { - this.cone.material.color.copy( this.light.color ); + this.cone.material.color.copy( this.light.color ); - } + } - }; + }; - }(); + }(); - /** - * @author Sean Griffin / http://twitter.com/sgrif - * @author Michael Guerrero / http://realitymeltdown.com - * @author mrdoob / http://mrdoob.com/ - * @author ikerr / http://verold.com - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author Sean Griffin / http://twitter.com/sgrif + * @author Michael Guerrero / http://realitymeltdown.com + * @author mrdoob / http://mrdoob.com/ + * @author ikerr / http://verold.com + * @author Mugen87 / https://github.com/Mugen87 + */ - function getBoneList( object ) { + function getBoneList( object ) { - var boneList = []; + var boneList = []; - if ( object && object.isBone ) { + if ( object && object.isBone ) { - boneList.push( object ); + boneList.push( object ); - } + } - for ( var i = 0; i < object.children.length; i ++ ) { + for ( var i = 0; i < object.children.length; i ++ ) { - boneList.push.apply( boneList, getBoneList( object.children[ i ] ) ); + boneList.push.apply( boneList, getBoneList( object.children[ i ] ) ); - } + } - return boneList; + return boneList; - } + } - function SkeletonHelper( object ) { + function SkeletonHelper( object ) { - var bones = getBoneList( object ); + var bones = getBoneList( object ); - var geometry = new BufferGeometry(); + var geometry = new BufferGeometry(); - var vertices = []; - var colors = []; + var vertices = []; + var colors = []; - var color1 = new Color( 0, 0, 1 ); - var color2 = new Color( 0, 1, 0 ); + var color1 = new Color( 0, 0, 1 ); + var color2 = new Color( 0, 1, 0 ); - for ( var i = 0; i < bones.length; i ++ ) { + for ( var i = 0; i < bones.length; i ++ ) { - var bone = bones[ i ]; + var bone = bones[ i ]; - if ( bone.parent && bone.parent.isBone ) { + if ( bone.parent && bone.parent.isBone ) { - vertices.push( 0, 0, 0 ); - vertices.push( 0, 0, 0 ); - colors.push( color1.r, color1.g, color1.b ); - colors.push( color2.r, color2.g, color2.b ); + vertices.push( 0, 0, 0 ); + vertices.push( 0, 0, 0 ); + colors.push( color1.r, color1.g, color1.b ); + colors.push( color2.r, color2.g, color2.b ); - } + } - } + } - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - var material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } ); + var material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } ); - LineSegments.call( this, geometry, material ); + LineSegments.call( this, geometry, material ); - this.root = object; - this.bones = bones; + this.root = object; + this.bones = bones; - this.matrix = object.matrixWorld; - this.matrixAutoUpdate = false; + this.matrix = object.matrixWorld; + this.matrixAutoUpdate = false; - } + } - SkeletonHelper.prototype = Object.create( LineSegments.prototype ); - SkeletonHelper.prototype.constructor = SkeletonHelper; + SkeletonHelper.prototype = Object.create( LineSegments.prototype ); + SkeletonHelper.prototype.constructor = SkeletonHelper; - SkeletonHelper.prototype.updateMatrixWorld = function () { + SkeletonHelper.prototype.updateMatrixWorld = function () { - var vector = new Vector3(); + var vector = new Vector3(); - var boneMatrix = new Matrix4(); - var matrixWorldInv = new Matrix4(); + var boneMatrix = new Matrix4(); + var matrixWorldInv = new Matrix4(); - return function updateMatrixWorld( force ) { + return function updateMatrixWorld( force ) { - var bones = this.bones; + var bones = this.bones; - var geometry = this.geometry; - var position = geometry.getAttribute( 'position' ); + var geometry = this.geometry; + var position = geometry.getAttribute( 'position' ); - matrixWorldInv.getInverse( this.root.matrixWorld ); + matrixWorldInv.getInverse( this.root.matrixWorld ); - for ( var i = 0, j = 0; i < bones.length; i ++ ) { + for ( var i = 0, j = 0; i < bones.length; i ++ ) { - var bone = bones[ i ]; + var bone = bones[ i ]; - if ( bone.parent && bone.parent.isBone ) { + if ( bone.parent && bone.parent.isBone ) { - boneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld ); - vector.setFromMatrixPosition( boneMatrix ); - position.setXYZ( j, vector.x, vector.y, vector.z ); + boneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld ); + vector.setFromMatrixPosition( boneMatrix ); + position.setXYZ( j, vector.x, vector.y, vector.z ); - boneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld ); - vector.setFromMatrixPosition( boneMatrix ); - position.setXYZ( j + 1, vector.x, vector.y, vector.z ); + boneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld ); + vector.setFromMatrixPosition( boneMatrix ); + position.setXYZ( j + 1, vector.x, vector.y, vector.z ); - j += 2; + j += 2; - } + } - } + } - geometry.getAttribute( 'position' ).needsUpdate = true; + geometry.getAttribute( 'position' ).needsUpdate = true; - Object3D.prototype.updateMatrixWorld.call( this, force ); + Object3D.prototype.updateMatrixWorld.call( this, force ); - }; + }; - }(); + }(); - /** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author alteredq / http://alteredqualia.com/ + * @author mrdoob / http://mrdoob.com/ + */ - function PointLightHelper( light, sphereSize, color ) { + function PointLightHelper( light, sphereSize, color ) { - this.light = light; - this.light.updateMatrixWorld(); + this.light = light; + this.light.updateMatrixWorld(); - this.color = color; + this.color = color; - var geometry = new SphereBufferGeometry( sphereSize, 4, 2 ); - var material = new MeshBasicMaterial( { wireframe: true, fog: false } ); + var geometry = new SphereBufferGeometry( sphereSize, 4, 2 ); + var material = new MeshBasicMaterial( { wireframe: true, fog: false } ); - Mesh.call( this, geometry, material ); + Mesh.call( this, geometry, material ); - this.matrix = this.light.matrixWorld; - this.matrixAutoUpdate = false; + this.matrix = this.light.matrixWorld; + this.matrixAutoUpdate = false; - this.update(); + this.update(); - /* - var distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 ); - var distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } ); + /* + var distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 ); + var distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } ); - this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial ); - this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial ); + this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial ); + this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial ); - var d = light.distance; + var d = light.distance; - if ( d === 0.0 ) { + if ( d === 0.0 ) { - this.lightDistance.visible = false; + this.lightDistance.visible = false; - } else { + } else { - this.lightDistance.scale.set( d, d, d ); + this.lightDistance.scale.set( d, d, d ); - } + } - this.add( this.lightDistance ); - */ + this.add( this.lightDistance ); + */ - } + } - PointLightHelper.prototype = Object.create( Mesh.prototype ); - PointLightHelper.prototype.constructor = PointLightHelper; + PointLightHelper.prototype = Object.create( Mesh.prototype ); + PointLightHelper.prototype.constructor = PointLightHelper; - PointLightHelper.prototype.dispose = function () { + PointLightHelper.prototype.dispose = function () { - this.geometry.dispose(); - this.material.dispose(); + this.geometry.dispose(); + this.material.dispose(); - }; + }; - PointLightHelper.prototype.update = function () { + PointLightHelper.prototype.update = function () { - if ( this.color !== undefined ) { + if ( this.color !== undefined ) { - this.material.color.set( this.color ); + this.material.color.set( this.color ); - } else { + } else { - this.material.color.copy( this.light.color ); + this.material.color.copy( this.light.color ); - } + } - /* - var d = this.light.distance; + /* + var d = this.light.distance; - if ( d === 0.0 ) { + if ( d === 0.0 ) { - this.lightDistance.visible = false; + this.lightDistance.visible = false; - } else { + } else { - this.lightDistance.visible = true; - this.lightDistance.scale.set( d, d, d ); + this.lightDistance.visible = true; + this.lightDistance.scale.set( d, d, d ); - } - */ + } + */ - }; + }; - /** - * @author abelnation / http://github.com/abelnation - * @author Mugen87 / http://github.com/Mugen87 - * @author WestLangley / http://github.com/WestLangley - */ + /** + * @author abelnation / http://github.com/abelnation + * @author Mugen87 / http://github.com/Mugen87 + * @author WestLangley / http://github.com/WestLangley + */ - function RectAreaLightHelper( light, color ) { + function RectAreaLightHelper( light, color ) { - Object3D.call( this ); + Object3D.call( this ); - this.light = light; - this.light.updateMatrixWorld(); + this.light = light; + this.light.updateMatrixWorld(); - this.matrix = light.matrixWorld; - this.matrixAutoUpdate = false; + this.matrix = light.matrixWorld; + this.matrixAutoUpdate = false; - this.color = color; + this.color = color; - var material = new LineBasicMaterial( { fog: false } ); + var material = new LineBasicMaterial( { fog: false } ); - var geometry = new BufferGeometry(); + var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 5 * 3 ), 3 ) ); + geometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 5 * 3 ), 3 ) ); - this.line = new Line( geometry, material ); - this.add( this.line ); + this.line = new Line( geometry, material ); + this.add( this.line ); - this.update(); + this.update(); - } + } - RectAreaLightHelper.prototype = Object.create( Object3D.prototype ); - RectAreaLightHelper.prototype.constructor = RectAreaLightHelper; + RectAreaLightHelper.prototype = Object.create( Object3D.prototype ); + RectAreaLightHelper.prototype.constructor = RectAreaLightHelper; - RectAreaLightHelper.prototype.dispose = function () { + RectAreaLightHelper.prototype.dispose = function () { - this.children[ 0 ].geometry.dispose(); - this.children[ 0 ].material.dispose(); + this.children[ 0 ].geometry.dispose(); + this.children[ 0 ].material.dispose(); - }; + }; - RectAreaLightHelper.prototype.update = function () { + RectAreaLightHelper.prototype.update = function () { - // calculate new dimensions of the helper + // calculate new dimensions of the helper - var hx = this.light.width * 0.5; - var hy = this.light.height * 0.5; + var hx = this.light.width * 0.5; + var hy = this.light.height * 0.5; - var position = this.line.geometry.attributes.position; - var array = position.array; + var position = this.line.geometry.attributes.position; + var array = position.array; - // update vertices + // update vertices - array[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0; - array[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0; - array[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0; - array[ 9 ] = - hx; array[ 10 ] = - hy; array[ 11 ] = 0; - array[ 12 ] = hx; array[ 13 ] = - hy; array[ 14 ] = 0; + array[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0; + array[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0; + array[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0; + array[ 9 ] = - hx; array[ 10 ] = - hy; array[ 11 ] = 0; + array[ 12 ] = hx; array[ 13 ] = - hy; array[ 14 ] = 0; - position.needsUpdate = true; + position.needsUpdate = true; - if ( this.color !== undefined ) { + if ( this.color !== undefined ) { - this.line.material.color.set( this.color ); + this.line.material.color.set( this.color ); - } else { + } else { - this.line.material.color.copy( this.light.color ); + this.line.material.color.copy( this.light.color ); - } + } - }; + }; - /** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - * @author Mugen87 / https://github.com/Mugen87 - */ + /** + * @author alteredq / http://alteredqualia.com/ + * @author mrdoob / http://mrdoob.com/ + * @author Mugen87 / https://github.com/Mugen87 + */ - function HemisphereLightHelper( light, size, color ) { + function HemisphereLightHelper( light, size, color ) { - Object3D.call( this ); + Object3D.call( this ); - this.light = light; - this.light.updateMatrixWorld(); + this.light = light; + this.light.updateMatrixWorld(); - this.matrix = light.matrixWorld; - this.matrixAutoUpdate = false; + this.matrix = light.matrixWorld; + this.matrixAutoUpdate = false; - this.color = color; + this.color = color; - var geometry = new OctahedronBufferGeometry( size ); - geometry.rotateY( Math.PI * 0.5 ); + var geometry = new OctahedronBufferGeometry( size ); + geometry.rotateY( Math.PI * 0.5 ); - this.material = new MeshBasicMaterial( { wireframe: true, fog: false } ); - if ( this.color === undefined ) this.material.vertexColors = VertexColors; + this.material = new MeshBasicMaterial( { wireframe: true, fog: false } ); + if ( this.color === undefined ) this.material.vertexColors = VertexColors; - var position = geometry.getAttribute( 'position' ); - var colors = new Float32Array( position.count * 3 ); + var position = geometry.getAttribute( 'position' ); + var colors = new Float32Array( position.count * 3 ); - geometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) ); + geometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) ); - this.add( new Mesh( geometry, this.material ) ); + this.add( new Mesh( geometry, this.material ) ); - this.update(); + this.update(); - } + } - HemisphereLightHelper.prototype = Object.create( Object3D.prototype ); - HemisphereLightHelper.prototype.constructor = HemisphereLightHelper; + HemisphereLightHelper.prototype = Object.create( Object3D.prototype ); + HemisphereLightHelper.prototype.constructor = HemisphereLightHelper; - HemisphereLightHelper.prototype.dispose = function () { + HemisphereLightHelper.prototype.dispose = function () { - this.children[ 0 ].geometry.dispose(); - this.children[ 0 ].material.dispose(); + this.children[ 0 ].geometry.dispose(); + this.children[ 0 ].material.dispose(); - }; + }; - HemisphereLightHelper.prototype.update = function () { + HemisphereLightHelper.prototype.update = function () { - var vector = new Vector3(); + var vector = new Vector3(); - var color1 = new Color(); - var color2 = new Color(); + var color1 = new Color(); + var color2 = new Color(); - return function update() { + return function update() { - var mesh = this.children[ 0 ]; + var mesh = this.children[ 0 ]; - if ( this.color !== undefined ) { + if ( this.color !== undefined ) { - this.material.color.set( this.color ); + this.material.color.set( this.color ); - } else { + } else { - var colors = mesh.geometry.getAttribute( 'color' ); + var colors = mesh.geometry.getAttribute( 'color' ); - color1.copy( this.light.color ); - color2.copy( this.light.groundColor ); + color1.copy( this.light.color ); + color2.copy( this.light.groundColor ); - for ( var i = 0, l = colors.count; i < l; i ++ ) { + for ( var i = 0, l = colors.count; i < l; i ++ ) { - var color = ( i < ( l / 2 ) ) ? color1 : color2; + var color = ( i < ( l / 2 ) ) ? color1 : color2; - colors.setXYZ( i, color.r, color.g, color.b ); + colors.setXYZ( i, color.r, color.g, color.b ); - } + } - colors.needsUpdate = true; + colors.needsUpdate = true; - } + } - mesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() ); + mesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() ); - }; + }; - }(); + }(); - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function GridHelper( size, divisions, color1, color2 ) { + function GridHelper( size, divisions, color1, color2 ) { - size = size || 10; - divisions = divisions || 10; - color1 = new Color( color1 !== undefined ? color1 : 0x444444 ); - color2 = new Color( color2 !== undefined ? color2 : 0x888888 ); + size = size || 10; + divisions = divisions || 10; + color1 = new Color( color1 !== undefined ? color1 : 0x444444 ); + color2 = new Color( color2 !== undefined ? color2 : 0x888888 ); - var center = divisions / 2; - var step = size / divisions; - var halfSize = size / 2; + var center = divisions / 2; + var step = size / divisions; + var halfSize = size / 2; - var vertices = [], colors = []; + var vertices = [], colors = []; - for ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) { + for ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) { - vertices.push( - halfSize, 0, k, halfSize, 0, k ); - vertices.push( k, 0, - halfSize, k, 0, halfSize ); + vertices.push( - halfSize, 0, k, halfSize, 0, k ); + vertices.push( k, 0, - halfSize, k, 0, halfSize ); - var color = i === center ? color1 : color2; + var color = i === center ? color1 : color2; - color.toArray( colors, j ); j += 3; - color.toArray( colors, j ); j += 3; - color.toArray( colors, j ); j += 3; - color.toArray( colors, j ); j += 3; + color.toArray( colors, j ); j += 3; + color.toArray( colors, j ); j += 3; + color.toArray( colors, j ); j += 3; + color.toArray( colors, j ); j += 3; - } + } - var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + var geometry = new BufferGeometry(); + geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - var material = new LineBasicMaterial( { vertexColors: VertexColors } ); + var material = new LineBasicMaterial( { vertexColors: VertexColors } ); - LineSegments.call( this, geometry, material ); + LineSegments.call( this, geometry, material ); - } + } - GridHelper.prototype = Object.create( LineSegments.prototype ); - GridHelper.prototype.constructor = GridHelper; + GridHelper.prototype = Object.create( LineSegments.prototype ); + GridHelper.prototype.constructor = GridHelper; - /** - * @author mrdoob / http://mrdoob.com/ - * @author Mugen87 / http://github.com/Mugen87 - * @author Hectate / http://www.github.com/Hectate - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author Mugen87 / http://github.com/Mugen87 + * @author Hectate / http://www.github.com/Hectate + */ - function PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) { + function PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) { - radius = radius || 10; - radials = radials || 16; - circles = circles || 8; - divisions = divisions || 64; - color1 = new Color( color1 !== undefined ? color1 : 0x444444 ); - color2 = new Color( color2 !== undefined ? color2 : 0x888888 ); + radius = radius || 10; + radials = radials || 16; + circles = circles || 8; + divisions = divisions || 64; + color1 = new Color( color1 !== undefined ? color1 : 0x444444 ); + color2 = new Color( color2 !== undefined ? color2 : 0x888888 ); - var vertices = []; - var colors = []; + var vertices = []; + var colors = []; - var x, z; - var v, i, j, r, color; + var x, z; + var v, i, j, r, color; - // create the radials + // create the radials - for ( i = 0; i <= radials; i ++ ) { + for ( i = 0; i <= radials; i ++ ) { - v = ( i / radials ) * ( Math.PI * 2 ); + v = ( i / radials ) * ( Math.PI * 2 ); - x = Math.sin( v ) * radius; - z = Math.cos( v ) * radius; + x = Math.sin( v ) * radius; + z = Math.cos( v ) * radius; - vertices.push( 0, 0, 0 ); - vertices.push( x, 0, z ); + vertices.push( 0, 0, 0 ); + vertices.push( x, 0, z ); - color = ( i & 1 ) ? color1 : color2; + color = ( i & 1 ) ? color1 : color2; - colors.push( color.r, color.g, color.b ); - colors.push( color.r, color.g, color.b ); + colors.push( color.r, color.g, color.b ); + colors.push( color.r, color.g, color.b ); - } + } - // create the circles + // create the circles - for ( i = 0; i <= circles; i ++ ) { + for ( i = 0; i <= circles; i ++ ) { - color = ( i & 1 ) ? color1 : color2; + color = ( i & 1 ) ? color1 : color2; - r = radius - ( radius / circles * i ); + r = radius - ( radius / circles * i ); - for ( j = 0; j < divisions; j ++ ) { + for ( j = 0; j < divisions; j ++ ) { - // first vertex + // first vertex - v = ( j / divisions ) * ( Math.PI * 2 ); + v = ( j / divisions ) * ( Math.PI * 2 ); - x = Math.sin( v ) * r; - z = Math.cos( v ) * r; + x = Math.sin( v ) * r; + z = Math.cos( v ) * r; - vertices.push( x, 0, z ); - colors.push( color.r, color.g, color.b ); + vertices.push( x, 0, z ); + colors.push( color.r, color.g, color.b ); - // second vertex + // second vertex - v = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 ); + v = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 ); - x = Math.sin( v ) * r; - z = Math.cos( v ) * r; + x = Math.sin( v ) * r; + z = Math.cos( v ) * r; - vertices.push( x, 0, z ); - colors.push( color.r, color.g, color.b ); + vertices.push( x, 0, z ); + colors.push( color.r, color.g, color.b ); - } + } - } + } - var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + var geometry = new BufferGeometry(); + geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - var material = new LineBasicMaterial( { vertexColors: VertexColors } ); + var material = new LineBasicMaterial( { vertexColors: VertexColors } ); - LineSegments.call( this, geometry, material ); + LineSegments.call( this, geometry, material ); - } + } - PolarGridHelper.prototype = Object.create( LineSegments.prototype ); - PolarGridHelper.prototype.constructor = PolarGridHelper; + PolarGridHelper.prototype = Object.create( LineSegments.prototype ); + PolarGridHelper.prototype.constructor = PolarGridHelper; - /** - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author WestLangley / http://github.com/WestLangley + */ - function FaceNormalsHelper( object, size, hex, linewidth ) { + function FaceNormalsHelper( object, size, hex, linewidth ) { - // FaceNormalsHelper only supports THREE.Geometry + // FaceNormalsHelper only supports THREE.Geometry - this.object = object; + this.object = object; - this.size = ( size !== undefined ) ? size : 1; + this.size = ( size !== undefined ) ? size : 1; - var color = ( hex !== undefined ) ? hex : 0xffff00; + var color = ( hex !== undefined ) ? hex : 0xffff00; - var width = ( linewidth !== undefined ) ? linewidth : 1; + var width = ( linewidth !== undefined ) ? linewidth : 1; - // + // - var nNormals = 0; + var nNormals = 0; - var objGeometry = this.object.geometry; + var objGeometry = this.object.geometry; - if ( objGeometry && objGeometry.isGeometry ) { + if ( objGeometry && objGeometry.isGeometry ) { - nNormals = objGeometry.faces.length; + nNormals = objGeometry.faces.length; - } else { + } else { - console.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' ); + console.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' ); - } + } - // + // - var geometry = new BufferGeometry(); + var geometry = new BufferGeometry(); - var positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 ); + var positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 ); - geometry.addAttribute( 'position', positions ); + geometry.addAttribute( 'position', positions ); - LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) ); + LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) ); - // + // - this.matrixAutoUpdate = false; - this.update(); + this.matrixAutoUpdate = false; + this.update(); - } + } - FaceNormalsHelper.prototype = Object.create( LineSegments.prototype ); - FaceNormalsHelper.prototype.constructor = FaceNormalsHelper; + FaceNormalsHelper.prototype = Object.create( LineSegments.prototype ); + FaceNormalsHelper.prototype.constructor = FaceNormalsHelper; - FaceNormalsHelper.prototype.update = ( function () { + FaceNormalsHelper.prototype.update = ( function () { - var v1 = new Vector3(); - var v2 = new Vector3(); - var normalMatrix = new Matrix3(); + var v1 = new Vector3(); + var v2 = new Vector3(); + var normalMatrix = new Matrix3(); - return function update() { + return function update() { - this.object.updateMatrixWorld( true ); + this.object.updateMatrixWorld( true ); - normalMatrix.getNormalMatrix( this.object.matrixWorld ); + normalMatrix.getNormalMatrix( this.object.matrixWorld ); - var matrixWorld = this.object.matrixWorld; + var matrixWorld = this.object.matrixWorld; - var position = this.geometry.attributes.position; + var position = this.geometry.attributes.position; - // + // - var objGeometry = this.object.geometry; + var objGeometry = this.object.geometry; - var vertices = objGeometry.vertices; + var vertices = objGeometry.vertices; - var faces = objGeometry.faces; + var faces = objGeometry.faces; - var idx = 0; + var idx = 0; - for ( var i = 0, l = faces.length; i < l; i ++ ) { + for ( var i = 0, l = faces.length; i < l; i ++ ) { - var face = faces[ i ]; + var face = faces[ i ]; - var normal = face.normal; + var normal = face.normal; - v1.copy( vertices[ face.a ] ) - .add( vertices[ face.b ] ) - .add( vertices[ face.c ] ) - .divideScalar( 3 ) - .applyMatrix4( matrixWorld ); + v1.copy( vertices[ face.a ] ) + .add( vertices[ face.b ] ) + .add( vertices[ face.c ] ) + .divideScalar( 3 ) + .applyMatrix4( matrixWorld ); - v2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 ); + v2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 ); - position.setXYZ( idx, v1.x, v1.y, v1.z ); + position.setXYZ( idx, v1.x, v1.y, v1.z ); - idx = idx + 1; + idx = idx + 1; - position.setXYZ( idx, v2.x, v2.y, v2.z ); + position.setXYZ( idx, v2.x, v2.y, v2.z ); - idx = idx + 1; + idx = idx + 1; - } + } - position.needsUpdate = true; + position.needsUpdate = true; - }; + }; - }() ); + }() ); - /** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley - */ + /** + * @author alteredq / http://alteredqualia.com/ + * @author mrdoob / http://mrdoob.com/ + * @author WestLangley / http://github.com/WestLangley + */ - function DirectionalLightHelper( light, size, color ) { + function DirectionalLightHelper( light, size, color ) { - Object3D.call( this ); + Object3D.call( this ); - this.light = light; - this.light.updateMatrixWorld(); + this.light = light; + this.light.updateMatrixWorld(); - this.matrix = light.matrixWorld; - this.matrixAutoUpdate = false; + this.matrix = light.matrixWorld; + this.matrixAutoUpdate = false; - this.color = color; + this.color = color; - if ( size === undefined ) size = 1; + if ( size === undefined ) size = 1; - var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( [ - - size, size, 0, - size, size, 0, - size, - size, 0, - - size, - size, 0, - - size, size, 0 - ], 3 ) ); + var geometry = new BufferGeometry(); + geometry.addAttribute( 'position', new Float32BufferAttribute( [ + - size, size, 0, + size, size, 0, + size, - size, 0, + - size, - size, 0, + - size, size, 0 + ], 3 ) ); - var material = new LineBasicMaterial( { fog: false } ); + var material = new LineBasicMaterial( { fog: false } ); - this.lightPlane = new Line( geometry, material ); - this.add( this.lightPlane ); + this.lightPlane = new Line( geometry, material ); + this.add( this.lightPlane ); - geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) ); + geometry = new BufferGeometry(); + geometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) ); - this.targetLine = new Line( geometry, material ); - this.add( this.targetLine ); + this.targetLine = new Line( geometry, material ); + this.add( this.targetLine ); - this.update(); + this.update(); - } + } - DirectionalLightHelper.prototype = Object.create( Object3D.prototype ); - DirectionalLightHelper.prototype.constructor = DirectionalLightHelper; + DirectionalLightHelper.prototype = Object.create( Object3D.prototype ); + DirectionalLightHelper.prototype.constructor = DirectionalLightHelper; - DirectionalLightHelper.prototype.dispose = function () { + DirectionalLightHelper.prototype.dispose = function () { - this.lightPlane.geometry.dispose(); - this.lightPlane.material.dispose(); - this.targetLine.geometry.dispose(); - this.targetLine.material.dispose(); + this.lightPlane.geometry.dispose(); + this.lightPlane.material.dispose(); + this.targetLine.geometry.dispose(); + this.targetLine.material.dispose(); - }; + }; - DirectionalLightHelper.prototype.update = function () { + DirectionalLightHelper.prototype.update = function () { - var v1 = new Vector3(); - var v2 = new Vector3(); - var v3 = new Vector3(); + var v1 = new Vector3(); + var v2 = new Vector3(); + var v3 = new Vector3(); - return function update() { + return function update() { - v1.setFromMatrixPosition( this.light.matrixWorld ); - v2.setFromMatrixPosition( this.light.target.matrixWorld ); - v3.subVectors( v2, v1 ); + v1.setFromMatrixPosition( this.light.matrixWorld ); + v2.setFromMatrixPosition( this.light.target.matrixWorld ); + v3.subVectors( v2, v1 ); - this.lightPlane.lookAt( v3 ); + this.lightPlane.lookAt( v3 ); - if ( this.color !== undefined ) { + if ( this.color !== undefined ) { - this.lightPlane.material.color.set( this.color ); - this.targetLine.material.color.set( this.color ); + this.lightPlane.material.color.set( this.color ); + this.targetLine.material.color.set( this.color ); - } else { + } else { - this.lightPlane.material.color.copy( this.light.color ); - this.targetLine.material.color.copy( this.light.color ); + this.lightPlane.material.color.copy( this.light.color ); + this.targetLine.material.color.copy( this.light.color ); - } + } - this.targetLine.lookAt( v3 ); - this.targetLine.scale.z = v3.length(); + this.targetLine.lookAt( v3 ); + this.targetLine.scale.z = v3.length(); - }; + }; - }(); + }(); - /** - * @author alteredq / http://alteredqualia.com/ - * @author Mugen87 / https://github.com/Mugen87 - * - * - shows frustum, line of sight and up of the camera - * - suitable for fast updates - * - based on frustum visualization in lightgl.js shadowmap example - * http://evanw.github.com/lightgl.js/tests/shadowmap.html - */ + /** + * @author alteredq / http://alteredqualia.com/ + * @author Mugen87 / https://github.com/Mugen87 + * + * - shows frustum, line of sight and up of the camera + * - suitable for fast updates + * - based on frustum visualization in lightgl.js shadowmap example + * http://evanw.github.com/lightgl.js/tests/shadowmap.html + */ - function CameraHelper( camera ) { + function CameraHelper( camera ) { - var geometry = new BufferGeometry(); - var material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } ); + var geometry = new BufferGeometry(); + var material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } ); - var vertices = []; - var colors = []; + var vertices = []; + var colors = []; - var pointMap = {}; + var pointMap = {}; - // colors + // colors - var colorFrustum = new Color( 0xffaa00 ); - var colorCone = new Color( 0xff0000 ); - var colorUp = new Color( 0x00aaff ); - var colorTarget = new Color( 0xffffff ); - var colorCross = new Color( 0x333333 ); + var colorFrustum = new Color( 0xffaa00 ); + var colorCone = new Color( 0xff0000 ); + var colorUp = new Color( 0x00aaff ); + var colorTarget = new Color( 0xffffff ); + var colorCross = new Color( 0x333333 ); - // near + // near - addLine( 'n1', 'n2', colorFrustum ); - addLine( 'n2', 'n4', colorFrustum ); - addLine( 'n4', 'n3', colorFrustum ); - addLine( 'n3', 'n1', colorFrustum ); + addLine( 'n1', 'n2', colorFrustum ); + addLine( 'n2', 'n4', colorFrustum ); + addLine( 'n4', 'n3', colorFrustum ); + addLine( 'n3', 'n1', colorFrustum ); - // far + // far - addLine( 'f1', 'f2', colorFrustum ); - addLine( 'f2', 'f4', colorFrustum ); - addLine( 'f4', 'f3', colorFrustum ); - addLine( 'f3', 'f1', colorFrustum ); + addLine( 'f1', 'f2', colorFrustum ); + addLine( 'f2', 'f4', colorFrustum ); + addLine( 'f4', 'f3', colorFrustum ); + addLine( 'f3', 'f1', colorFrustum ); - // sides + // sides - addLine( 'n1', 'f1', colorFrustum ); - addLine( 'n2', 'f2', colorFrustum ); - addLine( 'n3', 'f3', colorFrustum ); - addLine( 'n4', 'f4', colorFrustum ); + addLine( 'n1', 'f1', colorFrustum ); + addLine( 'n2', 'f2', colorFrustum ); + addLine( 'n3', 'f3', colorFrustum ); + addLine( 'n4', 'f4', colorFrustum ); - // cone + // cone - addLine( 'p', 'n1', colorCone ); - addLine( 'p', 'n2', colorCone ); - addLine( 'p', 'n3', colorCone ); - addLine( 'p', 'n4', colorCone ); + addLine( 'p', 'n1', colorCone ); + addLine( 'p', 'n2', colorCone ); + addLine( 'p', 'n3', colorCone ); + addLine( 'p', 'n4', colorCone ); - // up + // up - addLine( 'u1', 'u2', colorUp ); - addLine( 'u2', 'u3', colorUp ); - addLine( 'u3', 'u1', colorUp ); + addLine( 'u1', 'u2', colorUp ); + addLine( 'u2', 'u3', colorUp ); + addLine( 'u3', 'u1', colorUp ); - // target + // target - addLine( 'c', 't', colorTarget ); - addLine( 'p', 'c', colorCross ); + addLine( 'c', 't', colorTarget ); + addLine( 'p', 'c', colorCross ); - // cross + // cross - addLine( 'cn1', 'cn2', colorCross ); - addLine( 'cn3', 'cn4', colorCross ); + addLine( 'cn1', 'cn2', colorCross ); + addLine( 'cn3', 'cn4', colorCross ); - addLine( 'cf1', 'cf2', colorCross ); - addLine( 'cf3', 'cf4', colorCross ); + addLine( 'cf1', 'cf2', colorCross ); + addLine( 'cf3', 'cf4', colorCross ); - function addLine( a, b, color ) { + function addLine( a, b, color ) { - addPoint( a, color ); - addPoint( b, color ); + addPoint( a, color ); + addPoint( b, color ); - } + } - function addPoint( id, color ) { + function addPoint( id, color ) { - vertices.push( 0, 0, 0 ); - colors.push( color.r, color.g, color.b ); + vertices.push( 0, 0, 0 ); + colors.push( color.r, color.g, color.b ); - if ( pointMap[ id ] === undefined ) { + if ( pointMap[ id ] === undefined ) { - pointMap[ id ] = []; + pointMap[ id ] = []; - } + } - pointMap[ id ].push( ( vertices.length / 3 ) - 1 ); + pointMap[ id ].push( ( vertices.length / 3 ) - 1 ); - } + } - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - LineSegments.call( this, geometry, material ); + LineSegments.call( this, geometry, material ); - this.camera = camera; - if ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix(); + this.camera = camera; + if ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix(); - this.matrix = camera.matrixWorld; - this.matrixAutoUpdate = false; + this.matrix = camera.matrixWorld; + this.matrixAutoUpdate = false; - this.pointMap = pointMap; + this.pointMap = pointMap; - this.update(); + this.update(); - } + } - CameraHelper.prototype = Object.create( LineSegments.prototype ); - CameraHelper.prototype.constructor = CameraHelper; + CameraHelper.prototype = Object.create( LineSegments.prototype ); + CameraHelper.prototype.constructor = CameraHelper; - CameraHelper.prototype.update = function () { + CameraHelper.prototype.update = function () { - var geometry, pointMap; + var geometry, pointMap; - var vector = new Vector3(); - var camera = new Camera(); + var vector = new Vector3(); + var camera = new Camera(); - function setPoint( point, x, y, z ) { + function setPoint( point, x, y, z ) { - vector.set( x, y, z ).unproject( camera ); + vector.set( x, y, z ).unproject( camera ); - var points = pointMap[ point ]; + var points = pointMap[ point ]; - if ( points !== undefined ) { + if ( points !== undefined ) { - var position = geometry.getAttribute( 'position' ); + var position = geometry.getAttribute( 'position' ); - for ( var i = 0, l = points.length; i < l; i ++ ) { + for ( var i = 0, l = points.length; i < l; i ++ ) { - position.setXYZ( points[ i ], vector.x, vector.y, vector.z ); + position.setXYZ( points[ i ], vector.x, vector.y, vector.z ); - } + } - } + } - } + } - return function update() { + return function update() { - geometry = this.geometry; - pointMap = this.pointMap; + geometry = this.geometry; + pointMap = this.pointMap; - var w = 1, h = 1; + var w = 1, h = 1; - // we need just camera projection matrix - // world matrix must be identity + // we need just camera projection matrix + // world matrix must be identity - camera.projectionMatrix.copy( this.camera.projectionMatrix ); + camera.projectionMatrix.copy( this.camera.projectionMatrix ); - // center / target + // center / target - setPoint( 'c', 0, 0, - 1 ); - setPoint( 't', 0, 0, 1 ); + setPoint( 'c', 0, 0, - 1 ); + setPoint( 't', 0, 0, 1 ); - // near + // near - setPoint( 'n1', - w, - h, - 1 ); - setPoint( 'n2', w, - h, - 1 ); - setPoint( 'n3', - w, h, - 1 ); - setPoint( 'n4', w, h, - 1 ); + setPoint( 'n1', - w, - h, - 1 ); + setPoint( 'n2', w, - h, - 1 ); + setPoint( 'n3', - w, h, - 1 ); + setPoint( 'n4', w, h, - 1 ); - // far + // far - setPoint( 'f1', - w, - h, 1 ); - setPoint( 'f2', w, - h, 1 ); - setPoint( 'f3', - w, h, 1 ); - setPoint( 'f4', w, h, 1 ); + setPoint( 'f1', - w, - h, 1 ); + setPoint( 'f2', w, - h, 1 ); + setPoint( 'f3', - w, h, 1 ); + setPoint( 'f4', w, h, 1 ); - // up + // up - setPoint( 'u1', w * 0.7, h * 1.1, - 1 ); - setPoint( 'u2', - w * 0.7, h * 1.1, - 1 ); - setPoint( 'u3', 0, h * 2, - 1 ); + setPoint( 'u1', w * 0.7, h * 1.1, - 1 ); + setPoint( 'u2', - w * 0.7, h * 1.1, - 1 ); + setPoint( 'u3', 0, h * 2, - 1 ); - // cross + // cross - setPoint( 'cf1', - w, 0, 1 ); - setPoint( 'cf2', w, 0, 1 ); - setPoint( 'cf3', 0, - h, 1 ); - setPoint( 'cf4', 0, h, 1 ); + setPoint( 'cf1', - w, 0, 1 ); + setPoint( 'cf2', w, 0, 1 ); + setPoint( 'cf3', 0, - h, 1 ); + setPoint( 'cf4', 0, h, 1 ); - setPoint( 'cn1', - w, 0, - 1 ); - setPoint( 'cn2', w, 0, - 1 ); - setPoint( 'cn3', 0, - h, - 1 ); - setPoint( 'cn4', 0, h, - 1 ); + setPoint( 'cn1', - w, 0, - 1 ); + setPoint( 'cn2', w, 0, - 1 ); + setPoint( 'cn3', 0, - h, - 1 ); + setPoint( 'cn4', 0, h, - 1 ); - geometry.getAttribute( 'position' ).needsUpdate = true; + geometry.getAttribute( 'position' ).needsUpdate = true; - }; + }; - }(); + }(); - /** - * @author mrdoob / http://mrdoob.com/ - * @author Mugen87 / http://github.com/Mugen87 - */ + /** + * @author mrdoob / http://mrdoob.com/ + * @author Mugen87 / http://github.com/Mugen87 + */ - function BoxHelper( object, color ) { + function BoxHelper( object, color ) { - this.object = object; + this.object = object; - if ( color === undefined ) color = 0xffff00; + if ( color === undefined ) color = 0xffff00; - var indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] ); - var positions = new Float32Array( 8 * 3 ); + var indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] ); + var positions = new Float32Array( 8 * 3 ); - var geometry = new BufferGeometry(); - geometry.setIndex( new BufferAttribute( indices, 1 ) ); - geometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) ); + var geometry = new BufferGeometry(); + geometry.setIndex( new BufferAttribute( indices, 1 ) ); + geometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) ); - LineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) ); + LineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) ); - this.matrixAutoUpdate = false; + this.matrixAutoUpdate = false; - this.update(); + this.update(); - } + } - BoxHelper.prototype = Object.create( LineSegments.prototype ); - BoxHelper.prototype.constructor = BoxHelper; + BoxHelper.prototype = Object.create( LineSegments.prototype ); + BoxHelper.prototype.constructor = BoxHelper; - BoxHelper.prototype.update = ( function () { + BoxHelper.prototype.update = ( function () { - var box = new Box3(); + var box = new Box3(); - return function update( object ) { + return function update( object ) { - if ( object !== undefined ) { + if ( object !== undefined ) { - console.warn( 'THREE.BoxHelper: .update() has no longer arguments.' ); + console.warn( 'THREE.BoxHelper: .update() has no longer arguments.' ); - } + } - if ( this.object !== undefined ) { + if ( this.object !== undefined ) { - box.setFromObject( this.object ); + box.setFromObject( this.object ); - } + } - if ( box.isEmpty() ) return; + if ( box.isEmpty() ) return; - var min = box.min; - var max = box.max; + var min = box.min; + var max = box.max; - /* - 5____4 - 1/___0/| - | 6__|_7 - 2/___3/ + /* + 5____4 + 1/___0/| + | 6__|_7 + 2/___3/ - 0: max.x, max.y, max.z - 1: min.x, max.y, max.z - 2: min.x, min.y, max.z - 3: max.x, min.y, max.z - 4: max.x, max.y, min.z - 5: min.x, max.y, min.z - 6: min.x, min.y, min.z - 7: max.x, min.y, min.z - */ + 0: max.x, max.y, max.z + 1: min.x, max.y, max.z + 2: min.x, min.y, max.z + 3: max.x, min.y, max.z + 4: max.x, max.y, min.z + 5: min.x, max.y, min.z + 6: min.x, min.y, min.z + 7: max.x, min.y, min.z + */ - var position = this.geometry.attributes.position; - var array = position.array; + var position = this.geometry.attributes.position; + var array = position.array; - array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z; - array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z; - array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z; - array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z; - array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z; - array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z; - array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z; - array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z; + array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z; + array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z; + array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z; + array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z; + array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z; + array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z; + array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z; + array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z; - position.needsUpdate = true; + position.needsUpdate = true; - this.geometry.computeBoundingSphere(); + this.geometry.computeBoundingSphere(); - }; + }; - } )(); + } )(); - BoxHelper.prototype.setFromObject = function ( object ) { + BoxHelper.prototype.setFromObject = function ( object ) { - this.object = object; - this.update(); + this.object = object; + this.update(); - return this; + return this; - }; + }; - /** - * @author WestLangley / http://github.com/WestLangley - */ + /** + * @author WestLangley / http://github.com/WestLangley + */ - function Box3Helper( box, hex ) { + function Box3Helper( box, hex ) { - this.type = 'Box3Helper'; + this.type = 'Box3Helper'; - this.box = box; + this.box = box; - var color = ( hex !== undefined ) ? hex : 0xffff00; + var color = ( hex !== undefined ) ? hex : 0xffff00; - var indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] ); + var indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] ); - var positions = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 1, - 1, 1, - 1, - 1 ]; + var positions = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 1, - 1, 1, - 1, - 1 ]; - var geometry = new BufferGeometry(); + var geometry = new BufferGeometry(); - geometry.setIndex( new BufferAttribute( indices, 1 ) ); + geometry.setIndex( new BufferAttribute( indices, 1 ) ); - geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); + geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); - LineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) ); + LineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) ); - this.geometry.computeBoundingSphere(); + this.geometry.computeBoundingSphere(); - } + } - Box3Helper.prototype = Object.create( LineSegments.prototype ); - Box3Helper.prototype.constructor = Box3Helper; + Box3Helper.prototype = Object.create( LineSegments.prototype ); + Box3Helper.prototype.constructor = Box3Helper; - Box3Helper.prototype.updateMatrixWorld = function ( force ) { + Box3Helper.prototype.updateMatrixWorld = function ( force ) { - var box = this.box; + var box = this.box; - if ( box.isEmpty() ) return; + if ( box.isEmpty() ) return; - box.getCenter( this.position ); + box.getCenter( this.position ); - box.getSize( this.scale ); + box.getSize( this.scale ); - this.scale.multiplyScalar( 0.5 ); + this.scale.multiplyScalar( 0.5 ); - Object3D.prototype.updateMatrixWorld.call( this, force ); + Object3D.prototype.updateMatrixWorld.call( this, force ); - }; + }; - /** - * @author WestLangley / http://github.com/WestLangley - */ + /** + * @author WestLangley / http://github.com/WestLangley + */ - function PlaneHelper( plane, size, hex ) { + function PlaneHelper( plane, size, hex ) { - this.type = 'PlaneHelper'; + this.type = 'PlaneHelper'; - this.plane = plane; + this.plane = plane; - this.size = ( size === undefined ) ? 1 : size; + this.size = ( size === undefined ) ? 1 : size; - var color = ( hex !== undefined ) ? hex : 0xffff00; + var color = ( hex !== undefined ) ? hex : 0xffff00; - var positions = [ 1, - 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 ]; + var positions = [ 1, - 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 ]; - var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); - geometry.computeBoundingSphere(); + var geometry = new BufferGeometry(); + geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); + geometry.computeBoundingSphere(); - Line.call( this, geometry, new LineBasicMaterial( { color: color } ) ); + Line.call( this, geometry, new LineBasicMaterial( { color: color } ) ); - // + // - var positions2 = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, - 1, 1, 1, - 1, 1 ]; + var positions2 = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, - 1, 1, 1, - 1, 1 ]; - var geometry2 = new BufferGeometry(); - geometry2.addAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) ); - geometry2.computeBoundingSphere(); + var geometry2 = new BufferGeometry(); + geometry2.addAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) ); + geometry2.computeBoundingSphere(); - this.add( new Mesh( geometry2, new MeshBasicMaterial( { color: color, opacity: 0.2, transparent: true, depthWrite: false } ) ) ); + this.add( new Mesh( geometry2, new MeshBasicMaterial( { color: color, opacity: 0.2, transparent: true, depthWrite: false } ) ) ); - } + } - PlaneHelper.prototype = Object.create( Line.prototype ); - PlaneHelper.prototype.constructor = PlaneHelper; + PlaneHelper.prototype = Object.create( Line.prototype ); + PlaneHelper.prototype.constructor = PlaneHelper; - PlaneHelper.prototype.updateMatrixWorld = function ( force ) { + PlaneHelper.prototype.updateMatrixWorld = function ( force ) { - var scale = - this.plane.constant; + var scale = - this.plane.constant; - if ( Math.abs( scale ) < 1e-8 ) scale = 1e-8; // sign does not matter + if ( Math.abs( scale ) < 1e-8 ) scale = 1e-8; // sign does not matter - this.scale.set( 0.5 * this.size, 0.5 * this.size, scale ); + this.scale.set( 0.5 * this.size, 0.5 * this.size, scale ); - this.children[ 0 ].material.side = ( scale < 0 ) ? BackSide : FrontSide; // renderer flips side when determinant < 0; flipping not wanted here + this.children[ 0 ].material.side = ( scale < 0 ) ? BackSide : FrontSide; // renderer flips side when determinant < 0; flipping not wanted here - this.lookAt( this.plane.normal ); + this.lookAt( this.plane.normal ); - Object3D.prototype.updateMatrixWorld.call( this, force ); + Object3D.prototype.updateMatrixWorld.call( this, force ); - }; + }; - /** - * @author WestLangley / http://github.com/WestLangley - * @author zz85 / http://github.com/zz85 - * @author bhouston / http://clara.io - * - * Creates an arrow for visualizing directions - * - * Parameters: - * dir - Vector3 - * origin - Vector3 - * length - Number - * color - color in hex value - * headLength - Number - * headWidth - Number - */ + /** + * @author WestLangley / http://github.com/WestLangley + * @author zz85 / http://github.com/zz85 + * @author bhouston / http://clara.io + * + * Creates an arrow for visualizing directions + * + * Parameters: + * dir - Vector3 + * origin - Vector3 + * length - Number + * color - color in hex value + * headLength - Number + * headWidth - Number + */ - var lineGeometry, coneGeometry; + var lineGeometry, coneGeometry; - function ArrowHelper( dir, origin, length, color, headLength, headWidth ) { + function ArrowHelper( dir, origin, length, color, headLength, headWidth ) { - // dir is assumed to be normalized + // dir is assumed to be normalized - Object3D.call( this ); + Object3D.call( this ); - if ( color === undefined ) color = 0xffff00; - if ( length === undefined ) length = 1; - if ( headLength === undefined ) headLength = 0.2 * length; - if ( headWidth === undefined ) headWidth = 0.2 * headLength; + if ( color === undefined ) color = 0xffff00; + if ( length === undefined ) length = 1; + if ( headLength === undefined ) headLength = 0.2 * length; + if ( headWidth === undefined ) headWidth = 0.2 * headLength; - if ( lineGeometry === undefined ) { + if ( lineGeometry === undefined ) { - lineGeometry = new BufferGeometry(); - lineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) ); + lineGeometry = new BufferGeometry(); + lineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) ); - coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 ); - coneGeometry.translate( 0, - 0.5, 0 ); + coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 ); + coneGeometry.translate( 0, - 0.5, 0 ); - } + } - this.position.copy( origin ); + this.position.copy( origin ); - this.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) ); - this.line.matrixAutoUpdate = false; - this.add( this.line ); + this.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) ); + this.line.matrixAutoUpdate = false; + this.add( this.line ); - this.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) ); - this.cone.matrixAutoUpdate = false; - this.add( this.cone ); + this.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) ); + this.cone.matrixAutoUpdate = false; + this.add( this.cone ); - this.setDirection( dir ); - this.setLength( length, headLength, headWidth ); + this.setDirection( dir ); + this.setLength( length, headLength, headWidth ); - } + } - ArrowHelper.prototype = Object.create( Object3D.prototype ); - ArrowHelper.prototype.constructor = ArrowHelper; + ArrowHelper.prototype = Object.create( Object3D.prototype ); + ArrowHelper.prototype.constructor = ArrowHelper; - ArrowHelper.prototype.setDirection = ( function () { + ArrowHelper.prototype.setDirection = ( function () { - var axis = new Vector3(); - var radians; + var axis = new Vector3(); + var radians; - return function setDirection( dir ) { + return function setDirection( dir ) { - // dir is assumed to be normalized + // dir is assumed to be normalized - if ( dir.y > 0.99999 ) { + if ( dir.y > 0.99999 ) { - this.quaternion.set( 0, 0, 0, 1 ); + this.quaternion.set( 0, 0, 0, 1 ); - } else if ( dir.y < - 0.99999 ) { + } else if ( dir.y < - 0.99999 ) { - this.quaternion.set( 1, 0, 0, 0 ); + this.quaternion.set( 1, 0, 0, 0 ); - } else { + } else { - axis.set( dir.z, 0, - dir.x ).normalize(); + axis.set( dir.z, 0, - dir.x ).normalize(); - radians = Math.acos( dir.y ); + radians = Math.acos( dir.y ); - this.quaternion.setFromAxisAngle( axis, radians ); + this.quaternion.setFromAxisAngle( axis, radians ); - } + } - }; + }; - }() ); + }() ); - ArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) { + ArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) { - if ( headLength === undefined ) headLength = 0.2 * length; - if ( headWidth === undefined ) headWidth = 0.2 * headLength; + if ( headLength === undefined ) headLength = 0.2 * length; + if ( headWidth === undefined ) headWidth = 0.2 * headLength; - this.line.scale.set( 1, Math.max( 0, length - headLength ), 1 ); - this.line.updateMatrix(); + this.line.scale.set( 1, Math.max( 0, length - headLength ), 1 ); + this.line.updateMatrix(); - this.cone.scale.set( headWidth, headLength, headWidth ); - this.cone.position.y = length; - this.cone.updateMatrix(); + this.cone.scale.set( headWidth, headLength, headWidth ); + this.cone.position.y = length; + this.cone.updateMatrix(); - }; + }; - ArrowHelper.prototype.setColor = function ( color ) { + ArrowHelper.prototype.setColor = function ( color ) { - this.line.material.color.copy( color ); - this.cone.material.color.copy( color ); + this.line.material.color.copy( color ); + this.cone.material.color.copy( color ); - }; + }; - /** - * @author sroucheray / http://sroucheray.org/ - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author sroucheray / http://sroucheray.org/ + * @author mrdoob / http://mrdoob.com/ + */ - function AxesHelper( size ) { + function AxesHelper( size ) { - size = size || 1; + size = size || 1; - var vertices = [ - 0, 0, 0, size, 0, 0, - 0, 0, 0, 0, size, 0, - 0, 0, 0, 0, 0, size - ]; + var vertices = [ + 0, 0, 0, size, 0, 0, + 0, 0, 0, 0, size, 0, + 0, 0, 0, 0, 0, size + ]; - var colors = [ - 1, 0, 0, 1, 0.6, 0, - 0, 1, 0, 0.6, 1, 0, - 0, 0, 1, 0, 0.6, 1 - ]; + var colors = [ + 1, 0, 0, 1, 0.6, 0, + 0, 1, 0, 0.6, 1, 0, + 0, 0, 1, 0, 0.6, 1 + ]; - var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + var geometry = new BufferGeometry(); + geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - var material = new LineBasicMaterial( { vertexColors: VertexColors } ); + var material = new LineBasicMaterial( { vertexColors: VertexColors } ); - LineSegments.call( this, geometry, material ); + LineSegments.call( this, geometry, material ); - } + } - AxesHelper.prototype = Object.create( LineSegments.prototype ); - AxesHelper.prototype.constructor = AxesHelper; + AxesHelper.prototype = Object.create( LineSegments.prototype ); + AxesHelper.prototype.constructor = AxesHelper; - /** - * @author mrdoob / http://mrdoob.com/ - */ + /** + * @author mrdoob / http://mrdoob.com/ + */ - function Face4( a, b, c, d, normal, color, materialIndex ) { + function Face4( a, b, c, d, normal, color, materialIndex ) { - console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' ); - return new Face3( a, b, c, normal, color, materialIndex ); + console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' ); + return new Face3( a, b, c, normal, color, materialIndex ); - } + } - var LineStrip = 0; + var LineStrip = 0; - var LinePieces = 1; + var LinePieces = 1; - function MeshFaceMaterial( materials ) { + function MeshFaceMaterial( materials ) { - console.warn( 'THREE.MeshFaceMaterial has been removed. Use an Array instead.' ); - return materials; + console.warn( 'THREE.MeshFaceMaterial has been removed. Use an Array instead.' ); + return materials; - } + } - function MultiMaterial( materials ) { + function MultiMaterial( materials ) { - if ( materials === undefined ) materials = []; + if ( materials === undefined ) materials = []; - console.warn( 'THREE.MultiMaterial has been removed. Use an Array instead.' ); - materials.isMultiMaterial = true; - materials.materials = materials; - materials.clone = function () { + console.warn( 'THREE.MultiMaterial has been removed. Use an Array instead.' ); + materials.isMultiMaterial = true; + materials.materials = materials; + materials.clone = function () { - return materials.slice(); + return materials.slice(); - }; - return materials; + }; + return materials; - } + } - function PointCloud( geometry, material ) { + function PointCloud( geometry, material ) { - console.warn( 'THREE.PointCloud has been renamed to THREE.Points.' ); - return new Points( geometry, material ); + console.warn( 'THREE.PointCloud has been renamed to THREE.Points.' ); + return new Points( geometry, material ); - } + } - function Particle( material ) { + function Particle( material ) { - console.warn( 'THREE.Particle has been renamed to THREE.Sprite.' ); - return new Sprite( material ); + console.warn( 'THREE.Particle has been renamed to THREE.Sprite.' ); + return new Sprite( material ); - } + } - function ParticleSystem( geometry, material ) { + function ParticleSystem( geometry, material ) { - console.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' ); - return new Points( geometry, material ); + console.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' ); + return new Points( geometry, material ); - } + } - function PointCloudMaterial( parameters ) { + function PointCloudMaterial( parameters ) { - console.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' ); - return new PointsMaterial( parameters ); + console.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' ); + return new PointsMaterial( parameters ); - } + } - function ParticleBasicMaterial( parameters ) { + function ParticleBasicMaterial( parameters ) { - console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' ); - return new PointsMaterial( parameters ); + console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' ); + return new PointsMaterial( parameters ); - } + } - function ParticleSystemMaterial( parameters ) { + function ParticleSystemMaterial( parameters ) { - console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' ); - return new PointsMaterial( parameters ); + console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' ); + return new PointsMaterial( parameters ); - } + } - function Vertex( x, y, z ) { + function Vertex( x, y, z ) { - console.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' ); - return new Vector3( x, y, z ); + console.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' ); + return new Vector3( x, y, z ); - } + } - // + // - function DynamicBufferAttribute( array, itemSize ) { + function DynamicBufferAttribute( array, itemSize ) { - console.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' ); - return new BufferAttribute( array, itemSize ).setDynamic( true ); + console.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' ); + return new BufferAttribute( array, itemSize ).setDynamic( true ); - } + } - function Int8Attribute( array, itemSize ) { + function Int8Attribute( array, itemSize ) { - console.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' ); - return new Int8BufferAttribute( array, itemSize ); + console.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' ); + return new Int8BufferAttribute( array, itemSize ); - } + } - function Uint8Attribute( array, itemSize ) { + function Uint8Attribute( array, itemSize ) { - console.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' ); - return new Uint8BufferAttribute( array, itemSize ); + console.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' ); + return new Uint8BufferAttribute( array, itemSize ); - } + } - function Uint8ClampedAttribute( array, itemSize ) { + function Uint8ClampedAttribute( array, itemSize ) { - console.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' ); - return new Uint8ClampedBufferAttribute( array, itemSize ); + console.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' ); + return new Uint8ClampedBufferAttribute( array, itemSize ); - } + } - function Int16Attribute( array, itemSize ) { + function Int16Attribute( array, itemSize ) { - console.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' ); - return new Int16BufferAttribute( array, itemSize ); + console.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' ); + return new Int16BufferAttribute( array, itemSize ); - } + } - function Uint16Attribute( array, itemSize ) { + function Uint16Attribute( array, itemSize ) { - console.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' ); - return new Uint16BufferAttribute( array, itemSize ); + console.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' ); + return new Uint16BufferAttribute( array, itemSize ); - } + } - function Int32Attribute( array, itemSize ) { + function Int32Attribute( array, itemSize ) { - console.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' ); - return new Int32BufferAttribute( array, itemSize ); + console.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' ); + return new Int32BufferAttribute( array, itemSize ); - } + } - function Uint32Attribute( array, itemSize ) { + function Uint32Attribute( array, itemSize ) { - console.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' ); - return new Uint32BufferAttribute( array, itemSize ); + console.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' ); + return new Uint32BufferAttribute( array, itemSize ); - } + } - function Float32Attribute( array, itemSize ) { + function Float32Attribute( array, itemSize ) { - console.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' ); - return new Float32BufferAttribute( array, itemSize ); + console.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' ); + return new Float32BufferAttribute( array, itemSize ); - } + } - function Float64Attribute( array, itemSize ) { + function Float64Attribute( array, itemSize ) { - console.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' ); - return new Float64BufferAttribute( array, itemSize ); + console.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' ); + return new Float64BufferAttribute( array, itemSize ); - } + } - // + // - Curve.create = function ( construct, getPoint ) { + Curve.create = function ( construct, getPoint ) { - console.log( 'THREE.Curve.create() has been deprecated' ); + console.log( 'THREE.Curve.create() has been deprecated' ); - construct.prototype = Object.create( Curve.prototype ); - construct.prototype.constructor = construct; - construct.prototype.getPoint = getPoint; + construct.prototype = Object.create( Curve.prototype ); + construct.prototype.constructor = construct; + construct.prototype.getPoint = getPoint; - return construct; + return construct; - }; + }; - // + // - Object.assign( CurvePath.prototype, { + Object.assign( CurvePath.prototype, { - createPointsGeometry: function ( divisions ) { + createPointsGeometry: function ( divisions ) { - console.warn( 'THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' ); + console.warn( 'THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' ); - // generate geometry from path points (for Line or Points objects) + // generate geometry from path points (for Line or Points objects) - var pts = this.getPoints( divisions ); - return this.createGeometry( pts ); + var pts = this.getPoints( divisions ); + return this.createGeometry( pts ); - }, + }, - createSpacedPointsGeometry: function ( divisions ) { + createSpacedPointsGeometry: function ( divisions ) { - console.warn( 'THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' ); + console.warn( 'THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' ); - // generate geometry from equidistant sampling along the path + // generate geometry from equidistant sampling along the path - var pts = this.getSpacedPoints( divisions ); - return this.createGeometry( pts ); + var pts = this.getSpacedPoints( divisions ); + return this.createGeometry( pts ); - }, + }, - createGeometry: function ( points ) { + createGeometry: function ( points ) { - console.warn( 'THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' ); + console.warn( 'THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' ); - var geometry = new Geometry(); + var geometry = new Geometry(); - for ( var i = 0, l = points.length; i < l; i ++ ) { + for ( var i = 0, l = points.length; i < l; i ++ ) { - var point = points[ i ]; - geometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) ); + var point = points[ i ]; + geometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) ); - } + } - return geometry; + return geometry; - } + } - } ); + } ); - // + // - Object.assign( Path.prototype, { + Object.assign( Path.prototype, { - fromPoints: function ( points ) { + fromPoints: function ( points ) { - console.warn( 'THREE.Path: .fromPoints() has been renamed to .setFromPoints().' ); - this.setFromPoints( points ); + console.warn( 'THREE.Path: .fromPoints() has been renamed to .setFromPoints().' ); + this.setFromPoints( points ); - } + } - } ); + } ); - // + // - function ClosedSplineCurve3( points ) { + function ClosedSplineCurve3( points ) { - console.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' ); + console.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' ); - CatmullRomCurve3.call( this, points ); - this.type = 'catmullrom'; - this.closed = true; + CatmullRomCurve3.call( this, points ); + this.type = 'catmullrom'; + this.closed = true; - } + } - ClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype ); + ClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype ); - // + // - function SplineCurve3( points ) { + function SplineCurve3( points ) { - console.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' ); + console.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' ); - CatmullRomCurve3.call( this, points ); - this.type = 'catmullrom'; + CatmullRomCurve3.call( this, points ); + this.type = 'catmullrom'; - } + } - SplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype ); + SplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype ); - // + // - function Spline( points ) { + function Spline( points ) { - console.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' ); + console.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' ); - CatmullRomCurve3.call( this, points ); - this.type = 'catmullrom'; + CatmullRomCurve3.call( this, points ); + this.type = 'catmullrom'; - } + } - Spline.prototype = Object.create( CatmullRomCurve3.prototype ); + Spline.prototype = Object.create( CatmullRomCurve3.prototype ); - Object.assign( Spline.prototype, { + Object.assign( Spline.prototype, { - initFromArray: function ( /* a */ ) { + initFromArray: function ( /* a */ ) { - console.error( 'THREE.Spline: .initFromArray() has been removed.' ); + console.error( 'THREE.Spline: .initFromArray() has been removed.' ); - }, - getControlPointsArray: function ( /* optionalTarget */ ) { + }, + getControlPointsArray: function ( /* optionalTarget */ ) { - console.error( 'THREE.Spline: .getControlPointsArray() has been removed.' ); + console.error( 'THREE.Spline: .getControlPointsArray() has been removed.' ); - }, - reparametrizeByArcLength: function ( /* samplingCoef */ ) { + }, + reparametrizeByArcLength: function ( /* samplingCoef */ ) { - console.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' ); + console.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' ); - } + } - } ); + } ); - // + // - function AxisHelper( size ) { + function AxisHelper( size ) { - console.warn( 'THREE.AxisHelper has been renamed to THREE.AxesHelper.' ); - return new AxesHelper( size ); + console.warn( 'THREE.AxisHelper has been renamed to THREE.AxesHelper.' ); + return new AxesHelper( size ); - } + } - function BoundingBoxHelper( object, color ) { + function BoundingBoxHelper( object, color ) { - console.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' ); - return new BoxHelper( object, color ); + console.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' ); + return new BoxHelper( object, color ); - } + } - function EdgesHelper( object, hex ) { + function EdgesHelper( object, hex ) { - console.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' ); - return new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) ); + console.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' ); + return new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) ); - } + } - GridHelper.prototype.setColors = function () { + GridHelper.prototype.setColors = function () { - console.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' ); + console.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' ); - }; + }; - SkeletonHelper.prototype.update = function () { + SkeletonHelper.prototype.update = function () { - console.error( 'THREE.SkeletonHelper: update() no longer needs to be called.' ); + console.error( 'THREE.SkeletonHelper: update() no longer needs to be called.' ); - }; + }; - function WireframeHelper( object, hex ) { + function WireframeHelper( object, hex ) { - console.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' ); - return new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) ); + console.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' ); + return new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) ); - } + } - // + // - Object.assign( Loader.prototype, { + Object.assign( Loader.prototype, { - extractUrlBase: function ( url ) { + extractUrlBase: function ( url ) { - console.warn( 'THREE.Loader: .extractUrlBase() has been deprecated. Use THREE.LoaderUtils.extractUrlBase() instead.' ); - return LoaderUtils.extractUrlBase( url ); + console.warn( 'THREE.Loader: .extractUrlBase() has been deprecated. Use THREE.LoaderUtils.extractUrlBase() instead.' ); + return LoaderUtils.extractUrlBase( url ); - } + } - } ); + } ); - function XHRLoader( manager ) { + function XHRLoader( manager ) { - console.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' ); - return new FileLoader( manager ); + console.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' ); + return new FileLoader( manager ); - } + } - function BinaryTextureLoader( manager ) { + function BinaryTextureLoader( manager ) { - console.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' ); - return new DataTextureLoader( manager ); + console.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' ); + return new DataTextureLoader( manager ); - } + } - // + // - Object.assign( Box2.prototype, { + Object.assign( Box2.prototype, { - center: function ( optionalTarget ) { + center: function ( optionalTarget ) { - console.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' ); - return this.getCenter( optionalTarget ); + console.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' ); + return this.getCenter( optionalTarget ); - }, - empty: function () { + }, + empty: function () { - console.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' ); - return this.isEmpty(); + console.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' ); + return this.isEmpty(); - }, - isIntersectionBox: function ( box ) { + }, + isIntersectionBox: function ( box ) { - console.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' ); - return this.intersectsBox( box ); + console.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' ); + return this.intersectsBox( box ); - }, - size: function ( optionalTarget ) { + }, + size: function ( optionalTarget ) { - console.warn( 'THREE.Box2: .size() has been renamed to .getSize().' ); - return this.getSize( optionalTarget ); + console.warn( 'THREE.Box2: .size() has been renamed to .getSize().' ); + return this.getSize( optionalTarget ); - } - } ); + } + } ); - Object.assign( Box3.prototype, { + Object.assign( Box3.prototype, { - center: function ( optionalTarget ) { + center: function ( optionalTarget ) { - console.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' ); - return this.getCenter( optionalTarget ); + console.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' ); + return this.getCenter( optionalTarget ); - }, - empty: function () { + }, + empty: function () { - console.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' ); - return this.isEmpty(); + console.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' ); + return this.isEmpty(); - }, - isIntersectionBox: function ( box ) { + }, + isIntersectionBox: function ( box ) { - console.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' ); - return this.intersectsBox( box ); + console.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' ); + return this.intersectsBox( box ); - }, - isIntersectionSphere: function ( sphere ) { + }, + isIntersectionSphere: function ( sphere ) { - console.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' ); - return this.intersectsSphere( sphere ); + console.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' ); + return this.intersectsSphere( sphere ); - }, - size: function ( optionalTarget ) { + }, + size: function ( optionalTarget ) { - console.warn( 'THREE.Box3: .size() has been renamed to .getSize().' ); - return this.getSize( optionalTarget ); + console.warn( 'THREE.Box3: .size() has been renamed to .getSize().' ); + return this.getSize( optionalTarget ); - } - } ); + } + } ); - Line3.prototype.center = function ( optionalTarget ) { + Line3.prototype.center = function ( optionalTarget ) { - console.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' ); - return this.getCenter( optionalTarget ); + console.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' ); + return this.getCenter( optionalTarget ); - }; + }; - Object.assign( _Math, { + Object.assign( _Math, { - random16: function () { + random16: function () { - console.warn( 'THREE.Math: .random16() has been deprecated. Use Math.random() instead.' ); - return Math.random(); + console.warn( 'THREE.Math: .random16() has been deprecated. Use Math.random() instead.' ); + return Math.random(); - }, + }, - nearestPowerOfTwo: function ( value ) { + nearestPowerOfTwo: function ( value ) { - console.warn( 'THREE.Math: .nearestPowerOfTwo() has been renamed to .floorPowerOfTwo().' ); - return _Math.floorPowerOfTwo( value ); + console.warn( 'THREE.Math: .nearestPowerOfTwo() has been renamed to .floorPowerOfTwo().' ); + return _Math.floorPowerOfTwo( value ); - }, + }, - nextPowerOfTwo: function ( value ) { + nextPowerOfTwo: function ( value ) { - console.warn( 'THREE.Math: .nextPowerOfTwo() has been renamed to .ceilPowerOfTwo().' ); - return _Math.ceilPowerOfTwo( value ); + console.warn( 'THREE.Math: .nextPowerOfTwo() has been renamed to .ceilPowerOfTwo().' ); + return _Math.ceilPowerOfTwo( value ); - } + } - } ); + } ); - Object.assign( Matrix3.prototype, { + Object.assign( Matrix3.prototype, { - flattenToArrayOffset: function ( array, offset ) { + flattenToArrayOffset: function ( array, offset ) { - console.warn( "THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." ); - return this.toArray( array, offset ); + console.warn( "THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." ); + return this.toArray( array, offset ); - }, - multiplyVector3: function ( vector ) { + }, + multiplyVector3: function ( vector ) { - console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' ); - return vector.applyMatrix3( this ); + console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' ); + return vector.applyMatrix3( this ); - }, - multiplyVector3Array: function ( /* a */ ) { + }, + multiplyVector3Array: function ( /* a */ ) { - console.error( 'THREE.Matrix3: .multiplyVector3Array() has been removed.' ); + console.error( 'THREE.Matrix3: .multiplyVector3Array() has been removed.' ); - }, - applyToBuffer: function ( buffer /*, offset, length */ ) { + }, + applyToBuffer: function ( buffer /*, offset, length */ ) { - console.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' ); - return this.applyToBufferAttribute( buffer ); + console.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' ); + return this.applyToBufferAttribute( buffer ); - }, - applyToVector3Array: function ( /* array, offset, length */ ) { + }, + applyToVector3Array: function ( /* array, offset, length */ ) { - console.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' ); + console.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' ); - } + } - } ); + } ); - Object.assign( Matrix4.prototype, { + Object.assign( Matrix4.prototype, { - extractPosition: function ( m ) { + extractPosition: function ( m ) { - console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' ); - return this.copyPosition( m ); + console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' ); + return this.copyPosition( m ); - }, - flattenToArrayOffset: function ( array, offset ) { + }, + flattenToArrayOffset: function ( array, offset ) { - console.warn( "THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." ); - return this.toArray( array, offset ); + console.warn( "THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." ); + return this.toArray( array, offset ); - }, - getPosition: function () { + }, + getPosition: function () { - var v1; + var v1; - return function getPosition() { + return function getPosition() { - if ( v1 === undefined ) v1 = new Vector3(); - console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' ); - return v1.setFromMatrixColumn( this, 3 ); + if ( v1 === undefined ) v1 = new Vector3(); + console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' ); + return v1.setFromMatrixColumn( this, 3 ); - }; + }; - }(), - setRotationFromQuaternion: function ( q ) { + }(), + setRotationFromQuaternion: function ( q ) { - console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' ); - return this.makeRotationFromQuaternion( q ); + console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' ); + return this.makeRotationFromQuaternion( q ); - }, - multiplyToArray: function () { + }, + multiplyToArray: function () { - console.warn( 'THREE.Matrix4: .multiplyToArray() has been removed.' ); + console.warn( 'THREE.Matrix4: .multiplyToArray() has been removed.' ); - }, - multiplyVector3: function ( vector ) { + }, + multiplyVector3: function ( vector ) { - console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); - return vector.applyMatrix4( this ); + console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); + return vector.applyMatrix4( this ); - }, - multiplyVector4: function ( vector ) { + }, + multiplyVector4: function ( vector ) { - console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); - return vector.applyMatrix4( this ); + console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); + return vector.applyMatrix4( this ); - }, - multiplyVector3Array: function ( /* a */ ) { + }, + multiplyVector3Array: function ( /* a */ ) { - console.error( 'THREE.Matrix4: .multiplyVector3Array() has been removed.' ); + console.error( 'THREE.Matrix4: .multiplyVector3Array() has been removed.' ); - }, - rotateAxis: function ( v ) { + }, + rotateAxis: function ( v ) { - console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' ); - v.transformDirection( this ); + console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' ); + v.transformDirection( this ); - }, - crossVector: function ( vector ) { + }, + crossVector: function ( vector ) { - console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); - return vector.applyMatrix4( this ); + console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); + return vector.applyMatrix4( this ); - }, - translate: function () { + }, + translate: function () { - console.error( 'THREE.Matrix4: .translate() has been removed.' ); + console.error( 'THREE.Matrix4: .translate() has been removed.' ); - }, - rotateX: function () { + }, + rotateX: function () { - console.error( 'THREE.Matrix4: .rotateX() has been removed.' ); + console.error( 'THREE.Matrix4: .rotateX() has been removed.' ); - }, - rotateY: function () { + }, + rotateY: function () { - console.error( 'THREE.Matrix4: .rotateY() has been removed.' ); + console.error( 'THREE.Matrix4: .rotateY() has been removed.' ); - }, - rotateZ: function () { + }, + rotateZ: function () { - console.error( 'THREE.Matrix4: .rotateZ() has been removed.' ); + console.error( 'THREE.Matrix4: .rotateZ() has been removed.' ); - }, - rotateByAxis: function () { + }, + rotateByAxis: function () { - console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' ); + console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' ); - }, - applyToBuffer: function ( buffer /*, offset, length */ ) { + }, + applyToBuffer: function ( buffer /*, offset, length */ ) { - console.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' ); - return this.applyToBufferAttribute( buffer ); + console.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' ); + return this.applyToBufferAttribute( buffer ); - }, - applyToVector3Array: function ( /* array, offset, length */ ) { + }, + applyToVector3Array: function ( /* array, offset, length */ ) { - console.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' ); + console.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' ); - }, - makeFrustum: function ( left, right, bottom, top, near, far ) { + }, + makeFrustum: function ( left, right, bottom, top, near, far ) { - console.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' ); - return this.makePerspective( left, right, top, bottom, near, far ); + console.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' ); + return this.makePerspective( left, right, top, bottom, near, far ); - } + } - } ); + } ); - Plane.prototype.isIntersectionLine = function ( line ) { + Plane.prototype.isIntersectionLine = function ( line ) { - console.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' ); - return this.intersectsLine( line ); + console.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' ); + return this.intersectsLine( line ); - }; + }; - Quaternion.prototype.multiplyVector3 = function ( vector ) { + Quaternion.prototype.multiplyVector3 = function ( vector ) { - console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' ); - return vector.applyQuaternion( this ); + console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' ); + return vector.applyQuaternion( this ); - }; + }; - Object.assign( Ray.prototype, { + Object.assign( Ray.prototype, { - isIntersectionBox: function ( box ) { + isIntersectionBox: function ( box ) { - console.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' ); - return this.intersectsBox( box ); + console.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' ); + return this.intersectsBox( box ); - }, - isIntersectionPlane: function ( plane ) { + }, + isIntersectionPlane: function ( plane ) { - console.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' ); - return this.intersectsPlane( plane ); + console.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' ); + return this.intersectsPlane( plane ); - }, - isIntersectionSphere: function ( sphere ) { + }, + isIntersectionSphere: function ( sphere ) { - console.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' ); - return this.intersectsSphere( sphere ); + console.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' ); + return this.intersectsSphere( sphere ); - } + } - } ); + } ); - Object.assign( Triangle.prototype, { + Object.assign( Triangle.prototype, { - area: function () { + area: function () { - console.warn( 'THREE.Triangle: .area() has been renamed to .getArea().' ); - return this.getArea(); + console.warn( 'THREE.Triangle: .area() has been renamed to .getArea().' ); + return this.getArea(); - }, - barycoordFromPoint: function ( point, target ) { + }, + barycoordFromPoint: function ( point, target ) { - console.warn( 'THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().' ); - return this.getBarycoord( point, target ); + console.warn( 'THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().' ); + return this.getBarycoord( point, target ); - }, - midpoint: function ( target ) { + }, + midpoint: function ( target ) { - console.warn( 'THREE.Triangle: .midpoint() has been renamed to .getMidpoint().' ); - return this.getMidpoint( target ); + console.warn( 'THREE.Triangle: .midpoint() has been renamed to .getMidpoint().' ); + return this.getMidpoint( target ); - }, - normal: function ( target ) { + }, + normal: function ( target ) { - console.warn( 'THREE.Triangle: .normal() has been renamed to .getNormal().' ); - return this.getNormal( target ); + console.warn( 'THREE.Triangle: .normal() has been renamed to .getNormal().' ); + return this.getNormal( target ); - }, - plane: function ( target ) { + }, + plane: function ( target ) { - console.warn( 'THREE.Triangle: .plane() has been renamed to .getPlane().' ); - return this.getPlane( target ); + console.warn( 'THREE.Triangle: .plane() has been renamed to .getPlane().' ); + return this.getPlane( target ); - } + } - } ); + } ); - Object.assign( Triangle, { + Object.assign( Triangle, { - barycoordFromPoint: function ( point, a, b, c, target ) { + barycoordFromPoint: function ( point, a, b, c, target ) { - console.warn( 'THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().' ); - return Triangle.getBarycoord( point, a, b, c, target ); + console.warn( 'THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().' ); + return Triangle.getBarycoord( point, a, b, c, target ); - }, - normal: function ( a, b, c, target ) { + }, + normal: function ( a, b, c, target ) { - console.warn( 'THREE.Triangle: .normal() has been renamed to .getNormal().' ); - return Triangle.getNormal( a, b, c, target ); + console.warn( 'THREE.Triangle: .normal() has been renamed to .getNormal().' ); + return Triangle.getNormal( a, b, c, target ); - } + } - } ); + } ); - Object.assign( Shape.prototype, { + Object.assign( Shape.prototype, { - extractAllPoints: function ( divisions ) { + extractAllPoints: function ( divisions ) { - console.warn( 'THREE.Shape: .extractAllPoints() has been removed. Use .extractPoints() instead.' ); - return this.extractPoints( divisions ); + console.warn( 'THREE.Shape: .extractAllPoints() has been removed. Use .extractPoints() instead.' ); + return this.extractPoints( divisions ); - }, - extrude: function ( options ) { + }, + extrude: function ( options ) { - console.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' ); - return new ExtrudeGeometry( this, options ); + console.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' ); + return new ExtrudeGeometry( this, options ); - }, - makeGeometry: function ( options ) { + }, + makeGeometry: function ( options ) { - console.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' ); - return new ShapeGeometry( this, options ); + console.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' ); + return new ShapeGeometry( this, options ); - } + } - } ); + } ); - Object.assign( Vector2.prototype, { + Object.assign( Vector2.prototype, { - fromAttribute: function ( attribute, index, offset ) { + fromAttribute: function ( attribute, index, offset ) { - console.warn( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' ); - return this.fromBufferAttribute( attribute, index, offset ); + console.warn( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' ); + return this.fromBufferAttribute( attribute, index, offset ); - }, - distanceToManhattan: function ( v ) { + }, + distanceToManhattan: function ( v ) { - console.warn( 'THREE.Vector2: .distanceToManhattan() has been renamed to .manhattanDistanceTo().' ); - return this.manhattanDistanceTo( v ); + console.warn( 'THREE.Vector2: .distanceToManhattan() has been renamed to .manhattanDistanceTo().' ); + return this.manhattanDistanceTo( v ); - }, - lengthManhattan: function () { + }, + lengthManhattan: function () { - console.warn( 'THREE.Vector2: .lengthManhattan() has been renamed to .manhattanLength().' ); - return this.manhattanLength(); + console.warn( 'THREE.Vector2: .lengthManhattan() has been renamed to .manhattanLength().' ); + return this.manhattanLength(); - } + } - } ); + } ); - Object.assign( Vector3.prototype, { + Object.assign( Vector3.prototype, { - setEulerFromRotationMatrix: function () { + setEulerFromRotationMatrix: function () { - console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' ); + console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' ); - }, - setEulerFromQuaternion: function () { + }, + setEulerFromQuaternion: function () { - console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' ); + console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' ); - }, - getPositionFromMatrix: function ( m ) { + }, + getPositionFromMatrix: function ( m ) { - console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' ); - return this.setFromMatrixPosition( m ); + console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' ); + return this.setFromMatrixPosition( m ); - }, - getScaleFromMatrix: function ( m ) { + }, + getScaleFromMatrix: function ( m ) { - console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' ); - return this.setFromMatrixScale( m ); + console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' ); + return this.setFromMatrixScale( m ); - }, - getColumnFromMatrix: function ( index, matrix ) { + }, + getColumnFromMatrix: function ( index, matrix ) { - console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' ); - return this.setFromMatrixColumn( matrix, index ); + console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' ); + return this.setFromMatrixColumn( matrix, index ); - }, - applyProjection: function ( m ) { + }, + applyProjection: function ( m ) { - console.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' ); - return this.applyMatrix4( m ); + console.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' ); + return this.applyMatrix4( m ); - }, - fromAttribute: function ( attribute, index, offset ) { + }, + fromAttribute: function ( attribute, index, offset ) { - console.warn( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' ); - return this.fromBufferAttribute( attribute, index, offset ); + console.warn( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' ); + return this.fromBufferAttribute( attribute, index, offset ); - }, - distanceToManhattan: function ( v ) { + }, + distanceToManhattan: function ( v ) { - console.warn( 'THREE.Vector3: .distanceToManhattan() has been renamed to .manhattanDistanceTo().' ); - return this.manhattanDistanceTo( v ); + console.warn( 'THREE.Vector3: .distanceToManhattan() has been renamed to .manhattanDistanceTo().' ); + return this.manhattanDistanceTo( v ); - }, - lengthManhattan: function () { + }, + lengthManhattan: function () { - console.warn( 'THREE.Vector3: .lengthManhattan() has been renamed to .manhattanLength().' ); - return this.manhattanLength(); + console.warn( 'THREE.Vector3: .lengthManhattan() has been renamed to .manhattanLength().' ); + return this.manhattanLength(); - } + } - } ); + } ); - Object.assign( Vector4.prototype, { + Object.assign( Vector4.prototype, { - fromAttribute: function ( attribute, index, offset ) { + fromAttribute: function ( attribute, index, offset ) { - console.warn( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' ); - return this.fromBufferAttribute( attribute, index, offset ); + console.warn( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' ); + return this.fromBufferAttribute( attribute, index, offset ); - }, - lengthManhattan: function () { + }, + lengthManhattan: function () { - console.warn( 'THREE.Vector4: .lengthManhattan() has been renamed to .manhattanLength().' ); - return this.manhattanLength(); + console.warn( 'THREE.Vector4: .lengthManhattan() has been renamed to .manhattanLength().' ); + return this.manhattanLength(); - } + } - } ); + } ); - // + // - Object.assign( Geometry.prototype, { + Object.assign( Geometry.prototype, { - computeTangents: function () { + computeTangents: function () { - console.error( 'THREE.Geometry: .computeTangents() has been removed.' ); + console.error( 'THREE.Geometry: .computeTangents() has been removed.' ); - }, - computeLineDistances: function () { + }, + computeLineDistances: function () { - console.error( 'THREE.Geometry: .computeLineDistances() has been removed. Use THREE.Line.computeLineDistances() instead.' ); + console.error( 'THREE.Geometry: .computeLineDistances() has been removed. Use THREE.Line.computeLineDistances() instead.' ); - } + } - } ); + } ); - Object.assign( Object3D.prototype, { + Object.assign( Object3D.prototype, { - getChildByName: function ( name ) { + getChildByName: function ( name ) { - console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' ); - return this.getObjectByName( name ); + console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' ); + return this.getObjectByName( name ); - }, - renderDepth: function () { + }, + renderDepth: function () { - console.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' ); + console.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' ); - }, - translate: function ( distance, axis ) { + }, + translate: function ( distance, axis ) { - console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' ); - return this.translateOnAxis( axis, distance ); + console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' ); + return this.translateOnAxis( axis, distance ); - }, - getWorldRotation: function () { + }, + getWorldRotation: function () { - console.error( 'THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead.' ); + console.error( 'THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead.' ); - } + } - } ); + } ); - Object.defineProperties( Object3D.prototype, { + Object.defineProperties( Object3D.prototype, { - eulerOrder: { - get: function () { + eulerOrder: { + get: function () { - console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' ); - return this.rotation.order; + console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' ); + return this.rotation.order; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' ); - this.rotation.order = value; + console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' ); + this.rotation.order = value; - } - }, - useQuaternion: { - get: function () { + } + }, + useQuaternion: { + get: function () { - console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); + console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); - }, - set: function () { + }, + set: function () { - console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); + console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); - } - } + } + } - } ); + } ); - Object.defineProperties( LOD.prototype, { + Object.defineProperties( LOD.prototype, { - objects: { - get: function () { + objects: { + get: function () { - console.warn( 'THREE.LOD: .objects has been renamed to .levels.' ); - return this.levels; + console.warn( 'THREE.LOD: .objects has been renamed to .levels.' ); + return this.levels; - } - } + } + } - } ); + } ); - Object.defineProperty( Skeleton.prototype, 'useVertexTexture', { + Object.defineProperty( Skeleton.prototype, 'useVertexTexture', { - get: function () { + get: function () { - console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' ); + console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' ); - }, - set: function () { + }, + set: function () { - console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' ); + console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' ); - } + } - } ); + } ); - Object.defineProperty( Curve.prototype, '__arcLengthDivisions', { + Object.defineProperty( Curve.prototype, '__arcLengthDivisions', { - get: function () { + get: function () { - console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' ); - return this.arcLengthDivisions; + console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' ); + return this.arcLengthDivisions; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' ); - this.arcLengthDivisions = value; + console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' ); + this.arcLengthDivisions = value; - } + } - } ); + } ); - // + // - PerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) { + PerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) { - console.warn( "THREE.PerspectiveCamera.setLens is deprecated. " + - "Use .setFocalLength and .filmGauge for a photographic setup." ); + console.warn( "THREE.PerspectiveCamera.setLens is deprecated. " + + "Use .setFocalLength and .filmGauge for a photographic setup." ); - if ( filmGauge !== undefined ) this.filmGauge = filmGauge; - this.setFocalLength( focalLength ); + if ( filmGauge !== undefined ) this.filmGauge = filmGauge; + this.setFocalLength( focalLength ); - }; + }; - // + // - Object.defineProperties( Light.prototype, { - onlyShadow: { - set: function () { + Object.defineProperties( Light.prototype, { + onlyShadow: { + set: function () { - console.warn( 'THREE.Light: .onlyShadow has been removed.' ); + console.warn( 'THREE.Light: .onlyShadow has been removed.' ); - } - }, - shadowCameraFov: { - set: function ( value ) { + } + }, + shadowCameraFov: { + set: function ( value ) { - console.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' ); - this.shadow.camera.fov = value; + console.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' ); + this.shadow.camera.fov = value; - } - }, - shadowCameraLeft: { - set: function ( value ) { + } + }, + shadowCameraLeft: { + set: function ( value ) { - console.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' ); - this.shadow.camera.left = value; + console.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' ); + this.shadow.camera.left = value; - } - }, - shadowCameraRight: { - set: function ( value ) { + } + }, + shadowCameraRight: { + set: function ( value ) { - console.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' ); - this.shadow.camera.right = value; + console.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' ); + this.shadow.camera.right = value; - } - }, - shadowCameraTop: { - set: function ( value ) { + } + }, + shadowCameraTop: { + set: function ( value ) { - console.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' ); - this.shadow.camera.top = value; + console.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' ); + this.shadow.camera.top = value; - } - }, - shadowCameraBottom: { - set: function ( value ) { + } + }, + shadowCameraBottom: { + set: function ( value ) { - console.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' ); - this.shadow.camera.bottom = value; + console.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' ); + this.shadow.camera.bottom = value; - } - }, - shadowCameraNear: { - set: function ( value ) { + } + }, + shadowCameraNear: { + set: function ( value ) { - console.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' ); - this.shadow.camera.near = value; + console.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' ); + this.shadow.camera.near = value; - } - }, - shadowCameraFar: { - set: function ( value ) { + } + }, + shadowCameraFar: { + set: function ( value ) { - console.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' ); - this.shadow.camera.far = value; + console.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' ); + this.shadow.camera.far = value; - } - }, - shadowCameraVisible: { - set: function () { + } + }, + shadowCameraVisible: { + set: function () { - console.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' ); + console.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' ); - } - }, - shadowBias: { - set: function ( value ) { + } + }, + shadowBias: { + set: function ( value ) { - console.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' ); - this.shadow.bias = value; + console.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' ); + this.shadow.bias = value; - } - }, - shadowDarkness: { - set: function () { + } + }, + shadowDarkness: { + set: function () { - console.warn( 'THREE.Light: .shadowDarkness has been removed.' ); + console.warn( 'THREE.Light: .shadowDarkness has been removed.' ); - } - }, - shadowMapWidth: { - set: function ( value ) { + } + }, + shadowMapWidth: { + set: function ( value ) { - console.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' ); - this.shadow.mapSize.width = value; + console.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' ); + this.shadow.mapSize.width = value; - } - }, - shadowMapHeight: { - set: function ( value ) { + } + }, + shadowMapHeight: { + set: function ( value ) { - console.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' ); - this.shadow.mapSize.height = value; + console.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' ); + this.shadow.mapSize.height = value; - } - } - } ); + } + } + } ); - // + // - Object.defineProperties( BufferAttribute.prototype, { + Object.defineProperties( BufferAttribute.prototype, { - length: { - get: function () { + length: { + get: function () { - console.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' ); - return this.array.length; + console.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' ); + return this.array.length; - } - }, - copyIndicesArray: function ( /* indices */ ) { + } + }, + copyIndicesArray: function ( /* indices */ ) { - console.error( 'THREE.BufferAttribute: .copyIndicesArray() has been removed.' ); + console.error( 'THREE.BufferAttribute: .copyIndicesArray() has been removed.' ); - } + } - } ); + } ); - Object.assign( BufferGeometry.prototype, { + Object.assign( BufferGeometry.prototype, { - addIndex: function ( index ) { + addIndex: function ( index ) { - console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' ); - this.setIndex( index ); + console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' ); + this.setIndex( index ); - }, - addDrawCall: function ( start, count, indexOffset ) { + }, + addDrawCall: function ( start, count, indexOffset ) { - if ( indexOffset !== undefined ) { + if ( indexOffset !== undefined ) { - console.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' ); + console.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' ); - } - console.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' ); - this.addGroup( start, count ); + } + console.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' ); + this.addGroup( start, count ); - }, - clearDrawCalls: function () { + }, + clearDrawCalls: function () { - console.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' ); - this.clearGroups(); + console.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' ); + this.clearGroups(); - }, - computeTangents: function () { + }, + computeTangents: function () { - console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' ); + console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' ); - }, - computeOffsets: function () { + }, + computeOffsets: function () { - console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' ); + console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' ); - } + } - } ); + } ); - Object.defineProperties( BufferGeometry.prototype, { + Object.defineProperties( BufferGeometry.prototype, { - drawcalls: { - get: function () { + drawcalls: { + get: function () { - console.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' ); - return this.groups; + console.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' ); + return this.groups; - } - }, - offsets: { - get: function () { + } + }, + offsets: { + get: function () { - console.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' ); - return this.groups; + console.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' ); + return this.groups; - } - } + } + } - } ); + } ); - // + // - Object.assign( ExtrudeBufferGeometry.prototype, { + Object.assign( ExtrudeBufferGeometry.prototype, { - getArrays: function () { + getArrays: function () { - console.error( 'THREE.ExtrudeBufferGeometry: .getArrays() has been removed.' ); + console.error( 'THREE.ExtrudeBufferGeometry: .getArrays() has been removed.' ); - }, + }, - addShapeList: function () { + addShapeList: function () { - console.error( 'THREE.ExtrudeBufferGeometry: .addShapeList() has been removed.' ); + console.error( 'THREE.ExtrudeBufferGeometry: .addShapeList() has been removed.' ); - }, + }, - addShape: function () { + addShape: function () { - console.error( 'THREE.ExtrudeBufferGeometry: .addShape() has been removed.' ); + console.error( 'THREE.ExtrudeBufferGeometry: .addShape() has been removed.' ); - } + } - } ); + } ); - // + // - Object.defineProperties( Uniform.prototype, { + Object.defineProperties( Uniform.prototype, { - dynamic: { - set: function () { + dynamic: { + set: function () { - console.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' ); + console.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' ); - } - }, - onUpdate: { - value: function () { + } + }, + onUpdate: { + value: function () { - console.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' ); - return this; + console.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' ); + return this; - } - } + } + } - } ); + } ); - // + // - Object.defineProperties( Material.prototype, { + Object.defineProperties( Material.prototype, { - wrapAround: { - get: function () { + wrapAround: { + get: function () { - console.warn( 'THREE.Material: .wrapAround has been removed.' ); + console.warn( 'THREE.Material: .wrapAround has been removed.' ); - }, - set: function () { + }, + set: function () { - console.warn( 'THREE.Material: .wrapAround has been removed.' ); + console.warn( 'THREE.Material: .wrapAround has been removed.' ); - } - }, - wrapRGB: { - get: function () { + } + }, + wrapRGB: { + get: function () { - console.warn( 'THREE.Material: .wrapRGB has been removed.' ); - return new Color(); + console.warn( 'THREE.Material: .wrapRGB has been removed.' ); + return new Color(); - } - }, + } + }, - shading: { - get: function () { + shading: { + get: function () { - console.error( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); + console.error( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); - this.flatShading = ( value === FlatShading ); + console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); + this.flatShading = ( value === FlatShading ); - } - } + } + } - } ); + } ); - Object.defineProperties( MeshPhongMaterial.prototype, { + Object.defineProperties( MeshPhongMaterial.prototype, { - metal: { - get: function () { + metal: { + get: function () { - console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' ); - return false; + console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' ); + return false; - }, - set: function () { + }, + set: function () { - console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' ); + console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' ); - } - } + } + } - } ); + } ); - Object.defineProperties( ShaderMaterial.prototype, { + Object.defineProperties( ShaderMaterial.prototype, { - derivatives: { - get: function () { + derivatives: { + get: function () { - console.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' ); - return this.extensions.derivatives; + console.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' ); + return this.extensions.derivatives; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' ); - this.extensions.derivatives = value; + console.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' ); + this.extensions.derivatives = value; - } - } + } + } - } ); + } ); - // + // - Object.assign( WebGLRenderer.prototype, { + Object.assign( WebGLRenderer.prototype, { - animate: function ( callback ) { + animate: function ( callback ) { - console.warn( 'THREE.WebGLRenderer: .animate() is now .setAnimationLoop().' ); - this.setAnimationLoop( callback ); + console.warn( 'THREE.WebGLRenderer: .animate() is now .setAnimationLoop().' ); + this.setAnimationLoop( callback ); - }, + }, - getCurrentRenderTarget: function () { + getCurrentRenderTarget: function () { - console.warn( 'THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget().' ); - return this.getRenderTarget(); + console.warn( 'THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget().' ); + return this.getRenderTarget(); - }, + }, - getMaxAnisotropy: function () { + getMaxAnisotropy: function () { - console.warn( 'THREE.WebGLRenderer: .getMaxAnisotropy() is now .capabilities.getMaxAnisotropy().' ); - return this.capabilities.getMaxAnisotropy(); + console.warn( 'THREE.WebGLRenderer: .getMaxAnisotropy() is now .capabilities.getMaxAnisotropy().' ); + return this.capabilities.getMaxAnisotropy(); - }, + }, - getPrecision: function () { + getPrecision: function () { - console.warn( 'THREE.WebGLRenderer: .getPrecision() is now .capabilities.precision.' ); - return this.capabilities.precision; + console.warn( 'THREE.WebGLRenderer: .getPrecision() is now .capabilities.precision.' ); + return this.capabilities.precision; - }, + }, - resetGLState: function () { + resetGLState: function () { - console.warn( 'THREE.WebGLRenderer: .resetGLState() is now .state.reset().' ); - return this.state.reset(); + console.warn( 'THREE.WebGLRenderer: .resetGLState() is now .state.reset().' ); + return this.state.reset(); - }, + }, - supportsFloatTextures: function () { + supportsFloatTextures: function () { - console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' ); - return this.extensions.get( 'OES_texture_float' ); + console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' ); + return this.extensions.get( 'OES_texture_float' ); - }, - supportsHalfFloatTextures: function () { + }, + supportsHalfFloatTextures: function () { - console.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).' ); - return this.extensions.get( 'OES_texture_half_float' ); + console.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).' ); + return this.extensions.get( 'OES_texture_half_float' ); - }, - supportsStandardDerivatives: function () { + }, + supportsStandardDerivatives: function () { - console.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).' ); - return this.extensions.get( 'OES_standard_derivatives' ); + console.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).' ); + return this.extensions.get( 'OES_standard_derivatives' ); - }, - supportsCompressedTextureS3TC: function () { + }, + supportsCompressedTextureS3TC: function () { - console.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).' ); - return this.extensions.get( 'WEBGL_compressed_texture_s3tc' ); + console.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).' ); + return this.extensions.get( 'WEBGL_compressed_texture_s3tc' ); - }, - supportsCompressedTexturePVRTC: function () { + }, + supportsCompressedTexturePVRTC: function () { - console.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).' ); - return this.extensions.get( 'WEBGL_compressed_texture_pvrtc' ); + console.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).' ); + return this.extensions.get( 'WEBGL_compressed_texture_pvrtc' ); - }, - supportsBlendMinMax: function () { + }, + supportsBlendMinMax: function () { - console.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).' ); - return this.extensions.get( 'EXT_blend_minmax' ); + console.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).' ); + return this.extensions.get( 'EXT_blend_minmax' ); - }, - supportsVertexTextures: function () { + }, + supportsVertexTextures: function () { - console.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' ); - return this.capabilities.vertexTextures; + console.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' ); + return this.capabilities.vertexTextures; - }, - supportsInstancedArrays: function () { + }, + supportsInstancedArrays: function () { - console.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_instanced_arrays\' ).' ); - return this.extensions.get( 'ANGLE_instanced_arrays' ); + console.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_instanced_arrays\' ).' ); + return this.extensions.get( 'ANGLE_instanced_arrays' ); - }, - enableScissorTest: function ( boolean ) { + }, + enableScissorTest: function ( boolean ) { - console.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' ); - this.setScissorTest( boolean ); + console.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' ); + this.setScissorTest( boolean ); - }, - initMaterial: function () { + }, + initMaterial: function () { - console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' ); + console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' ); - }, - addPrePlugin: function () { + }, + addPrePlugin: function () { - console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' ); + console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' ); - }, - addPostPlugin: function () { + }, + addPostPlugin: function () { - console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' ); + console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' ); - }, - updateShadowMap: function () { + }, + updateShadowMap: function () { - console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' ); + console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' ); - }, - setFaceCulling: function () { + }, + setFaceCulling: function () { - console.warn( 'THREE.WebGLRenderer: .setFaceCulling() has been removed.' ); + console.warn( 'THREE.WebGLRenderer: .setFaceCulling() has been removed.' ); - } + } - } ); + } ); - Object.defineProperties( WebGLRenderer.prototype, { + Object.defineProperties( WebGLRenderer.prototype, { - shadowMapEnabled: { - get: function () { + shadowMapEnabled: { + get: function () { - return this.shadowMap.enabled; + return this.shadowMap.enabled; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' ); - this.shadowMap.enabled = value; + console.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' ); + this.shadowMap.enabled = value; - } - }, - shadowMapType: { - get: function () { + } + }, + shadowMapType: { + get: function () { - return this.shadowMap.type; + return this.shadowMap.type; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' ); - this.shadowMap.type = value; + console.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' ); + this.shadowMap.type = value; - } - }, - shadowMapCullFace: { - get: function () { + } + }, + shadowMapCullFace: { + get: function () { - console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.' ); - return undefined; + console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.' ); + return undefined; - }, - set: function ( /* value */ ) { + }, + set: function ( /* value */ ) { - console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.' ); + console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.' ); - } - } - } ); + } + } + } ); - Object.defineProperties( WebGLShadowMap.prototype, { + Object.defineProperties( WebGLShadowMap.prototype, { - cullFace: { - get: function () { + cullFace: { + get: function () { - console.warn( 'THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.' ); - return undefined; + console.warn( 'THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.' ); + return undefined; - }, - set: function ( /* cullFace */ ) { + }, + set: function ( /* cullFace */ ) { - console.warn( 'THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.' ); + console.warn( 'THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.' ); - } - }, - renderReverseSided: { - get: function () { + } + }, + renderReverseSided: { + get: function () { - console.warn( 'THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.' ); - return undefined; + console.warn( 'THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.' ); + return undefined; - }, - set: function () { + }, + set: function () { - console.warn( 'THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.' ); + console.warn( 'THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.' ); - } - }, - renderSingleSided: { - get: function () { + } + }, + renderSingleSided: { + get: function () { - console.warn( 'THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.' ); - return undefined; + console.warn( 'THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.' ); + return undefined; - }, - set: function () { + }, + set: function () { - console.warn( 'THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.' ); + console.warn( 'THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.' ); - } - } + } + } - } ); + } ); - // + // - Object.defineProperties( WebGLRenderTarget.prototype, { + Object.defineProperties( WebGLRenderTarget.prototype, { - wrapS: { - get: function () { + wrapS: { + get: function () { - console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' ); - return this.texture.wrapS; + console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' ); + return this.texture.wrapS; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' ); - this.texture.wrapS = value; + console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' ); + this.texture.wrapS = value; - } - }, - wrapT: { - get: function () { + } + }, + wrapT: { + get: function () { - console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' ); - return this.texture.wrapT; + console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' ); + return this.texture.wrapT; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' ); - this.texture.wrapT = value; + console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' ); + this.texture.wrapT = value; - } - }, - magFilter: { - get: function () { + } + }, + magFilter: { + get: function () { - console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' ); - return this.texture.magFilter; + console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' ); + return this.texture.magFilter; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' ); - this.texture.magFilter = value; + console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' ); + this.texture.magFilter = value; - } - }, - minFilter: { - get: function () { + } + }, + minFilter: { + get: function () { - console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' ); - return this.texture.minFilter; + console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' ); + return this.texture.minFilter; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' ); - this.texture.minFilter = value; + console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' ); + this.texture.minFilter = value; - } - }, - anisotropy: { - get: function () { + } + }, + anisotropy: { + get: function () { - console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' ); - return this.texture.anisotropy; + console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' ); + return this.texture.anisotropy; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' ); - this.texture.anisotropy = value; + console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' ); + this.texture.anisotropy = value; - } - }, - offset: { - get: function () { + } + }, + offset: { + get: function () { - console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' ); - return this.texture.offset; + console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' ); + return this.texture.offset; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' ); - this.texture.offset = value; + console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' ); + this.texture.offset = value; - } - }, - repeat: { - get: function () { + } + }, + repeat: { + get: function () { - console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' ); - return this.texture.repeat; + console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' ); + return this.texture.repeat; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' ); - this.texture.repeat = value; + console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' ); + this.texture.repeat = value; - } - }, - format: { - get: function () { + } + }, + format: { + get: function () { - console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' ); - return this.texture.format; + console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' ); + return this.texture.format; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' ); - this.texture.format = value; + console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' ); + this.texture.format = value; - } - }, - type: { - get: function () { + } + }, + type: { + get: function () { - console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' ); - return this.texture.type; + console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' ); + return this.texture.type; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' ); - this.texture.type = value; + console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' ); + this.texture.type = value; - } - }, - generateMipmaps: { - get: function () { + } + }, + generateMipmaps: { + get: function () { - console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' ); - return this.texture.generateMipmaps; + console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' ); + return this.texture.generateMipmaps; - }, - set: function ( value ) { + }, + set: function ( value ) { - console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' ); - this.texture.generateMipmaps = value; + console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' ); + this.texture.generateMipmaps = value; - } - } + } + } - } ); + } ); - // + // - Object.defineProperties( WebVRManager.prototype, { + Object.defineProperties( WebVRManager.prototype, { - standing: { - set: function ( /* value */ ) { + standing: { + set: function ( /* value */ ) { - console.warn( 'THREE.WebVRManager: .standing has been removed.' ); + console.warn( 'THREE.WebVRManager: .standing has been removed.' ); - } - } + } + } - } ); + } ); - // + // - Audio.prototype.load = function ( file ) { + Audio.prototype.load = function ( file ) { - console.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' ); - var scope = this; - var audioLoader = new AudioLoader(); - audioLoader.load( file, function ( buffer ) { + console.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' ); + var scope = this; + var audioLoader = new AudioLoader(); + audioLoader.load( file, function ( buffer ) { - scope.setBuffer( buffer ); + scope.setBuffer( buffer ); - } ); - return this; + } ); + return this; - }; + }; - AudioAnalyser.prototype.getData = function () { + AudioAnalyser.prototype.getData = function () { - console.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' ); - return this.getFrequencyData(); + console.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' ); + return this.getFrequencyData(); - }; + }; - // + // - CubeCamera.prototype.updateCubeMap = function ( renderer, scene ) { + CubeCamera.prototype.updateCubeMap = function ( renderer, scene ) { - console.warn( 'THREE.CubeCamera: .updateCubeMap() is now .update().' ); - return this.update( renderer, scene ); + console.warn( 'THREE.CubeCamera: .updateCubeMap() is now .update().' ); + return this.update( renderer, scene ); - }; + }; - // + // - var GeometryUtils = { + var GeometryUtils = { - merge: function ( geometry1, geometry2, materialIndexOffset ) { + merge: function ( geometry1, geometry2, materialIndexOffset ) { - console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' ); - var matrix; + console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' ); + var matrix; - if ( geometry2.isMesh ) { + if ( geometry2.isMesh ) { - geometry2.matrixAutoUpdate && geometry2.updateMatrix(); + geometry2.matrixAutoUpdate && geometry2.updateMatrix(); - matrix = geometry2.matrix; - geometry2 = geometry2.geometry; + matrix = geometry2.matrix; + geometry2 = geometry2.geometry; - } + } - geometry1.merge( geometry2, matrix, materialIndexOffset ); + geometry1.merge( geometry2, matrix, materialIndexOffset ); - }, + }, - center: function ( geometry ) { + center: function ( geometry ) { - console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' ); - return geometry.center(); + console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' ); + return geometry.center(); - } + } - }; + }; - ImageUtils.crossOrigin = undefined; + ImageUtils.crossOrigin = undefined; - ImageUtils.loadTexture = function ( url, mapping, onLoad, onError ) { + ImageUtils.loadTexture = function ( url, mapping, onLoad, onError ) { - console.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' ); + console.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' ); - var loader = new TextureLoader(); - loader.setCrossOrigin( this.crossOrigin ); + var loader = new TextureLoader(); + loader.setCrossOrigin( this.crossOrigin ); - var texture = loader.load( url, onLoad, undefined, onError ); + var texture = loader.load( url, onLoad, undefined, onError ); - if ( mapping ) texture.mapping = mapping; + if ( mapping ) texture.mapping = mapping; - return texture; + return texture; - }; + }; - ImageUtils.loadTextureCube = function ( urls, mapping, onLoad, onError ) { + ImageUtils.loadTextureCube = function ( urls, mapping, onLoad, onError ) { - console.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' ); + console.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' ); - var loader = new CubeTextureLoader(); - loader.setCrossOrigin( this.crossOrigin ); + var loader = new CubeTextureLoader(); + loader.setCrossOrigin( this.crossOrigin ); - var texture = loader.load( urls, onLoad, undefined, onError ); + var texture = loader.load( urls, onLoad, undefined, onError ); - if ( mapping ) texture.mapping = mapping; + if ( mapping ) texture.mapping = mapping; - return texture; + return texture; - }; + }; - ImageUtils.loadCompressedTexture = function () { + ImageUtils.loadCompressedTexture = function () { - console.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' ); + console.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' ); - }; + }; - ImageUtils.loadCompressedTextureCube = function () { + ImageUtils.loadCompressedTextureCube = function () { - console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' ); + console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' ); - }; + }; - // + // - function Projector() { + function Projector() { - console.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' ); + console.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' ); - this.projectVector = function ( vector, camera ) { + this.projectVector = function ( vector, camera ) { - console.warn( 'THREE.Projector: .projectVector() is now vector.project().' ); - vector.project( camera ); + console.warn( 'THREE.Projector: .projectVector() is now vector.project().' ); + vector.project( camera ); - }; + }; - this.unprojectVector = function ( vector, camera ) { + this.unprojectVector = function ( vector, camera ) { - console.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' ); - vector.unproject( camera ); + console.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' ); + vector.unproject( camera ); - }; + }; - this.pickingRay = function () { + this.pickingRay = function () { - console.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' ); + console.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' ); - }; + }; - } + } - // + // - function CanvasRenderer() { + function CanvasRenderer() { - console.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' ); + console.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' ); - this.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); - this.clear = function () {}; - this.render = function () {}; - this.setClearColor = function () {}; - this.setSize = function () {}; + this.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); + this.clear = function () {}; + this.render = function () {}; + this.setClearColor = function () {}; + this.setSize = function () {}; - } + } - // + // - var SceneUtils = { + var SceneUtils = { - createMultiMaterialObject: function ( /* geometry, materials */ ) { + createMultiMaterialObject: function ( /* geometry, materials */ ) { - console.error( 'THREE.SceneUtils has been moved to /examples/js/utils/SceneUtils.js' ); + console.error( 'THREE.SceneUtils has been moved to /examples/js/utils/SceneUtils.js' ); - }, + }, - detach: function ( /* child, parent, scene */ ) { + detach: function ( /* child, parent, scene */ ) { - console.error( 'THREE.SceneUtils has been moved to /examples/js/utils/SceneUtils.js' ); + console.error( 'THREE.SceneUtils has been moved to /examples/js/utils/SceneUtils.js' ); - }, + }, - attach: function ( /* child, scene, parent */ ) { + attach: function ( /* child, scene, parent */ ) { - console.error( 'THREE.SceneUtils has been moved to /examples/js/utils/SceneUtils.js' ); + console.error( 'THREE.SceneUtils has been moved to /examples/js/utils/SceneUtils.js' ); - } + } - }; + }; - // + // - function LensFlare() { - - console.error( 'THREE.LensFlare has been moved to /examples/js/objects/Lensflare.js' ); - - } - - exports.WebGLRenderTargetCube = WebGLRenderTargetCube; - exports.WebGLRenderTarget = WebGLRenderTarget; - exports.WebGLRenderer = WebGLRenderer; - exports.ShaderLib = ShaderLib; - exports.UniformsLib = UniformsLib; - exports.UniformsUtils = UniformsUtils; - exports.ShaderChunk = ShaderChunk; - exports.FogExp2 = FogExp2; - exports.Fog = Fog; - exports.Scene = Scene; - exports.Sprite = Sprite; - exports.LOD = LOD; - exports.SkinnedMesh = SkinnedMesh; - exports.Skeleton = Skeleton; - exports.Bone = Bone; - exports.Mesh = Mesh; - exports.LineSegments = LineSegments; - exports.LineLoop = LineLoop; - exports.Line = Line; - exports.Points = Points; - exports.Group = Group; - exports.VideoTexture = VideoTexture; - exports.DataTexture = DataTexture; - exports.CompressedTexture = CompressedTexture; - exports.CubeTexture = CubeTexture; - exports.CanvasTexture = CanvasTexture; - exports.DepthTexture = DepthTexture; - exports.Texture = Texture; - exports.CompressedTextureLoader = CompressedTextureLoader; - exports.DataTextureLoader = DataTextureLoader; - exports.CubeTextureLoader = CubeTextureLoader; - exports.TextureLoader = TextureLoader; - exports.ObjectLoader = ObjectLoader; - exports.MaterialLoader = MaterialLoader; - exports.BufferGeometryLoader = BufferGeometryLoader; - exports.DefaultLoadingManager = DefaultLoadingManager; - exports.LoadingManager = LoadingManager; - exports.JSONLoader = JSONLoader; - exports.ImageLoader = ImageLoader; - exports.ImageBitmapLoader = ImageBitmapLoader; - exports.FontLoader = FontLoader; - exports.FileLoader = FileLoader; - exports.Loader = Loader; - exports.LoaderUtils = LoaderUtils; - exports.Cache = Cache; - exports.AudioLoader = AudioLoader; - exports.SpotLightShadow = SpotLightShadow; - exports.SpotLight = SpotLight; - exports.PointLight = PointLight; - exports.RectAreaLight = RectAreaLight; - exports.HemisphereLight = HemisphereLight; - exports.DirectionalLightShadow = DirectionalLightShadow; - exports.DirectionalLight = DirectionalLight; - exports.AmbientLight = AmbientLight; - exports.LightShadow = LightShadow; - exports.Light = Light; - exports.StereoCamera = StereoCamera; - exports.PerspectiveCamera = PerspectiveCamera; - exports.OrthographicCamera = OrthographicCamera; - exports.CubeCamera = CubeCamera; - exports.ArrayCamera = ArrayCamera; - exports.Camera = Camera; - exports.AudioListener = AudioListener; - exports.PositionalAudio = PositionalAudio; - exports.AudioContext = AudioContext; - exports.AudioAnalyser = AudioAnalyser; - exports.Audio = Audio; - exports.VectorKeyframeTrack = VectorKeyframeTrack; - exports.StringKeyframeTrack = StringKeyframeTrack; - exports.QuaternionKeyframeTrack = QuaternionKeyframeTrack; - exports.NumberKeyframeTrack = NumberKeyframeTrack; - exports.ColorKeyframeTrack = ColorKeyframeTrack; - exports.BooleanKeyframeTrack = BooleanKeyframeTrack; - exports.PropertyMixer = PropertyMixer; - exports.PropertyBinding = PropertyBinding; - exports.KeyframeTrack = KeyframeTrack; - exports.AnimationUtils = AnimationUtils; - exports.AnimationObjectGroup = AnimationObjectGroup; - exports.AnimationMixer = AnimationMixer; - exports.AnimationClip = AnimationClip; - exports.Uniform = Uniform; - exports.InstancedBufferGeometry = InstancedBufferGeometry; - exports.BufferGeometry = BufferGeometry; - exports.Geometry = Geometry; - exports.InterleavedBufferAttribute = InterleavedBufferAttribute; - exports.InstancedInterleavedBuffer = InstancedInterleavedBuffer; - exports.InterleavedBuffer = InterleavedBuffer; - exports.InstancedBufferAttribute = InstancedBufferAttribute; - exports.Face3 = Face3; - exports.Object3D = Object3D; - exports.Raycaster = Raycaster; - exports.Layers = Layers; - exports.EventDispatcher = EventDispatcher; - exports.Clock = Clock; - exports.QuaternionLinearInterpolant = QuaternionLinearInterpolant; - exports.LinearInterpolant = LinearInterpolant; - exports.DiscreteInterpolant = DiscreteInterpolant; - exports.CubicInterpolant = CubicInterpolant; - exports.Interpolant = Interpolant; - exports.Triangle = Triangle; - exports.Math = _Math; - exports.Spherical = Spherical; - exports.Cylindrical = Cylindrical; - exports.Plane = Plane; - exports.Frustum = Frustum; - exports.Sphere = Sphere; - exports.Ray = Ray; - exports.Matrix4 = Matrix4; - exports.Matrix3 = Matrix3; - exports.Box3 = Box3; - exports.Box2 = Box2; - exports.Line3 = Line3; - exports.Euler = Euler; - exports.Vector4 = Vector4; - exports.Vector3 = Vector3; - exports.Vector2 = Vector2; - exports.Quaternion = Quaternion; - exports.Color = Color; - exports.ImmediateRenderObject = ImmediateRenderObject; - exports.VertexNormalsHelper = VertexNormalsHelper; - exports.SpotLightHelper = SpotLightHelper; - exports.SkeletonHelper = SkeletonHelper; - exports.PointLightHelper = PointLightHelper; - exports.RectAreaLightHelper = RectAreaLightHelper; - exports.HemisphereLightHelper = HemisphereLightHelper; - exports.GridHelper = GridHelper; - exports.PolarGridHelper = PolarGridHelper; - exports.FaceNormalsHelper = FaceNormalsHelper; - exports.DirectionalLightHelper = DirectionalLightHelper; - exports.CameraHelper = CameraHelper; - exports.BoxHelper = BoxHelper; - exports.Box3Helper = Box3Helper; - exports.PlaneHelper = PlaneHelper; - exports.ArrowHelper = ArrowHelper; - exports.AxesHelper = AxesHelper; - exports.Shape = Shape; - exports.Path = Path; - exports.ShapePath = ShapePath; - exports.Font = Font; - exports.CurvePath = CurvePath; - exports.Curve = Curve; - exports.ImageUtils = ImageUtils; - exports.ShapeUtils = ShapeUtils; - exports.WebGLUtils = WebGLUtils; - exports.WireframeGeometry = WireframeGeometry; - exports.ParametricGeometry = ParametricGeometry; - exports.ParametricBufferGeometry = ParametricBufferGeometry; - exports.TetrahedronGeometry = TetrahedronGeometry; - exports.TetrahedronBufferGeometry = TetrahedronBufferGeometry; - exports.OctahedronGeometry = OctahedronGeometry; - exports.OctahedronBufferGeometry = OctahedronBufferGeometry; - exports.IcosahedronGeometry = IcosahedronGeometry; - exports.IcosahedronBufferGeometry = IcosahedronBufferGeometry; - exports.DodecahedronGeometry = DodecahedronGeometry; - exports.DodecahedronBufferGeometry = DodecahedronBufferGeometry; - exports.PolyhedronGeometry = PolyhedronGeometry; - exports.PolyhedronBufferGeometry = PolyhedronBufferGeometry; - exports.TubeGeometry = TubeGeometry; - exports.TubeBufferGeometry = TubeBufferGeometry; - exports.TorusKnotGeometry = TorusKnotGeometry; - exports.TorusKnotBufferGeometry = TorusKnotBufferGeometry; - exports.TorusGeometry = TorusGeometry; - exports.TorusBufferGeometry = TorusBufferGeometry; - exports.TextGeometry = TextGeometry; - exports.TextBufferGeometry = TextBufferGeometry; - exports.SphereGeometry = SphereGeometry; - exports.SphereBufferGeometry = SphereBufferGeometry; - exports.RingGeometry = RingGeometry; - exports.RingBufferGeometry = RingBufferGeometry; - exports.PlaneGeometry = PlaneGeometry; - exports.PlaneBufferGeometry = PlaneBufferGeometry; - exports.LatheGeometry = LatheGeometry; - exports.LatheBufferGeometry = LatheBufferGeometry; - exports.ShapeGeometry = ShapeGeometry; - exports.ShapeBufferGeometry = ShapeBufferGeometry; - exports.ExtrudeGeometry = ExtrudeGeometry; - exports.ExtrudeBufferGeometry = ExtrudeBufferGeometry; - exports.EdgesGeometry = EdgesGeometry; - exports.ConeGeometry = ConeGeometry; - exports.ConeBufferGeometry = ConeBufferGeometry; - exports.CylinderGeometry = CylinderGeometry; - exports.CylinderBufferGeometry = CylinderBufferGeometry; - exports.CircleGeometry = CircleGeometry; - exports.CircleBufferGeometry = CircleBufferGeometry; - exports.BoxGeometry = BoxGeometry; - exports.BoxBufferGeometry = BoxBufferGeometry; - exports.ShadowMaterial = ShadowMaterial; - exports.SpriteMaterial = SpriteMaterial; - exports.RawShaderMaterial = RawShaderMaterial; - exports.ShaderMaterial = ShaderMaterial; - exports.PointsMaterial = PointsMaterial; - exports.MeshPhysicalMaterial = MeshPhysicalMaterial; - exports.MeshStandardMaterial = MeshStandardMaterial; - exports.MeshPhongMaterial = MeshPhongMaterial; - exports.MeshToonMaterial = MeshToonMaterial; - exports.MeshNormalMaterial = MeshNormalMaterial; - exports.MeshLambertMaterial = MeshLambertMaterial; - exports.MeshDepthMaterial = MeshDepthMaterial; - exports.MeshDistanceMaterial = MeshDistanceMaterial; - exports.MeshBasicMaterial = MeshBasicMaterial; - exports.LineDashedMaterial = LineDashedMaterial; - exports.LineBasicMaterial = LineBasicMaterial; - exports.Material = Material; - exports.Float64BufferAttribute = Float64BufferAttribute; - exports.Float32BufferAttribute = Float32BufferAttribute; - exports.Uint32BufferAttribute = Uint32BufferAttribute; - exports.Int32BufferAttribute = Int32BufferAttribute; - exports.Uint16BufferAttribute = Uint16BufferAttribute; - exports.Int16BufferAttribute = Int16BufferAttribute; - exports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute; - exports.Uint8BufferAttribute = Uint8BufferAttribute; - exports.Int8BufferAttribute = Int8BufferAttribute; - exports.BufferAttribute = BufferAttribute; - exports.ArcCurve = ArcCurve; - exports.CatmullRomCurve3 = CatmullRomCurve3; - exports.CubicBezierCurve = CubicBezierCurve; - exports.CubicBezierCurve3 = CubicBezierCurve3; - exports.EllipseCurve = EllipseCurve; - exports.LineCurve = LineCurve; - exports.LineCurve3 = LineCurve3; - exports.QuadraticBezierCurve = QuadraticBezierCurve; - exports.QuadraticBezierCurve3 = QuadraticBezierCurve3; - exports.SplineCurve = SplineCurve; - exports.REVISION = REVISION; - exports.MOUSE = MOUSE; - exports.CullFaceNone = CullFaceNone; - exports.CullFaceBack = CullFaceBack; - exports.CullFaceFront = CullFaceFront; - exports.CullFaceFrontBack = CullFaceFrontBack; - exports.FrontFaceDirectionCW = FrontFaceDirectionCW; - exports.FrontFaceDirectionCCW = FrontFaceDirectionCCW; - exports.BasicShadowMap = BasicShadowMap; - exports.PCFShadowMap = PCFShadowMap; - exports.PCFSoftShadowMap = PCFSoftShadowMap; - exports.FrontSide = FrontSide; - exports.BackSide = BackSide; - exports.DoubleSide = DoubleSide; - exports.FlatShading = FlatShading; - exports.SmoothShading = SmoothShading; - exports.NoColors = NoColors; - exports.FaceColors = FaceColors; - exports.VertexColors = VertexColors; - exports.NoBlending = NoBlending; - exports.NormalBlending = NormalBlending; - exports.AdditiveBlending = AdditiveBlending; - exports.SubtractiveBlending = SubtractiveBlending; - exports.MultiplyBlending = MultiplyBlending; - exports.CustomBlending = CustomBlending; - exports.AddEquation = AddEquation; - exports.SubtractEquation = SubtractEquation; - exports.ReverseSubtractEquation = ReverseSubtractEquation; - exports.MinEquation = MinEquation; - exports.MaxEquation = MaxEquation; - exports.ZeroFactor = ZeroFactor; - exports.OneFactor = OneFactor; - exports.SrcColorFactor = SrcColorFactor; - exports.OneMinusSrcColorFactor = OneMinusSrcColorFactor; - exports.SrcAlphaFactor = SrcAlphaFactor; - exports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor; - exports.DstAlphaFactor = DstAlphaFactor; - exports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor; - exports.DstColorFactor = DstColorFactor; - exports.OneMinusDstColorFactor = OneMinusDstColorFactor; - exports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor; - exports.NeverDepth = NeverDepth; - exports.AlwaysDepth = AlwaysDepth; - exports.LessDepth = LessDepth; - exports.LessEqualDepth = LessEqualDepth; - exports.EqualDepth = EqualDepth; - exports.GreaterEqualDepth = GreaterEqualDepth; - exports.GreaterDepth = GreaterDepth; - exports.NotEqualDepth = NotEqualDepth; - exports.MultiplyOperation = MultiplyOperation; - exports.MixOperation = MixOperation; - exports.AddOperation = AddOperation; - exports.NoToneMapping = NoToneMapping; - exports.LinearToneMapping = LinearToneMapping; - exports.ReinhardToneMapping = ReinhardToneMapping; - exports.Uncharted2ToneMapping = Uncharted2ToneMapping; - exports.CineonToneMapping = CineonToneMapping; - exports.UVMapping = UVMapping; - exports.CubeReflectionMapping = CubeReflectionMapping; - exports.CubeRefractionMapping = CubeRefractionMapping; - exports.EquirectangularReflectionMapping = EquirectangularReflectionMapping; - exports.EquirectangularRefractionMapping = EquirectangularRefractionMapping; - exports.SphericalReflectionMapping = SphericalReflectionMapping; - exports.CubeUVReflectionMapping = CubeUVReflectionMapping; - exports.CubeUVRefractionMapping = CubeUVRefractionMapping; - exports.RepeatWrapping = RepeatWrapping; - exports.ClampToEdgeWrapping = ClampToEdgeWrapping; - exports.MirroredRepeatWrapping = MirroredRepeatWrapping; - exports.NearestFilter = NearestFilter; - exports.NearestMipMapNearestFilter = NearestMipMapNearestFilter; - exports.NearestMipMapLinearFilter = NearestMipMapLinearFilter; - exports.LinearFilter = LinearFilter; - exports.LinearMipMapNearestFilter = LinearMipMapNearestFilter; - exports.LinearMipMapLinearFilter = LinearMipMapLinearFilter; - exports.UnsignedByteType = UnsignedByteType; - exports.ByteType = ByteType; - exports.ShortType = ShortType; - exports.UnsignedShortType = UnsignedShortType; - exports.IntType = IntType; - exports.UnsignedIntType = UnsignedIntType; - exports.FloatType = FloatType; - exports.HalfFloatType = HalfFloatType; - exports.UnsignedShort4444Type = UnsignedShort4444Type; - exports.UnsignedShort5551Type = UnsignedShort5551Type; - exports.UnsignedShort565Type = UnsignedShort565Type; - exports.UnsignedInt248Type = UnsignedInt248Type; - exports.AlphaFormat = AlphaFormat; - exports.RGBFormat = RGBFormat; - exports.RGBAFormat = RGBAFormat; - exports.LuminanceFormat = LuminanceFormat; - exports.LuminanceAlphaFormat = LuminanceAlphaFormat; - exports.RGBEFormat = RGBEFormat; - exports.DepthFormat = DepthFormat; - exports.DepthStencilFormat = DepthStencilFormat; - exports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format; - exports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format; - exports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format; - exports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format; - exports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format; - exports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format; - exports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format; - exports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format; - exports.RGB_ETC1_Format = RGB_ETC1_Format; - exports.RGBA_ASTC_4x4_Format = RGBA_ASTC_4x4_Format; - exports.RGBA_ASTC_5x4_Format = RGBA_ASTC_5x4_Format; - exports.RGBA_ASTC_5x5_Format = RGBA_ASTC_5x5_Format; - exports.RGBA_ASTC_6x5_Format = RGBA_ASTC_6x5_Format; - exports.RGBA_ASTC_6x6_Format = RGBA_ASTC_6x6_Format; - exports.RGBA_ASTC_8x5_Format = RGBA_ASTC_8x5_Format; - exports.RGBA_ASTC_8x6_Format = RGBA_ASTC_8x6_Format; - exports.RGBA_ASTC_8x8_Format = RGBA_ASTC_8x8_Format; - exports.RGBA_ASTC_10x5_Format = RGBA_ASTC_10x5_Format; - exports.RGBA_ASTC_10x6_Format = RGBA_ASTC_10x6_Format; - exports.RGBA_ASTC_10x8_Format = RGBA_ASTC_10x8_Format; - exports.RGBA_ASTC_10x10_Format = RGBA_ASTC_10x10_Format; - exports.RGBA_ASTC_12x10_Format = RGBA_ASTC_12x10_Format; - exports.RGBA_ASTC_12x12_Format = RGBA_ASTC_12x12_Format; - exports.LoopOnce = LoopOnce; - exports.LoopRepeat = LoopRepeat; - exports.LoopPingPong = LoopPingPong; - exports.InterpolateDiscrete = InterpolateDiscrete; - exports.InterpolateLinear = InterpolateLinear; - exports.InterpolateSmooth = InterpolateSmooth; - exports.ZeroCurvatureEnding = ZeroCurvatureEnding; - exports.ZeroSlopeEnding = ZeroSlopeEnding; - exports.WrapAroundEnding = WrapAroundEnding; - exports.TrianglesDrawMode = TrianglesDrawMode; - exports.TriangleStripDrawMode = TriangleStripDrawMode; - exports.TriangleFanDrawMode = TriangleFanDrawMode; - exports.LinearEncoding = LinearEncoding; - exports.sRGBEncoding = sRGBEncoding; - exports.GammaEncoding = GammaEncoding; - exports.RGBEEncoding = RGBEEncoding; - exports.LogLuvEncoding = LogLuvEncoding; - exports.RGBM7Encoding = RGBM7Encoding; - exports.RGBM16Encoding = RGBM16Encoding; - exports.RGBDEncoding = RGBDEncoding; - exports.BasicDepthPacking = BasicDepthPacking; - exports.RGBADepthPacking = RGBADepthPacking; - exports.TangentSpaceNormalMap = TangentSpaceNormalMap; - exports.ObjectSpaceNormalMap = ObjectSpaceNormalMap; - exports.CubeGeometry = BoxGeometry; - exports.Face4 = Face4; - exports.LineStrip = LineStrip; - exports.LinePieces = LinePieces; - exports.MeshFaceMaterial = MeshFaceMaterial; - exports.MultiMaterial = MultiMaterial; - exports.PointCloud = PointCloud; - exports.Particle = Particle; - exports.ParticleSystem = ParticleSystem; - exports.PointCloudMaterial = PointCloudMaterial; - exports.ParticleBasicMaterial = ParticleBasicMaterial; - exports.ParticleSystemMaterial = ParticleSystemMaterial; - exports.Vertex = Vertex; - exports.DynamicBufferAttribute = DynamicBufferAttribute; - exports.Int8Attribute = Int8Attribute; - exports.Uint8Attribute = Uint8Attribute; - exports.Uint8ClampedAttribute = Uint8ClampedAttribute; - exports.Int16Attribute = Int16Attribute; - exports.Uint16Attribute = Uint16Attribute; - exports.Int32Attribute = Int32Attribute; - exports.Uint32Attribute = Uint32Attribute; - exports.Float32Attribute = Float32Attribute; - exports.Float64Attribute = Float64Attribute; - exports.ClosedSplineCurve3 = ClosedSplineCurve3; - exports.SplineCurve3 = SplineCurve3; - exports.Spline = Spline; - exports.AxisHelper = AxisHelper; - exports.BoundingBoxHelper = BoundingBoxHelper; - exports.EdgesHelper = EdgesHelper; - exports.WireframeHelper = WireframeHelper; - exports.XHRLoader = XHRLoader; - exports.BinaryTextureLoader = BinaryTextureLoader; - exports.GeometryUtils = GeometryUtils; - exports.Projector = Projector; - exports.CanvasRenderer = CanvasRenderer; - exports.SceneUtils = SceneUtils; - exports.LensFlare = LensFlare; - - Object.defineProperty(exports, '__esModule', { value: true }); + function LensFlare() { + + console.error( 'THREE.LensFlare has been moved to /examples/js/objects/Lensflare.js' ); + + } + + exports.WebGLRenderTargetCube = WebGLRenderTargetCube; + exports.WebGLRenderTarget = WebGLRenderTarget; + exports.WebGLRenderer = WebGLRenderer; + exports.ShaderLib = ShaderLib; + exports.UniformsLib = UniformsLib; + exports.UniformsUtils = UniformsUtils; + exports.ShaderChunk = ShaderChunk; + exports.FogExp2 = FogExp2; + exports.Fog = Fog; + exports.Scene = Scene; + exports.Sprite = Sprite; + exports.LOD = LOD; + exports.SkinnedMesh = SkinnedMesh; + exports.Skeleton = Skeleton; + exports.Bone = Bone; + exports.Mesh = Mesh; + exports.LineSegments = LineSegments; + exports.LineLoop = LineLoop; + exports.Line = Line; + exports.Points = Points; + exports.Group = Group; + exports.VideoTexture = VideoTexture; + exports.DataTexture = DataTexture; + exports.CompressedTexture = CompressedTexture; + exports.CubeTexture = CubeTexture; + exports.CanvasTexture = CanvasTexture; + exports.DepthTexture = DepthTexture; + exports.Texture = Texture; + exports.CompressedTextureLoader = CompressedTextureLoader; + exports.DataTextureLoader = DataTextureLoader; + exports.CubeTextureLoader = CubeTextureLoader; + exports.TextureLoader = TextureLoader; + exports.ObjectLoader = ObjectLoader; + exports.MaterialLoader = MaterialLoader; + exports.BufferGeometryLoader = BufferGeometryLoader; + exports.DefaultLoadingManager = DefaultLoadingManager; + exports.LoadingManager = LoadingManager; + exports.JSONLoader = JSONLoader; + exports.ImageLoader = ImageLoader; + exports.ImageBitmapLoader = ImageBitmapLoader; + exports.FontLoader = FontLoader; + exports.FileLoader = FileLoader; + exports.Loader = Loader; + exports.LoaderUtils = LoaderUtils; + exports.Cache = Cache; + exports.AudioLoader = AudioLoader; + exports.SpotLightShadow = SpotLightShadow; + exports.SpotLight = SpotLight; + exports.PointLight = PointLight; + exports.RectAreaLight = RectAreaLight; + exports.HemisphereLight = HemisphereLight; + exports.DirectionalLightShadow = DirectionalLightShadow; + exports.DirectionalLight = DirectionalLight; + exports.AmbientLight = AmbientLight; + exports.LightShadow = LightShadow; + exports.Light = Light; + exports.StereoCamera = StereoCamera; + exports.PerspectiveCamera = PerspectiveCamera; + exports.OrthographicCamera = OrthographicCamera; + exports.CubeCamera = CubeCamera; + exports.ArrayCamera = ArrayCamera; + exports.Camera = Camera; + exports.AudioListener = AudioListener; + exports.PositionalAudio = PositionalAudio; + exports.AudioContext = AudioContext; + exports.AudioAnalyser = AudioAnalyser; + exports.Audio = Audio; + exports.VectorKeyframeTrack = VectorKeyframeTrack; + exports.StringKeyframeTrack = StringKeyframeTrack; + exports.QuaternionKeyframeTrack = QuaternionKeyframeTrack; + exports.NumberKeyframeTrack = NumberKeyframeTrack; + exports.ColorKeyframeTrack = ColorKeyframeTrack; + exports.BooleanKeyframeTrack = BooleanKeyframeTrack; + exports.PropertyMixer = PropertyMixer; + exports.PropertyBinding = PropertyBinding; + exports.KeyframeTrack = KeyframeTrack; + exports.AnimationUtils = AnimationUtils; + exports.AnimationObjectGroup = AnimationObjectGroup; + exports.AnimationMixer = AnimationMixer; + exports.AnimationClip = AnimationClip; + exports.Uniform = Uniform; + exports.InstancedBufferGeometry = InstancedBufferGeometry; + exports.BufferGeometry = BufferGeometry; + exports.Geometry = Geometry; + exports.InterleavedBufferAttribute = InterleavedBufferAttribute; + exports.InstancedInterleavedBuffer = InstancedInterleavedBuffer; + exports.InterleavedBuffer = InterleavedBuffer; + exports.InstancedBufferAttribute = InstancedBufferAttribute; + exports.Face3 = Face3; + exports.Object3D = Object3D; + exports.Raycaster = Raycaster; + exports.Layers = Layers; + exports.EventDispatcher = EventDispatcher; + exports.Clock = Clock; + exports.QuaternionLinearInterpolant = QuaternionLinearInterpolant; + exports.LinearInterpolant = LinearInterpolant; + exports.DiscreteInterpolant = DiscreteInterpolant; + exports.CubicInterpolant = CubicInterpolant; + exports.Interpolant = Interpolant; + exports.Triangle = Triangle; + exports.Math = _Math; + exports.Spherical = Spherical; + exports.Cylindrical = Cylindrical; + exports.Plane = Plane; + exports.Frustum = Frustum; + exports.Sphere = Sphere; + exports.Ray = Ray; + exports.Matrix4 = Matrix4; + exports.Matrix3 = Matrix3; + exports.Box3 = Box3; + exports.Box2 = Box2; + exports.Line3 = Line3; + exports.Euler = Euler; + exports.Vector4 = Vector4; + exports.Vector3 = Vector3; + exports.Vector2 = Vector2; + exports.Quaternion = Quaternion; + exports.Color = Color; + exports.ImmediateRenderObject = ImmediateRenderObject; + exports.VertexNormalsHelper = VertexNormalsHelper; + exports.SpotLightHelper = SpotLightHelper; + exports.SkeletonHelper = SkeletonHelper; + exports.PointLightHelper = PointLightHelper; + exports.RectAreaLightHelper = RectAreaLightHelper; + exports.HemisphereLightHelper = HemisphereLightHelper; + exports.GridHelper = GridHelper; + exports.PolarGridHelper = PolarGridHelper; + exports.FaceNormalsHelper = FaceNormalsHelper; + exports.DirectionalLightHelper = DirectionalLightHelper; + exports.CameraHelper = CameraHelper; + exports.BoxHelper = BoxHelper; + exports.Box3Helper = Box3Helper; + exports.PlaneHelper = PlaneHelper; + exports.ArrowHelper = ArrowHelper; + exports.AxesHelper = AxesHelper; + exports.Shape = Shape; + exports.Path = Path; + exports.ShapePath = ShapePath; + exports.Font = Font; + exports.CurvePath = CurvePath; + exports.Curve = Curve; + exports.ImageUtils = ImageUtils; + exports.ShapeUtils = ShapeUtils; + exports.WebGLUtils = WebGLUtils; + exports.WireframeGeometry = WireframeGeometry; + exports.ParametricGeometry = ParametricGeometry; + exports.ParametricBufferGeometry = ParametricBufferGeometry; + exports.TetrahedronGeometry = TetrahedronGeometry; + exports.TetrahedronBufferGeometry = TetrahedronBufferGeometry; + exports.OctahedronGeometry = OctahedronGeometry; + exports.OctahedronBufferGeometry = OctahedronBufferGeometry; + exports.IcosahedronGeometry = IcosahedronGeometry; + exports.IcosahedronBufferGeometry = IcosahedronBufferGeometry; + exports.DodecahedronGeometry = DodecahedronGeometry; + exports.DodecahedronBufferGeometry = DodecahedronBufferGeometry; + exports.PolyhedronGeometry = PolyhedronGeometry; + exports.PolyhedronBufferGeometry = PolyhedronBufferGeometry; + exports.TubeGeometry = TubeGeometry; + exports.TubeBufferGeometry = TubeBufferGeometry; + exports.TorusKnotGeometry = TorusKnotGeometry; + exports.TorusKnotBufferGeometry = TorusKnotBufferGeometry; + exports.TorusGeometry = TorusGeometry; + exports.TorusBufferGeometry = TorusBufferGeometry; + exports.TextGeometry = TextGeometry; + exports.TextBufferGeometry = TextBufferGeometry; + exports.SphereGeometry = SphereGeometry; + exports.SphereBufferGeometry = SphereBufferGeometry; + exports.RingGeometry = RingGeometry; + exports.RingBufferGeometry = RingBufferGeometry; + exports.PlaneGeometry = PlaneGeometry; + exports.PlaneBufferGeometry = PlaneBufferGeometry; + exports.LatheGeometry = LatheGeometry; + exports.LatheBufferGeometry = LatheBufferGeometry; + exports.ShapeGeometry = ShapeGeometry; + exports.ShapeBufferGeometry = ShapeBufferGeometry; + exports.ExtrudeGeometry = ExtrudeGeometry; + exports.ExtrudeBufferGeometry = ExtrudeBufferGeometry; + exports.EdgesGeometry = EdgesGeometry; + exports.ConeGeometry = ConeGeometry; + exports.ConeBufferGeometry = ConeBufferGeometry; + exports.CylinderGeometry = CylinderGeometry; + exports.CylinderBufferGeometry = CylinderBufferGeometry; + exports.CircleGeometry = CircleGeometry; + exports.CircleBufferGeometry = CircleBufferGeometry; + exports.BoxGeometry = BoxGeometry; + exports.BoxBufferGeometry = BoxBufferGeometry; + exports.ShadowMaterial = ShadowMaterial; + exports.SpriteMaterial = SpriteMaterial; + exports.RawShaderMaterial = RawShaderMaterial; + exports.ShaderMaterial = ShaderMaterial; + exports.PointsMaterial = PointsMaterial; + exports.MeshPhysicalMaterial = MeshPhysicalMaterial; + exports.MeshStandardMaterial = MeshStandardMaterial; + exports.MeshPhongMaterial = MeshPhongMaterial; + exports.MeshToonMaterial = MeshToonMaterial; + exports.MeshNormalMaterial = MeshNormalMaterial; + exports.MeshLambertMaterial = MeshLambertMaterial; + exports.MeshDepthMaterial = MeshDepthMaterial; + exports.MeshDistanceMaterial = MeshDistanceMaterial; + exports.MeshBasicMaterial = MeshBasicMaterial; + exports.LineDashedMaterial = LineDashedMaterial; + exports.LineBasicMaterial = LineBasicMaterial; + exports.Material = Material; + exports.Float64BufferAttribute = Float64BufferAttribute; + exports.Float32BufferAttribute = Float32BufferAttribute; + exports.Uint32BufferAttribute = Uint32BufferAttribute; + exports.Int32BufferAttribute = Int32BufferAttribute; + exports.Uint16BufferAttribute = Uint16BufferAttribute; + exports.Int16BufferAttribute = Int16BufferAttribute; + exports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute; + exports.Uint8BufferAttribute = Uint8BufferAttribute; + exports.Int8BufferAttribute = Int8BufferAttribute; + exports.BufferAttribute = BufferAttribute; + exports.ArcCurve = ArcCurve; + exports.CatmullRomCurve3 = CatmullRomCurve3; + exports.CubicBezierCurve = CubicBezierCurve; + exports.CubicBezierCurve3 = CubicBezierCurve3; + exports.EllipseCurve = EllipseCurve; + exports.LineCurve = LineCurve; + exports.LineCurve3 = LineCurve3; + exports.QuadraticBezierCurve = QuadraticBezierCurve; + exports.QuadraticBezierCurve3 = QuadraticBezierCurve3; + exports.SplineCurve = SplineCurve; + exports.REVISION = REVISION; + exports.MOUSE = MOUSE; + exports.CullFaceNone = CullFaceNone; + exports.CullFaceBack = CullFaceBack; + exports.CullFaceFront = CullFaceFront; + exports.CullFaceFrontBack = CullFaceFrontBack; + exports.FrontFaceDirectionCW = FrontFaceDirectionCW; + exports.FrontFaceDirectionCCW = FrontFaceDirectionCCW; + exports.BasicShadowMap = BasicShadowMap; + exports.PCFShadowMap = PCFShadowMap; + exports.PCFSoftShadowMap = PCFSoftShadowMap; + exports.FrontSide = FrontSide; + exports.BackSide = BackSide; + exports.DoubleSide = DoubleSide; + exports.FlatShading = FlatShading; + exports.SmoothShading = SmoothShading; + exports.NoColors = NoColors; + exports.FaceColors = FaceColors; + exports.VertexColors = VertexColors; + exports.NoBlending = NoBlending; + exports.NormalBlending = NormalBlending; + exports.AdditiveBlending = AdditiveBlending; + exports.SubtractiveBlending = SubtractiveBlending; + exports.MultiplyBlending = MultiplyBlending; + exports.CustomBlending = CustomBlending; + exports.AddEquation = AddEquation; + exports.SubtractEquation = SubtractEquation; + exports.ReverseSubtractEquation = ReverseSubtractEquation; + exports.MinEquation = MinEquation; + exports.MaxEquation = MaxEquation; + exports.ZeroFactor = ZeroFactor; + exports.OneFactor = OneFactor; + exports.SrcColorFactor = SrcColorFactor; + exports.OneMinusSrcColorFactor = OneMinusSrcColorFactor; + exports.SrcAlphaFactor = SrcAlphaFactor; + exports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor; + exports.DstAlphaFactor = DstAlphaFactor; + exports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor; + exports.DstColorFactor = DstColorFactor; + exports.OneMinusDstColorFactor = OneMinusDstColorFactor; + exports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor; + exports.NeverDepth = NeverDepth; + exports.AlwaysDepth = AlwaysDepth; + exports.LessDepth = LessDepth; + exports.LessEqualDepth = LessEqualDepth; + exports.EqualDepth = EqualDepth; + exports.GreaterEqualDepth = GreaterEqualDepth; + exports.GreaterDepth = GreaterDepth; + exports.NotEqualDepth = NotEqualDepth; + exports.MultiplyOperation = MultiplyOperation; + exports.MixOperation = MixOperation; + exports.AddOperation = AddOperation; + exports.NoToneMapping = NoToneMapping; + exports.LinearToneMapping = LinearToneMapping; + exports.ReinhardToneMapping = ReinhardToneMapping; + exports.Uncharted2ToneMapping = Uncharted2ToneMapping; + exports.CineonToneMapping = CineonToneMapping; + exports.UVMapping = UVMapping; + exports.CubeReflectionMapping = CubeReflectionMapping; + exports.CubeRefractionMapping = CubeRefractionMapping; + exports.EquirectangularReflectionMapping = EquirectangularReflectionMapping; + exports.EquirectangularRefractionMapping = EquirectangularRefractionMapping; + exports.SphericalReflectionMapping = SphericalReflectionMapping; + exports.CubeUVReflectionMapping = CubeUVReflectionMapping; + exports.CubeUVRefractionMapping = CubeUVRefractionMapping; + exports.RepeatWrapping = RepeatWrapping; + exports.ClampToEdgeWrapping = ClampToEdgeWrapping; + exports.MirroredRepeatWrapping = MirroredRepeatWrapping; + exports.NearestFilter = NearestFilter; + exports.NearestMipMapNearestFilter = NearestMipMapNearestFilter; + exports.NearestMipMapLinearFilter = NearestMipMapLinearFilter; + exports.LinearFilter = LinearFilter; + exports.LinearMipMapNearestFilter = LinearMipMapNearestFilter; + exports.LinearMipMapLinearFilter = LinearMipMapLinearFilter; + exports.UnsignedByteType = UnsignedByteType; + exports.ByteType = ByteType; + exports.ShortType = ShortType; + exports.UnsignedShortType = UnsignedShortType; + exports.IntType = IntType; + exports.UnsignedIntType = UnsignedIntType; + exports.FloatType = FloatType; + exports.HalfFloatType = HalfFloatType; + exports.UnsignedShort4444Type = UnsignedShort4444Type; + exports.UnsignedShort5551Type = UnsignedShort5551Type; + exports.UnsignedShort565Type = UnsignedShort565Type; + exports.UnsignedInt248Type = UnsignedInt248Type; + exports.AlphaFormat = AlphaFormat; + exports.RGBFormat = RGBFormat; + exports.RGBAFormat = RGBAFormat; + exports.LuminanceFormat = LuminanceFormat; + exports.LuminanceAlphaFormat = LuminanceAlphaFormat; + exports.RGBEFormat = RGBEFormat; + exports.DepthFormat = DepthFormat; + exports.DepthStencilFormat = DepthStencilFormat; + exports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format; + exports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format; + exports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format; + exports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format; + exports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format; + exports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format; + exports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format; + exports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format; + exports.RGB_ETC1_Format = RGB_ETC1_Format; + exports.RGBA_ASTC_4x4_Format = RGBA_ASTC_4x4_Format; + exports.RGBA_ASTC_5x4_Format = RGBA_ASTC_5x4_Format; + exports.RGBA_ASTC_5x5_Format = RGBA_ASTC_5x5_Format; + exports.RGBA_ASTC_6x5_Format = RGBA_ASTC_6x5_Format; + exports.RGBA_ASTC_6x6_Format = RGBA_ASTC_6x6_Format; + exports.RGBA_ASTC_8x5_Format = RGBA_ASTC_8x5_Format; + exports.RGBA_ASTC_8x6_Format = RGBA_ASTC_8x6_Format; + exports.RGBA_ASTC_8x8_Format = RGBA_ASTC_8x8_Format; + exports.RGBA_ASTC_10x5_Format = RGBA_ASTC_10x5_Format; + exports.RGBA_ASTC_10x6_Format = RGBA_ASTC_10x6_Format; + exports.RGBA_ASTC_10x8_Format = RGBA_ASTC_10x8_Format; + exports.RGBA_ASTC_10x10_Format = RGBA_ASTC_10x10_Format; + exports.RGBA_ASTC_12x10_Format = RGBA_ASTC_12x10_Format; + exports.RGBA_ASTC_12x12_Format = RGBA_ASTC_12x12_Format; + exports.LoopOnce = LoopOnce; + exports.LoopRepeat = LoopRepeat; + exports.LoopPingPong = LoopPingPong; + exports.InterpolateDiscrete = InterpolateDiscrete; + exports.InterpolateLinear = InterpolateLinear; + exports.InterpolateSmooth = InterpolateSmooth; + exports.ZeroCurvatureEnding = ZeroCurvatureEnding; + exports.ZeroSlopeEnding = ZeroSlopeEnding; + exports.WrapAroundEnding = WrapAroundEnding; + exports.TrianglesDrawMode = TrianglesDrawMode; + exports.TriangleStripDrawMode = TriangleStripDrawMode; + exports.TriangleFanDrawMode = TriangleFanDrawMode; + exports.LinearEncoding = LinearEncoding; + exports.sRGBEncoding = sRGBEncoding; + exports.GammaEncoding = GammaEncoding; + exports.RGBEEncoding = RGBEEncoding; + exports.LogLuvEncoding = LogLuvEncoding; + exports.RGBM7Encoding = RGBM7Encoding; + exports.RGBM16Encoding = RGBM16Encoding; + exports.RGBDEncoding = RGBDEncoding; + exports.BasicDepthPacking = BasicDepthPacking; + exports.RGBADepthPacking = RGBADepthPacking; + exports.TangentSpaceNormalMap = TangentSpaceNormalMap; + exports.ObjectSpaceNormalMap = ObjectSpaceNormalMap; + exports.CubeGeometry = BoxGeometry; + exports.Face4 = Face4; + exports.LineStrip = LineStrip; + exports.LinePieces = LinePieces; + exports.MeshFaceMaterial = MeshFaceMaterial; + exports.MultiMaterial = MultiMaterial; + exports.PointCloud = PointCloud; + exports.Particle = Particle; + exports.ParticleSystem = ParticleSystem; + exports.PointCloudMaterial = PointCloudMaterial; + exports.ParticleBasicMaterial = ParticleBasicMaterial; + exports.ParticleSystemMaterial = ParticleSystemMaterial; + exports.Vertex = Vertex; + exports.DynamicBufferAttribute = DynamicBufferAttribute; + exports.Int8Attribute = Int8Attribute; + exports.Uint8Attribute = Uint8Attribute; + exports.Uint8ClampedAttribute = Uint8ClampedAttribute; + exports.Int16Attribute = Int16Attribute; + exports.Uint16Attribute = Uint16Attribute; + exports.Int32Attribute = Int32Attribute; + exports.Uint32Attribute = Uint32Attribute; + exports.Float32Attribute = Float32Attribute; + exports.Float64Attribute = Float64Attribute; + exports.ClosedSplineCurve3 = ClosedSplineCurve3; + exports.SplineCurve3 = SplineCurve3; + exports.Spline = Spline; + exports.AxisHelper = AxisHelper; + exports.BoundingBoxHelper = BoundingBoxHelper; + exports.EdgesHelper = EdgesHelper; + exports.WireframeHelper = WireframeHelper; + exports.XHRLoader = XHRLoader; + exports.BinaryTextureLoader = BinaryTextureLoader; + exports.GeometryUtils = GeometryUtils; + exports.Projector = Projector; + exports.CanvasRenderer = CanvasRenderer; + exports.SceneUtils = SceneUtils; + exports.LensFlare = LensFlare; + + Object.defineProperty(exports, '__esModule', { value: true }); }))); -},{}],40:[function(_dereq_,module,exports){ +},{}],37:[function(_dereq_,module,exports){ /** * @author mrdoob / http://mrdoob.com/ * @author Mugen87 / https://github.com/Mugen87 @@ -51847,3889 +51493,3889 @@ function rebuildAttribute (attrib, data, itemSize) { THREE.ColladaLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; }; THREE.ColladaLoader.prototype = { - constructor: THREE.ColladaLoader, + constructor: THREE.ColladaLoader, - crossOrigin: 'anonymous', + crossOrigin: 'anonymous', - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - var scope = this; + var scope = this; - var path = scope.path === undefined ? THREE.LoaderUtils.extractUrlBase( url ) : scope.path; + var path = scope.path === undefined ? THREE.LoaderUtils.extractUrlBase( url ) : scope.path; - var loader = new THREE.FileLoader( scope.manager ); - loader.load( url, function ( text ) { + var loader = new THREE.FileLoader( scope.manager ); + loader.load( url, function ( text ) { - onLoad( scope.parse( text, path ) ); + onLoad( scope.parse( text, path ) ); - }, onProgress, onError ); + }, onProgress, onError ); - }, + }, - setPath: function ( value ) { + setPath: function ( value ) { - this.path = value; - return this; + this.path = value; + return this; - }, + }, - options: { + options: { - set convertUpAxis( value ) { + set convertUpAxis( value ) { - console.warn( 'THREE.ColladaLoader: options.convertUpAxis() has been removed. Up axis is converted automatically.' ); + console.warn( 'THREE.ColladaLoader: options.convertUpAxis() has been removed. Up axis is converted automatically.' ); - } + } - }, + }, - setCrossOrigin: function ( value ) { + setCrossOrigin: function ( value ) { - this.crossOrigin = value; - return this; + this.crossOrigin = value; + return this; - }, + }, - parse: function ( text, path ) { + parse: function ( text, path ) { - function getElementsByTagName( xml, name ) { + function getElementsByTagName( xml, name ) { - // Non recursive xml.getElementsByTagName() ... + // Non recursive xml.getElementsByTagName() ... - var array = []; - var childNodes = xml.childNodes; + var array = []; + var childNodes = xml.childNodes; - for ( var i = 0, l = childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = childNodes.length; i < l; i ++ ) { - var child = childNodes[ i ]; + var child = childNodes[ i ]; - if ( child.nodeName === name ) { + if ( child.nodeName === name ) { - array.push( child ); + array.push( child ); - } + } - } + } - return array; + return array; - } + } - function parseStrings( text ) { + function parseStrings( text ) { - if ( text.length === 0 ) return []; + if ( text.length === 0 ) return []; - var parts = text.trim().split( /\s+/ ); - var array = new Array( parts.length ); + var parts = text.trim().split( /\s+/ ); + var array = new Array( parts.length ); - for ( var i = 0, l = parts.length; i < l; i ++ ) { + for ( var i = 0, l = parts.length; i < l; i ++ ) { - array[ i ] = parts[ i ]; + array[ i ] = parts[ i ]; - } + } - return array; + return array; - } + } - function parseFloats( text ) { + function parseFloats( text ) { - if ( text.length === 0 ) return []; + if ( text.length === 0 ) return []; - var parts = text.trim().split( /\s+/ ); - var array = new Array( parts.length ); + var parts = text.trim().split( /\s+/ ); + var array = new Array( parts.length ); - for ( var i = 0, l = parts.length; i < l; i ++ ) { + for ( var i = 0, l = parts.length; i < l; i ++ ) { - array[ i ] = parseFloat( parts[ i ] ); + array[ i ] = parseFloat( parts[ i ] ); - } + } - return array; + return array; - } + } - function parseInts( text ) { + function parseInts( text ) { - if ( text.length === 0 ) return []; + if ( text.length === 0 ) return []; - var parts = text.trim().split( /\s+/ ); - var array = new Array( parts.length ); + var parts = text.trim().split( /\s+/ ); + var array = new Array( parts.length ); - for ( var i = 0, l = parts.length; i < l; i ++ ) { + for ( var i = 0, l = parts.length; i < l; i ++ ) { - array[ i ] = parseInt( parts[ i ] ); + array[ i ] = parseInt( parts[ i ] ); - } + } - return array; + return array; - } + } - function parseId( text ) { + function parseId( text ) { - return text.substring( 1 ); + return text.substring( 1 ); - } + } - function generateId() { + function generateId() { - return 'three_default_' + ( count ++ ); + return 'three_default_' + ( count ++ ); - } + } - function isEmpty( object ) { + function isEmpty( object ) { - return Object.keys( object ).length === 0; + return Object.keys( object ).length === 0; - } + } - // asset + // asset - function parseAsset( xml ) { + function parseAsset( xml ) { - return { - unit: parseAssetUnit( getElementsByTagName( xml, 'unit' )[ 0 ] ), - upAxis: parseAssetUpAxis( getElementsByTagName( xml, 'up_axis' )[ 0 ] ) - }; + return { + unit: parseAssetUnit( getElementsByTagName( xml, 'unit' )[ 0 ] ), + upAxis: parseAssetUpAxis( getElementsByTagName( xml, 'up_axis' )[ 0 ] ) + }; - } + } - function parseAssetUnit( xml ) { + function parseAssetUnit( xml ) { - if ( ( xml !== undefined ) && ( xml.hasAttribute( 'meter' ) === true ) ) { + if ( ( xml !== undefined ) && ( xml.hasAttribute( 'meter' ) === true ) ) { - return parseFloat( xml.getAttribute( 'meter' ) ); + return parseFloat( xml.getAttribute( 'meter' ) ); - } else { + } else { - return 1; // default 1 meter + return 1; // default 1 meter - } + } - } + } - function parseAssetUpAxis( xml ) { + function parseAssetUpAxis( xml ) { - return xml !== undefined ? xml.textContent : 'Y_UP'; + return xml !== undefined ? xml.textContent : 'Y_UP'; - } + } - // library + // library - function parseLibrary( xml, libraryName, nodeName, parser ) { + function parseLibrary( xml, libraryName, nodeName, parser ) { - var library = getElementsByTagName( xml, libraryName )[ 0 ]; + var library = getElementsByTagName( xml, libraryName )[ 0 ]; - if ( library !== undefined ) { + if ( library !== undefined ) { - var elements = getElementsByTagName( library, nodeName ); + var elements = getElementsByTagName( library, nodeName ); - for ( var i = 0; i < elements.length; i ++ ) { + for ( var i = 0; i < elements.length; i ++ ) { - parser( elements[ i ] ); + parser( elements[ i ] ); - } + } - } + } - } + } - function buildLibrary( data, builder ) { + function buildLibrary( data, builder ) { - for ( var name in data ) { + for ( var name in data ) { - var object = data[ name ]; - object.build = builder( data[ name ] ); + var object = data[ name ]; + object.build = builder( data[ name ] ); - } + } - } + } - // get + // get - function getBuild( data, builder ) { + function getBuild( data, builder ) { - if ( data.build !== undefined ) return data.build; + if ( data.build !== undefined ) return data.build; - data.build = builder( data ); + data.build = builder( data ); - return data.build; + return data.build; - } + } - // animation + // animation - function parseAnimation( xml ) { + function parseAnimation( xml ) { - var data = { - sources: {}, - samplers: {}, - channels: {} - }; + var data = { + sources: {}, + samplers: {}, + channels: {} + }; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - var id; + var id; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'source': - id = child.getAttribute( 'id' ); - data.sources[ id ] = parseSource( child ); - break; + case 'source': + id = child.getAttribute( 'id' ); + data.sources[ id ] = parseSource( child ); + break; - case 'sampler': - id = child.getAttribute( 'id' ); - data.samplers[ id ] = parseAnimationSampler( child ); - break; + case 'sampler': + id = child.getAttribute( 'id' ); + data.samplers[ id ] = parseAnimationSampler( child ); + break; - case 'channel': - id = child.getAttribute( 'target' ); - data.channels[ id ] = parseAnimationChannel( child ); - break; + case 'channel': + id = child.getAttribute( 'target' ); + data.channels[ id ] = parseAnimationChannel( child ); + break; - default: - console.log( child ); + default: + console.log( child ); - } + } - } + } - library.animations[ xml.getAttribute( 'id' ) ] = data; + library.animations[ xml.getAttribute( 'id' ) ] = data; - } + } - function parseAnimationSampler( xml ) { + function parseAnimationSampler( xml ) { - var data = { - inputs: {}, - }; + var data = { + inputs: {}, + }; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'input': - var id = parseId( child.getAttribute( 'source' ) ); - var semantic = child.getAttribute( 'semantic' ); - data.inputs[ semantic ] = id; - break; + case 'input': + var id = parseId( child.getAttribute( 'source' ) ); + var semantic = child.getAttribute( 'semantic' ); + data.inputs[ semantic ] = id; + break; - } + } - } + } - return data; + return data; - } + } - function parseAnimationChannel( xml ) { + function parseAnimationChannel( xml ) { - var data = {}; + var data = {}; - var target = xml.getAttribute( 'target' ); + var target = xml.getAttribute( 'target' ); - // parsing SID Addressing Syntax + // parsing SID Addressing Syntax - var parts = target.split( '/' ); + var parts = target.split( '/' ); - var id = parts.shift(); - var sid = parts.shift(); + var id = parts.shift(); + var sid = parts.shift(); - // check selection syntax + // check selection syntax - var arraySyntax = ( sid.indexOf( '(' ) !== - 1 ); - var memberSyntax = ( sid.indexOf( '.' ) !== - 1 ); + var arraySyntax = ( sid.indexOf( '(' ) !== - 1 ); + var memberSyntax = ( sid.indexOf( '.' ) !== - 1 ); - if ( memberSyntax ) { + if ( memberSyntax ) { - // member selection access + // member selection access - parts = sid.split( '.' ); - sid = parts.shift(); - data.member = parts.shift(); + parts = sid.split( '.' ); + sid = parts.shift(); + data.member = parts.shift(); - } else if ( arraySyntax ) { + } else if ( arraySyntax ) { - // array-access syntax. can be used to express fields in one-dimensional vectors or two-dimensional matrices. + // array-access syntax. can be used to express fields in one-dimensional vectors or two-dimensional matrices. - var indices = sid.split( '(' ); - sid = indices.shift(); + var indices = sid.split( '(' ); + sid = indices.shift(); - for ( var i = 0; i < indices.length; i ++ ) { + for ( var i = 0; i < indices.length; i ++ ) { - indices[ i ] = parseInt( indices[ i ].replace( /\)/, '' ) ); + indices[ i ] = parseInt( indices[ i ].replace( /\)/, '' ) ); - } + } - data.indices = indices; + data.indices = indices; - } + } - data.id = id; - data.sid = sid; + data.id = id; + data.sid = sid; - data.arraySyntax = arraySyntax; - data.memberSyntax = memberSyntax; + data.arraySyntax = arraySyntax; + data.memberSyntax = memberSyntax; - data.sampler = parseId( xml.getAttribute( 'source' ) ); + data.sampler = parseId( xml.getAttribute( 'source' ) ); - return data; + return data; - } + } - function buildAnimation( data ) { + function buildAnimation( data ) { - var tracks = []; + var tracks = []; - var channels = data.channels; - var samplers = data.samplers; - var sources = data.sources; + var channels = data.channels; + var samplers = data.samplers; + var sources = data.sources; - for ( var target in channels ) { + for ( var target in channels ) { - if ( channels.hasOwnProperty( target ) ) { + if ( channels.hasOwnProperty( target ) ) { - var channel = channels[ target ]; - var sampler = samplers[ channel.sampler ]; + var channel = channels[ target ]; + var sampler = samplers[ channel.sampler ]; - var inputId = sampler.inputs.INPUT; - var outputId = sampler.inputs.OUTPUT; + var inputId = sampler.inputs.INPUT; + var outputId = sampler.inputs.OUTPUT; - var inputSource = sources[ inputId ]; - var outputSource = sources[ outputId ]; + var inputSource = sources[ inputId ]; + var outputSource = sources[ outputId ]; - var animation = buildAnimationChannel( channel, inputSource, outputSource ); + var animation = buildAnimationChannel( channel, inputSource, outputSource ); - createKeyframeTracks( animation, tracks ); + createKeyframeTracks( animation, tracks ); - } + } - } + } - return tracks; + return tracks; - } + } - function getAnimation( id ) { + function getAnimation( id ) { - return getBuild( library.animations[ id ], buildAnimation ); + return getBuild( library.animations[ id ], buildAnimation ); - } + } - function buildAnimationChannel( channel, inputSource, outputSource ) { + function buildAnimationChannel( channel, inputSource, outputSource ) { - var node = library.nodes[ channel.id ]; - var object3D = getNode( node.id ); + var node = library.nodes[ channel.id ]; + var object3D = getNode( node.id ); - var transform = node.transforms[ channel.sid ]; - var defaultMatrix = node.matrix.clone().transpose(); + var transform = node.transforms[ channel.sid ]; + var defaultMatrix = node.matrix.clone().transpose(); - var time, stride; - var i, il, j, jl; + var time, stride; + var i, il, j, jl; - var data = {}; + var data = {}; - // the collada spec allows the animation of data in various ways. - // depending on the transform type (matrix, translate, rotate, scale), we execute different logic + // the collada spec allows the animation of data in various ways. + // depending on the transform type (matrix, translate, rotate, scale), we execute different logic - switch ( transform ) { + switch ( transform ) { - case 'matrix': + case 'matrix': - for ( i = 0, il = inputSource.array.length; i < il; i ++ ) { + for ( i = 0, il = inputSource.array.length; i < il; i ++ ) { - time = inputSource.array[ i ]; - stride = i * outputSource.stride; + time = inputSource.array[ i ]; + stride = i * outputSource.stride; - if ( data[ time ] === undefined ) data[ time ] = {}; + if ( data[ time ] === undefined ) data[ time ] = {}; - if ( channel.arraySyntax === true ) { + if ( channel.arraySyntax === true ) { - var value = outputSource.array[ stride ]; - var index = channel.indices[ 0 ] + 4 * channel.indices[ 1 ]; + var value = outputSource.array[ stride ]; + var index = channel.indices[ 0 ] + 4 * channel.indices[ 1 ]; - data[ time ][ index ] = value; + data[ time ][ index ] = value; - } else { + } else { - for ( j = 0, jl = outputSource.stride; j < jl; j ++ ) { + for ( j = 0, jl = outputSource.stride; j < jl; j ++ ) { - data[ time ][ j ] = outputSource.array[ stride + j ]; + data[ time ][ j ] = outputSource.array[ stride + j ]; - } + } - } + } - } + } - break; + break; - case 'translate': - console.warn( 'THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform ); - break; + case 'translate': + console.warn( 'THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform ); + break; - case 'rotate': - console.warn( 'THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform ); - break; + case 'rotate': + console.warn( 'THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform ); + break; - case 'scale': - console.warn( 'THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform ); - break; + case 'scale': + console.warn( 'THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform ); + break; - } + } - var keyframes = prepareAnimationData( data, defaultMatrix ); + var keyframes = prepareAnimationData( data, defaultMatrix ); - var animation = { - name: object3D.uuid, - keyframes: keyframes - }; + var animation = { + name: object3D.uuid, + keyframes: keyframes + }; - return animation; + return animation; - } + } - function prepareAnimationData( data, defaultMatrix ) { + function prepareAnimationData( data, defaultMatrix ) { - var keyframes = []; + var keyframes = []; - // transfer data into a sortable array + // transfer data into a sortable array - for ( var time in data ) { + for ( var time in data ) { - keyframes.push( { time: parseFloat( time ), value: data[ time ] } ); + keyframes.push( { time: parseFloat( time ), value: data[ time ] } ); - } + } - // ensure keyframes are sorted by time + // ensure keyframes are sorted by time - keyframes.sort( ascending ); + keyframes.sort( ascending ); - // now we clean up all animation data, so we can use them for keyframe tracks + // now we clean up all animation data, so we can use them for keyframe tracks - for ( var i = 0; i < 16; i ++ ) { + for ( var i = 0; i < 16; i ++ ) { - transformAnimationData( keyframes, i, defaultMatrix.elements[ i ] ); + transformAnimationData( keyframes, i, defaultMatrix.elements[ i ] ); - } + } - return keyframes; + return keyframes; - // array sort function + // array sort function - function ascending( a, b ) { + function ascending( a, b ) { - return a.time - b.time; + return a.time - b.time; - } + } - } + } - var position = new THREE.Vector3(); - var scale = new THREE.Vector3(); - var quaternion = new THREE.Quaternion(); + var position = new THREE.Vector3(); + var scale = new THREE.Vector3(); + var quaternion = new THREE.Quaternion(); - function createKeyframeTracks( animation, tracks ) { + function createKeyframeTracks( animation, tracks ) { - var keyframes = animation.keyframes; - var name = animation.name; + var keyframes = animation.keyframes; + var name = animation.name; - var times = []; - var positionData = []; - var quaternionData = []; - var scaleData = []; + var times = []; + var positionData = []; + var quaternionData = []; + var scaleData = []; - for ( var i = 0, l = keyframes.length; i < l; i ++ ) { + for ( var i = 0, l = keyframes.length; i < l; i ++ ) { - var keyframe = keyframes[ i ]; + var keyframe = keyframes[ i ]; - var time = keyframe.time; - var value = keyframe.value; + var time = keyframe.time; + var value = keyframe.value; - matrix.fromArray( value ).transpose(); - matrix.decompose( position, quaternion, scale ); + matrix.fromArray( value ).transpose(); + matrix.decompose( position, quaternion, scale ); - times.push( time ); - positionData.push( position.x, position.y, position.z ); - quaternionData.push( quaternion.x, quaternion.y, quaternion.z, quaternion.w ); - scaleData.push( scale.x, scale.y, scale.z ); + times.push( time ); + positionData.push( position.x, position.y, position.z ); + quaternionData.push( quaternion.x, quaternion.y, quaternion.z, quaternion.w ); + scaleData.push( scale.x, scale.y, scale.z ); - } + } - if ( positionData.length > 0 ) tracks.push( new THREE.VectorKeyframeTrack( name + '.position', times, positionData ) ); - if ( quaternionData.length > 0 ) tracks.push( new THREE.QuaternionKeyframeTrack( name + '.quaternion', times, quaternionData ) ); - if ( scaleData.length > 0 ) tracks.push( new THREE.VectorKeyframeTrack( name + '.scale', times, scaleData ) ); + if ( positionData.length > 0 ) tracks.push( new THREE.VectorKeyframeTrack( name + '.position', times, positionData ) ); + if ( quaternionData.length > 0 ) tracks.push( new THREE.QuaternionKeyframeTrack( name + '.quaternion', times, quaternionData ) ); + if ( scaleData.length > 0 ) tracks.push( new THREE.VectorKeyframeTrack( name + '.scale', times, scaleData ) ); - return tracks; + return tracks; - } + } - function transformAnimationData( keyframes, property, defaultValue ) { + function transformAnimationData( keyframes, property, defaultValue ) { - var keyframe; + var keyframe; - var empty = true; - var i, l; + var empty = true; + var i, l; - // check, if values of a property are missing in our keyframes + // check, if values of a property are missing in our keyframes - for ( i = 0, l = keyframes.length; i < l; i ++ ) { + for ( i = 0, l = keyframes.length; i < l; i ++ ) { - keyframe = keyframes[ i ]; + keyframe = keyframes[ i ]; - if ( keyframe.value[ property ] === undefined ) { + if ( keyframe.value[ property ] === undefined ) { - keyframe.value[ property ] = null; // mark as missing + keyframe.value[ property ] = null; // mark as missing - } else { + } else { - empty = false; + empty = false; - } + } - } + } - if ( empty === true ) { + if ( empty === true ) { - // no values at all, so we set a default value + // no values at all, so we set a default value - for ( i = 0, l = keyframes.length; i < l; i ++ ) { + for ( i = 0, l = keyframes.length; i < l; i ++ ) { - keyframe = keyframes[ i ]; + keyframe = keyframes[ i ]; - keyframe.value[ property ] = defaultValue; + keyframe.value[ property ] = defaultValue; - } + } - } else { + } else { - // filling gaps + // filling gaps - createMissingKeyframes( keyframes, property ); + createMissingKeyframes( keyframes, property ); - } + } - } + } - function createMissingKeyframes( keyframes, property ) { + function createMissingKeyframes( keyframes, property ) { - var prev, next; + var prev, next; - for ( var i = 0, l = keyframes.length; i < l; i ++ ) { + for ( var i = 0, l = keyframes.length; i < l; i ++ ) { - var keyframe = keyframes[ i ]; + var keyframe = keyframes[ i ]; - if ( keyframe.value[ property ] === null ) { + if ( keyframe.value[ property ] === null ) { - prev = getPrev( keyframes, i, property ); - next = getNext( keyframes, i, property ); + prev = getPrev( keyframes, i, property ); + next = getNext( keyframes, i, property ); - if ( prev === null ) { + if ( prev === null ) { - keyframe.value[ property ] = next.value[ property ]; - continue; + keyframe.value[ property ] = next.value[ property ]; + continue; - } + } - if ( next === null ) { + if ( next === null ) { - keyframe.value[ property ] = prev.value[ property ]; - continue; + keyframe.value[ property ] = prev.value[ property ]; + continue; - } + } - interpolate( keyframe, prev, next, property ); + interpolate( keyframe, prev, next, property ); - } + } - } + } - } + } - function getPrev( keyframes, i, property ) { + function getPrev( keyframes, i, property ) { - while ( i >= 0 ) { + while ( i >= 0 ) { - var keyframe = keyframes[ i ]; + var keyframe = keyframes[ i ]; - if ( keyframe.value[ property ] !== null ) return keyframe; + if ( keyframe.value[ property ] !== null ) return keyframe; - i --; + i --; - } + } - return null; + return null; - } + } - function getNext( keyframes, i, property ) { + function getNext( keyframes, i, property ) { - while ( i < keyframes.length ) { + while ( i < keyframes.length ) { - var keyframe = keyframes[ i ]; + var keyframe = keyframes[ i ]; - if ( keyframe.value[ property ] !== null ) return keyframe; + if ( keyframe.value[ property ] !== null ) return keyframe; - i ++; + i ++; - } + } - return null; + return null; - } + } - function interpolate( key, prev, next, property ) { + function interpolate( key, prev, next, property ) { - if ( ( next.time - prev.time ) === 0 ) { + if ( ( next.time - prev.time ) === 0 ) { - key.value[ property ] = prev.value[ property ]; - return; + key.value[ property ] = prev.value[ property ]; + return; - } + } - key.value[ property ] = ( ( key.time - prev.time ) * ( next.value[ property ] - prev.value[ property ] ) / ( next.time - prev.time ) ) + prev.value[ property ]; + key.value[ property ] = ( ( key.time - prev.time ) * ( next.value[ property ] - prev.value[ property ] ) / ( next.time - prev.time ) ) + prev.value[ property ]; - } + } - // animation clips + // animation clips - function parseAnimationClip( xml ) { + function parseAnimationClip( xml ) { - var data = { - name: xml.getAttribute( 'id' ) || 'default', - start: parseFloat( xml.getAttribute( 'start' ) || 0 ), - end: parseFloat( xml.getAttribute( 'end' ) || 0 ), - animations: [] - }; + var data = { + name: xml.getAttribute( 'id' ) || 'default', + start: parseFloat( xml.getAttribute( 'start' ) || 0 ), + end: parseFloat( xml.getAttribute( 'end' ) || 0 ), + animations: [] + }; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'instance_animation': - data.animations.push( parseId( child.getAttribute( 'url' ) ) ); - break; + case 'instance_animation': + data.animations.push( parseId( child.getAttribute( 'url' ) ) ); + break; - } + } - } + } - library.clips[ xml.getAttribute( 'id' ) ] = data; + library.clips[ xml.getAttribute( 'id' ) ] = data; - } + } - function buildAnimationClip( data ) { + function buildAnimationClip( data ) { - var tracks = []; + var tracks = []; - var name = data.name; - var duration = ( data.end - data.start ) || - 1; - var animations = data.animations; + var name = data.name; + var duration = ( data.end - data.start ) || - 1; + var animations = data.animations; - for ( var i = 0, il = animations.length; i < il; i ++ ) { + for ( var i = 0, il = animations.length; i < il; i ++ ) { - var animationTracks = getAnimation( animations[ i ] ); + var animationTracks = getAnimation( animations[ i ] ); - for ( var j = 0, jl = animationTracks.length; j < jl; j ++ ) { + for ( var j = 0, jl = animationTracks.length; j < jl; j ++ ) { - tracks.push( animationTracks[ j ] ); + tracks.push( animationTracks[ j ] ); - } + } - } + } - return new THREE.AnimationClip( name, duration, tracks ); + return new THREE.AnimationClip( name, duration, tracks ); - } + } - function getAnimationClip( id ) { + function getAnimationClip( id ) { - return getBuild( library.clips[ id ], buildAnimationClip ); + return getBuild( library.clips[ id ], buildAnimationClip ); - } + } - // controller + // controller - function parseController( xml ) { + function parseController( xml ) { - var data = {}; + var data = {}; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'skin': - // there is exactly one skin per controller - data.id = parseId( child.getAttribute( 'source' ) ); - data.skin = parseSkin( child ); - break; + case 'skin': + // there is exactly one skin per controller + data.id = parseId( child.getAttribute( 'source' ) ); + data.skin = parseSkin( child ); + break; - case 'morph': - data.id = parseId( child.getAttribute( 'source' ) ); - console.warn( 'THREE.ColladaLoader: Morph target animation not supported yet.' ); - break; + case 'morph': + data.id = parseId( child.getAttribute( 'source' ) ); + console.warn( 'THREE.ColladaLoader: Morph target animation not supported yet.' ); + break; - } + } - } + } - library.controllers[ xml.getAttribute( 'id' ) ] = data; + library.controllers[ xml.getAttribute( 'id' ) ] = data; - } + } - function parseSkin( xml ) { + function parseSkin( xml ) { - var data = { - sources: {} - }; + var data = { + sources: {} + }; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'bind_shape_matrix': - data.bindShapeMatrix = parseFloats( child.textContent ); - break; + case 'bind_shape_matrix': + data.bindShapeMatrix = parseFloats( child.textContent ); + break; - case 'source': - var id = child.getAttribute( 'id' ); - data.sources[ id ] = parseSource( child ); - break; + case 'source': + var id = child.getAttribute( 'id' ); + data.sources[ id ] = parseSource( child ); + break; - case 'joints': - data.joints = parseJoints( child ); - break; + case 'joints': + data.joints = parseJoints( child ); + break; - case 'vertex_weights': - data.vertexWeights = parseVertexWeights( child ); - break; + case 'vertex_weights': + data.vertexWeights = parseVertexWeights( child ); + break; - } + } - } + } - return data; + return data; - } + } - function parseJoints( xml ) { + function parseJoints( xml ) { - var data = { - inputs: {} - }; + var data = { + inputs: {} + }; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'input': - var semantic = child.getAttribute( 'semantic' ); - var id = parseId( child.getAttribute( 'source' ) ); - data.inputs[ semantic ] = id; - break; + case 'input': + var semantic = child.getAttribute( 'semantic' ); + var id = parseId( child.getAttribute( 'source' ) ); + data.inputs[ semantic ] = id; + break; - } + } - } + } - return data; + return data; - } + } - function parseVertexWeights( xml ) { + function parseVertexWeights( xml ) { - var data = { - inputs: {} - }; + var data = { + inputs: {} + }; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'input': - var semantic = child.getAttribute( 'semantic' ); - var id = parseId( child.getAttribute( 'source' ) ); - var offset = parseInt( child.getAttribute( 'offset' ) ); - data.inputs[ semantic ] = { id: id, offset: offset }; - break; + case 'input': + var semantic = child.getAttribute( 'semantic' ); + var id = parseId( child.getAttribute( 'source' ) ); + var offset = parseInt( child.getAttribute( 'offset' ) ); + data.inputs[ semantic ] = { id: id, offset: offset }; + break; - case 'vcount': - data.vcount = parseInts( child.textContent ); - break; + case 'vcount': + data.vcount = parseInts( child.textContent ); + break; - case 'v': - data.v = parseInts( child.textContent ); - break; + case 'v': + data.v = parseInts( child.textContent ); + break; - } + } - } + } - return data; + return data; - } + } - function buildController( data ) { + function buildController( data ) { - var build = { - id: data.id - }; + var build = { + id: data.id + }; - var geometry = library.geometries[ build.id ]; + var geometry = library.geometries[ build.id ]; - if ( data.skin !== undefined ) { + if ( data.skin !== undefined ) { - build.skin = buildSkin( data.skin ); + build.skin = buildSkin( data.skin ); - // we enhance the 'sources' property of the corresponding geometry with our skin data + // we enhance the 'sources' property of the corresponding geometry with our skin data - geometry.sources.skinIndices = build.skin.indices; - geometry.sources.skinWeights = build.skin.weights; + geometry.sources.skinIndices = build.skin.indices; + geometry.sources.skinWeights = build.skin.weights; - } + } - return build; + return build; - } + } - function buildSkin( data ) { + function buildSkin( data ) { - var BONE_LIMIT = 4; + var BONE_LIMIT = 4; - var build = { - joints: [], // this must be an array to preserve the joint order - indices: { - array: [], - stride: BONE_LIMIT - }, - weights: { - array: [], - stride: BONE_LIMIT - } - }; + var build = { + joints: [], // this must be an array to preserve the joint order + indices: { + array: [], + stride: BONE_LIMIT + }, + weights: { + array: [], + stride: BONE_LIMIT + } + }; - var sources = data.sources; - var vertexWeights = data.vertexWeights; + var sources = data.sources; + var vertexWeights = data.vertexWeights; - var vcount = vertexWeights.vcount; - var v = vertexWeights.v; - var jointOffset = vertexWeights.inputs.JOINT.offset; - var weightOffset = vertexWeights.inputs.WEIGHT.offset; + var vcount = vertexWeights.vcount; + var v = vertexWeights.v; + var jointOffset = vertexWeights.inputs.JOINT.offset; + var weightOffset = vertexWeights.inputs.WEIGHT.offset; - var jointSource = data.sources[ data.joints.inputs.JOINT ]; - var inverseSource = data.sources[ data.joints.inputs.INV_BIND_MATRIX ]; + var jointSource = data.sources[ data.joints.inputs.JOINT ]; + var inverseSource = data.sources[ data.joints.inputs.INV_BIND_MATRIX ]; - var weights = sources[ vertexWeights.inputs.WEIGHT.id ].array; - var stride = 0; + var weights = sources[ vertexWeights.inputs.WEIGHT.id ].array; + var stride = 0; - var i, j, l; + var i, j, l; - // procces skin data for each vertex + // procces skin data for each vertex - for ( i = 0, l = vcount.length; i < l; i ++ ) { + for ( i = 0, l = vcount.length; i < l; i ++ ) { - var jointCount = vcount[ i ]; // this is the amount of joints that affect a single vertex - var vertexSkinData = []; + var jointCount = vcount[ i ]; // this is the amount of joints that affect a single vertex + var vertexSkinData = []; - for ( j = 0; j < jointCount; j ++ ) { + for ( j = 0; j < jointCount; j ++ ) { - var skinIndex = v[ stride + jointOffset ]; - var weightId = v[ stride + weightOffset ]; - var skinWeight = weights[ weightId ]; + var skinIndex = v[ stride + jointOffset ]; + var weightId = v[ stride + weightOffset ]; + var skinWeight = weights[ weightId ]; - vertexSkinData.push( { index: skinIndex, weight: skinWeight } ); + vertexSkinData.push( { index: skinIndex, weight: skinWeight } ); - stride += 2; + stride += 2; - } + } - // we sort the joints in descending order based on the weights. - // this ensures, we only procced the most important joints of the vertex + // we sort the joints in descending order based on the weights. + // this ensures, we only procced the most important joints of the vertex - vertexSkinData.sort( descending ); + vertexSkinData.sort( descending ); - // now we provide for each vertex a set of four index and weight values. - // the order of the skin data matches the order of vertices + // now we provide for each vertex a set of four index and weight values. + // the order of the skin data matches the order of vertices - for ( j = 0; j < BONE_LIMIT; j ++ ) { + for ( j = 0; j < BONE_LIMIT; j ++ ) { - var d = vertexSkinData[ j ]; + var d = vertexSkinData[ j ]; - if ( d !== undefined ) { + if ( d !== undefined ) { - build.indices.array.push( d.index ); - build.weights.array.push( d.weight ); + build.indices.array.push( d.index ); + build.weights.array.push( d.weight ); - } else { + } else { - build.indices.array.push( 0 ); - build.weights.array.push( 0 ); + build.indices.array.push( 0 ); + build.weights.array.push( 0 ); - } + } - } + } - } + } - // setup bind matrix + // setup bind matrix - if ( data.bindShapeMatrix ) { + if ( data.bindShapeMatrix ) { - build.bindMatrix = new THREE.Matrix4().fromArray( data.bindShapeMatrix ).transpose(); + build.bindMatrix = new THREE.Matrix4().fromArray( data.bindShapeMatrix ).transpose(); - } else { + } else { - build.bindMatrix = new THREE.Matrix4().identity(); + build.bindMatrix = new THREE.Matrix4().identity(); - } + } - // process bones and inverse bind matrix data + // process bones and inverse bind matrix data - for ( i = 0, l = jointSource.array.length; i < l; i ++ ) { + for ( i = 0, l = jointSource.array.length; i < l; i ++ ) { - var name = jointSource.array[ i ]; - var boneInverse = new THREE.Matrix4().fromArray( inverseSource.array, i * inverseSource.stride ).transpose(); + var name = jointSource.array[ i ]; + var boneInverse = new THREE.Matrix4().fromArray( inverseSource.array, i * inverseSource.stride ).transpose(); - build.joints.push( { name: name, boneInverse: boneInverse } ); + build.joints.push( { name: name, boneInverse: boneInverse } ); - } + } - return build; + return build; - // array sort function + // array sort function - function descending( a, b ) { + function descending( a, b ) { - return b.weight - a.weight; + return b.weight - a.weight; - } + } - } + } - function getController( id ) { + function getController( id ) { - return getBuild( library.controllers[ id ], buildController ); + return getBuild( library.controllers[ id ], buildController ); - } + } - // image + // image - function parseImage( xml ) { + function parseImage( xml ) { - var data = { - init_from: getElementsByTagName( xml, 'init_from' )[ 0 ].textContent - }; + var data = { + init_from: getElementsByTagName( xml, 'init_from' )[ 0 ].textContent + }; - library.images[ xml.getAttribute( 'id' ) ] = data; + library.images[ xml.getAttribute( 'id' ) ] = data; - } + } - function buildImage( data ) { + function buildImage( data ) { - if ( data.build !== undefined ) return data.build; + if ( data.build !== undefined ) return data.build; - return data.init_from; + return data.init_from; - } + } - function getImage( id ) { + function getImage( id ) { - var data = library.images[ id ]; + var data = library.images[ id ]; - if ( data !== undefined ) { + if ( data !== undefined ) { - return getBuild( data, buildImage ); + return getBuild( data, buildImage ); - } + } - console.warn( 'THREE.ColladaLoader: Couldn\'t find image with ID:', id ); + console.warn( 'THREE.ColladaLoader: Couldn\'t find image with ID:', id ); - return null; + return null; - } + } - // effect + // effect - function parseEffect( xml ) { + function parseEffect( xml ) { - var data = {}; + var data = {}; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'profile_COMMON': - data.profile = parseEffectProfileCOMMON( child ); - break; + case 'profile_COMMON': + data.profile = parseEffectProfileCOMMON( child ); + break; - } + } - } + } - library.effects[ xml.getAttribute( 'id' ) ] = data; + library.effects[ xml.getAttribute( 'id' ) ] = data; - } + } - function parseEffectProfileCOMMON( xml ) { + function parseEffectProfileCOMMON( xml ) { - var data = { - surfaces: {}, - samplers: {} - }; + var data = { + surfaces: {}, + samplers: {} + }; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'newparam': - parseEffectNewparam( child, data ); - break; + case 'newparam': + parseEffectNewparam( child, data ); + break; - case 'technique': - data.technique = parseEffectTechnique( child ); - break; + case 'technique': + data.technique = parseEffectTechnique( child ); + break; - case 'extra': - data.extra = parseEffectExtra( child ); - break; + case 'extra': + data.extra = parseEffectExtra( child ); + break; - } + } - } + } - return data; + return data; - } + } - function parseEffectNewparam( xml, data ) { + function parseEffectNewparam( xml, data ) { - var sid = xml.getAttribute( 'sid' ); + var sid = xml.getAttribute( 'sid' ); - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'surface': - data.surfaces[ sid ] = parseEffectSurface( child ); - break; + case 'surface': + data.surfaces[ sid ] = parseEffectSurface( child ); + break; - case 'sampler2D': - data.samplers[ sid ] = parseEffectSampler( child ); - break; + case 'sampler2D': + data.samplers[ sid ] = parseEffectSampler( child ); + break; - } + } - } + } - } + } - function parseEffectSurface( xml ) { + function parseEffectSurface( xml ) { - var data = {}; + var data = {}; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'init_from': - data.init_from = child.textContent; - break; + case 'init_from': + data.init_from = child.textContent; + break; - } + } - } + } - return data; + return data; - } + } - function parseEffectSampler( xml ) { + function parseEffectSampler( xml ) { - var data = {}; + var data = {}; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'source': - data.source = child.textContent; - break; + case 'source': + data.source = child.textContent; + break; - } + } - } + } - return data; + return data; - } + } - function parseEffectTechnique( xml ) { + function parseEffectTechnique( xml ) { - var data = {}; + var data = {}; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'constant': - case 'lambert': - case 'blinn': - case 'phong': - data.type = child.nodeName; - data.parameters = parseEffectParameters( child ); - break; + case 'constant': + case 'lambert': + case 'blinn': + case 'phong': + data.type = child.nodeName; + data.parameters = parseEffectParameters( child ); + break; - } + } - } + } - return data; + return data; - } + } - function parseEffectParameters( xml ) { + function parseEffectParameters( xml ) { - var data = {}; + var data = {}; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'emission': - case 'diffuse': - case 'specular': - case 'shininess': - case 'transparency': - data[ child.nodeName ] = parseEffectParameter( child ); - break; - case 'transparent': - data[ child.nodeName ] = { - opaque: child.getAttribute( 'opaque' ), - data: parseEffectParameter( child ) - }; - break; + case 'emission': + case 'diffuse': + case 'specular': + case 'shininess': + case 'transparency': + data[ child.nodeName ] = parseEffectParameter( child ); + break; + case 'transparent': + data[ child.nodeName ] = { + opaque: child.getAttribute( 'opaque' ), + data: parseEffectParameter( child ) + }; + break; - } + } - } + } - return data; + return data; - } + } - function parseEffectParameter( xml ) { + function parseEffectParameter( xml ) { - var data = {}; + var data = {}; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'color': - data[ child.nodeName ] = parseFloats( child.textContent ); - break; + case 'color': + data[ child.nodeName ] = parseFloats( child.textContent ); + break; - case 'float': - data[ child.nodeName ] = parseFloat( child.textContent ); - break; + case 'float': + data[ child.nodeName ] = parseFloat( child.textContent ); + break; - case 'texture': - data[ child.nodeName ] = { id: child.getAttribute( 'texture' ), extra: parseEffectParameterTexture( child ) }; - break; + case 'texture': + data[ child.nodeName ] = { id: child.getAttribute( 'texture' ), extra: parseEffectParameterTexture( child ) }; + break; - } + } - } + } - return data; + return data; - } + } - function parseEffectParameterTexture( xml ) { + function parseEffectParameterTexture( xml ) { - var data = { - technique: {} - }; + var data = { + technique: {} + }; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'extra': - parseEffectParameterTextureExtra( child, data ); - break; + case 'extra': + parseEffectParameterTextureExtra( child, data ); + break; - } + } - } + } - return data; + return data; - } + } - function parseEffectParameterTextureExtra( xml, data ) { + function parseEffectParameterTextureExtra( xml, data ) { - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'technique': - parseEffectParameterTextureExtraTechnique( child, data ); - break; + case 'technique': + parseEffectParameterTextureExtraTechnique( child, data ); + break; - } + } - } + } - } + } - function parseEffectParameterTextureExtraTechnique( xml, data ) { + function parseEffectParameterTextureExtraTechnique( xml, data ) { - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'repeatU': - case 'repeatV': - case 'offsetU': - case 'offsetV': - data.technique[ child.nodeName ] = parseFloat( child.textContent ); - break; + case 'repeatU': + case 'repeatV': + case 'offsetU': + case 'offsetV': + data.technique[ child.nodeName ] = parseFloat( child.textContent ); + break; - case 'wrapU': - case 'wrapV': + case 'wrapU': + case 'wrapV': - // some files have values for wrapU/wrapV which become NaN via parseInt + // some files have values for wrapU/wrapV which become NaN via parseInt - if ( child.textContent.toUpperCase() === 'TRUE' ) { + if ( child.textContent.toUpperCase() === 'TRUE' ) { - data.technique[ child.nodeName ] = 1; + data.technique[ child.nodeName ] = 1; - } else if ( child.textContent.toUpperCase() === 'FALSE' ) { + } else if ( child.textContent.toUpperCase() === 'FALSE' ) { - data.technique[ child.nodeName ] = 0; + data.technique[ child.nodeName ] = 0; - } else { + } else { - data.technique[ child.nodeName ] = parseInt( child.textContent ); + data.technique[ child.nodeName ] = parseInt( child.textContent ); - } + } - break; + break; - } + } - } + } - } + } - function parseEffectExtra( xml ) { + function parseEffectExtra( xml ) { - var data = {}; + var data = {}; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'technique': - data.technique = parseEffectExtraTechnique( child ); - break; + case 'technique': + data.technique = parseEffectExtraTechnique( child ); + break; - } + } - } + } - return data; + return data; - } + } - function parseEffectExtraTechnique( xml ) { + function parseEffectExtraTechnique( xml ) { - var data = {}; + var data = {}; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'double_sided': - data[ child.nodeName ] = parseInt( child.textContent ); - break; + case 'double_sided': + data[ child.nodeName ] = parseInt( child.textContent ); + break; - } + } - } + } - return data; + return data; - } + } - function buildEffect( data ) { + function buildEffect( data ) { - return data; + return data; - } + } - function getEffect( id ) { + function getEffect( id ) { - return getBuild( library.effects[ id ], buildEffect ); + return getBuild( library.effects[ id ], buildEffect ); - } + } - // material + // material - function parseMaterial( xml ) { + function parseMaterial( xml ) { - var data = { - name: xml.getAttribute( 'name' ) - }; + var data = { + name: xml.getAttribute( 'name' ) + }; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'instance_effect': - data.url = parseId( child.getAttribute( 'url' ) ); - break; + case 'instance_effect': + data.url = parseId( child.getAttribute( 'url' ) ); + break; - } + } - } + } - library.materials[ xml.getAttribute( 'id' ) ] = data; + library.materials[ xml.getAttribute( 'id' ) ] = data; - } + } - function getTextureLoader( image ) { + function getTextureLoader( image ) { - var loader; + var loader; - var extension = image.slice( ( image.lastIndexOf( '.' ) - 1 >>> 0 ) + 2 ); // http://www.jstips.co/en/javascript/get-file-extension/ - extension = extension.toLowerCase(); + var extension = image.slice( ( image.lastIndexOf( '.' ) - 1 >>> 0 ) + 2 ); // http://www.jstips.co/en/javascript/get-file-extension/ + extension = extension.toLowerCase(); - switch ( extension ) { + switch ( extension ) { - case 'tga': - loader = tgaLoader; - break; + case 'tga': + loader = tgaLoader; + break; - default: - loader = textureLoader; + default: + loader = textureLoader; - } + } - return loader; + return loader; - } + } - function buildMaterial( data ) { + function buildMaterial( data ) { - var effect = getEffect( data.url ); - var technique = effect.profile.technique; - var extra = effect.profile.extra; + var effect = getEffect( data.url ); + var technique = effect.profile.technique; + var extra = effect.profile.extra; - var material; + var material; - switch ( technique.type ) { + switch ( technique.type ) { - case 'phong': - case 'blinn': - material = new THREE.MeshPhongMaterial(); - break; + case 'phong': + case 'blinn': + material = new THREE.MeshPhongMaterial(); + break; - case 'lambert': - material = new THREE.MeshLambertMaterial(); - break; + case 'lambert': + material = new THREE.MeshLambertMaterial(); + break; - default: - material = new THREE.MeshBasicMaterial(); - break; + default: + material = new THREE.MeshBasicMaterial(); + break; - } + } - material.name = data.name; + material.name = data.name; - function getTexture( textureObject ) { + function getTexture( textureObject ) { - var sampler = effect.profile.samplers[ textureObject.id ]; - var image = null; + var sampler = effect.profile.samplers[ textureObject.id ]; + var image = null; - // get image + // get image - if ( sampler !== undefined ) { + if ( sampler !== undefined ) { - var surface = effect.profile.surfaces[ sampler.source ]; - image = getImage( surface.init_from ); + var surface = effect.profile.surfaces[ sampler.source ]; + image = getImage( surface.init_from ); - } else { + } else { - console.warn( 'THREE.ColladaLoader: Undefined sampler. Access image directly (see #12530).' ); - image = getImage( textureObject.id ); + console.warn( 'THREE.ColladaLoader: Undefined sampler. Access image directly (see #12530).' ); + image = getImage( textureObject.id ); - } + } - // create texture if image is avaiable + // create texture if image is avaiable - if ( image !== null ) { + if ( image !== null ) { - var loader = getTextureLoader( image ); + var loader = getTextureLoader( image ); - if ( loader !== undefined ) { + if ( loader !== undefined ) { - var texture = loader.load( image ); + var texture = loader.load( image ); - var extra = textureObject.extra; + var extra = textureObject.extra; - if ( extra !== undefined && extra.technique !== undefined && isEmpty( extra.technique ) === false ) { + if ( extra !== undefined && extra.technique !== undefined && isEmpty( extra.technique ) === false ) { - var technique = extra.technique; + var technique = extra.technique; - texture.wrapS = technique.wrapU ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping; - texture.wrapT = technique.wrapV ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping; + texture.wrapS = technique.wrapU ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping; + texture.wrapT = technique.wrapV ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping; - texture.offset.set( technique.offsetU || 0, technique.offsetV || 0 ); - texture.repeat.set( technique.repeatU || 1, technique.repeatV || 1 ); + texture.offset.set( technique.offsetU || 0, technique.offsetV || 0 ); + texture.repeat.set( technique.repeatU || 1, technique.repeatV || 1 ); - } else { + } else { - texture.wrapS = THREE.RepeatWrapping; - texture.wrapT = THREE.RepeatWrapping; + texture.wrapS = THREE.RepeatWrapping; + texture.wrapT = THREE.RepeatWrapping; - } + } - return texture; + return texture; - } else { + } else { - console.warn( 'THREE.ColladaLoader: Loader for texture %s not found.', image ); + console.warn( 'THREE.ColladaLoader: Loader for texture %s not found.', image ); - return null; + return null; - } + } - } else { + } else { - console.warn( 'THREE.ColladaLoader: Couldn\'t create texture with ID:', textureObject.id ); + console.warn( 'THREE.ColladaLoader: Couldn\'t create texture with ID:', textureObject.id ); - return null; + return null; - } + } - } + } - var parameters = technique.parameters; + var parameters = technique.parameters; - for ( var key in parameters ) { + for ( var key in parameters ) { - var parameter = parameters[ key ]; + var parameter = parameters[ key ]; - switch ( key ) { + switch ( key ) { - case 'diffuse': - if ( parameter.color ) material.color.fromArray( parameter.color ); - if ( parameter.texture ) material.map = getTexture( parameter.texture ); - break; - case 'specular': - if ( parameter.color && material.specular ) material.specular.fromArray( parameter.color ); - if ( parameter.texture ) material.specularMap = getTexture( parameter.texture ); - break; - case 'shininess': - if ( parameter.float && material.shininess ) material.shininess = parameter.float; - break; - case 'emission': - if ( parameter.color && material.emissive ) material.emissive.fromArray( parameter.color ); - if ( parameter.texture ) material.emissiveMap = getTexture( parameter.texture ); - break; + case 'diffuse': + if ( parameter.color ) material.color.fromArray( parameter.color ); + if ( parameter.texture ) material.map = getTexture( parameter.texture ); + break; + case 'specular': + if ( parameter.color && material.specular ) material.specular.fromArray( parameter.color ); + if ( parameter.texture ) material.specularMap = getTexture( parameter.texture ); + break; + case 'shininess': + if ( parameter.float && material.shininess ) material.shininess = parameter.float; + break; + case 'emission': + if ( parameter.color && material.emissive ) material.emissive.fromArray( parameter.color ); + if ( parameter.texture ) material.emissiveMap = getTexture( parameter.texture ); + break; - } + } - } + } - // + // - var transparent = parameters[ 'transparent' ]; - var transparency = parameters[ 'transparency' ]; + var transparent = parameters[ 'transparent' ]; + var transparency = parameters[ 'transparency' ]; - // does not exist but + // does not exist but - if ( transparency === undefined && transparent ) { + if ( transparency === undefined && transparent ) { - transparency = { - float: 1 - }; + transparency = { + float: 1 + }; - } + } - // does not exist but + // does not exist but - if ( transparent === undefined && transparency ) { + if ( transparent === undefined && transparency ) { - transparent = { - opaque: 'A_ONE', - data: { - color: [ 1, 1, 1, 1 ] - } }; + transparent = { + opaque: 'A_ONE', + data: { + color: [ 1, 1, 1, 1 ] + } }; - } + } - if ( transparent && transparency ) { + if ( transparent && transparency ) { - // handle case if a texture exists but no color + // handle case if a texture exists but no color - if ( transparent.data.texture ) { + if ( transparent.data.texture ) { - // we do not set an alpha map (see #13792) + // we do not set an alpha map (see #13792) - material.transparent = true; + material.transparent = true; - } else { + } else { - var color = transparent.data.color; + var color = transparent.data.color; - switch ( transparent.opaque ) { + switch ( transparent.opaque ) { - case 'A_ONE': - material.opacity = color[ 3 ] * transparency.float; - break; - case 'RGB_ZERO': - material.opacity = 1 - ( color[ 0 ] * transparency.float ); - break; - case 'A_ZERO': - material.opacity = 1 - ( color[ 3 ] * transparency.float ); - break; - case 'RGB_ONE': - material.opacity = color[ 0 ] * transparency.float; - break; - default: - console.warn( 'THREE.ColladaLoader: Invalid opaque type "%s" of transparent tag.', transparent.opaque ); + case 'A_ONE': + material.opacity = color[ 3 ] * transparency.float; + break; + case 'RGB_ZERO': + material.opacity = 1 - ( color[ 0 ] * transparency.float ); + break; + case 'A_ZERO': + material.opacity = 1 - ( color[ 3 ] * transparency.float ); + break; + case 'RGB_ONE': + material.opacity = color[ 0 ] * transparency.float; + break; + default: + console.warn( 'THREE.ColladaLoader: Invalid opaque type "%s" of transparent tag.', transparent.opaque ); - } + } - if ( material.opacity < 1 ) material.transparent = true; + if ( material.opacity < 1 ) material.transparent = true; - } + } - } + } - // + // - if ( extra !== undefined && extra.technique !== undefined && extra.technique.double_sided === 1 ) { + if ( extra !== undefined && extra.technique !== undefined && extra.technique.double_sided === 1 ) { - material.side = THREE.DoubleSide; + material.side = THREE.DoubleSide; - } + } - return material; + return material; - } + } - function getMaterial( id ) { + function getMaterial( id ) { - return getBuild( library.materials[ id ], buildMaterial ); + return getBuild( library.materials[ id ], buildMaterial ); - } + } - // camera + // camera - function parseCamera( xml ) { + function parseCamera( xml ) { - var data = { - name: xml.getAttribute( 'name' ) - }; + var data = { + name: xml.getAttribute( 'name' ) + }; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'optics': - data.optics = parseCameraOptics( child ); - break; + case 'optics': + data.optics = parseCameraOptics( child ); + break; - } + } - } + } - library.cameras[ xml.getAttribute( 'id' ) ] = data; + library.cameras[ xml.getAttribute( 'id' ) ] = data; - } + } - function parseCameraOptics( xml ) { + function parseCameraOptics( xml ) { - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'technique_common': - return parseCameraTechnique( child ); + case 'technique_common': + return parseCameraTechnique( child ); - } + } - } + } - return {}; + return {}; - } + } - function parseCameraTechnique( xml ) { + function parseCameraTechnique( xml ) { - var data = {}; + var data = {}; - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'perspective': - case 'orthographic': + case 'perspective': + case 'orthographic': - data.technique = child.nodeName; - data.parameters = parseCameraParameters( child ); + data.technique = child.nodeName; + data.parameters = parseCameraParameters( child ); - break; + break; - } + } - } + } - return data; + return data; - } + } - function parseCameraParameters( xml ) { + function parseCameraParameters( xml ) { - var data = {}; + var data = {}; - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'xfov': - case 'yfov': - case 'xmag': - case 'ymag': - case 'znear': - case 'zfar': - case 'aspect_ratio': - data[ child.nodeName ] = parseFloat( child.textContent ); - break; + case 'xfov': + case 'yfov': + case 'xmag': + case 'ymag': + case 'znear': + case 'zfar': + case 'aspect_ratio': + data[ child.nodeName ] = parseFloat( child.textContent ); + break; - } + } - } + } - return data; + return data; - } + } - function buildCamera( data ) { + function buildCamera( data ) { - var camera; + var camera; - switch ( data.optics.technique ) { + switch ( data.optics.technique ) { - case 'perspective': - camera = new THREE.PerspectiveCamera( - data.optics.parameters.yfov, - data.optics.parameters.aspect_ratio, - data.optics.parameters.znear, - data.optics.parameters.zfar - ); - break; + case 'perspective': + camera = new THREE.PerspectiveCamera( + data.optics.parameters.yfov, + data.optics.parameters.aspect_ratio, + data.optics.parameters.znear, + data.optics.parameters.zfar + ); + break; - case 'orthographic': - var ymag = data.optics.parameters.ymag; - var xmag = data.optics.parameters.xmag; - var aspectRatio = data.optics.parameters.aspect_ratio; + case 'orthographic': + var ymag = data.optics.parameters.ymag; + var xmag = data.optics.parameters.xmag; + var aspectRatio = data.optics.parameters.aspect_ratio; - xmag = ( xmag === undefined ) ? ( ymag * aspectRatio ) : xmag; - ymag = ( ymag === undefined ) ? ( xmag / aspectRatio ) : ymag; + xmag = ( xmag === undefined ) ? ( ymag * aspectRatio ) : xmag; + ymag = ( ymag === undefined ) ? ( xmag / aspectRatio ) : ymag; - xmag *= 0.5; - ymag *= 0.5; + xmag *= 0.5; + ymag *= 0.5; - camera = new THREE.OrthographicCamera( - - xmag, xmag, ymag, - ymag, // left, right, top, bottom - data.optics.parameters.znear, - data.optics.parameters.zfar - ); - break; + camera = new THREE.OrthographicCamera( + - xmag, xmag, ymag, - ymag, // left, right, top, bottom + data.optics.parameters.znear, + data.optics.parameters.zfar + ); + break; - default: - camera = new THREE.PerspectiveCamera(); - break; + default: + camera = new THREE.PerspectiveCamera(); + break; - } + } - camera.name = data.name; + camera.name = data.name; - return camera; + return camera; - } + } - function getCamera( id ) { + function getCamera( id ) { - var data = library.cameras[ id ]; + var data = library.cameras[ id ]; - if ( data !== undefined ) { + if ( data !== undefined ) { - return getBuild( data, buildCamera ); + return getBuild( data, buildCamera ); - } + } - console.warn( 'THREE.ColladaLoader: Couldn\'t find camera with ID:', id ); + console.warn( 'THREE.ColladaLoader: Couldn\'t find camera with ID:', id ); - return null; + return null; - } + } - // light + // light - function parseLight( xml ) { + function parseLight( xml ) { - var data = {}; + var data = {}; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'technique_common': - data = parseLightTechnique( child ); - break; + case 'technique_common': + data = parseLightTechnique( child ); + break; - } + } - } + } - library.lights[ xml.getAttribute( 'id' ) ] = data; + library.lights[ xml.getAttribute( 'id' ) ] = data; - } + } - function parseLightTechnique( xml ) { + function parseLightTechnique( xml ) { - var data = {}; + var data = {}; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'directional': - case 'point': - case 'spot': - case 'ambient': + case 'directional': + case 'point': + case 'spot': + case 'ambient': - data.technique = child.nodeName; - data.parameters = parseLightParameters( child ); + data.technique = child.nodeName; + data.parameters = parseLightParameters( child ); - } + } - } + } - return data; + return data; - } + } - function parseLightParameters( xml ) { + function parseLightParameters( xml ) { - var data = {}; + var data = {}; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'color': - var array = parseFloats( child.textContent ); - data.color = new THREE.Color().fromArray( array ); - break; + case 'color': + var array = parseFloats( child.textContent ); + data.color = new THREE.Color().fromArray( array ); + break; - case 'falloff_angle': - data.falloffAngle = parseFloat( child.textContent ); - break; + case 'falloff_angle': + data.falloffAngle = parseFloat( child.textContent ); + break; - case 'quadratic_attenuation': - var f = parseFloat( child.textContent ); - data.distance = f ? Math.sqrt( 1 / f ) : 0; - break; + case 'quadratic_attenuation': + var f = parseFloat( child.textContent ); + data.distance = f ? Math.sqrt( 1 / f ) : 0; + break; - } + } - } + } - return data; + return data; - } + } - function buildLight( data ) { + function buildLight( data ) { - var light; + var light; - switch ( data.technique ) { + switch ( data.technique ) { - case 'directional': - light = new THREE.DirectionalLight(); - break; + case 'directional': + light = new THREE.DirectionalLight(); + break; - case 'point': - light = new THREE.PointLight(); - break; + case 'point': + light = new THREE.PointLight(); + break; - case 'spot': - light = new THREE.SpotLight(); - break; + case 'spot': + light = new THREE.SpotLight(); + break; - case 'ambient': - light = new THREE.AmbientLight(); - break; + case 'ambient': + light = new THREE.AmbientLight(); + break; - } + } - if ( data.parameters.color ) light.color.copy( data.parameters.color ); - if ( data.parameters.distance ) light.distance = data.parameters.distance; + if ( data.parameters.color ) light.color.copy( data.parameters.color ); + if ( data.parameters.distance ) light.distance = data.parameters.distance; - return light; + return light; - } + } - function getLight( id ) { + function getLight( id ) { - var data = library.lights[ id ]; + var data = library.lights[ id ]; - if ( data !== undefined ) { + if ( data !== undefined ) { - return getBuild( data, buildLight ); + return getBuild( data, buildLight ); - } + } - console.warn( 'THREE.ColladaLoader: Couldn\'t find light with ID:', id ); + console.warn( 'THREE.ColladaLoader: Couldn\'t find light with ID:', id ); - return null; + return null; - } + } - // geometry + // geometry - function parseGeometry( xml ) { + function parseGeometry( xml ) { - var data = { - name: xml.getAttribute( 'name' ), - sources: {}, - vertices: {}, - primitives: [] - }; + var data = { + name: xml.getAttribute( 'name' ), + sources: {}, + vertices: {}, + primitives: [] + }; - var mesh = getElementsByTagName( xml, 'mesh' )[ 0 ]; + var mesh = getElementsByTagName( xml, 'mesh' )[ 0 ]; - // the following tags inside geometry are not supported yet (see https://github.com/mrdoob/three.js/pull/12606): convex_mesh, spline, brep - if ( mesh === undefined ) return; + // the following tags inside geometry are not supported yet (see https://github.com/mrdoob/three.js/pull/12606): convex_mesh, spline, brep + if ( mesh === undefined ) return; - for ( var i = 0; i < mesh.childNodes.length; i ++ ) { + for ( var i = 0; i < mesh.childNodes.length; i ++ ) { - var child = mesh.childNodes[ i ]; + var child = mesh.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - var id = child.getAttribute( 'id' ); + var id = child.getAttribute( 'id' ); - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'source': - data.sources[ id ] = parseSource( child ); - break; + case 'source': + data.sources[ id ] = parseSource( child ); + break; - case 'vertices': - // data.sources[ id ] = data.sources[ parseId( getElementsByTagName( child, 'input' )[ 0 ].getAttribute( 'source' ) ) ]; - data.vertices = parseGeometryVertices( child ); - break; + case 'vertices': + // data.sources[ id ] = data.sources[ parseId( getElementsByTagName( child, 'input' )[ 0 ].getAttribute( 'source' ) ) ]; + data.vertices = parseGeometryVertices( child ); + break; - case 'polygons': - console.warn( 'THREE.ColladaLoader: Unsupported primitive type: ', child.nodeName ); - break; + case 'polygons': + console.warn( 'THREE.ColladaLoader: Unsupported primitive type: ', child.nodeName ); + break; - case 'lines': - case 'linestrips': - case 'polylist': - case 'triangles': - data.primitives.push( parseGeometryPrimitive( child ) ); - break; + case 'lines': + case 'linestrips': + case 'polylist': + case 'triangles': + data.primitives.push( parseGeometryPrimitive( child ) ); + break; - default: - console.log( child ); + default: + console.log( child ); - } + } - } + } - library.geometries[ xml.getAttribute( 'id' ) ] = data; + library.geometries[ xml.getAttribute( 'id' ) ] = data; - } + } - function parseSource( xml ) { + function parseSource( xml ) { - var data = { - array: [], - stride: 3 - }; + var data = { + array: [], + stride: 3 + }; - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'float_array': - data.array = parseFloats( child.textContent ); - break; + case 'float_array': + data.array = parseFloats( child.textContent ); + break; - case 'Name_array': - data.array = parseStrings( child.textContent ); - break; + case 'Name_array': + data.array = parseStrings( child.textContent ); + break; - case 'technique_common': - var accessor = getElementsByTagName( child, 'accessor' )[ 0 ]; + case 'technique_common': + var accessor = getElementsByTagName( child, 'accessor' )[ 0 ]; - if ( accessor !== undefined ) { + if ( accessor !== undefined ) { - data.stride = parseInt( accessor.getAttribute( 'stride' ) ); + data.stride = parseInt( accessor.getAttribute( 'stride' ) ); - } - break; + } + break; - } + } - } + } - return data; + return data; - } + } - function parseGeometryVertices( xml ) { + function parseGeometryVertices( xml ) { - var data = {}; + var data = {}; - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - data[ child.getAttribute( 'semantic' ) ] = parseId( child.getAttribute( 'source' ) ); + data[ child.getAttribute( 'semantic' ) ] = parseId( child.getAttribute( 'source' ) ); - } + } - return data; + return data; - } + } - function parseGeometryPrimitive( xml ) { + function parseGeometryPrimitive( xml ) { - var primitive = { - type: xml.nodeName, - material: xml.getAttribute( 'material' ), - count: parseInt( xml.getAttribute( 'count' ) ), - inputs: {}, - stride: 0, - hasUV: false - }; + var primitive = { + type: xml.nodeName, + material: xml.getAttribute( 'material' ), + count: parseInt( xml.getAttribute( 'count' ) ), + inputs: {}, + stride: 0, + hasUV: false + }; - for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { + for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'input': - var id = parseId( child.getAttribute( 'source' ) ); - var semantic = child.getAttribute( 'semantic' ); - var offset = parseInt( child.getAttribute( 'offset' ) ); - primitive.inputs[ semantic ] = { id: id, offset: offset }; - primitive.stride = Math.max( primitive.stride, offset + 1 ); - if ( semantic === 'TEXCOORD' ) primitive.hasUV = true; - break; + case 'input': + var id = parseId( child.getAttribute( 'source' ) ); + var semantic = child.getAttribute( 'semantic' ); + var offset = parseInt( child.getAttribute( 'offset' ) ); + primitive.inputs[ semantic ] = { id: id, offset: offset }; + primitive.stride = Math.max( primitive.stride, offset + 1 ); + if ( semantic === 'TEXCOORD' ) primitive.hasUV = true; + break; - case 'vcount': - primitive.vcount = parseInts( child.textContent ); - break; + case 'vcount': + primitive.vcount = parseInts( child.textContent ); + break; - case 'p': - primitive.p = parseInts( child.textContent ); - break; + case 'p': + primitive.p = parseInts( child.textContent ); + break; - } + } - } + } - return primitive; + return primitive; - } + } - function groupPrimitives( primitives ) { + function groupPrimitives( primitives ) { - var build = {}; + var build = {}; - for ( var i = 0; i < primitives.length; i ++ ) { + for ( var i = 0; i < primitives.length; i ++ ) { - var primitive = primitives[ i ]; + var primitive = primitives[ i ]; - if ( build[ primitive.type ] === undefined ) build[ primitive.type ] = []; + if ( build[ primitive.type ] === undefined ) build[ primitive.type ] = []; - build[ primitive.type ].push( primitive ); + build[ primitive.type ].push( primitive ); - } + } - return build; + return build; - } + } - function checkUVCoordinates( primitives ) { + function checkUVCoordinates( primitives ) { - var count = 0; + var count = 0; - for ( var i = 0, l = primitives.length; i < l; i ++ ) { + for ( var i = 0, l = primitives.length; i < l; i ++ ) { - var primitive = primitives[ i ]; + var primitive = primitives[ i ]; - if ( primitive.hasUV === true ) { + if ( primitive.hasUV === true ) { - count ++; + count ++; - } + } - } + } - if ( count > 0 && count < primitives.length ) { + if ( count > 0 && count < primitives.length ) { - primitives.uvsNeedsFix = true; + primitives.uvsNeedsFix = true; - } + } - } + } - function buildGeometry( data ) { + function buildGeometry( data ) { - var build = {}; + var build = {}; - var sources = data.sources; - var vertices = data.vertices; - var primitives = data.primitives; + var sources = data.sources; + var vertices = data.vertices; + var primitives = data.primitives; - if ( primitives.length === 0 ) return {}; + if ( primitives.length === 0 ) return {}; - // our goal is to create one buffer geometry for a single type of primitives - // first, we group all primitives by their type + // our goal is to create one buffer geometry for a single type of primitives + // first, we group all primitives by their type - var groupedPrimitives = groupPrimitives( primitives ); + var groupedPrimitives = groupPrimitives( primitives ); - for ( var type in groupedPrimitives ) { + for ( var type in groupedPrimitives ) { - var primitiveType = groupedPrimitives[ type ]; + var primitiveType = groupedPrimitives[ type ]; - // second, ensure consistent uv coordinates for each type of primitives (polylist,triangles or lines) + // second, ensure consistent uv coordinates for each type of primitives (polylist,triangles or lines) - checkUVCoordinates( primitiveType ); + checkUVCoordinates( primitiveType ); - // third, create a buffer geometry for each type of primitives + // third, create a buffer geometry for each type of primitives - build[ type ] = buildGeometryType( primitiveType, sources, vertices ); + build[ type ] = buildGeometryType( primitiveType, sources, vertices ); - } + } - return build; + return build; - } + } - function buildGeometryType( primitives, sources, vertices ) { + function buildGeometryType( primitives, sources, vertices ) { - var build = {}; + var build = {}; - var position = { array: [], stride: 0 }; - var normal = { array: [], stride: 0 }; - var uv = { array: [], stride: 0 }; - var color = { array: [], stride: 0 }; + var position = { array: [], stride: 0 }; + var normal = { array: [], stride: 0 }; + var uv = { array: [], stride: 0 }; + var color = { array: [], stride: 0 }; - var skinIndex = { array: [], stride: 4 }; - var skinWeight = { array: [], stride: 4 }; + var skinIndex = { array: [], stride: 4 }; + var skinWeight = { array: [], stride: 4 }; - var geometry = new THREE.BufferGeometry(); + var geometry = new THREE.BufferGeometry(); - var materialKeys = []; + var materialKeys = []; - var start = 0; + var start = 0; - for ( var p = 0; p < primitives.length; p ++ ) { + for ( var p = 0; p < primitives.length; p ++ ) { - var primitive = primitives[ p ]; - var inputs = primitive.inputs; + var primitive = primitives[ p ]; + var inputs = primitive.inputs; - // groups + // groups - var count = 0; + var count = 0; - switch ( primitive.type ) { + switch ( primitive.type ) { - case 'lines': - case 'linestrips': - count = primitive.count * 2; - break; + case 'lines': + case 'linestrips': + count = primitive.count * 2; + break; - case 'triangles': - count = primitive.count * 3; - break; + case 'triangles': + count = primitive.count * 3; + break; - case 'polylist': + case 'polylist': - for ( var g = 0; g < primitive.count; g ++ ) { + for ( var g = 0; g < primitive.count; g ++ ) { - var vc = primitive.vcount[ g ]; + var vc = primitive.vcount[ g ]; - switch ( vc ) { + switch ( vc ) { - case 3: - count += 3; // single triangle - break; + case 3: + count += 3; // single triangle + break; - case 4: - count += 6; // quad, subdivided into two triangles - break; + case 4: + count += 6; // quad, subdivided into two triangles + break; - default: - count += ( vc - 2 ) * 3; // polylist with more than four vertices - break; + default: + count += ( vc - 2 ) * 3; // polylist with more than four vertices + break; - } + } - } + } - break; + break; - default: - console.warn( 'THREE.ColladaLoader: Unknow primitive type:', primitive.type ); + default: + console.warn( 'THREE.ColladaLoader: Unknow primitive type:', primitive.type ); - } + } - geometry.addGroup( start, count, p ); - start += count; + geometry.addGroup( start, count, p ); + start += count; - // material + // material - if ( primitive.material ) { + if ( primitive.material ) { - materialKeys.push( primitive.material ); + materialKeys.push( primitive.material ); - } + } - // geometry data + // geometry data - for ( var name in inputs ) { + for ( var name in inputs ) { - var input = inputs[ name ]; + var input = inputs[ name ]; - switch ( name ) { + switch ( name ) { - case 'VERTEX': - for ( var key in vertices ) { + case 'VERTEX': + for ( var key in vertices ) { - var id = vertices[ key ]; + var id = vertices[ key ]; - switch ( key ) { + switch ( key ) { - case 'POSITION': - var prevLength = position.array.length; - buildGeometryData( primitive, sources[ id ], input.offset, position.array ); - position.stride = sources[ id ].stride; + case 'POSITION': + var prevLength = position.array.length; + buildGeometryData( primitive, sources[ id ], input.offset, position.array ); + position.stride = sources[ id ].stride; - if ( sources.skinWeights && sources.skinIndices ) { + if ( sources.skinWeights && sources.skinIndices ) { - buildGeometryData( primitive, sources.skinIndices, input.offset, skinIndex.array ); - buildGeometryData( primitive, sources.skinWeights, input.offset, skinWeight.array ); + buildGeometryData( primitive, sources.skinIndices, input.offset, skinIndex.array ); + buildGeometryData( primitive, sources.skinWeights, input.offset, skinWeight.array ); - } + } - // see #3803 + // see #3803 - if ( primitive.hasUV === false && primitives.uvsNeedsFix === true ) { + if ( primitive.hasUV === false && primitives.uvsNeedsFix === true ) { - var count = ( position.array.length - prevLength ) / position.stride; + var count = ( position.array.length - prevLength ) / position.stride; - for ( var i = 0; i < count; i ++ ) { + for ( var i = 0; i < count; i ++ ) { - // fill missing uv coordinates + // fill missing uv coordinates - uv.array.push( 0, 0 ); + uv.array.push( 0, 0 ); - } + } - } - break; + } + break; - case 'NORMAL': - buildGeometryData( primitive, sources[ id ], input.offset, normal.array ); - normal.stride = sources[ id ].stride; - break; + case 'NORMAL': + buildGeometryData( primitive, sources[ id ], input.offset, normal.array ); + normal.stride = sources[ id ].stride; + break; - case 'COLOR': - buildGeometryData( primitive, sources[ id ], input.offset, color.array ); - color.stride = sources[ id ].stride; - break; + case 'COLOR': + buildGeometryData( primitive, sources[ id ], input.offset, color.array ); + color.stride = sources[ id ].stride; + break; - case 'TEXCOORD': - buildGeometryData( primitive, sources[ id ], input.offset, uv.array ); - uv.stride = sources[ id ].stride; - break; + case 'TEXCOORD': + buildGeometryData( primitive, sources[ id ], input.offset, uv.array ); + uv.stride = sources[ id ].stride; + break; - default: - console.warn( 'THREE.ColladaLoader: Semantic "%s" not handled in geometry build process.', key ); + default: + console.warn( 'THREE.ColladaLoader: Semantic "%s" not handled in geometry build process.', key ); - } + } - } - break; + } + break; - case 'NORMAL': - buildGeometryData( primitive, sources[ input.id ], input.offset, normal.array ); - normal.stride = sources[ input.id ].stride; - break; + case 'NORMAL': + buildGeometryData( primitive, sources[ input.id ], input.offset, normal.array ); + normal.stride = sources[ input.id ].stride; + break; - case 'COLOR': - buildGeometryData( primitive, sources[ input.id ], input.offset, color.array ); - color.stride = sources[ input.id ].stride; - break; + case 'COLOR': + buildGeometryData( primitive, sources[ input.id ], input.offset, color.array ); + color.stride = sources[ input.id ].stride; + break; - case 'TEXCOORD': - buildGeometryData( primitive, sources[ input.id ], input.offset, uv.array ); - uv.stride = sources[ input.id ].stride; - break; + case 'TEXCOORD': + buildGeometryData( primitive, sources[ input.id ], input.offset, uv.array ); + uv.stride = sources[ input.id ].stride; + break; - } + } - } + } - } + } - // build geometry + // build geometry - if ( position.array.length > 0 ) geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position.array, position.stride ) ); - if ( normal.array.length > 0 ) geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normal.array, normal.stride ) ); - if ( color.array.length > 0 ) geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( color.array, color.stride ) ); - if ( uv.array.length > 0 ) geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uv.array, uv.stride ) ); + if ( position.array.length > 0 ) geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position.array, position.stride ) ); + if ( normal.array.length > 0 ) geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normal.array, normal.stride ) ); + if ( color.array.length > 0 ) geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( color.array, color.stride ) ); + if ( uv.array.length > 0 ) geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uv.array, uv.stride ) ); - if ( skinIndex.array.length > 0 ) geometry.addAttribute( 'skinIndex', new THREE.Float32BufferAttribute( skinIndex.array, skinIndex.stride ) ); - if ( skinWeight.array.length > 0 ) geometry.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeight.array, skinWeight.stride ) ); + if ( skinIndex.array.length > 0 ) geometry.addAttribute( 'skinIndex', new THREE.Float32BufferAttribute( skinIndex.array, skinIndex.stride ) ); + if ( skinWeight.array.length > 0 ) geometry.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeight.array, skinWeight.stride ) ); - build.data = geometry; - build.type = primitives[ 0 ].type; - build.materialKeys = materialKeys; + build.data = geometry; + build.type = primitives[ 0 ].type; + build.materialKeys = materialKeys; - return build; + return build; - } + } - function buildGeometryData( primitive, source, offset, array ) { + function buildGeometryData( primitive, source, offset, array ) { - var indices = primitive.p; - var stride = primitive.stride; - var vcount = primitive.vcount; + var indices = primitive.p; + var stride = primitive.stride; + var vcount = primitive.vcount; - function pushVector( i ) { + function pushVector( i ) { - var index = indices[ i + offset ] * sourceStride; - var length = index + sourceStride; + var index = indices[ i + offset ] * sourceStride; + var length = index + sourceStride; - for ( ; index < length; index ++ ) { + for ( ; index < length; index ++ ) { - array.push( sourceArray[ index ] ); + array.push( sourceArray[ index ] ); - } + } - } + } - var sourceArray = source.array; - var sourceStride = source.stride; + var sourceArray = source.array; + var sourceStride = source.stride; - if ( primitive.vcount !== undefined ) { + if ( primitive.vcount !== undefined ) { - var index = 0; + var index = 0; - for ( var i = 0, l = vcount.length; i < l; i ++ ) { + for ( var i = 0, l = vcount.length; i < l; i ++ ) { - var count = vcount[ i ]; + var count = vcount[ i ]; - if ( count === 4 ) { + if ( count === 4 ) { - var a = index + stride * 0; - var b = index + stride * 1; - var c = index + stride * 2; - var d = index + stride * 3; + var a = index + stride * 0; + var b = index + stride * 1; + var c = index + stride * 2; + var d = index + stride * 3; - pushVector( a ); pushVector( b ); pushVector( d ); - pushVector( b ); pushVector( c ); pushVector( d ); + pushVector( a ); pushVector( b ); pushVector( d ); + pushVector( b ); pushVector( c ); pushVector( d ); - } else if ( count === 3 ) { + } else if ( count === 3 ) { - var a = index + stride * 0; - var b = index + stride * 1; - var c = index + stride * 2; + var a = index + stride * 0; + var b = index + stride * 1; + var c = index + stride * 2; - pushVector( a ); pushVector( b ); pushVector( c ); + pushVector( a ); pushVector( b ); pushVector( c ); - } else if ( count > 4 ) { + } else if ( count > 4 ) { - for ( var k = 1, kl = ( count - 2 ); k <= kl; k ++ ) { + for ( var k = 1, kl = ( count - 2 ); k <= kl; k ++ ) { - var a = index + stride * 0; - var b = index + stride * k; - var c = index + stride * ( k + 1 ); + var a = index + stride * 0; + var b = index + stride * k; + var c = index + stride * ( k + 1 ); - pushVector( a ); pushVector( b ); pushVector( c ); + pushVector( a ); pushVector( b ); pushVector( c ); - } + } - } + } - index += stride * count; + index += stride * count; - } + } - } else { + } else { - for ( var i = 0, l = indices.length; i < l; i += stride ) { + for ( var i = 0, l = indices.length; i < l; i += stride ) { - pushVector( i ); + pushVector( i ); - } + } - } + } - } + } - function getGeometry( id ) { + function getGeometry( id ) { - return getBuild( library.geometries[ id ], buildGeometry ); + return getBuild( library.geometries[ id ], buildGeometry ); - } + } - // kinematics + // kinematics - function parseKinematicsModel( xml ) { + function parseKinematicsModel( xml ) { - var data = { - name: xml.getAttribute( 'name' ) || '', - joints: {}, - links: [] - }; + var data = { + name: xml.getAttribute( 'name' ) || '', + joints: {}, + links: [] + }; - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'technique_common': - parseKinematicsTechniqueCommon( child, data ); - break; + case 'technique_common': + parseKinematicsTechniqueCommon( child, data ); + break; - } + } - } + } - library.kinematicsModels[ xml.getAttribute( 'id' ) ] = data; + library.kinematicsModels[ xml.getAttribute( 'id' ) ] = data; - } + } - function buildKinematicsModel( data ) { + function buildKinematicsModel( data ) { - if ( data.build !== undefined ) return data.build; + if ( data.build !== undefined ) return data.build; - return data; + return data; - } + } - function getKinematicsModel( id ) { + function getKinematicsModel( id ) { - return getBuild( library.kinematicsModels[ id ], buildKinematicsModel ); + return getBuild( library.kinematicsModels[ id ], buildKinematicsModel ); - } + } - function parseKinematicsTechniqueCommon( xml, data ) { + function parseKinematicsTechniqueCommon( xml, data ) { - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'joint': - data.joints[ child.getAttribute( 'sid' ) ] = parseKinematicsJoint( child ); - break; + case 'joint': + data.joints[ child.getAttribute( 'sid' ) ] = parseKinematicsJoint( child ); + break; - case 'link': - data.links.push( parseKinematicsLink( child ) ); - break; + case 'link': + data.links.push( parseKinematicsLink( child ) ); + break; - } + } - } + } - } + } - function parseKinematicsJoint( xml ) { + function parseKinematicsJoint( xml ) { - var data; + var data; - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'prismatic': - case 'revolute': - data = parseKinematicsJointParameter( child ); - break; + case 'prismatic': + case 'revolute': + data = parseKinematicsJointParameter( child ); + break; - } + } - } + } - return data; + return data; - } + } - function parseKinematicsJointParameter( xml, data ) { + function parseKinematicsJointParameter( xml, data ) { - var data = { - sid: xml.getAttribute( 'sid' ), - name: xml.getAttribute( 'name' ) || '', - axis: new THREE.Vector3(), - limits: { - min: 0, - max: 0 - }, - type: xml.nodeName, - static: false, - zeroPosition: 0, - middlePosition: 0 - }; + var data = { + sid: xml.getAttribute( 'sid' ), + name: xml.getAttribute( 'name' ) || '', + axis: new THREE.Vector3(), + limits: { + min: 0, + max: 0 + }, + type: xml.nodeName, + static: false, + zeroPosition: 0, + middlePosition: 0 + }; - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'axis': - var array = parseFloats( child.textContent ); - data.axis.fromArray( array ); - break; - case 'limits': - var max = child.getElementsByTagName( 'max' )[ 0 ]; - var min = child.getElementsByTagName( 'min' )[ 0 ]; + case 'axis': + var array = parseFloats( child.textContent ); + data.axis.fromArray( array ); + break; + case 'limits': + var max = child.getElementsByTagName( 'max' )[ 0 ]; + var min = child.getElementsByTagName( 'min' )[ 0 ]; - data.limits.max = parseFloat( max.textContent ); - data.limits.min = parseFloat( min.textContent ); - break; + data.limits.max = parseFloat( max.textContent ); + data.limits.min = parseFloat( min.textContent ); + break; - } + } - } + } - // if min is equal to or greater than max, consider the joint static + // if min is equal to or greater than max, consider the joint static - if ( data.limits.min >= data.limits.max ) { + if ( data.limits.min >= data.limits.max ) { - data.static = true; + data.static = true; - } + } - // calculate middle position + // calculate middle position - data.middlePosition = ( data.limits.min + data.limits.max ) / 2.0; + data.middlePosition = ( data.limits.min + data.limits.max ) / 2.0; - return data; + return data; - } + } - function parseKinematicsLink( xml ) { + function parseKinematicsLink( xml ) { - var data = { - sid: xml.getAttribute( 'sid' ), - name: xml.getAttribute( 'name' ) || '', - attachments: [], - transforms: [] - }; + var data = { + sid: xml.getAttribute( 'sid' ), + name: xml.getAttribute( 'name' ) || '', + attachments: [], + transforms: [] + }; - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'attachment_full': - data.attachments.push( parseKinematicsAttachment( child ) ); - break; + case 'attachment_full': + data.attachments.push( parseKinematicsAttachment( child ) ); + break; - case 'matrix': - case 'translate': - case 'rotate': - data.transforms.push( parseKinematicsTransform( child ) ); - break; + case 'matrix': + case 'translate': + case 'rotate': + data.transforms.push( parseKinematicsTransform( child ) ); + break; - } + } - } + } - return data; + return data; - } + } - function parseKinematicsAttachment( xml ) { + function parseKinematicsAttachment( xml ) { - var data = { - joint: xml.getAttribute( 'joint' ).split( '/' ).pop(), - transforms: [], - links: [] - }; + var data = { + joint: xml.getAttribute( 'joint' ).split( '/' ).pop(), + transforms: [], + links: [] + }; - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'link': - data.links.push( parseKinematicsLink( child ) ); - break; + case 'link': + data.links.push( parseKinematicsLink( child ) ); + break; - case 'matrix': - case 'translate': - case 'rotate': - data.transforms.push( parseKinematicsTransform( child ) ); - break; + case 'matrix': + case 'translate': + case 'rotate': + data.transforms.push( parseKinematicsTransform( child ) ); + break; - } + } - } + } - return data; + return data; - } + } - function parseKinematicsTransform( xml ) { + function parseKinematicsTransform( xml ) { - var data = { - type: xml.nodeName - }; + var data = { + type: xml.nodeName + }; - var array = parseFloats( xml.textContent ); + var array = parseFloats( xml.textContent ); - switch ( data.type ) { + switch ( data.type ) { - case 'matrix': - data.obj = new THREE.Matrix4(); - data.obj.fromArray( array ).transpose(); - break; + case 'matrix': + data.obj = new THREE.Matrix4(); + data.obj.fromArray( array ).transpose(); + break; - case 'translate': - data.obj = new THREE.Vector3(); - data.obj.fromArray( array ); - break; + case 'translate': + data.obj = new THREE.Vector3(); + data.obj.fromArray( array ); + break; - case 'rotate': - data.obj = new THREE.Vector3(); - data.obj.fromArray( array ); - data.angle = THREE.Math.degToRad( array[ 3 ] ); - break; + case 'rotate': + data.obj = new THREE.Vector3(); + data.obj.fromArray( array ); + data.angle = THREE.Math.degToRad( array[ 3 ] ); + break; - } + } - return data; + return data; - } + } - // physics + // physics - function parsePhysicsModel( xml ) { + function parsePhysicsModel( xml ) { - var data = { - name: xml.getAttribute( 'name' ) || '', - rigidBodies: {} - }; + var data = { + name: xml.getAttribute( 'name' ) || '', + rigidBodies: {} + }; - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'rigid_body': - data.rigidBodies[ child.getAttribute( 'name' ) ] = {}; - parsePhysicsRigidBody( child, data.rigidBodies[ child.getAttribute( 'name' ) ] ); - break; + case 'rigid_body': + data.rigidBodies[ child.getAttribute( 'name' ) ] = {}; + parsePhysicsRigidBody( child, data.rigidBodies[ child.getAttribute( 'name' ) ] ); + break; - } + } - } + } - library.physicsModels[ xml.getAttribute( 'id' ) ] = data; + library.physicsModels[ xml.getAttribute( 'id' ) ] = data; - } + } - function parsePhysicsRigidBody( xml, data ) { + function parsePhysicsRigidBody( xml, data ) { - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'technique_common': - parsePhysicsTechniqueCommon( child, data ); - break; + case 'technique_common': + parsePhysicsTechniqueCommon( child, data ); + break; - } + } - } + } - } + } - function parsePhysicsTechniqueCommon( xml, data ) { + function parsePhysicsTechniqueCommon( xml, data ) { - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'inertia': - data.inertia = parseFloats( child.textContent ); - break; + case 'inertia': + data.inertia = parseFloats( child.textContent ); + break; - case 'mass': - data.mass = parseFloats( child.textContent )[0]; - break; + case 'mass': + data.mass = parseFloats( child.textContent )[0]; + break; - } + } - } + } - } + } - // scene + // scene - function parseKinematicsScene( xml ) { + function parseKinematicsScene( xml ) { - var data = { - bindJointAxis: [] - }; + var data = { + bindJointAxis: [] + }; - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'bind_joint_axis': - data.bindJointAxis.push( parseKinematicsBindJointAxis( child ) ); - break; + case 'bind_joint_axis': + data.bindJointAxis.push( parseKinematicsBindJointAxis( child ) ); + break; - } + } - } + } - library.kinematicsScenes[ parseId( xml.getAttribute( 'url' ) ) ] = data; + library.kinematicsScenes[ parseId( xml.getAttribute( 'url' ) ) ] = data; - } + } - function parseKinematicsBindJointAxis( xml ) { + function parseKinematicsBindJointAxis( xml ) { - var data = { - target: xml.getAttribute( 'target' ).split( '/' ).pop() - }; + var data = { + target: xml.getAttribute( 'target' ).split( '/' ).pop() + }; - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'axis': - var param = child.getElementsByTagName( 'param' )[ 0 ]; - data.axis = param.textContent; - var tmpJointIndex = data.axis.split( 'inst_' ).pop().split( 'axis' )[ 0 ]; - data.jointIndex = tmpJointIndex.substr( 0, tmpJointIndex.length - 1 ); - break; + case 'axis': + var param = child.getElementsByTagName( 'param' )[ 0 ]; + data.axis = param.textContent; + var tmpJointIndex = data.axis.split( 'inst_' ).pop().split( 'axis' )[ 0 ]; + data.jointIndex = tmpJointIndex.substr( 0, tmpJointIndex.length - 1 ); + break; - } + } - } + } - return data; + return data; - } + } - function buildKinematicsScene( data ) { + function buildKinematicsScene( data ) { - if ( data.build !== undefined ) return data.build; + if ( data.build !== undefined ) return data.build; - return data; + return data; - } + } - function getKinematicsScene( id ) { + function getKinematicsScene( id ) { - return getBuild( library.kinematicsScenes[ id ], buildKinematicsScene ); + return getBuild( library.kinematicsScenes[ id ], buildKinematicsScene ); - } + } - function setupKinematics() { + function setupKinematics() { - var kinematicsModelId = Object.keys( library.kinematicsModels )[ 0 ]; - var kinematicsSceneId = Object.keys( library.kinematicsScenes )[ 0 ]; - var visualSceneId = Object.keys( library.visualScenes )[ 0 ]; + var kinematicsModelId = Object.keys( library.kinematicsModels )[ 0 ]; + var kinematicsSceneId = Object.keys( library.kinematicsScenes )[ 0 ]; + var visualSceneId = Object.keys( library.visualScenes )[ 0 ]; - if ( kinematicsModelId === undefined || kinematicsSceneId === undefined ) return; + if ( kinematicsModelId === undefined || kinematicsSceneId === undefined ) return; - var kinematicsModel = getKinematicsModel( kinematicsModelId ); - var kinematicsScene = getKinematicsScene( kinematicsSceneId ); - var visualScene = getVisualScene( visualSceneId ); + var kinematicsModel = getKinematicsModel( kinematicsModelId ); + var kinematicsScene = getKinematicsScene( kinematicsSceneId ); + var visualScene = getVisualScene( visualSceneId ); - var bindJointAxis = kinematicsScene.bindJointAxis; - var jointMap = {}; + var bindJointAxis = kinematicsScene.bindJointAxis; + var jointMap = {}; - for ( var i = 0, l = bindJointAxis.length; i < l; i ++ ) { + for ( var i = 0, l = bindJointAxis.length; i < l; i ++ ) { - var axis = bindJointAxis[ i ]; + var axis = bindJointAxis[ i ]; - // the result of the following query is an element of type 'translate', 'rotate','scale' or 'matrix' + // the result of the following query is an element of type 'translate', 'rotate','scale' or 'matrix' - var targetElement = collada.querySelector( '[sid="' + axis.target + '"]' ); + var targetElement = collada.querySelector( '[sid="' + axis.target + '"]' ); - if ( targetElement ) { + if ( targetElement ) { - // get the parent of the transfrom element + // get the parent of the transfrom element - var parentVisualElement = targetElement.parentElement; + var parentVisualElement = targetElement.parentElement; - // connect the joint of the kinematics model with the element in the visual scene + // connect the joint of the kinematics model with the element in the visual scene - connect( axis.jointIndex, parentVisualElement ); + connect( axis.jointIndex, parentVisualElement ); - } + } - } + } - function connect( jointIndex, visualElement ) { + function connect( jointIndex, visualElement ) { - var visualElementName = visualElement.getAttribute( 'name' ); - var joint = kinematicsModel.joints[ jointIndex ]; + var visualElementName = visualElement.getAttribute( 'name' ); + var joint = kinematicsModel.joints[ jointIndex ]; - visualScene.traverse( function ( object ) { + visualScene.traverse( function ( object ) { - if ( object.name === visualElementName ) { + if ( object.name === visualElementName ) { - jointMap[ jointIndex ] = { - object: object, - transforms: buildTransformList( visualElement ), - joint: joint, - position: joint.zeroPosition - }; + jointMap[ jointIndex ] = { + object: object, + transforms: buildTransformList( visualElement ), + joint: joint, + position: joint.zeroPosition + }; - } + } - } ); + } ); - } + } - var m0 = new THREE.Matrix4(); + var m0 = new THREE.Matrix4(); - kinematics = { + kinematics = { - joints: kinematicsModel && kinematicsModel.joints, + joints: kinematicsModel && kinematicsModel.joints, - getJointValue: function ( jointIndex ) { + getJointValue: function ( jointIndex ) { - var jointData = jointMap[ jointIndex ]; + var jointData = jointMap[ jointIndex ]; - if ( jointData ) { + if ( jointData ) { - return jointData.position; + return jointData.position; - } else { + } else { - console.warn( 'THREE.ColladaLoader: Joint ' + jointIndex + ' doesn\'t exist.' ); + console.warn( 'THREE.ColladaLoader: Joint ' + jointIndex + ' doesn\'t exist.' ); - } + } - }, + }, - setJointValue: function ( jointIndex, value ) { + setJointValue: function ( jointIndex, value ) { - var jointData = jointMap[ jointIndex ]; + var jointData = jointMap[ jointIndex ]; - if ( jointData ) { + if ( jointData ) { - var joint = jointData.joint; + var joint = jointData.joint; - if ( value > joint.limits.max || value < joint.limits.min ) { + if ( value > joint.limits.max || value < joint.limits.min ) { - console.warn( 'THREE.ColladaLoader: Joint ' + jointIndex + ' value ' + value + ' outside of limits (min: ' + joint.limits.min + ', max: ' + joint.limits.max + ').' ); + console.warn( 'THREE.ColladaLoader: Joint ' + jointIndex + ' value ' + value + ' outside of limits (min: ' + joint.limits.min + ', max: ' + joint.limits.max + ').' ); - } else if ( joint.static ) { + } else if ( joint.static ) { - console.warn( 'THREE.ColladaLoader: Joint ' + jointIndex + ' is static.' ); + console.warn( 'THREE.ColladaLoader: Joint ' + jointIndex + ' is static.' ); - } else { + } else { - var object = jointData.object; - var axis = joint.axis; - var transforms = jointData.transforms; + var object = jointData.object; + var axis = joint.axis; + var transforms = jointData.transforms; - matrix.identity(); + matrix.identity(); - // each update, we have to apply all transforms in the correct order + // each update, we have to apply all transforms in the correct order - for ( var i = 0; i < transforms.length; i ++ ) { + for ( var i = 0; i < transforms.length; i ++ ) { - var transform = transforms[ i ]; + var transform = transforms[ i ]; - // if there is a connection of the transform node with a joint, apply the joint value + // if there is a connection of the transform node with a joint, apply the joint value - if ( transform.sid && transform.sid.indexOf( jointIndex ) !== - 1 ) { + if ( transform.sid && transform.sid.indexOf( jointIndex ) !== - 1 ) { - switch ( joint.type ) { + switch ( joint.type ) { - case 'revolute': - matrix.multiply( m0.makeRotationAxis( axis, THREE.Math.degToRad( value ) ) ); - break; + case 'revolute': + matrix.multiply( m0.makeRotationAxis( axis, THREE.Math.degToRad( value ) ) ); + break; - case 'prismatic': - matrix.multiply( m0.makeTranslation( axis.x * value, axis.y * value, axis.z * value ) ); - break; + case 'prismatic': + matrix.multiply( m0.makeTranslation( axis.x * value, axis.y * value, axis.z * value ) ); + break; - default: - console.warn( 'THREE.ColladaLoader: Unknown joint type: ' + joint.type ); - break; + default: + console.warn( 'THREE.ColladaLoader: Unknown joint type: ' + joint.type ); + break; - } + } - } else { + } else { - switch ( transform.type ) { + switch ( transform.type ) { - case 'matrix': - matrix.multiply( transform.obj ); - break; + case 'matrix': + matrix.multiply( transform.obj ); + break; - case 'translate': - matrix.multiply( m0.makeTranslation( transform.obj.x, transform.obj.y, transform.obj.z ) ); - break; + case 'translate': + matrix.multiply( m0.makeTranslation( transform.obj.x, transform.obj.y, transform.obj.z ) ); + break; - case 'scale': - matrix.scale( transform.obj ); - break; + case 'scale': + matrix.scale( transform.obj ); + break; - case 'rotate': - matrix.multiply( m0.makeRotationAxis( transform.obj, transform.angle ) ); - break; + case 'rotate': + matrix.multiply( m0.makeRotationAxis( transform.obj, transform.angle ) ); + break; - } + } - } + } - } + } - object.matrix.copy( matrix ); - object.matrix.decompose( object.position, object.quaternion, object.scale ); + object.matrix.copy( matrix ); + object.matrix.decompose( object.position, object.quaternion, object.scale ); - jointMap[ jointIndex ].position = value; + jointMap[ jointIndex ].position = value; - } + } - } else { + } else { - console.log( 'THREE.ColladaLoader: ' + jointIndex + ' does not exist.' ); + console.log( 'THREE.ColladaLoader: ' + jointIndex + ' does not exist.' ); - } + } - } + } - }; + }; - } + } - function buildTransformList( node ) { + function buildTransformList( node ) { - var transforms = []; + var transforms = []; - var xml = collada.querySelector( '[id="' + node.id + '"]' ); + var xml = collada.querySelector( '[id="' + node.id + '"]' ); - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'matrix': - var array = parseFloats( child.textContent ); - var matrix = new THREE.Matrix4().fromArray( array ).transpose(); - transforms.push( { - sid: child.getAttribute( 'sid' ), - type: child.nodeName, - obj: matrix - } ); - break; + case 'matrix': + var array = parseFloats( child.textContent ); + var matrix = new THREE.Matrix4().fromArray( array ).transpose(); + transforms.push( { + sid: child.getAttribute( 'sid' ), + type: child.nodeName, + obj: matrix + } ); + break; - case 'translate': - case 'scale': - var array = parseFloats( child.textContent ); - var vector = new THREE.Vector3().fromArray( array ); - transforms.push( { - sid: child.getAttribute( 'sid' ), - type: child.nodeName, - obj: vector - } ); - break; + case 'translate': + case 'scale': + var array = parseFloats( child.textContent ); + var vector = new THREE.Vector3().fromArray( array ); + transforms.push( { + sid: child.getAttribute( 'sid' ), + type: child.nodeName, + obj: vector + } ); + break; - case 'rotate': - var array = parseFloats( child.textContent ); - var vector = new THREE.Vector3().fromArray( array ); - var angle = THREE.Math.degToRad( array[ 3 ] ); - transforms.push( { - sid: child.getAttribute( 'sid' ), - type: child.nodeName, - obj: vector, - angle: angle - } ); - break; + case 'rotate': + var array = parseFloats( child.textContent ); + var vector = new THREE.Vector3().fromArray( array ); + var angle = THREE.Math.degToRad( array[ 3 ] ); + transforms.push( { + sid: child.getAttribute( 'sid' ), + type: child.nodeName, + obj: vector, + angle: angle + } ); + break; - } + } - } + } - return transforms; + return transforms; - } + } - // nodes + // nodes - function prepareNodes( xml ) { + function prepareNodes( xml ) { - var elements = xml.getElementsByTagName( 'node' ); + var elements = xml.getElementsByTagName( 'node' ); - // ensure all node elements have id attributes + // ensure all node elements have id attributes - for ( var i = 0; i < elements.length; i ++ ) { + for ( var i = 0; i < elements.length; i ++ ) { - var element = elements[ i ]; + var element = elements[ i ]; - if ( element.hasAttribute( 'id' ) === false ) { + if ( element.hasAttribute( 'id' ) === false ) { - element.setAttribute( 'id', generateId() ); + element.setAttribute( 'id', generateId() ); - } + } - } + } - } + } - var matrix = new THREE.Matrix4(); - var vector = new THREE.Vector3(); + var matrix = new THREE.Matrix4(); + var vector = new THREE.Vector3(); - function parseNode( xml ) { + function parseNode( xml ) { - var data = { - name: xml.getAttribute( 'name' ) || '', - type: xml.getAttribute( 'type' ), - id: xml.getAttribute( 'id' ), - sid: xml.getAttribute( 'sid' ), - matrix: new THREE.Matrix4(), - nodes: [], - instanceCameras: [], - instanceControllers: [], - instanceLights: [], - instanceGeometries: [], - instanceNodes: [], - transforms: {} - }; + var data = { + name: xml.getAttribute( 'name' ) || '', + type: xml.getAttribute( 'type' ), + id: xml.getAttribute( 'id' ), + sid: xml.getAttribute( 'sid' ), + matrix: new THREE.Matrix4(), + nodes: [], + instanceCameras: [], + instanceControllers: [], + instanceLights: [], + instanceGeometries: [], + instanceNodes: [], + transforms: {} + }; - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - if ( child.nodeType !== 1 ) continue; + if ( child.nodeType !== 1 ) continue; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'node': - data.nodes.push( child.getAttribute( 'id' ) ); - parseNode( child ); - break; + case 'node': + data.nodes.push( child.getAttribute( 'id' ) ); + parseNode( child ); + break; - case 'instance_camera': - data.instanceCameras.push( parseId( child.getAttribute( 'url' ) ) ); - break; + case 'instance_camera': + data.instanceCameras.push( parseId( child.getAttribute( 'url' ) ) ); + break; - case 'instance_controller': - data.instanceControllers.push( parseNodeInstance( child ) ); - break; + case 'instance_controller': + data.instanceControllers.push( parseNodeInstance( child ) ); + break; - case 'instance_light': - data.instanceLights.push( parseId( child.getAttribute( 'url' ) ) ); - break; + case 'instance_light': + data.instanceLights.push( parseId( child.getAttribute( 'url' ) ) ); + break; - case 'instance_geometry': - data.instanceGeometries.push( parseNodeInstance( child ) ); - break; + case 'instance_geometry': + data.instanceGeometries.push( parseNodeInstance( child ) ); + break; - case 'instance_node': - data.instanceNodes.push( parseId( child.getAttribute( 'url' ) ) ); - break; + case 'instance_node': + data.instanceNodes.push( parseId( child.getAttribute( 'url' ) ) ); + break; - case 'matrix': - var array = parseFloats( child.textContent ); - data.matrix.multiply( matrix.fromArray( array ).transpose() ); - data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName; - break; + case 'matrix': + var array = parseFloats( child.textContent ); + data.matrix.multiply( matrix.fromArray( array ).transpose() ); + data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName; + break; - case 'translate': - var array = parseFloats( child.textContent ); - vector.fromArray( array ); - data.matrix.multiply( matrix.makeTranslation( vector.x, vector.y, vector.z ) ); - data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName; - break; + case 'translate': + var array = parseFloats( child.textContent ); + vector.fromArray( array ); + data.matrix.multiply( matrix.makeTranslation( vector.x, vector.y, vector.z ) ); + data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName; + break; - case 'rotate': - var array = parseFloats( child.textContent ); - var angle = THREE.Math.degToRad( array[ 3 ] ); - data.matrix.multiply( matrix.makeRotationAxis( vector.fromArray( array ), angle ) ); - data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName; - break; + case 'rotate': + var array = parseFloats( child.textContent ); + var angle = THREE.Math.degToRad( array[ 3 ] ); + data.matrix.multiply( matrix.makeRotationAxis( vector.fromArray( array ), angle ) ); + data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName; + break; - case 'scale': - var array = parseFloats( child.textContent ); - data.matrix.scale( vector.fromArray( array ) ); - data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName; - break; + case 'scale': + var array = parseFloats( child.textContent ); + data.matrix.scale( vector.fromArray( array ) ); + data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName; + break; - case 'extra': - break; + case 'extra': + break; - default: - console.log( child ); + default: + console.log( child ); - } + } - } + } - if ( hasNode( data.id ) ) { + if ( hasNode( data.id ) ) { - console.warn( 'THREE.ColladaLoader: There is already a node with ID %s. Exclude current node from further processing.', data.id ); + console.warn( 'THREE.ColladaLoader: There is already a node with ID %s. Exclude current node from further processing.', data.id ); - } else { + } else { - library.nodes[ data.id ] = data; + library.nodes[ data.id ] = data; - } + } - return data; + return data; - } + } - function parseNodeInstance( xml ) { + function parseNodeInstance( xml ) { - var data = { - id: parseId( xml.getAttribute( 'url' ) ), - materials: {}, - skeletons: [] - }; + var data = { + id: parseId( xml.getAttribute( 'url' ) ), + materials: {}, + skeletons: [] + }; - for ( var i = 0; i < xml.childNodes.length; i ++ ) { + for ( var i = 0; i < xml.childNodes.length; i ++ ) { - var child = xml.childNodes[ i ]; + var child = xml.childNodes[ i ]; - switch ( child.nodeName ) { + switch ( child.nodeName ) { - case 'bind_material': - var instances = child.getElementsByTagName( 'instance_material' ); + case 'bind_material': + var instances = child.getElementsByTagName( 'instance_material' ); - for ( var j = 0; j < instances.length; j ++ ) { + for ( var j = 0; j < instances.length; j ++ ) { - var instance = instances[ j ]; - var symbol = instance.getAttribute( 'symbol' ); - var target = instance.getAttribute( 'target' ); + var instance = instances[ j ]; + var symbol = instance.getAttribute( 'symbol' ); + var target = instance.getAttribute( 'target' ); - data.materials[ symbol ] = parseId( target ); + data.materials[ symbol ] = parseId( target ); - } + } - break; + break; - case 'skeleton': - data.skeletons.push( parseId( child.textContent ) ); - break; + case 'skeleton': + data.skeletons.push( parseId( child.textContent ) ); + break; - default: - break; + default: + break; - } + } - } + } - return data; + return data; - } + } - function buildSkeleton( skeletons, joints ) { + function buildSkeleton( skeletons, joints ) { - var boneData = []; - var sortedBoneData = []; + var boneData = []; + var sortedBoneData = []; - var i, j, data; + var i, j, data; - // a skeleton can have multiple root bones. collada expresses this - // situtation with multiple "skeleton" tags per controller instance + // a skeleton can have multiple root bones. collada expresses this + // situtation with multiple "skeleton" tags per controller instance - for ( i = 0; i < skeletons.length; i ++ ) { + for ( i = 0; i < skeletons.length; i ++ ) { - var skeleton = skeletons[ i ]; + var skeleton = skeletons[ i ]; - var root; + var root; - if ( hasNode( skeleton ) ) { + if ( hasNode( skeleton ) ) { - root = getNode( skeleton ); - buildBoneHierarchy( root, joints, boneData ); + root = getNode( skeleton ); + buildBoneHierarchy( root, joints, boneData ); - } else if ( hasVisualScene( skeleton ) ) { + } else if ( hasVisualScene( skeleton ) ) { - // handle case where the skeleton refers to the visual scene (#13335) + // handle case where the skeleton refers to the visual scene (#13335) - var visualScene = library.visualScenes[ skeleton ]; - var children = visualScene.children; + var visualScene = library.visualScenes[ skeleton ]; + var children = visualScene.children; - for ( var j = 0; j < children.length; j ++ ) { + for ( var j = 0; j < children.length; j ++ ) { - var child = children[ j ]; + var child = children[ j ]; - if ( child.type === 'JOINT' ) { + if ( child.type === 'JOINT' ) { - var root = getNode( child.id ); - buildBoneHierarchy( root, joints, boneData ); + var root = getNode( child.id ); + buildBoneHierarchy( root, joints, boneData ); - } + } - } + } - } else { + } else { - console.error( 'THREE.ColladaLoader: Unable to find root bone of skeleton with ID:', skeleton ); + console.error( 'THREE.ColladaLoader: Unable to find root bone of skeleton with ID:', skeleton ); - } + } - } + } - // sort bone data (the order is defined in the corresponding controller) + // sort bone data (the order is defined in the corresponding controller) - for ( i = 0; i < joints.length; i ++ ) { + for ( i = 0; i < joints.length; i ++ ) { - for ( j = 0; j < boneData.length; j ++ ) { + for ( j = 0; j < boneData.length; j ++ ) { - data = boneData[ j ]; + data = boneData[ j ]; - if ( data.bone.name === joints[ i ].name ) { + if ( data.bone.name === joints[ i ].name ) { - sortedBoneData[ i ] = data; - data.processed = true; - break; + sortedBoneData[ i ] = data; + data.processed = true; + break; - } + } - } + } - } + } - // add unprocessed bone data at the end of the list + // add unprocessed bone data at the end of the list - for ( i = 0; i < boneData.length; i ++ ) { + for ( i = 0; i < boneData.length; i ++ ) { - data = boneData[ i ]; + data = boneData[ i ]; - if ( data.processed === false ) { + if ( data.processed === false ) { - sortedBoneData.push( data ); - data.processed = true; + sortedBoneData.push( data ); + data.processed = true; - } + } - } + } - // setup arrays for skeleton creation + // setup arrays for skeleton creation - var bones = []; - var boneInverses = []; + var bones = []; + var boneInverses = []; - for ( i = 0; i < sortedBoneData.length; i ++ ) { + for ( i = 0; i < sortedBoneData.length; i ++ ) { - data = sortedBoneData[ i ]; + data = sortedBoneData[ i ]; - bones.push( data.bone ); - boneInverses.push( data.boneInverse ); + bones.push( data.bone ); + boneInverses.push( data.boneInverse ); - } + } - return new THREE.Skeleton( bones, boneInverses ); + return new THREE.Skeleton( bones, boneInverses ); - } + } - function buildBoneHierarchy( root, joints, boneData ) { + function buildBoneHierarchy( root, joints, boneData ) { - // setup bone data from visual scene + // setup bone data from visual scene - root.traverse( function ( object ) { + root.traverse( function ( object ) { - if ( object.isBone === true ) { + if ( object.isBone === true ) { - var boneInverse; + var boneInverse; - // retrieve the boneInverse from the controller data + // retrieve the boneInverse from the controller data - for ( var i = 0; i < joints.length; i ++ ) { + for ( var i = 0; i < joints.length; i ++ ) { - var joint = joints[ i ]; + var joint = joints[ i ]; - if ( joint.name === object.name ) { + if ( joint.name === object.name ) { - boneInverse = joint.boneInverse; - break; + boneInverse = joint.boneInverse; + break; - } + } - } + } - if ( boneInverse === undefined ) { + if ( boneInverse === undefined ) { - // Unfortunately, there can be joints in the visual scene that are not part of the - // corresponding controller. In this case, we have to create a dummy boneInverse matrix - // for the respective bone. This bone won't affect any vertices, because there are no skin indices - // and weights defined for it. But we still have to add the bone to the sorted bone list in order to - // ensure a correct animation of the model. + // Unfortunately, there can be joints in the visual scene that are not part of the + // corresponding controller. In this case, we have to create a dummy boneInverse matrix + // for the respective bone. This bone won't affect any vertices, because there are no skin indices + // and weights defined for it. But we still have to add the bone to the sorted bone list in order to + // ensure a correct animation of the model. - boneInverse = new THREE.Matrix4(); + boneInverse = new THREE.Matrix4(); - } + } - boneData.push( { bone: object, boneInverse: boneInverse, processed: false } ); + boneData.push( { bone: object, boneInverse: boneInverse, processed: false } ); - } + } - } ); + } ); - } + } - function buildNode( data ) { + function buildNode( data ) { - var objects = []; + var objects = []; - var matrix = data.matrix; - var nodes = data.nodes; - var type = data.type; - var instanceCameras = data.instanceCameras; - var instanceControllers = data.instanceControllers; - var instanceLights = data.instanceLights; - var instanceGeometries = data.instanceGeometries; - var instanceNodes = data.instanceNodes; + var matrix = data.matrix; + var nodes = data.nodes; + var type = data.type; + var instanceCameras = data.instanceCameras; + var instanceControllers = data.instanceControllers; + var instanceLights = data.instanceLights; + var instanceGeometries = data.instanceGeometries; + var instanceNodes = data.instanceNodes; - // nodes + // nodes - for ( var i = 0, l = nodes.length; i < l; i ++ ) { + for ( var i = 0, l = nodes.length; i < l; i ++ ) { - objects.push( getNode( nodes[ i ] ) ); + objects.push( getNode( nodes[ i ] ) ); - } + } - // instance cameras + // instance cameras - for ( var i = 0, l = instanceCameras.length; i < l; i ++ ) { + for ( var i = 0, l = instanceCameras.length; i < l; i ++ ) { - var instanceCamera = getCamera( instanceCameras[ i ] ); + var instanceCamera = getCamera( instanceCameras[ i ] ); - if ( instanceCamera !== null ) { + if ( instanceCamera !== null ) { - objects.push( instanceCamera.clone() ); + objects.push( instanceCamera.clone() ); - } + } - } + } - // instance controllers + // instance controllers - for ( var i = 0, l = instanceControllers.length; i < l; i ++ ) { + for ( var i = 0, l = instanceControllers.length; i < l; i ++ ) { - var instance = instanceControllers[ i ]; - var controller = getController( instance.id ); - var geometries = getGeometry( controller.id ); - var newObjects = buildObjects( geometries, instance.materials ); + var instance = instanceControllers[ i ]; + var controller = getController( instance.id ); + var geometries = getGeometry( controller.id ); + var newObjects = buildObjects( geometries, instance.materials ); - var skeletons = instance.skeletons; - var joints = controller.skin.joints; + var skeletons = instance.skeletons; + var joints = controller.skin.joints; - var skeleton = buildSkeleton( skeletons, joints ); + var skeleton = buildSkeleton( skeletons, joints ); - for ( var j = 0, jl = newObjects.length; j < jl; j ++ ) { + for ( var j = 0, jl = newObjects.length; j < jl; j ++ ) { - var object = newObjects[ j ]; + var object = newObjects[ j ]; - if ( object.isSkinnedMesh ) { + if ( object.isSkinnedMesh ) { - object.bind( skeleton, controller.skin.bindMatrix ); - object.normalizeSkinWeights(); + object.bind( skeleton, controller.skin.bindMatrix ); + object.normalizeSkinWeights(); - } + } - objects.push( object ); + objects.push( object ); - } + } - } + } - // instance lights + // instance lights - for ( var i = 0, l = instanceLights.length; i < l; i ++ ) { + for ( var i = 0, l = instanceLights.length; i < l; i ++ ) { - var instanceLight = getLight( instanceLights[ i ] ); + var instanceLight = getLight( instanceLights[ i ] ); - if ( instanceLight !== null ) { + if ( instanceLight !== null ) { - objects.push( instanceLight.clone() ); + objects.push( instanceLight.clone() ); - } + } - } + } - // instance geometries + // instance geometries - for ( var i = 0, l = instanceGeometries.length; i < l; i ++ ) { + for ( var i = 0, l = instanceGeometries.length; i < l; i ++ ) { - var instance = instanceGeometries[ i ]; + var instance = instanceGeometries[ i ]; - // a single geometry instance in collada can lead to multiple object3Ds. - // this is the case when primitives are combined like triangles and lines + // a single geometry instance in collada can lead to multiple object3Ds. + // this is the case when primitives are combined like triangles and lines - var geometries = getGeometry( instance.id ); - var newObjects = buildObjects( geometries, instance.materials ); + var geometries = getGeometry( instance.id ); + var newObjects = buildObjects( geometries, instance.materials ); - for ( var j = 0, jl = newObjects.length; j < jl; j ++ ) { + for ( var j = 0, jl = newObjects.length; j < jl; j ++ ) { - objects.push( newObjects[ j ] ); + objects.push( newObjects[ j ] ); - } + } - } + } - // instance nodes + // instance nodes - for ( var i = 0, l = instanceNodes.length; i < l; i ++ ) { + for ( var i = 0, l = instanceNodes.length; i < l; i ++ ) { - objects.push( getNode( instanceNodes[ i ] ).clone() ); + objects.push( getNode( instanceNodes[ i ] ).clone() ); - } + } - var object; + var object; - if ( nodes.length === 0 && objects.length === 1 ) { + if ( nodes.length === 0 && objects.length === 1 ) { - object = objects[ 0 ]; + object = objects[ 0 ]; - } else { + } else { - object = ( type === 'JOINT' ) ? new THREE.Bone() : new THREE.Group(); + object = ( type === 'JOINT' ) ? new THREE.Bone() : new THREE.Group(); - for ( var i = 0; i < objects.length; i ++ ) { + for ( var i = 0; i < objects.length; i ++ ) { - object.add( objects[ i ] ); + object.add( objects[ i ] ); - } + } - } + } - if ( object.name === '' ) { + if ( object.name === '' ) { - object.name = ( type === 'JOINT' ) ? data.sid : data.name; + object.name = ( type === 'JOINT' ) ? data.sid : data.name; - } + } - object.matrix.copy( matrix ); - object.matrix.decompose( object.position, object.quaternion, object.scale ); + object.matrix.copy( matrix ); + object.matrix.decompose( object.position, object.quaternion, object.scale ); - return object; + return object; - } + } - var fallbackMaterial = new THREE.MeshBasicMaterial( { color: 0xff00ff } ); + var fallbackMaterial = new THREE.MeshBasicMaterial( { color: 0xff00ff } ); - function resolveMaterialBinding( keys, instanceMaterials ) { + function resolveMaterialBinding( keys, instanceMaterials ) { - var materials = []; + var materials = []; - for ( var i = 0, l = keys.length; i < l; i ++ ) { + for ( var i = 0, l = keys.length; i < l; i ++ ) { - var id = instanceMaterials[ keys[ i ] ]; + var id = instanceMaterials[ keys[ i ] ]; - if ( id === undefined ) { + if ( id === undefined ) { - console.warn( 'THREE.ColladaLoader: Material with key %s not found. Apply fallback material.', keys[ i ] ); - materials.push( fallbackMaterial ); + console.warn( 'THREE.ColladaLoader: Material with key %s not found. Apply fallback material.', keys[ i ] ); + materials.push( fallbackMaterial ); - } else { + } else { - materials.push( getMaterial( id ) ); + materials.push( getMaterial( id ) ); - } + } - } + } - return materials; + return materials; - } + } - function buildObjects( geometries, instanceMaterials ) { + function buildObjects( geometries, instanceMaterials ) { - var objects = []; + var objects = []; - for ( var type in geometries ) { + for ( var type in geometries ) { - var geometry = geometries[ type ]; + var geometry = geometries[ type ]; - var materials = resolveMaterialBinding( geometry.materialKeys, instanceMaterials ); + var materials = resolveMaterialBinding( geometry.materialKeys, instanceMaterials ); - // handle case if no materials are defined + // handle case if no materials are defined - if ( materials.length === 0 ) { + if ( materials.length === 0 ) { - if ( type === 'lines' || type === 'linestrips' ) { + if ( type === 'lines' || type === 'linestrips' ) { - materials.push( new THREE.LineBasicMaterial() ); + materials.push( new THREE.LineBasicMaterial() ); - } else { + } else { - materials.push( new THREE.MeshPhongMaterial() ); + materials.push( new THREE.MeshPhongMaterial() ); - } + } - } + } - // regard skinning + // regard skinning - var skinning = ( geometry.data.attributes.skinIndex !== undefined ); + var skinning = ( geometry.data.attributes.skinIndex !== undefined ); - if ( skinning ) { + if ( skinning ) { - for ( var i = 0, l = materials.length; i < l; i ++ ) { + for ( var i = 0, l = materials.length; i < l; i ++ ) { - materials[ i ].skinning = true; + materials[ i ].skinning = true; - } + } - } + } - // choose between a single or multi materials (material array) + // choose between a single or multi materials (material array) - var material = ( materials.length === 1 ) ? materials[ 0 ] : materials; + var material = ( materials.length === 1 ) ? materials[ 0 ] : materials; - // now create a specific 3D object + // now create a specific 3D object - var object; + var object; - switch ( type ) { + switch ( type ) { - case 'lines': - object = new THREE.LineSegments( geometry.data, material ); - break; + case 'lines': + object = new THREE.LineSegments( geometry.data, material ); + break; - case 'linestrips': - object = new THREE.Line( geometry.data, material ); - break; + case 'linestrips': + object = new THREE.Line( geometry.data, material ); + break; - case 'triangles': - case 'polylist': - if ( skinning ) { + case 'triangles': + case 'polylist': + if ( skinning ) { - object = new THREE.SkinnedMesh( geometry.data, material ); + object = new THREE.SkinnedMesh( geometry.data, material ); - } else { + } else { - object = new THREE.Mesh( geometry.data, material ); + object = new THREE.Mesh( geometry.data, material ); - } - break; + } + break; - } + } - objects.push( object ); + objects.push( object ); - } + } - return objects; + return objects; - } + } - function hasNode( id ) { + function hasNode( id ) { - return library.nodes[ id ] !== undefined; + return library.nodes[ id ] !== undefined; - } + } - function getNode( id ) { + function getNode( id ) { - return getBuild( library.nodes[ id ], buildNode ); + return getBuild( library.nodes[ id ], buildNode ); - } + } - // visual scenes + // visual scenes - function parseVisualScene( xml ) { + function parseVisualScene( xml ) { - var data = { - name: xml.getAttribute( 'name' ), - children: [] - }; + var data = { + name: xml.getAttribute( 'name' ), + children: [] + }; - prepareNodes( xml ); + prepareNodes( xml ); - var elements = getElementsByTagName( xml, 'node' ); + var elements = getElementsByTagName( xml, 'node' ); - for ( var i = 0; i < elements.length; i ++ ) { + for ( var i = 0; i < elements.length; i ++ ) { - data.children.push( parseNode( elements[ i ] ) ); + data.children.push( parseNode( elements[ i ] ) ); - } + } - library.visualScenes[ xml.getAttribute( 'id' ) ] = data; + library.visualScenes[ xml.getAttribute( 'id' ) ] = data; - } + } - function buildVisualScene( data ) { + function buildVisualScene( data ) { - var group = new THREE.Group(); - group.name = data.name; + var group = new THREE.Group(); + group.name = data.name; - var children = data.children; + var children = data.children; - for ( var i = 0; i < children.length; i ++ ) { + for ( var i = 0; i < children.length; i ++ ) { - var child = children[ i ]; + var child = children[ i ]; - group.add( getNode( child.id ) ); + group.add( getNode( child.id ) ); - } + } - return group; + return group; - } + } - function hasVisualScene( id ) { + function hasVisualScene( id ) { - return library.visualScenes[ id ] !== undefined; + return library.visualScenes[ id ] !== undefined; - } + } - function getVisualScene( id ) { + function getVisualScene( id ) { - return getBuild( library.visualScenes[ id ], buildVisualScene ); + return getBuild( library.visualScenes[ id ], buildVisualScene ); - } + } - // scenes + // scenes - function parseScene( xml ) { + function parseScene( xml ) { - var instance = getElementsByTagName( xml, 'instance_visual_scene' )[ 0 ]; - return getVisualScene( parseId( instance.getAttribute( 'url' ) ) ); + var instance = getElementsByTagName( xml, 'instance_visual_scene' )[ 0 ]; + return getVisualScene( parseId( instance.getAttribute( 'url' ) ) ); - } + } - function setupAnimations() { + function setupAnimations() { - var clips = library.clips; + var clips = library.clips; - if ( isEmpty( clips ) === true ) { + if ( isEmpty( clips ) === true ) { - if ( isEmpty( library.animations ) === false ) { + if ( isEmpty( library.animations ) === false ) { - // if there are animations but no clips, we create a default clip for playback + // if there are animations but no clips, we create a default clip for playback - var tracks = []; + var tracks = []; - for ( var id in library.animations ) { + for ( var id in library.animations ) { - var animationTracks = getAnimation( id ); + var animationTracks = getAnimation( id ); - for ( var i = 0, l = animationTracks.length; i < l; i ++ ) { + for ( var i = 0, l = animationTracks.length; i < l; i ++ ) { - tracks.push( animationTracks[ i ] ); + tracks.push( animationTracks[ i ] ); - } + } - } + } - animations.push( new THREE.AnimationClip( 'default', - 1, tracks ) ); + animations.push( new THREE.AnimationClip( 'default', - 1, tracks ) ); - } + } - } else { + } else { - for ( var id in clips ) { + for ( var id in clips ) { - animations.push( getAnimationClip( id ) ); + animations.push( getAnimationClip( id ) ); - } + } - } + } - } + } - if ( text.length === 0 ) { + if ( text.length === 0 ) { - return { scene: new THREE.Scene() }; + return { scene: new THREE.Scene() }; - } + } - var xml = new DOMParser().parseFromString( text, 'application/xml' ); + var xml = new DOMParser().parseFromString( text, 'application/xml' ); - var collada = getElementsByTagName( xml, 'COLLADA' )[ 0 ]; + var collada = getElementsByTagName( xml, 'COLLADA' )[ 0 ]; - // metadata + // metadata - var version = collada.getAttribute( 'version' ); - console.log( 'THREE.ColladaLoader: File version', version ); + var version = collada.getAttribute( 'version' ); + console.log( 'THREE.ColladaLoader: File version', version ); - var asset = parseAsset( getElementsByTagName( collada, 'asset' )[ 0 ] ); - var textureLoader = new THREE.TextureLoader( this.manager ); - textureLoader.setPath( path ).setCrossOrigin( this.crossOrigin ); + var asset = parseAsset( getElementsByTagName( collada, 'asset' )[ 0 ] ); + var textureLoader = new THREE.TextureLoader( this.manager ); + textureLoader.setPath( path ).setCrossOrigin( this.crossOrigin ); - var tgaLoader; + var tgaLoader; - if ( THREE.TGALoader ) { + if ( THREE.TGALoader ) { - tgaLoader = new THREE.TGALoader( this.manager ); - tgaLoader.setPath( path ); + tgaLoader = new THREE.TGALoader( this.manager ); + tgaLoader.setPath( path ); - } + } - // + // - var animations = []; - var kinematics = {}; - var count = 0; + var animations = []; + var kinematics = {}; + var count = 0; - // + // - var library = { - animations: {}, - clips: {}, - controllers: {}, - images: {}, - effects: {}, - materials: {}, - cameras: {}, - lights: {}, - geometries: {}, - nodes: {}, - visualScenes: {}, - kinematicsModels: {}, - physicsModels: {}, - kinematicsScenes: {} - }; + var library = { + animations: {}, + clips: {}, + controllers: {}, + images: {}, + effects: {}, + materials: {}, + cameras: {}, + lights: {}, + geometries: {}, + nodes: {}, + visualScenes: {}, + kinematicsModels: {}, + physicsModels: {}, + kinematicsScenes: {} + }; - parseLibrary( collada, 'library_animations', 'animation', parseAnimation ); - parseLibrary( collada, 'library_animation_clips', 'animation_clip', parseAnimationClip ); - parseLibrary( collada, 'library_controllers', 'controller', parseController ); - parseLibrary( collada, 'library_images', 'image', parseImage ); - parseLibrary( collada, 'library_effects', 'effect', parseEffect ); - parseLibrary( collada, 'library_materials', 'material', parseMaterial ); - parseLibrary( collada, 'library_cameras', 'camera', parseCamera ); - parseLibrary( collada, 'library_lights', 'light', parseLight ); - parseLibrary( collada, 'library_geometries', 'geometry', parseGeometry ); - parseLibrary( collada, 'library_nodes', 'node', parseNode ); - parseLibrary( collada, 'library_visual_scenes', 'visual_scene', parseVisualScene ); - parseLibrary( collada, 'library_kinematics_models', 'kinematics_model', parseKinematicsModel ); - parseLibrary( collada, 'library_physics_models', 'physics_model', parsePhysicsModel ); - parseLibrary( collada, 'scene', 'instance_kinematics_scene', parseKinematicsScene ); + parseLibrary( collada, 'library_animations', 'animation', parseAnimation ); + parseLibrary( collada, 'library_animation_clips', 'animation_clip', parseAnimationClip ); + parseLibrary( collada, 'library_controllers', 'controller', parseController ); + parseLibrary( collada, 'library_images', 'image', parseImage ); + parseLibrary( collada, 'library_effects', 'effect', parseEffect ); + parseLibrary( collada, 'library_materials', 'material', parseMaterial ); + parseLibrary( collada, 'library_cameras', 'camera', parseCamera ); + parseLibrary( collada, 'library_lights', 'light', parseLight ); + parseLibrary( collada, 'library_geometries', 'geometry', parseGeometry ); + parseLibrary( collada, 'library_nodes', 'node', parseNode ); + parseLibrary( collada, 'library_visual_scenes', 'visual_scene', parseVisualScene ); + parseLibrary( collada, 'library_kinematics_models', 'kinematics_model', parseKinematicsModel ); + parseLibrary( collada, 'library_physics_models', 'physics_model', parsePhysicsModel ); + parseLibrary( collada, 'scene', 'instance_kinematics_scene', parseKinematicsScene ); - buildLibrary( library.animations, buildAnimation ); - buildLibrary( library.clips, buildAnimationClip ); - buildLibrary( library.controllers, buildController ); - buildLibrary( library.images, buildImage ); - buildLibrary( library.effects, buildEffect ); - buildLibrary( library.materials, buildMaterial ); - buildLibrary( library.cameras, buildCamera ); - buildLibrary( library.lights, buildLight ); - buildLibrary( library.geometries, buildGeometry ); - buildLibrary( library.visualScenes, buildVisualScene ); + buildLibrary( library.animations, buildAnimation ); + buildLibrary( library.clips, buildAnimationClip ); + buildLibrary( library.controllers, buildController ); + buildLibrary( library.images, buildImage ); + buildLibrary( library.effects, buildEffect ); + buildLibrary( library.materials, buildMaterial ); + buildLibrary( library.cameras, buildCamera ); + buildLibrary( library.lights, buildLight ); + buildLibrary( library.geometries, buildGeometry ); + buildLibrary( library.visualScenes, buildVisualScene ); - setupAnimations(); - setupKinematics(); + setupAnimations(); + setupKinematics(); - var scene = parseScene( getElementsByTagName( collada, 'scene' )[ 0 ] ); + var scene = parseScene( getElementsByTagName( collada, 'scene' )[ 0 ] ); - if ( asset.upAxis === 'Z_UP' ) { + if ( asset.upAxis === 'Z_UP' ) { - scene.quaternion.setFromEuler( new THREE.Euler( - Math.PI / 2, 0, 0 ) ); + scene.quaternion.setFromEuler( new THREE.Euler( - Math.PI / 2, 0, 0 ) ); - } + } - scene.scale.multiplyScalar( asset.unit ); + scene.scale.multiplyScalar( asset.unit ); - return { - animations: animations, - kinematics: kinematics, - library: library, - scene: scene - }; + return { + animations: animations, + kinematics: kinematics, + library: library, + scene: scene + }; - } + } }; -},{}],41:[function(_dereq_,module,exports){ +},{}],38:[function(_dereq_,module,exports){ // Copyright 2016 The Draco Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -56243,7 +55889,7 @@ THREE.DRACOLoader._loadArrayBuffer = function ( src ) { }); }; -},{}],42:[function(_dereq_,module,exports){ +},{}],39:[function(_dereq_,module,exports){ /** * @author Rich Tibbett / https://github.com/richtr * @author mrdoob / http://mrdoob.com/ @@ -56254,3106 +55900,3106 @@ THREE.DRACOLoader._loadArrayBuffer = function ( src ) { THREE.GLTFLoader = ( function () { - function GLTFLoader( manager ) { + function GLTFLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - this.dracoLoader = null; + this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + this.dracoLoader = null; - } + } - GLTFLoader.prototype = { + GLTFLoader.prototype = { - constructor: GLTFLoader, + constructor: GLTFLoader, - crossOrigin: 'anonymous', + crossOrigin: 'anonymous', - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - var scope = this; + var scope = this; - var path = this.path !== undefined ? this.path : THREE.LoaderUtils.extractUrlBase( url ); + var path = this.path !== undefined ? this.path : THREE.LoaderUtils.extractUrlBase( url ); - var loader = new THREE.FileLoader( scope.manager ); + var loader = new THREE.FileLoader( scope.manager ); - loader.setResponseType( 'arraybuffer' ); + loader.setResponseType( 'arraybuffer' ); - loader.load( url, function ( data ) { + loader.load( url, function ( data ) { - try { + try { - scope.parse( data, path, onLoad, onError ); + scope.parse( data, path, onLoad, onError ); - } catch ( e ) { + } catch ( e ) { - if ( onError !== undefined ) { + if ( onError !== undefined ) { - onError( e ); + onError( e ); - } else { + } else { - throw e; + throw e; - } + } - } + } - }, onProgress, onError ); + }, onProgress, onError ); - }, + }, - setCrossOrigin: function ( value ) { + setCrossOrigin: function ( value ) { - this.crossOrigin = value; - return this; + this.crossOrigin = value; + return this; - }, + }, - setPath: function ( value ) { + setPath: function ( value ) { - this.path = value; - return this; + this.path = value; + return this; - }, + }, - setDRACOLoader: function ( dracoLoader ) { + setDRACOLoader: function ( dracoLoader ) { - this.dracoLoader = dracoLoader; - return this; + this.dracoLoader = dracoLoader; + return this; - }, + }, - parse: function ( data, path, onLoad, onError ) { + parse: function ( data, path, onLoad, onError ) { - var content; - var extensions = {}; + var content; + var extensions = {}; - if ( typeof data === 'string' ) { + if ( typeof data === 'string' ) { - content = data; + content = data; - } else { + } else { - var magic = THREE.LoaderUtils.decodeText( new Uint8Array( data, 0, 4 ) ); + var magic = THREE.LoaderUtils.decodeText( new Uint8Array( data, 0, 4 ) ); - if ( magic === BINARY_EXTENSION_HEADER_MAGIC ) { + if ( magic === BINARY_EXTENSION_HEADER_MAGIC ) { - try { + try { - extensions[ EXTENSIONS.KHR_BINARY_GLTF ] = new GLTFBinaryExtension( data ); + extensions[ EXTENSIONS.KHR_BINARY_GLTF ] = new GLTFBinaryExtension( data ); - } catch ( error ) { + } catch ( error ) { - if ( onError ) onError( error ); - return; + if ( onError ) onError( error ); + return; - } + } - content = extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content; + content = extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content; - } else { + } else { - content = THREE.LoaderUtils.decodeText( new Uint8Array( data ) ); + content = THREE.LoaderUtils.decodeText( new Uint8Array( data ) ); - } + } - } + } - var json = JSON.parse( content ); + var json = JSON.parse( content ); - if ( json.asset === undefined || json.asset.version[ 0 ] < 2 ) { + if ( json.asset === undefined || json.asset.version[ 0 ] < 2 ) { - if ( onError ) onError( new Error( 'THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported. Use LegacyGLTFLoader instead.' ) ); - return; + if ( onError ) onError( new Error( 'THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported. Use LegacyGLTFLoader instead.' ) ); + return; - } + } - if ( json.extensionsUsed ) { + if ( json.extensionsUsed ) { - for ( var i = 0; i < json.extensionsUsed.length; ++ i ) { + for ( var i = 0; i < json.extensionsUsed.length; ++ i ) { - var extensionName = json.extensionsUsed[ i ]; - var extensionsRequired = json.extensionsRequired || []; + var extensionName = json.extensionsUsed[ i ]; + var extensionsRequired = json.extensionsRequired || []; - switch ( extensionName ) { + switch ( extensionName ) { - case EXTENSIONS.KHR_LIGHTS_PUNCTUAL: - extensions[ extensionName ] = new GLTFLightsExtension( json ); - break; + case EXTENSIONS.KHR_LIGHTS_PUNCTUAL: + extensions[ extensionName ] = new GLTFLightsExtension( json ); + break; - case EXTENSIONS.KHR_MATERIALS_UNLIT: - extensions[ extensionName ] = new GLTFMaterialsUnlitExtension( json ); - break; + case EXTENSIONS.KHR_MATERIALS_UNLIT: + extensions[ extensionName ] = new GLTFMaterialsUnlitExtension( json ); + break; - case EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: - extensions[ extensionName ] = new GLTFMaterialsPbrSpecularGlossinessExtension(); - break; + case EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: + extensions[ extensionName ] = new GLTFMaterialsPbrSpecularGlossinessExtension(); + break; - case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION: - extensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( json, this.dracoLoader ); - break; + case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION: + extensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( json, this.dracoLoader ); + break; - case EXTENSIONS.MSFT_TEXTURE_DDS: - extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] = new GLTFTextureDDSExtension(); - break; + case EXTENSIONS.MSFT_TEXTURE_DDS: + extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] = new GLTFTextureDDSExtension(); + break; - default: + default: - if ( extensionsRequired.indexOf( extensionName ) >= 0 ) { + if ( extensionsRequired.indexOf( extensionName ) >= 0 ) { - console.warn( 'THREE.GLTFLoader: Unknown extension "' + extensionName + '".' ); + console.warn( 'THREE.GLTFLoader: Unknown extension "' + extensionName + '".' ); - } + } - } + } - } + } - } + } - var parser = new GLTFParser( json, extensions, { + var parser = new GLTFParser( json, extensions, { - path: path || this.path || '', - crossOrigin: this.crossOrigin, - manager: this.manager + path: path || this.path || '', + crossOrigin: this.crossOrigin, + manager: this.manager - } ); + } ); - parser.parse( function ( scene, scenes, cameras, animations, json ) { + parser.parse( function ( scene, scenes, cameras, animations, json ) { - var glTF = { - scene: scene, - scenes: scenes, - cameras: cameras, - animations: animations, - asset: json.asset, - parser: parser, - userData: {} - }; + var glTF = { + scene: scene, + scenes: scenes, + cameras: cameras, + animations: animations, + asset: json.asset, + parser: parser, + userData: {} + }; - addUnknownExtensionsToUserData( extensions, glTF, json ); + addUnknownExtensionsToUserData( extensions, glTF, json ); - onLoad( glTF ); + onLoad( glTF ); - }, onError ); + }, onError ); - } + } - }; + }; - /* GLTFREGISTRY */ + /* GLTFREGISTRY */ - function GLTFRegistry() { + function GLTFRegistry() { - var objects = {}; + var objects = {}; - return { + return { - get: function ( key ) { + get: function ( key ) { - return objects[ key ]; + return objects[ key ]; - }, + }, - add: function ( key, object ) { + add: function ( key, object ) { - objects[ key ] = object; + objects[ key ] = object; - }, + }, - remove: function ( key ) { + remove: function ( key ) { - delete objects[ key ]; + delete objects[ key ]; - }, + }, - removeAll: function () { + removeAll: function () { - objects = {}; + objects = {}; - } + } - }; + }; - } + } - /*********************************/ - /********** EXTENSIONS ***********/ - /*********************************/ + /*********************************/ + /********** EXTENSIONS ***********/ + /*********************************/ - var EXTENSIONS = { - KHR_BINARY_GLTF: 'KHR_binary_glTF', - KHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression', - KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual', - KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness', - KHR_MATERIALS_UNLIT: 'KHR_materials_unlit', - MSFT_TEXTURE_DDS: 'MSFT_texture_dds' - }; + var EXTENSIONS = { + KHR_BINARY_GLTF: 'KHR_binary_glTF', + KHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression', + KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual', + KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness', + KHR_MATERIALS_UNLIT: 'KHR_materials_unlit', + MSFT_TEXTURE_DDS: 'MSFT_texture_dds' + }; - /** - * DDS Texture Extension - * - * Specification: - * https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_texture_dds - * - */ - function GLTFTextureDDSExtension() { + /** + * DDS Texture Extension + * + * Specification: + * https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_texture_dds + * + */ + function GLTFTextureDDSExtension() { - if ( ! THREE.DDSLoader ) { + if ( ! THREE.DDSLoader ) { - throw new Error( 'THREE.GLTFLoader: Attempting to load .dds texture without importing THREE.DDSLoader' ); + throw new Error( 'THREE.GLTFLoader: Attempting to load .dds texture without importing THREE.DDSLoader' ); - } + } - this.name = EXTENSIONS.MSFT_TEXTURE_DDS; - this.ddsLoader = new THREE.DDSLoader(); + this.name = EXTENSIONS.MSFT_TEXTURE_DDS; + this.ddsLoader = new THREE.DDSLoader(); - } + } - /** - * Lights Extension - * - * Specification: PENDING - */ - function GLTFLightsExtension( json ) { + /** + * Lights Extension + * + * Specification: PENDING + */ + function GLTFLightsExtension( json ) { - this.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL; + this.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL; - this.lights = []; + this.lights = []; - var extension = ( json.extensions && json.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ] ) || {}; - var lightDefs = extension.lights || []; + var extension = ( json.extensions && json.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ] ) || {}; + var lightDefs = extension.lights || []; - for ( var i = 0; i < lightDefs.length; i ++ ) { + for ( var i = 0; i < lightDefs.length; i ++ ) { - var lightDef = lightDefs[ i ]; - var lightNode; + var lightDef = lightDefs[ i ]; + var lightNode; - var color = new THREE.Color( 0xffffff ); - if ( lightDef.color !== undefined ) color.fromArray( lightDef.color ); + var color = new THREE.Color( 0xffffff ); + if ( lightDef.color !== undefined ) color.fromArray( lightDef.color ); - var range = lightDef.range !== undefined ? lightDef.range : 0; + var range = lightDef.range !== undefined ? lightDef.range : 0; - switch ( lightDef.type ) { + switch ( lightDef.type ) { - case 'directional': - lightNode = new THREE.DirectionalLight( color ); - lightNode.target.position.set( 0, 0, 1 ); - lightNode.add( lightNode.target ); - break; + case 'directional': + lightNode = new THREE.DirectionalLight( color ); + lightNode.target.position.set( 0, 0, 1 ); + lightNode.add( lightNode.target ); + break; - case 'point': - lightNode = new THREE.PointLight( color ); - lightNode.distance = range; - break; + case 'point': + lightNode = new THREE.PointLight( color ); + lightNode.distance = range; + break; - case 'spot': - lightNode = new THREE.SpotLight( color ); - lightNode.distance = range; - // Handle spotlight properties. - lightDef.spot = lightDef.spot || {}; - lightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0; - lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0; - lightNode.angle = lightDef.spot.outerConeAngle; - lightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle; - lightNode.target.position.set( 0, 0, 1 ); - lightNode.add( lightNode.target ); - break; + case 'spot': + lightNode = new THREE.SpotLight( color ); + lightNode.distance = range; + // Handle spotlight properties. + lightDef.spot = lightDef.spot || {}; + lightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0; + lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0; + lightNode.angle = lightDef.spot.outerConeAngle; + lightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle; + lightNode.target.position.set( 0, 0, 1 ); + lightNode.add( lightNode.target ); + break; - default: - throw new Error( 'THREE.GLTFLoader: Unexpected light type, "' + lightDef.type + '".' ); + default: + throw new Error( 'THREE.GLTFLoader: Unexpected light type, "' + lightDef.type + '".' ); - } + } - lightNode.decay = 2; + lightNode.decay = 2; - if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity; + if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity; - lightNode.name = lightDef.name || ( 'light_' + i ); + lightNode.name = lightDef.name || ( 'light_' + i ); - this.lights.push( lightNode ); + this.lights.push( lightNode ); - } + } - } + } - /** - * Unlit Materials Extension (pending) - * - * PR: https://github.com/KhronosGroup/glTF/pull/1163 - */ - function GLTFMaterialsUnlitExtension( json ) { + /** + * Unlit Materials Extension (pending) + * + * PR: https://github.com/KhronosGroup/glTF/pull/1163 + */ + function GLTFMaterialsUnlitExtension( json ) { - this.name = EXTENSIONS.KHR_MATERIALS_UNLIT; + this.name = EXTENSIONS.KHR_MATERIALS_UNLIT; - } + } - GLTFMaterialsUnlitExtension.prototype.getMaterialType = function ( material ) { + GLTFMaterialsUnlitExtension.prototype.getMaterialType = function ( material ) { - return THREE.MeshBasicMaterial; + return THREE.MeshBasicMaterial; - }; + }; - GLTFMaterialsUnlitExtension.prototype.extendParams = function ( materialParams, material, parser ) { + GLTFMaterialsUnlitExtension.prototype.extendParams = function ( materialParams, material, parser ) { - var pending = []; + var pending = []; - materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 ); - materialParams.opacity = 1.0; + materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 ); + materialParams.opacity = 1.0; - var metallicRoughness = material.pbrMetallicRoughness; + var metallicRoughness = material.pbrMetallicRoughness; - if ( metallicRoughness ) { + if ( metallicRoughness ) { - if ( Array.isArray( metallicRoughness.baseColorFactor ) ) { + if ( Array.isArray( metallicRoughness.baseColorFactor ) ) { - var array = metallicRoughness.baseColorFactor; + var array = metallicRoughness.baseColorFactor; - materialParams.color.fromArray( array ); - materialParams.opacity = array[ 3 ]; + materialParams.color.fromArray( array ); + materialParams.opacity = array[ 3 ]; - } + } - if ( metallicRoughness.baseColorTexture !== undefined ) { + if ( metallicRoughness.baseColorTexture !== undefined ) { - pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) ); - } + } - } + } - return Promise.all( pending ); + return Promise.all( pending ); - }; + }; - /* BINARY EXTENSION */ + /* BINARY EXTENSION */ - var BINARY_EXTENSION_BUFFER_NAME = 'binary_glTF'; - var BINARY_EXTENSION_HEADER_MAGIC = 'glTF'; - var BINARY_EXTENSION_HEADER_LENGTH = 12; - var BINARY_EXTENSION_CHUNK_TYPES = { JSON: 0x4E4F534A, BIN: 0x004E4942 }; + var BINARY_EXTENSION_BUFFER_NAME = 'binary_glTF'; + var BINARY_EXTENSION_HEADER_MAGIC = 'glTF'; + var BINARY_EXTENSION_HEADER_LENGTH = 12; + var BINARY_EXTENSION_CHUNK_TYPES = { JSON: 0x4E4F534A, BIN: 0x004E4942 }; - function GLTFBinaryExtension( data ) { + function GLTFBinaryExtension( data ) { - this.name = EXTENSIONS.KHR_BINARY_GLTF; - this.content = null; - this.body = null; + this.name = EXTENSIONS.KHR_BINARY_GLTF; + this.content = null; + this.body = null; - var headerView = new DataView( data, 0, BINARY_EXTENSION_HEADER_LENGTH ); + var headerView = new DataView( data, 0, BINARY_EXTENSION_HEADER_LENGTH ); - this.header = { - magic: THREE.LoaderUtils.decodeText( new Uint8Array( data.slice( 0, 4 ) ) ), - version: headerView.getUint32( 4, true ), - length: headerView.getUint32( 8, true ) - }; + this.header = { + magic: THREE.LoaderUtils.decodeText( new Uint8Array( data.slice( 0, 4 ) ) ), + version: headerView.getUint32( 4, true ), + length: headerView.getUint32( 8, true ) + }; - if ( this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC ) { + if ( this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC ) { - throw new Error( 'THREE.GLTFLoader: Unsupported glTF-Binary header.' ); + throw new Error( 'THREE.GLTFLoader: Unsupported glTF-Binary header.' ); - } else if ( this.header.version < 2.0 ) { + } else if ( this.header.version < 2.0 ) { - throw new Error( 'THREE.GLTFLoader: Legacy binary file detected. Use LegacyGLTFLoader instead.' ); + throw new Error( 'THREE.GLTFLoader: Legacy binary file detected. Use LegacyGLTFLoader instead.' ); - } + } - var chunkView = new DataView( data, BINARY_EXTENSION_HEADER_LENGTH ); - var chunkIndex = 0; + var chunkView = new DataView( data, BINARY_EXTENSION_HEADER_LENGTH ); + var chunkIndex = 0; - while ( chunkIndex < chunkView.byteLength ) { + while ( chunkIndex < chunkView.byteLength ) { - var chunkLength = chunkView.getUint32( chunkIndex, true ); - chunkIndex += 4; + var chunkLength = chunkView.getUint32( chunkIndex, true ); + chunkIndex += 4; - var chunkType = chunkView.getUint32( chunkIndex, true ); - chunkIndex += 4; + var chunkType = chunkView.getUint32( chunkIndex, true ); + chunkIndex += 4; - if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON ) { + if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON ) { - var contentArray = new Uint8Array( data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength ); - this.content = THREE.LoaderUtils.decodeText( contentArray ); + var contentArray = new Uint8Array( data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength ); + this.content = THREE.LoaderUtils.decodeText( contentArray ); - } else if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.BIN ) { + } else if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.BIN ) { - var byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex; - this.body = data.slice( byteOffset, byteOffset + chunkLength ); + var byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex; + this.body = data.slice( byteOffset, byteOffset + chunkLength ); - } + } - // Clients must ignore chunks with unknown types. + // Clients must ignore chunks with unknown types. - chunkIndex += chunkLength; + chunkIndex += chunkLength; - } + } - if ( this.content === null ) { + if ( this.content === null ) { - throw new Error( 'THREE.GLTFLoader: JSON content not found.' ); + throw new Error( 'THREE.GLTFLoader: JSON content not found.' ); - } + } - } + } - /** - * DRACO Mesh Compression Extension - * - * Specification: https://github.com/KhronosGroup/glTF/pull/874 - */ - function GLTFDracoMeshCompressionExtension( json, dracoLoader ) { + /** + * DRACO Mesh Compression Extension + * + * Specification: https://github.com/KhronosGroup/glTF/pull/874 + */ + function GLTFDracoMeshCompressionExtension( json, dracoLoader ) { - if ( ! dracoLoader ) { + if ( ! dracoLoader ) { - throw new Error( 'THREE.GLTFLoader: No DRACOLoader instance provided.' ); + throw new Error( 'THREE.GLTFLoader: No DRACOLoader instance provided.' ); - } + } - this.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION; - this.json = json; - this.dracoLoader = dracoLoader; + this.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION; + this.json = json; + this.dracoLoader = dracoLoader; - } + } - GLTFDracoMeshCompressionExtension.prototype.decodePrimitive = function ( primitive, parser ) { + GLTFDracoMeshCompressionExtension.prototype.decodePrimitive = function ( primitive, parser ) { - var json = this.json; - var dracoLoader = this.dracoLoader; - var bufferViewIndex = primitive.extensions[ this.name ].bufferView; - var gltfAttributeMap = primitive.extensions[ this.name ].attributes; - var threeAttributeMap = {}; - var attributeNormalizedMap = {}; - var attributeTypeMap = {}; + var json = this.json; + var dracoLoader = this.dracoLoader; + var bufferViewIndex = primitive.extensions[ this.name ].bufferView; + var gltfAttributeMap = primitive.extensions[ this.name ].attributes; + var threeAttributeMap = {}; + var attributeNormalizedMap = {}; + var attributeTypeMap = {}; - for ( var attributeName in gltfAttributeMap ) { + for ( var attributeName in gltfAttributeMap ) { - if ( ! ( attributeName in ATTRIBUTES ) ) continue; + if ( ! ( attributeName in ATTRIBUTES ) ) continue; - threeAttributeMap[ ATTRIBUTES[ attributeName ] ] = gltfAttributeMap[ attributeName ]; + threeAttributeMap[ ATTRIBUTES[ attributeName ] ] = gltfAttributeMap[ attributeName ]; - } + } - for ( attributeName in primitive.attributes ) { + for ( attributeName in primitive.attributes ) { - if ( ATTRIBUTES[ attributeName ] !== undefined && gltfAttributeMap[ attributeName ] !== undefined ) { + if ( ATTRIBUTES[ attributeName ] !== undefined && gltfAttributeMap[ attributeName ] !== undefined ) { - var accessorDef = json.accessors[ primitive.attributes[ attributeName ] ]; - var componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ]; + var accessorDef = json.accessors[ primitive.attributes[ attributeName ] ]; + var componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ]; - attributeTypeMap[ ATTRIBUTES[ attributeName ] ] = componentType; - attributeNormalizedMap[ ATTRIBUTES[ attributeName ] ] = accessorDef.normalized === true; + attributeTypeMap[ ATTRIBUTES[ attributeName ] ] = componentType; + attributeNormalizedMap[ ATTRIBUTES[ attributeName ] ] = accessorDef.normalized === true; - } + } - } + } - return parser.getDependency( 'bufferView', bufferViewIndex ).then( function ( bufferView ) { + return parser.getDependency( 'bufferView', bufferViewIndex ).then( function ( bufferView ) { - return new Promise( function ( resolve ) { + return new Promise( function ( resolve ) { - dracoLoader.decodeDracoFile( bufferView, function ( geometry ) { + dracoLoader.decodeDracoFile( bufferView, function ( geometry ) { - for ( var attributeName in geometry.attributes ) { + for ( var attributeName in geometry.attributes ) { - var attribute = geometry.attributes[ attributeName ]; - var normalized = attributeNormalizedMap[ attributeName ]; + var attribute = geometry.attributes[ attributeName ]; + var normalized = attributeNormalizedMap[ attributeName ]; - if ( normalized !== undefined ) attribute.normalized = normalized; + if ( normalized !== undefined ) attribute.normalized = normalized; - } + } - resolve( geometry ); + resolve( geometry ); - }, threeAttributeMap, attributeTypeMap ); + }, threeAttributeMap, attributeTypeMap ); - } ); + } ); - } ); + } ); - }; + }; - /** - * Specular-Glossiness Extension - * - * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness - */ - function GLTFMaterialsPbrSpecularGlossinessExtension() { + /** + * Specular-Glossiness Extension + * + * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness + */ + function GLTFMaterialsPbrSpecularGlossinessExtension() { - return { + return { - name: EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS, + name: EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS, - specularGlossinessParams: [ - 'color', - 'map', - 'lightMap', - 'lightMapIntensity', - 'aoMap', - 'aoMapIntensity', - 'emissive', - 'emissiveIntensity', - 'emissiveMap', - 'bumpMap', - 'bumpScale', - 'normalMap', - 'displacementMap', - 'displacementScale', - 'displacementBias', - 'specularMap', - 'specular', - 'glossinessMap', - 'glossiness', - 'alphaMap', - 'envMap', - 'envMapIntensity', - 'refractionRatio', - ], + specularGlossinessParams: [ + 'color', + 'map', + 'lightMap', + 'lightMapIntensity', + 'aoMap', + 'aoMapIntensity', + 'emissive', + 'emissiveIntensity', + 'emissiveMap', + 'bumpMap', + 'bumpScale', + 'normalMap', + 'displacementMap', + 'displacementScale', + 'displacementBias', + 'specularMap', + 'specular', + 'glossinessMap', + 'glossiness', + 'alphaMap', + 'envMap', + 'envMapIntensity', + 'refractionRatio', + ], - getMaterialType: function () { + getMaterialType: function () { - return THREE.ShaderMaterial; + return THREE.ShaderMaterial; - }, + }, - extendParams: function ( params, material, parser ) { + extendParams: function ( params, material, parser ) { - var pbrSpecularGlossiness = material.extensions[ this.name ]; + var pbrSpecularGlossiness = material.extensions[ this.name ]; - var shader = THREE.ShaderLib[ 'standard' ]; + var shader = THREE.ShaderLib[ 'standard' ]; - var uniforms = THREE.UniformsUtils.clone( shader.uniforms ); + var uniforms = THREE.UniformsUtils.clone( shader.uniforms ); - var specularMapParsFragmentChunk = [ - '#ifdef USE_SPECULARMAP', - ' uniform sampler2D specularMap;', - '#endif' - ].join( '\n' ); + var specularMapParsFragmentChunk = [ + '#ifdef USE_SPECULARMAP', + ' uniform sampler2D specularMap;', + '#endif' + ].join( '\n' ); - var glossinessMapParsFragmentChunk = [ - '#ifdef USE_GLOSSINESSMAP', - ' uniform sampler2D glossinessMap;', - '#endif' - ].join( '\n' ); + var glossinessMapParsFragmentChunk = [ + '#ifdef USE_GLOSSINESSMAP', + ' uniform sampler2D glossinessMap;', + '#endif' + ].join( '\n' ); - var specularMapFragmentChunk = [ - 'vec3 specularFactor = specular;', - '#ifdef USE_SPECULARMAP', - ' vec4 texelSpecular = texture2D( specularMap, vUv );', - ' texelSpecular = sRGBToLinear( texelSpecular );', - ' // reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture', - ' specularFactor *= texelSpecular.rgb;', - '#endif' - ].join( '\n' ); + var specularMapFragmentChunk = [ + 'vec3 specularFactor = specular;', + '#ifdef USE_SPECULARMAP', + ' vec4 texelSpecular = texture2D( specularMap, vUv );', + ' texelSpecular = sRGBToLinear( texelSpecular );', + ' // reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture', + ' specularFactor *= texelSpecular.rgb;', + '#endif' + ].join( '\n' ); - var glossinessMapFragmentChunk = [ - 'float glossinessFactor = glossiness;', - '#ifdef USE_GLOSSINESSMAP', - ' vec4 texelGlossiness = texture2D( glossinessMap, vUv );', - ' // reads channel A, compatible with a glTF Specular-Glossiness (RGBA) texture', - ' glossinessFactor *= texelGlossiness.a;', - '#endif' - ].join( '\n' ); + var glossinessMapFragmentChunk = [ + 'float glossinessFactor = glossiness;', + '#ifdef USE_GLOSSINESSMAP', + ' vec4 texelGlossiness = texture2D( glossinessMap, vUv );', + ' // reads channel A, compatible with a glTF Specular-Glossiness (RGBA) texture', + ' glossinessFactor *= texelGlossiness.a;', + '#endif' + ].join( '\n' ); - var lightPhysicalFragmentChunk = [ - 'PhysicalMaterial material;', - 'material.diffuseColor = diffuseColor.rgb;', - 'material.specularRoughness = clamp( 1.0 - glossinessFactor, 0.04, 1.0 );', - 'material.specularColor = specularFactor.rgb;', - ].join( '\n' ); + var lightPhysicalFragmentChunk = [ + 'PhysicalMaterial material;', + 'material.diffuseColor = diffuseColor.rgb;', + 'material.specularRoughness = clamp( 1.0 - glossinessFactor, 0.04, 1.0 );', + 'material.specularColor = specularFactor.rgb;', + ].join( '\n' ); - var fragmentShader = shader.fragmentShader - .replace( 'uniform float roughness;', 'uniform vec3 specular;' ) - .replace( 'uniform float metalness;', 'uniform float glossiness;' ) - .replace( '#include ', specularMapParsFragmentChunk ) - .replace( '#include ', glossinessMapParsFragmentChunk ) - .replace( '#include ', specularMapFragmentChunk ) - .replace( '#include ', glossinessMapFragmentChunk ) - .replace( '#include ', lightPhysicalFragmentChunk ); + var fragmentShader = shader.fragmentShader + .replace( 'uniform float roughness;', 'uniform vec3 specular;' ) + .replace( 'uniform float metalness;', 'uniform float glossiness;' ) + .replace( '#include ', specularMapParsFragmentChunk ) + .replace( '#include ', glossinessMapParsFragmentChunk ) + .replace( '#include ', specularMapFragmentChunk ) + .replace( '#include ', glossinessMapFragmentChunk ) + .replace( '#include ', lightPhysicalFragmentChunk ); - delete uniforms.roughness; - delete uniforms.metalness; - delete uniforms.roughnessMap; - delete uniforms.metalnessMap; + delete uniforms.roughness; + delete uniforms.metalness; + delete uniforms.roughnessMap; + delete uniforms.metalnessMap; - uniforms.specular = { value: new THREE.Color().setHex( 0x111111 ) }; - uniforms.glossiness = { value: 0.5 }; - uniforms.specularMap = { value: null }; - uniforms.glossinessMap = { value: null }; + uniforms.specular = { value: new THREE.Color().setHex( 0x111111 ) }; + uniforms.glossiness = { value: 0.5 }; + uniforms.specularMap = { value: null }; + uniforms.glossinessMap = { value: null }; - params.vertexShader = shader.vertexShader; - params.fragmentShader = fragmentShader; - params.uniforms = uniforms; - params.defines = { 'STANDARD': '' }; + params.vertexShader = shader.vertexShader; + params.fragmentShader = fragmentShader; + params.uniforms = uniforms; + params.defines = { 'STANDARD': '' }; - params.color = new THREE.Color( 1.0, 1.0, 1.0 ); - params.opacity = 1.0; + params.color = new THREE.Color( 1.0, 1.0, 1.0 ); + params.opacity = 1.0; - var pending = []; + var pending = []; - if ( Array.isArray( pbrSpecularGlossiness.diffuseFactor ) ) { + if ( Array.isArray( pbrSpecularGlossiness.diffuseFactor ) ) { - var array = pbrSpecularGlossiness.diffuseFactor; + var array = pbrSpecularGlossiness.diffuseFactor; - params.color.fromArray( array ); - params.opacity = array[ 3 ]; + params.color.fromArray( array ); + params.opacity = array[ 3 ]; - } + } - if ( pbrSpecularGlossiness.diffuseTexture !== undefined ) { + if ( pbrSpecularGlossiness.diffuseTexture !== undefined ) { - pending.push( parser.assignTexture( params, 'map', pbrSpecularGlossiness.diffuseTexture.index ) ); + pending.push( parser.assignTexture( params, 'map', pbrSpecularGlossiness.diffuseTexture.index ) ); - } + } - params.emissive = new THREE.Color( 0.0, 0.0, 0.0 ); - params.glossiness = pbrSpecularGlossiness.glossinessFactor !== undefined ? pbrSpecularGlossiness.glossinessFactor : 1.0; - params.specular = new THREE.Color( 1.0, 1.0, 1.0 ); + params.emissive = new THREE.Color( 0.0, 0.0, 0.0 ); + params.glossiness = pbrSpecularGlossiness.glossinessFactor !== undefined ? pbrSpecularGlossiness.glossinessFactor : 1.0; + params.specular = new THREE.Color( 1.0, 1.0, 1.0 ); - if ( Array.isArray( pbrSpecularGlossiness.specularFactor ) ) { + if ( Array.isArray( pbrSpecularGlossiness.specularFactor ) ) { - params.specular.fromArray( pbrSpecularGlossiness.specularFactor ); + params.specular.fromArray( pbrSpecularGlossiness.specularFactor ); - } + } - if ( pbrSpecularGlossiness.specularGlossinessTexture !== undefined ) { + if ( pbrSpecularGlossiness.specularGlossinessTexture !== undefined ) { - var specGlossIndex = pbrSpecularGlossiness.specularGlossinessTexture.index; - pending.push( parser.assignTexture( params, 'glossinessMap', specGlossIndex ) ); - pending.push( parser.assignTexture( params, 'specularMap', specGlossIndex ) ); + var specGlossIndex = pbrSpecularGlossiness.specularGlossinessTexture.index; + pending.push( parser.assignTexture( params, 'glossinessMap', specGlossIndex ) ); + pending.push( parser.assignTexture( params, 'specularMap', specGlossIndex ) ); - } + } - return Promise.all( pending ); + return Promise.all( pending ); - }, + }, - createMaterial: function ( params ) { + createMaterial: function ( params ) { - // setup material properties based on MeshStandardMaterial for Specular-Glossiness + // setup material properties based on MeshStandardMaterial for Specular-Glossiness - var material = new THREE.ShaderMaterial( { - defines: params.defines, - vertexShader: params.vertexShader, - fragmentShader: params.fragmentShader, - uniforms: params.uniforms, - fog: true, - lights: true, - opacity: params.opacity, - transparent: params.transparent - } ); + var material = new THREE.ShaderMaterial( { + defines: params.defines, + vertexShader: params.vertexShader, + fragmentShader: params.fragmentShader, + uniforms: params.uniforms, + fog: true, + lights: true, + opacity: params.opacity, + transparent: params.transparent + } ); - material.isGLTFSpecularGlossinessMaterial = true; + material.isGLTFSpecularGlossinessMaterial = true; - material.color = params.color; + material.color = params.color; - material.map = params.map === undefined ? null : params.map; + material.map = params.map === undefined ? null : params.map; - material.lightMap = null; - material.lightMapIntensity = 1.0; + material.lightMap = null; + material.lightMapIntensity = 1.0; - material.aoMap = params.aoMap === undefined ? null : params.aoMap; - material.aoMapIntensity = 1.0; + material.aoMap = params.aoMap === undefined ? null : params.aoMap; + material.aoMapIntensity = 1.0; - material.emissive = params.emissive; - material.emissiveIntensity = 1.0; - material.emissiveMap = params.emissiveMap === undefined ? null : params.emissiveMap; + material.emissive = params.emissive; + material.emissiveIntensity = 1.0; + material.emissiveMap = params.emissiveMap === undefined ? null : params.emissiveMap; - material.bumpMap = params.bumpMap === undefined ? null : params.bumpMap; - material.bumpScale = 1; + material.bumpMap = params.bumpMap === undefined ? null : params.bumpMap; + material.bumpScale = 1; - material.normalMap = params.normalMap === undefined ? null : params.normalMap; - if ( params.normalScale ) material.normalScale = params.normalScale; + material.normalMap = params.normalMap === undefined ? null : params.normalMap; + if ( params.normalScale ) material.normalScale = params.normalScale; - material.displacementMap = null; - material.displacementScale = 1; - material.displacementBias = 0; + material.displacementMap = null; + material.displacementScale = 1; + material.displacementBias = 0; - material.specularMap = params.specularMap === undefined ? null : params.specularMap; - material.specular = params.specular; + material.specularMap = params.specularMap === undefined ? null : params.specularMap; + material.specular = params.specular; - material.glossinessMap = params.glossinessMap === undefined ? null : params.glossinessMap; - material.glossiness = params.glossiness; + material.glossinessMap = params.glossinessMap === undefined ? null : params.glossinessMap; + material.glossiness = params.glossiness; - material.alphaMap = null; + material.alphaMap = null; - material.envMap = params.envMap === undefined ? null : params.envMap; - material.envMapIntensity = 1.0; + material.envMap = params.envMap === undefined ? null : params.envMap; + material.envMapIntensity = 1.0; - material.refractionRatio = 0.98; + material.refractionRatio = 0.98; - material.extensions.derivatives = true; + material.extensions.derivatives = true; - return material; + return material; - }, + }, - /** - * Clones a GLTFSpecularGlossinessMaterial instance. The ShaderMaterial.copy() method can - * copy only properties it knows about or inherits, and misses many properties that would - * normally be defined by MeshStandardMaterial. - * - * This method allows GLTFSpecularGlossinessMaterials to be cloned in the process of - * loading a glTF model, but cloning later (e.g. by the user) would require these changes - * AND also updating `.onBeforeRender` on the parent mesh. - * - * @param {THREE.ShaderMaterial} source - * @return {THREE.ShaderMaterial} - */ - cloneMaterial: function ( source ) { + /** + * Clones a GLTFSpecularGlossinessMaterial instance. The ShaderMaterial.copy() method can + * copy only properties it knows about or inherits, and misses many properties that would + * normally be defined by MeshStandardMaterial. + * + * This method allows GLTFSpecularGlossinessMaterials to be cloned in the process of + * loading a glTF model, but cloning later (e.g. by the user) would require these changes + * AND also updating `.onBeforeRender` on the parent mesh. + * + * @param {THREE.ShaderMaterial} source + * @return {THREE.ShaderMaterial} + */ + cloneMaterial: function ( source ) { - var target = source.clone(); + var target = source.clone(); - target.isGLTFSpecularGlossinessMaterial = true; + target.isGLTFSpecularGlossinessMaterial = true; - var params = this.specularGlossinessParams; + var params = this.specularGlossinessParams; - for ( var i = 0, il = params.length; i < il; i ++ ) { + for ( var i = 0, il = params.length; i < il; i ++ ) { - target[ params[ i ] ] = source[ params[ i ] ]; + target[ params[ i ] ] = source[ params[ i ] ]; - } + } - return target; + return target; - }, + }, - // Here's based on refreshUniformsCommon() and refreshUniformsStandard() in WebGLRenderer. - refreshUniforms: function ( renderer, scene, camera, geometry, material, group ) { + // Here's based on refreshUniformsCommon() and refreshUniformsStandard() in WebGLRenderer. + refreshUniforms: function ( renderer, scene, camera, geometry, material, group ) { - if ( material.isGLTFSpecularGlossinessMaterial !== true ) { + if ( material.isGLTFSpecularGlossinessMaterial !== true ) { - return; + return; - } + } - var uniforms = material.uniforms; - var defines = material.defines; + var uniforms = material.uniforms; + var defines = material.defines; - uniforms.opacity.value = material.opacity; + uniforms.opacity.value = material.opacity; - uniforms.diffuse.value.copy( material.color ); - uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity ); + uniforms.diffuse.value.copy( material.color ); + uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity ); - uniforms.map.value = material.map; - uniforms.specularMap.value = material.specularMap; - uniforms.alphaMap.value = material.alphaMap; + uniforms.map.value = material.map; + uniforms.specularMap.value = material.specularMap; + uniforms.alphaMap.value = material.alphaMap; - uniforms.lightMap.value = material.lightMap; - uniforms.lightMapIntensity.value = material.lightMapIntensity; + uniforms.lightMap.value = material.lightMap; + uniforms.lightMapIntensity.value = material.lightMapIntensity; - uniforms.aoMap.value = material.aoMap; - uniforms.aoMapIntensity.value = material.aoMapIntensity; + uniforms.aoMap.value = material.aoMap; + uniforms.aoMapIntensity.value = material.aoMapIntensity; - // uv repeat and offset setting priorities - // 1. color map - // 2. specular map - // 3. normal map - // 4. bump map - // 5. alpha map - // 6. emissive map + // uv repeat and offset setting priorities + // 1. color map + // 2. specular map + // 3. normal map + // 4. bump map + // 5. alpha map + // 6. emissive map - var uvScaleMap; + var uvScaleMap; - if ( material.map ) { + if ( material.map ) { - uvScaleMap = material.map; + uvScaleMap = material.map; - } else if ( material.specularMap ) { + } else if ( material.specularMap ) { - uvScaleMap = material.specularMap; + uvScaleMap = material.specularMap; - } else if ( material.displacementMap ) { + } else if ( material.displacementMap ) { - uvScaleMap = material.displacementMap; + uvScaleMap = material.displacementMap; - } else if ( material.normalMap ) { + } else if ( material.normalMap ) { - uvScaleMap = material.normalMap; + uvScaleMap = material.normalMap; - } else if ( material.bumpMap ) { + } else if ( material.bumpMap ) { - uvScaleMap = material.bumpMap; + uvScaleMap = material.bumpMap; - } else if ( material.glossinessMap ) { + } else if ( material.glossinessMap ) { - uvScaleMap = material.glossinessMap; + uvScaleMap = material.glossinessMap; - } else if ( material.alphaMap ) { + } else if ( material.alphaMap ) { - uvScaleMap = material.alphaMap; + uvScaleMap = material.alphaMap; - } else if ( material.emissiveMap ) { + } else if ( material.emissiveMap ) { - uvScaleMap = material.emissiveMap; + uvScaleMap = material.emissiveMap; - } + } - if ( uvScaleMap !== undefined ) { + if ( uvScaleMap !== undefined ) { - // backwards compatibility - if ( uvScaleMap.isWebGLRenderTarget ) { + // backwards compatibility + if ( uvScaleMap.isWebGLRenderTarget ) { - uvScaleMap = uvScaleMap.texture; + uvScaleMap = uvScaleMap.texture; - } + } - if ( uvScaleMap.matrixAutoUpdate === true ) { + if ( uvScaleMap.matrixAutoUpdate === true ) { - uvScaleMap.updateMatrix(); + uvScaleMap.updateMatrix(); - } + } - uniforms.uvTransform.value.copy( uvScaleMap.matrix ); + uniforms.uvTransform.value.copy( uvScaleMap.matrix ); - } + } - uniforms.envMap.value = material.envMap; - uniforms.envMapIntensity.value = material.envMapIntensity; - uniforms.flipEnvMap.value = ( material.envMap && material.envMap.isCubeTexture ) ? - 1 : 1; + uniforms.envMap.value = material.envMap; + uniforms.envMapIntensity.value = material.envMapIntensity; + uniforms.flipEnvMap.value = ( material.envMap && material.envMap.isCubeTexture ) ? - 1 : 1; - uniforms.refractionRatio.value = material.refractionRatio; + uniforms.refractionRatio.value = material.refractionRatio; - uniforms.specular.value.copy( material.specular ); - uniforms.glossiness.value = material.glossiness; + uniforms.specular.value.copy( material.specular ); + uniforms.glossiness.value = material.glossiness; - uniforms.glossinessMap.value = material.glossinessMap; + uniforms.glossinessMap.value = material.glossinessMap; - uniforms.emissiveMap.value = material.emissiveMap; - uniforms.bumpMap.value = material.bumpMap; - uniforms.normalMap.value = material.normalMap; + uniforms.emissiveMap.value = material.emissiveMap; + uniforms.bumpMap.value = material.bumpMap; + uniforms.normalMap.value = material.normalMap; - uniforms.displacementMap.value = material.displacementMap; - uniforms.displacementScale.value = material.displacementScale; - uniforms.displacementBias.value = material.displacementBias; + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; - if ( uniforms.glossinessMap.value !== null && defines.USE_GLOSSINESSMAP === undefined ) { + if ( uniforms.glossinessMap.value !== null && defines.USE_GLOSSINESSMAP === undefined ) { - defines.USE_GLOSSINESSMAP = ''; - // set USE_ROUGHNESSMAP to enable vUv - defines.USE_ROUGHNESSMAP = ''; + defines.USE_GLOSSINESSMAP = ''; + // set USE_ROUGHNESSMAP to enable vUv + defines.USE_ROUGHNESSMAP = ''; - } + } - if ( uniforms.glossinessMap.value === null && defines.USE_GLOSSINESSMAP !== undefined ) { + if ( uniforms.glossinessMap.value === null && defines.USE_GLOSSINESSMAP !== undefined ) { - delete defines.USE_GLOSSINESSMAP; - delete defines.USE_ROUGHNESSMAP; + delete defines.USE_GLOSSINESSMAP; + delete defines.USE_ROUGHNESSMAP; - } + } - } + } - }; + }; - } + } - /*********************************/ - /********** INTERPOLATION ********/ - /*********************************/ + /*********************************/ + /********** INTERPOLATION ********/ + /*********************************/ - // Spline Interpolation - // Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#appendix-c-spline-interpolation - function GLTFCubicSplineInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { + // Spline Interpolation + // Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#appendix-c-spline-interpolation + function GLTFCubicSplineInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) { - THREE.Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); + THREE.Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer ); - } + } - GLTFCubicSplineInterpolant.prototype = Object.create( THREE.Interpolant.prototype ); - GLTFCubicSplineInterpolant.prototype.constructor = GLTFCubicSplineInterpolant; + GLTFCubicSplineInterpolant.prototype = Object.create( THREE.Interpolant.prototype ); + GLTFCubicSplineInterpolant.prototype.constructor = GLTFCubicSplineInterpolant; - GLTFCubicSplineInterpolant.prototype.interpolate_ = function ( i1, t0, t, t1 ) { + GLTFCubicSplineInterpolant.prototype.interpolate_ = function ( i1, t0, t, t1 ) { - var result = this.resultBuffer; - var values = this.sampleValues; - var stride = this.valueSize; + var result = this.resultBuffer; + var values = this.sampleValues; + var stride = this.valueSize; - var stride2 = stride * 2; - var stride3 = stride * 3; + var stride2 = stride * 2; + var stride3 = stride * 3; - var td = t1 - t0; + var td = t1 - t0; - var p = ( t - t0 ) / td; - var pp = p * p; - var ppp = pp * p; + var p = ( t - t0 ) / td; + var pp = p * p; + var ppp = pp * p; - var offset1 = i1 * stride3; - var offset0 = offset1 - stride3; + var offset1 = i1 * stride3; + var offset0 = offset1 - stride3; - var s0 = 2 * ppp - 3 * pp + 1; - var s1 = ppp - 2 * pp + p; - var s2 = - 2 * ppp + 3 * pp; - var s3 = ppp - pp; + var s0 = 2 * ppp - 3 * pp + 1; + var s1 = ppp - 2 * pp + p; + var s2 = - 2 * ppp + 3 * pp; + var s3 = ppp - pp; - // Layout of keyframe output values for CUBICSPLINE animations: - // [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ] - for ( var i = 0; i !== stride; i ++ ) { + // Layout of keyframe output values for CUBICSPLINE animations: + // [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ] + for ( var i = 0; i !== stride; i ++ ) { - var p0 = values[ offset0 + i + stride ]; // splineVertex_k - var m0 = values[ offset0 + i + stride2 ] * td; // outTangent_k * (t_k+1 - t_k) - var p1 = values[ offset1 + i + stride ]; // splineVertex_k+1 - var m1 = values[ offset1 + i ] * td; // inTangent_k+1 * (t_k+1 - t_k) + var p0 = values[ offset0 + i + stride ]; // splineVertex_k + var m0 = values[ offset0 + i + stride2 ] * td; // outTangent_k * (t_k+1 - t_k) + var p1 = values[ offset1 + i + stride ]; // splineVertex_k+1 + var m1 = values[ offset1 + i ] * td; // inTangent_k+1 * (t_k+1 - t_k) - result[ i ] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1; - - } - - return result; - - }; - - /*********************************/ - /********** INTERNALS ************/ - /*********************************/ - - /* CONSTANTS */ - - var WEBGL_CONSTANTS = { - FLOAT: 5126, - //FLOAT_MAT2: 35674, - FLOAT_MAT3: 35675, - FLOAT_MAT4: 35676, - FLOAT_VEC2: 35664, - FLOAT_VEC3: 35665, - FLOAT_VEC4: 35666, - LINEAR: 9729, - REPEAT: 10497, - SAMPLER_2D: 35678, - POINTS: 0, - LINES: 1, - LINE_LOOP: 2, - LINE_STRIP: 3, - TRIANGLES: 4, - TRIANGLE_STRIP: 5, - TRIANGLE_FAN: 6, - UNSIGNED_BYTE: 5121, - UNSIGNED_SHORT: 5123 - }; - - var WEBGL_TYPE = { - 5126: Number, - //35674: THREE.Matrix2, - 35675: THREE.Matrix3, - 35676: THREE.Matrix4, - 35664: THREE.Vector2, - 35665: THREE.Vector3, - 35666: THREE.Vector4, - 35678: THREE.Texture - }; - - var WEBGL_COMPONENT_TYPES = { - 5120: Int8Array, - 5121: Uint8Array, - 5122: Int16Array, - 5123: Uint16Array, - 5125: Uint32Array, - 5126: Float32Array - }; - - var WEBGL_FILTERS = { - 9728: THREE.NearestFilter, - 9729: THREE.LinearFilter, - 9984: THREE.NearestMipMapNearestFilter, - 9985: THREE.LinearMipMapNearestFilter, - 9986: THREE.NearestMipMapLinearFilter, - 9987: THREE.LinearMipMapLinearFilter - }; - - var WEBGL_WRAPPINGS = { - 33071: THREE.ClampToEdgeWrapping, - 33648: THREE.MirroredRepeatWrapping, - 10497: THREE.RepeatWrapping - }; - - var WEBGL_SIDES = { - 1028: THREE.BackSide, // Culling front - 1029: THREE.FrontSide // Culling back - //1032: THREE.NoSide // Culling front and back, what to do? - }; - - var WEBGL_DEPTH_FUNCS = { - 512: THREE.NeverDepth, - 513: THREE.LessDepth, - 514: THREE.EqualDepth, - 515: THREE.LessEqualDepth, - 516: THREE.GreaterEqualDepth, - 517: THREE.NotEqualDepth, - 518: THREE.GreaterEqualDepth, - 519: THREE.AlwaysDepth - }; - - var WEBGL_BLEND_EQUATIONS = { - 32774: THREE.AddEquation, - 32778: THREE.SubtractEquation, - 32779: THREE.ReverseSubtractEquation - }; - - var WEBGL_BLEND_FUNCS = { - 0: THREE.ZeroFactor, - 1: THREE.OneFactor, - 768: THREE.SrcColorFactor, - 769: THREE.OneMinusSrcColorFactor, - 770: THREE.SrcAlphaFactor, - 771: THREE.OneMinusSrcAlphaFactor, - 772: THREE.DstAlphaFactor, - 773: THREE.OneMinusDstAlphaFactor, - 774: THREE.DstColorFactor, - 775: THREE.OneMinusDstColorFactor, - 776: THREE.SrcAlphaSaturateFactor - // The followings are not supported by Three.js yet - //32769: CONSTANT_COLOR, - //32770: ONE_MINUS_CONSTANT_COLOR, - //32771: CONSTANT_ALPHA, - //32772: ONE_MINUS_CONSTANT_COLOR - }; - - var WEBGL_TYPE_SIZES = { - 'SCALAR': 1, - 'VEC2': 2, - 'VEC3': 3, - 'VEC4': 4, - 'MAT2': 4, - 'MAT3': 9, - 'MAT4': 16 - }; - - var ATTRIBUTES = { - POSITION: 'position', - NORMAL: 'normal', - TEXCOORD_0: 'uv', - TEXCOORD0: 'uv', // deprecated - TEXCOORD: 'uv', // deprecated - TEXCOORD_1: 'uv2', - COLOR_0: 'color', - COLOR0: 'color', // deprecated - COLOR: 'color', // deprecated - WEIGHTS_0: 'skinWeight', - WEIGHT: 'skinWeight', // deprecated - JOINTS_0: 'skinIndex', - JOINT: 'skinIndex' // deprecated - }; - - var PATH_PROPERTIES = { - scale: 'scale', - translation: 'position', - rotation: 'quaternion', - weights: 'morphTargetInfluences' - }; - - var INTERPOLATION = { - CUBICSPLINE: THREE.InterpolateSmooth, // We use custom interpolation GLTFCubicSplineInterpolation for CUBICSPLINE. - // KeyframeTrack.optimize() can't handle glTF Cubic Spline output values layout, - // using THREE.InterpolateSmooth for KeyframeTrack instantiation to prevent optimization. - // See KeyframeTrack.optimize() for the detail. - LINEAR: THREE.InterpolateLinear, - STEP: THREE.InterpolateDiscrete - }; - - var STATES_ENABLES = { - 2884: 'CULL_FACE', - 2929: 'DEPTH_TEST', - 3042: 'BLEND', - 3089: 'SCISSOR_TEST', - 32823: 'POLYGON_OFFSET_FILL', - 32926: 'SAMPLE_ALPHA_TO_COVERAGE' - }; - - var ALPHA_MODES = { - OPAQUE: 'OPAQUE', - MASK: 'MASK', - BLEND: 'BLEND' - }; - - /* UTILITY FUNCTIONS */ - - function resolveURL( url, path ) { - - // Invalid URL - if ( typeof url !== 'string' || url === '' ) return ''; - - // Absolute URL http://,https://,// - if ( /^(https?:)?\/\//i.test( url ) ) return url; - - // Data URI - if ( /^data:.*,.*$/i.test( url ) ) return url; - - // Blob URL - if ( /^blob:.*$/i.test( url ) ) return url; - - // Relative URL - return path + url; - - } - - /** - * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material - */ - function createDefaultMaterial() { - - return new THREE.MeshStandardMaterial( { - color: 0xFFFFFF, - emissive: 0x000000, - metalness: 1, - roughness: 1, - transparent: false, - depthTest: true, - side: THREE.FrontSide - } ); + result[ i ] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1; + + } + + return result; + + }; + + /*********************************/ + /********** INTERNALS ************/ + /*********************************/ + + /* CONSTANTS */ + + var WEBGL_CONSTANTS = { + FLOAT: 5126, + //FLOAT_MAT2: 35674, + FLOAT_MAT3: 35675, + FLOAT_MAT4: 35676, + FLOAT_VEC2: 35664, + FLOAT_VEC3: 35665, + FLOAT_VEC4: 35666, + LINEAR: 9729, + REPEAT: 10497, + SAMPLER_2D: 35678, + POINTS: 0, + LINES: 1, + LINE_LOOP: 2, + LINE_STRIP: 3, + TRIANGLES: 4, + TRIANGLE_STRIP: 5, + TRIANGLE_FAN: 6, + UNSIGNED_BYTE: 5121, + UNSIGNED_SHORT: 5123 + }; + + var WEBGL_TYPE = { + 5126: Number, + //35674: THREE.Matrix2, + 35675: THREE.Matrix3, + 35676: THREE.Matrix4, + 35664: THREE.Vector2, + 35665: THREE.Vector3, + 35666: THREE.Vector4, + 35678: THREE.Texture + }; + + var WEBGL_COMPONENT_TYPES = { + 5120: Int8Array, + 5121: Uint8Array, + 5122: Int16Array, + 5123: Uint16Array, + 5125: Uint32Array, + 5126: Float32Array + }; + + var WEBGL_FILTERS = { + 9728: THREE.NearestFilter, + 9729: THREE.LinearFilter, + 9984: THREE.NearestMipMapNearestFilter, + 9985: THREE.LinearMipMapNearestFilter, + 9986: THREE.NearestMipMapLinearFilter, + 9987: THREE.LinearMipMapLinearFilter + }; + + var WEBGL_WRAPPINGS = { + 33071: THREE.ClampToEdgeWrapping, + 33648: THREE.MirroredRepeatWrapping, + 10497: THREE.RepeatWrapping + }; + + var WEBGL_SIDES = { + 1028: THREE.BackSide, // Culling front + 1029: THREE.FrontSide // Culling back + //1032: THREE.NoSide // Culling front and back, what to do? + }; + + var WEBGL_DEPTH_FUNCS = { + 512: THREE.NeverDepth, + 513: THREE.LessDepth, + 514: THREE.EqualDepth, + 515: THREE.LessEqualDepth, + 516: THREE.GreaterEqualDepth, + 517: THREE.NotEqualDepth, + 518: THREE.GreaterEqualDepth, + 519: THREE.AlwaysDepth + }; + + var WEBGL_BLEND_EQUATIONS = { + 32774: THREE.AddEquation, + 32778: THREE.SubtractEquation, + 32779: THREE.ReverseSubtractEquation + }; + + var WEBGL_BLEND_FUNCS = { + 0: THREE.ZeroFactor, + 1: THREE.OneFactor, + 768: THREE.SrcColorFactor, + 769: THREE.OneMinusSrcColorFactor, + 770: THREE.SrcAlphaFactor, + 771: THREE.OneMinusSrcAlphaFactor, + 772: THREE.DstAlphaFactor, + 773: THREE.OneMinusDstAlphaFactor, + 774: THREE.DstColorFactor, + 775: THREE.OneMinusDstColorFactor, + 776: THREE.SrcAlphaSaturateFactor + // The followings are not supported by Three.js yet + //32769: CONSTANT_COLOR, + //32770: ONE_MINUS_CONSTANT_COLOR, + //32771: CONSTANT_ALPHA, + //32772: ONE_MINUS_CONSTANT_COLOR + }; + + var WEBGL_TYPE_SIZES = { + 'SCALAR': 1, + 'VEC2': 2, + 'VEC3': 3, + 'VEC4': 4, + 'MAT2': 4, + 'MAT3': 9, + 'MAT4': 16 + }; + + var ATTRIBUTES = { + POSITION: 'position', + NORMAL: 'normal', + TEXCOORD_0: 'uv', + TEXCOORD0: 'uv', // deprecated + TEXCOORD: 'uv', // deprecated + TEXCOORD_1: 'uv2', + COLOR_0: 'color', + COLOR0: 'color', // deprecated + COLOR: 'color', // deprecated + WEIGHTS_0: 'skinWeight', + WEIGHT: 'skinWeight', // deprecated + JOINTS_0: 'skinIndex', + JOINT: 'skinIndex' // deprecated + }; + + var PATH_PROPERTIES = { + scale: 'scale', + translation: 'position', + rotation: 'quaternion', + weights: 'morphTargetInfluences' + }; + + var INTERPOLATION = { + CUBICSPLINE: THREE.InterpolateSmooth, // We use custom interpolation GLTFCubicSplineInterpolation for CUBICSPLINE. + // KeyframeTrack.optimize() can't handle glTF Cubic Spline output values layout, + // using THREE.InterpolateSmooth for KeyframeTrack instantiation to prevent optimization. + // See KeyframeTrack.optimize() for the detail. + LINEAR: THREE.InterpolateLinear, + STEP: THREE.InterpolateDiscrete + }; + + var STATES_ENABLES = { + 2884: 'CULL_FACE', + 2929: 'DEPTH_TEST', + 3042: 'BLEND', + 3089: 'SCISSOR_TEST', + 32823: 'POLYGON_OFFSET_FILL', + 32926: 'SAMPLE_ALPHA_TO_COVERAGE' + }; + + var ALPHA_MODES = { + OPAQUE: 'OPAQUE', + MASK: 'MASK', + BLEND: 'BLEND' + }; + + /* UTILITY FUNCTIONS */ + + function resolveURL( url, path ) { + + // Invalid URL + if ( typeof url !== 'string' || url === '' ) return ''; + + // Absolute URL http://,https://,// + if ( /^(https?:)?\/\//i.test( url ) ) return url; + + // Data URI + if ( /^data:.*,.*$/i.test( url ) ) return url; + + // Blob URL + if ( /^blob:.*$/i.test( url ) ) return url; + + // Relative URL + return path + url; + + } + + /** + * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material + */ + function createDefaultMaterial() { + + return new THREE.MeshStandardMaterial( { + color: 0xFFFFFF, + emissive: 0x000000, + metalness: 1, + roughness: 1, + transparent: false, + depthTest: true, + side: THREE.FrontSide + } ); - } + } - function addUnknownExtensionsToUserData( knownExtensions, object, objectDef ) { + function addUnknownExtensionsToUserData( knownExtensions, object, objectDef ) { - // Add unknown glTF extensions to an object's userData. + // Add unknown glTF extensions to an object's userData. - for ( var name in objectDef.extensions ) { + for ( var name in objectDef.extensions ) { - if ( knownExtensions[ name ] === undefined ) { + if ( knownExtensions[ name ] === undefined ) { - object.userData.gltfExtensions = object.userData.gltfExtensions || {}; - object.userData.gltfExtensions[ name ] = objectDef.extensions[ name ]; + object.userData.gltfExtensions = object.userData.gltfExtensions || {}; + object.userData.gltfExtensions[ name ] = objectDef.extensions[ name ]; - } + } - } + } - } + } - /** - * @param {THREE.Object3D|THREE.Material|THREE.BufferGeometry} object - * @param {GLTF.definition} def - */ - function assignExtrasToUserData( object, gltfDef ) { + /** + * @param {THREE.Object3D|THREE.Material|THREE.BufferGeometry} object + * @param {GLTF.definition} def + */ + function assignExtrasToUserData( object, gltfDef ) { - if ( gltfDef.extras !== undefined ) { + if ( gltfDef.extras !== undefined ) { - if ( typeof gltfDef.extras === 'object' ) { + if ( typeof gltfDef.extras === 'object' ) { - object.userData = gltfDef.extras; + object.userData = gltfDef.extras; - } else { + } else { - console.warn( 'THREE.GLTFLoader: Ignoring primitive type .extras, ' + gltfDef.extras ); + console.warn( 'THREE.GLTFLoader: Ignoring primitive type .extras, ' + gltfDef.extras ); - } + } - } + } - } + } - /** - * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets - * - * @param {THREE.BufferGeometry} geometry - * @param {Array} targets - * @param {Array} accessors - */ - function addMorphTargets( geometry, targets, accessors ) { + /** + * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets + * + * @param {THREE.BufferGeometry} geometry + * @param {Array} targets + * @param {Array} accessors + */ + function addMorphTargets( geometry, targets, accessors ) { - var hasMorphPosition = false; - var hasMorphNormal = false; + var hasMorphPosition = false; + var hasMorphNormal = false; - for ( var i = 0, il = targets.length; i < il; i ++ ) { + for ( var i = 0, il = targets.length; i < il; i ++ ) { - var target = targets[ i ]; + var target = targets[ i ]; - if ( target.POSITION !== undefined ) hasMorphPosition = true; - if ( target.NORMAL !== undefined ) hasMorphNormal = true; + if ( target.POSITION !== undefined ) hasMorphPosition = true; + if ( target.NORMAL !== undefined ) hasMorphNormal = true; - if ( hasMorphPosition && hasMorphNormal ) break; + if ( hasMorphPosition && hasMorphNormal ) break; - } + } - if ( ! hasMorphPosition && ! hasMorphNormal ) return; + if ( ! hasMorphPosition && ! hasMorphNormal ) return; - var morphPositions = []; - var morphNormals = []; + var morphPositions = []; + var morphNormals = []; - for ( var i = 0, il = targets.length; i < il; i ++ ) { + for ( var i = 0, il = targets.length; i < il; i ++ ) { - var target = targets[ i ]; - var attributeName = 'morphTarget' + i; + var target = targets[ i ]; + var attributeName = 'morphTarget' + i; - if ( hasMorphPosition ) { + if ( hasMorphPosition ) { - // Three.js morph position is absolute value. The formula is - // basePosition - // + weight0 * ( morphPosition0 - basePosition ) - // + weight1 * ( morphPosition1 - basePosition ) - // ... - // while the glTF one is relative - // basePosition - // + weight0 * glTFmorphPosition0 - // + weight1 * glTFmorphPosition1 - // ... - // then we need to convert from relative to absolute here. + // Three.js morph position is absolute value. The formula is + // basePosition + // + weight0 * ( morphPosition0 - basePosition ) + // + weight1 * ( morphPosition1 - basePosition ) + // ... + // while the glTF one is relative + // basePosition + // + weight0 * glTFmorphPosition0 + // + weight1 * glTFmorphPosition1 + // ... + // then we need to convert from relative to absolute here. - if ( target.POSITION !== undefined ) { + if ( target.POSITION !== undefined ) { - // Cloning not to pollute original accessor - var positionAttribute = cloneBufferAttribute( accessors[ target.POSITION ] ); - positionAttribute.name = attributeName; + // Cloning not to pollute original accessor + var positionAttribute = cloneBufferAttribute( accessors[ target.POSITION ] ); + positionAttribute.name = attributeName; - var position = geometry.attributes.position; + var position = geometry.attributes.position; - for ( var j = 0, jl = positionAttribute.count; j < jl; j ++ ) { + for ( var j = 0, jl = positionAttribute.count; j < jl; j ++ ) { - positionAttribute.setXYZ( - j, - positionAttribute.getX( j ) + position.getX( j ), - positionAttribute.getY( j ) + position.getY( j ), - positionAttribute.getZ( j ) + position.getZ( j ) - ); + positionAttribute.setXYZ( + j, + positionAttribute.getX( j ) + position.getX( j ), + positionAttribute.getY( j ) + position.getY( j ), + positionAttribute.getZ( j ) + position.getZ( j ) + ); - } + } - } else { + } else { - positionAttribute = geometry.attributes.position; + positionAttribute = geometry.attributes.position; - } + } - morphPositions.push( positionAttribute ); + morphPositions.push( positionAttribute ); - } + } - if ( hasMorphNormal ) { + if ( hasMorphNormal ) { - // see target.POSITION's comment + // see target.POSITION's comment - var normalAttribute; + var normalAttribute; - if ( target.NORMAL !== undefined ) { + if ( target.NORMAL !== undefined ) { - var normalAttribute = cloneBufferAttribute( accessors[ target.NORMAL ] ); - normalAttribute.name = attributeName; + var normalAttribute = cloneBufferAttribute( accessors[ target.NORMAL ] ); + normalAttribute.name = attributeName; - var normal = geometry.attributes.normal; + var normal = geometry.attributes.normal; - for ( var j = 0, jl = normalAttribute.count; j < jl; j ++ ) { + for ( var j = 0, jl = normalAttribute.count; j < jl; j ++ ) { - normalAttribute.setXYZ( - j, - normalAttribute.getX( j ) + normal.getX( j ), - normalAttribute.getY( j ) + normal.getY( j ), - normalAttribute.getZ( j ) + normal.getZ( j ) - ); + normalAttribute.setXYZ( + j, + normalAttribute.getX( j ) + normal.getX( j ), + normalAttribute.getY( j ) + normal.getY( j ), + normalAttribute.getZ( j ) + normal.getZ( j ) + ); - } + } - } else { + } else { - normalAttribute = geometry.attributes.normal; + normalAttribute = geometry.attributes.normal; - } + } - morphNormals.push( normalAttribute ); + morphNormals.push( normalAttribute ); - } + } - } + } - if ( hasMorphPosition ) geometry.morphAttributes.position = morphPositions; - if ( hasMorphNormal ) geometry.morphAttributes.normal = morphNormals; + if ( hasMorphPosition ) geometry.morphAttributes.position = morphPositions; + if ( hasMorphNormal ) geometry.morphAttributes.normal = morphNormals; - } + } - /** - * @param {THREE.Mesh} mesh - * @param {GLTF.Mesh} meshDef - */ - function updateMorphTargets( mesh, meshDef ) { + /** + * @param {THREE.Mesh} mesh + * @param {GLTF.Mesh} meshDef + */ + function updateMorphTargets( mesh, meshDef ) { - mesh.updateMorphTargets(); + mesh.updateMorphTargets(); - if ( meshDef.weights !== undefined ) { + if ( meshDef.weights !== undefined ) { - for ( var i = 0, il = meshDef.weights.length; i < il; i ++ ) { + for ( var i = 0, il = meshDef.weights.length; i < il; i ++ ) { - mesh.morphTargetInfluences[ i ] = meshDef.weights[ i ]; + mesh.morphTargetInfluences[ i ] = meshDef.weights[ i ]; - } + } - } + } - // .extras has user-defined data, so check that .extras.targetNames is an array. - if ( meshDef.extras && Array.isArray( meshDef.extras.targetNames ) ) { + // .extras has user-defined data, so check that .extras.targetNames is an array. + if ( meshDef.extras && Array.isArray( meshDef.extras.targetNames ) ) { - var targetNames = meshDef.extras.targetNames; + var targetNames = meshDef.extras.targetNames; - if ( mesh.morphTargetInfluences.length === targetNames.length ) { + if ( mesh.morphTargetInfluences.length === targetNames.length ) { - mesh.morphTargetDictionary = {}; + mesh.morphTargetDictionary = {}; - for ( var i = 0, il = targetNames.length; i < il; i ++ ) { + for ( var i = 0, il = targetNames.length; i < il; i ++ ) { - mesh.morphTargetDictionary[ targetNames[ i ] ] = i; + mesh.morphTargetDictionary[ targetNames[ i ] ] = i; - } + } - } else { + } else { - console.warn( 'THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.' ); + console.warn( 'THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.' ); - } + } - } + } - } + } - function isPrimitiveEqual( a, b ) { + function isPrimitiveEqual( a, b ) { - if ( a.indices !== b.indices ) { + if ( a.indices !== b.indices ) { - return false; + return false; - } + } - return isObjectEqual( a.attributes, b.attributes ); + return isObjectEqual( a.attributes, b.attributes ); - } + } - function isObjectEqual( a, b ) { + function isObjectEqual( a, b ) { - if ( Object.keys( a ).length !== Object.keys( b ).length ) return false; + if ( Object.keys( a ).length !== Object.keys( b ).length ) return false; - for ( var key in a ) { + for ( var key in a ) { - if ( a[ key ] !== b[ key ] ) return false; + if ( a[ key ] !== b[ key ] ) return false; - } + } - return true; + return true; - } + } - function isArrayEqual( a, b ) { + function isArrayEqual( a, b ) { - if ( a.length !== b.length ) return false; + if ( a.length !== b.length ) return false; - for ( var i = 0, il = a.length; i < il; i ++ ) { + for ( var i = 0, il = a.length; i < il; i ++ ) { - if ( a[ i ] !== b[ i ] ) return false; + if ( a[ i ] !== b[ i ] ) return false; - } + } - return true; + return true; - } + } - function getCachedGeometry( cache, newPrimitive ) { + function getCachedGeometry( cache, newPrimitive ) { - for ( var i = 0, il = cache.length; i < il; i ++ ) { + for ( var i = 0, il = cache.length; i < il; i ++ ) { - var cached = cache[ i ]; + var cached = cache[ i ]; - if ( isPrimitiveEqual( cached.primitive, newPrimitive ) ) return cached.promise; + if ( isPrimitiveEqual( cached.primitive, newPrimitive ) ) return cached.promise; - } + } - return null; + return null; - } + } - function getCachedCombinedGeometry( cache, geometries ) { + function getCachedCombinedGeometry( cache, geometries ) { - for ( var i = 0, il = cache.length; i < il; i ++ ) { + for ( var i = 0, il = cache.length; i < il; i ++ ) { - var cached = cache[ i ]; + var cached = cache[ i ]; - if ( isArrayEqual( geometries, cached.baseGeometries ) ) return cached.geometry; + if ( isArrayEqual( geometries, cached.baseGeometries ) ) return cached.geometry; - } + } - return null; + return null; - } + } - function getCachedMultiPassGeometry( cache, geometry, primitives ) { + function getCachedMultiPassGeometry( cache, geometry, primitives ) { - for ( var i = 0, il = cache.length; i < il; i ++ ) { + for ( var i = 0, il = cache.length; i < il; i ++ ) { - var cached = cache[ i ]; + var cached = cache[ i ]; - if ( geometry === cached.baseGeometry && isArrayEqual( primitives, cached.primitives ) ) return cached.geometry; + if ( geometry === cached.baseGeometry && isArrayEqual( primitives, cached.primitives ) ) return cached.geometry; - } + } - return null; + return null; - } + } - function cloneBufferAttribute( attribute ) { + function cloneBufferAttribute( attribute ) { - if ( attribute.isInterleavedBufferAttribute ) { + if ( attribute.isInterleavedBufferAttribute ) { - var count = attribute.count; - var itemSize = attribute.itemSize; - var array = attribute.array.slice( 0, count * itemSize ); + var count = attribute.count; + var itemSize = attribute.itemSize; + var array = attribute.array.slice( 0, count * itemSize ); - for ( var i = 0; i < count; ++ i ) { + for ( var i = 0; i < count; ++ i ) { - array[ i ] = attribute.getX( i ); - if ( itemSize >= 2 ) array[ i + 1 ] = attribute.getY( i ); - if ( itemSize >= 3 ) array[ i + 2 ] = attribute.getZ( i ); - if ( itemSize >= 4 ) array[ i + 3 ] = attribute.getW( i ); + array[ i ] = attribute.getX( i ); + if ( itemSize >= 2 ) array[ i + 1 ] = attribute.getY( i ); + if ( itemSize >= 3 ) array[ i + 2 ] = attribute.getZ( i ); + if ( itemSize >= 4 ) array[ i + 3 ] = attribute.getW( i ); - } + } - return new THREE.BufferAttribute( array, itemSize, attribute.normalized ); + return new THREE.BufferAttribute( array, itemSize, attribute.normalized ); - } + } - return attribute.clone(); + return attribute.clone(); - } + } - /** - * Checks if we can build a single Mesh with MultiMaterial from multiple primitives. - * Returns true if all primitives use the same attributes/morphAttributes/mode - * and also have index. Otherwise returns false. - * - * @param {Array} primitives - * @return {Boolean} - */ - function isMultiPassGeometry( primitives ) { + /** + * Checks if we can build a single Mesh with MultiMaterial from multiple primitives. + * Returns true if all primitives use the same attributes/morphAttributes/mode + * and also have index. Otherwise returns false. + * + * @param {Array} primitives + * @return {Boolean} + */ + function isMultiPassGeometry( primitives ) { - if ( primitives.length < 2 ) return false; + if ( primitives.length < 2 ) return false; - var primitive0 = primitives[ 0 ]; - var targets0 = primitive0.targets || []; + var primitive0 = primitives[ 0 ]; + var targets0 = primitive0.targets || []; - if ( primitive0.indices === undefined ) return false; + if ( primitive0.indices === undefined ) return false; - for ( var i = 1, il = primitives.length; i < il; i ++ ) { + for ( var i = 1, il = primitives.length; i < il; i ++ ) { - var primitive = primitives[ i ]; + var primitive = primitives[ i ]; - if ( primitive0.mode !== primitive.mode ) return false; - if ( primitive.indices === undefined ) return false; - if ( ! isObjectEqual( primitive0.attributes, primitive.attributes ) ) return false; + if ( primitive0.mode !== primitive.mode ) return false; + if ( primitive.indices === undefined ) return false; + if ( ! isObjectEqual( primitive0.attributes, primitive.attributes ) ) return false; - var targets = primitive.targets || []; + var targets = primitive.targets || []; - if ( targets0.length !== targets.length ) return false; + if ( targets0.length !== targets.length ) return false; - for ( var j = 0, jl = targets0.length; j < jl; j ++ ) { + for ( var j = 0, jl = targets0.length; j < jl; j ++ ) { - if ( ! isObjectEqual( targets0[ j ], targets[ j ] ) ) return false; + if ( ! isObjectEqual( targets0[ j ], targets[ j ] ) ) return false; - } + } - } + } - return true; + return true; - } + } - /* GLTF PARSER */ + /* GLTF PARSER */ - function GLTFParser( json, extensions, options ) { + function GLTFParser( json, extensions, options ) { - this.json = json || {}; - this.extensions = extensions || {}; - this.options = options || {}; + this.json = json || {}; + this.extensions = extensions || {}; + this.options = options || {}; - // loader object cache - this.cache = new GLTFRegistry(); + // loader object cache + this.cache = new GLTFRegistry(); - // BufferGeometry caching - this.primitiveCache = []; - this.multiplePrimitivesCache = []; - this.multiPassGeometryCache = []; + // BufferGeometry caching + this.primitiveCache = []; + this.multiplePrimitivesCache = []; + this.multiPassGeometryCache = []; - this.textureLoader = new THREE.TextureLoader( this.options.manager ); - this.textureLoader.setCrossOrigin( this.options.crossOrigin ); + this.textureLoader = new THREE.TextureLoader( this.options.manager ); + this.textureLoader.setCrossOrigin( this.options.crossOrigin ); - this.fileLoader = new THREE.FileLoader( this.options.manager ); - this.fileLoader.setResponseType( 'arraybuffer' ); + this.fileLoader = new THREE.FileLoader( this.options.manager ); + this.fileLoader.setResponseType( 'arraybuffer' ); - } + } - GLTFParser.prototype.parse = function ( onLoad, onError ) { + GLTFParser.prototype.parse = function ( onLoad, onError ) { - var json = this.json; + var json = this.json; - // Clear the loader cache - this.cache.removeAll(); + // Clear the loader cache + this.cache.removeAll(); - // Mark the special nodes/meshes in json for efficient parse - this.markDefs(); + // Mark the special nodes/meshes in json for efficient parse + this.markDefs(); - // Fire the callback on complete - this.getMultiDependencies( [ + // Fire the callback on complete + this.getMultiDependencies( [ - 'scene', - 'animation', - 'camera' + 'scene', + 'animation', + 'camera' - ] ).then( function ( dependencies ) { + ] ).then( function ( dependencies ) { - var scenes = dependencies.scenes || []; - var scene = scenes[ json.scene || 0 ]; - var animations = dependencies.animations || []; - var cameras = dependencies.cameras || []; + var scenes = dependencies.scenes || []; + var scene = scenes[ json.scene || 0 ]; + var animations = dependencies.animations || []; + var cameras = dependencies.cameras || []; - onLoad( scene, scenes, cameras, animations, json ); + onLoad( scene, scenes, cameras, animations, json ); - } ).catch( onError ); + } ).catch( onError ); - }; + }; - /** - * Marks the special nodes/meshes in json for efficient parse. - */ - GLTFParser.prototype.markDefs = function () { + /** + * Marks the special nodes/meshes in json for efficient parse. + */ + GLTFParser.prototype.markDefs = function () { - var nodeDefs = this.json.nodes || []; - var skinDefs = this.json.skins || []; - var meshDefs = this.json.meshes || []; + var nodeDefs = this.json.nodes || []; + var skinDefs = this.json.skins || []; + var meshDefs = this.json.meshes || []; - var meshReferences = {}; - var meshUses = {}; + var meshReferences = {}; + var meshUses = {}; - // Nothing in the node definition indicates whether it is a Bone or an - // Object3D. Use the skins' joint references to mark bones. - for ( var skinIndex = 0, skinLength = skinDefs.length; skinIndex < skinLength; skinIndex ++ ) { + // Nothing in the node definition indicates whether it is a Bone or an + // Object3D. Use the skins' joint references to mark bones. + for ( var skinIndex = 0, skinLength = skinDefs.length; skinIndex < skinLength; skinIndex ++ ) { - var joints = skinDefs[ skinIndex ].joints; + var joints = skinDefs[ skinIndex ].joints; - for ( var i = 0, il = joints.length; i < il; i ++ ) { + for ( var i = 0, il = joints.length; i < il; i ++ ) { - nodeDefs[ joints[ i ] ].isBone = true; + nodeDefs[ joints[ i ] ].isBone = true; - } + } - } + } - // Meshes can (and should) be reused by multiple nodes in a glTF asset. To - // avoid having more than one THREE.Mesh with the same name, count - // references and rename instances below. - // - // Example: CesiumMilkTruck sample model reuses "Wheel" meshes. - for ( var nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) { + // Meshes can (and should) be reused by multiple nodes in a glTF asset. To + // avoid having more than one THREE.Mesh with the same name, count + // references and rename instances below. + // + // Example: CesiumMilkTruck sample model reuses "Wheel" meshes. + for ( var nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) { - var nodeDef = nodeDefs[ nodeIndex ]; + var nodeDef = nodeDefs[ nodeIndex ]; - if ( nodeDef.mesh !== undefined ) { + if ( nodeDef.mesh !== undefined ) { - if ( meshReferences[ nodeDef.mesh ] === undefined ) { + if ( meshReferences[ nodeDef.mesh ] === undefined ) { - meshReferences[ nodeDef.mesh ] = meshUses[ nodeDef.mesh ] = 0; + meshReferences[ nodeDef.mesh ] = meshUses[ nodeDef.mesh ] = 0; - } + } - meshReferences[ nodeDef.mesh ] ++; + meshReferences[ nodeDef.mesh ] ++; - // Nothing in the mesh definition indicates whether it is - // a SkinnedMesh or Mesh. Use the node's mesh reference - // to mark SkinnedMesh if node has skin. - if ( nodeDef.skin !== undefined ) { + // Nothing in the mesh definition indicates whether it is + // a SkinnedMesh or Mesh. Use the node's mesh reference + // to mark SkinnedMesh if node has skin. + if ( nodeDef.skin !== undefined ) { - meshDefs[ nodeDef.mesh ].isSkinnedMesh = true; + meshDefs[ nodeDef.mesh ].isSkinnedMesh = true; - } + } - } + } - } + } - this.json.meshReferences = meshReferences; - this.json.meshUses = meshUses; + this.json.meshReferences = meshReferences; + this.json.meshUses = meshUses; - }; + }; - /** - * Requests the specified dependency asynchronously, with caching. - * @param {string} type - * @param {number} index - * @return {Promise} - */ - GLTFParser.prototype.getDependency = function ( type, index ) { + /** + * Requests the specified dependency asynchronously, with caching. + * @param {string} type + * @param {number} index + * @return {Promise} + */ + GLTFParser.prototype.getDependency = function ( type, index ) { - var cacheKey = type + ':' + index; - var dependency = this.cache.get( cacheKey ); + var cacheKey = type + ':' + index; + var dependency = this.cache.get( cacheKey ); - if ( ! dependency ) { + if ( ! dependency ) { - switch ( type ) { + switch ( type ) { - case 'scene': - dependency = this.loadScene( index ); - break; + case 'scene': + dependency = this.loadScene( index ); + break; - case 'node': - dependency = this.loadNode( index ); - break; + case 'node': + dependency = this.loadNode( index ); + break; - case 'mesh': - dependency = this.loadMesh( index ); - break; + case 'mesh': + dependency = this.loadMesh( index ); + break; - case 'accessor': - dependency = this.loadAccessor( index ); - break; + case 'accessor': + dependency = this.loadAccessor( index ); + break; - case 'bufferView': - dependency = this.loadBufferView( index ); - break; + case 'bufferView': + dependency = this.loadBufferView( index ); + break; - case 'buffer': - dependency = this.loadBuffer( index ); - break; + case 'buffer': + dependency = this.loadBuffer( index ); + break; - case 'material': - dependency = this.loadMaterial( index ); - break; + case 'material': + dependency = this.loadMaterial( index ); + break; - case 'texture': - dependency = this.loadTexture( index ); - break; + case 'texture': + dependency = this.loadTexture( index ); + break; - case 'skin': - dependency = this.loadSkin( index ); - break; + case 'skin': + dependency = this.loadSkin( index ); + break; - case 'animation': - dependency = this.loadAnimation( index ); - break; + case 'animation': + dependency = this.loadAnimation( index ); + break; - case 'camera': - dependency = this.loadCamera( index ); - break; + case 'camera': + dependency = this.loadCamera( index ); + break; - default: - throw new Error( 'Unknown type: ' + type ); + default: + throw new Error( 'Unknown type: ' + type ); - } + } - this.cache.add( cacheKey, dependency ); + this.cache.add( cacheKey, dependency ); - } + } - return dependency; + return dependency; - }; + }; - /** - * Requests all dependencies of the specified type asynchronously, with caching. - * @param {string} type - * @return {Promise>} - */ - GLTFParser.prototype.getDependencies = function ( type ) { + /** + * Requests all dependencies of the specified type asynchronously, with caching. + * @param {string} type + * @return {Promise>} + */ + GLTFParser.prototype.getDependencies = function ( type ) { - var dependencies = this.cache.get( type ); + var dependencies = this.cache.get( type ); - if ( ! dependencies ) { + if ( ! dependencies ) { - var parser = this; - var defs = this.json[ type + ( type === 'mesh' ? 'es' : 's' ) ] || []; + var parser = this; + var defs = this.json[ type + ( type === 'mesh' ? 'es' : 's' ) ] || []; - dependencies = Promise.all( defs.map( function ( def, index ) { + dependencies = Promise.all( defs.map( function ( def, index ) { - return parser.getDependency( type, index ); + return parser.getDependency( type, index ); - } ) ); + } ) ); - this.cache.add( type, dependencies ); + this.cache.add( type, dependencies ); - } + } - return dependencies; + return dependencies; - }; + }; - /** - * Requests all multiple dependencies of the specified types asynchronously, with caching. - * @param {Array} types - * @return {Promise>>} - */ - GLTFParser.prototype.getMultiDependencies = function ( types ) { + /** + * Requests all multiple dependencies of the specified types asynchronously, with caching. + * @param {Array} types + * @return {Promise>>} + */ + GLTFParser.prototype.getMultiDependencies = function ( types ) { - var results = {}; - var pendings = []; + var results = {}; + var pendings = []; - for ( var i = 0, il = types.length; i < il; i ++ ) { + for ( var i = 0, il = types.length; i < il; i ++ ) { - var type = types[ i ]; - var value = this.getDependencies( type ); + var type = types[ i ]; + var value = this.getDependencies( type ); - value = value.then( function ( key, value ) { + value = value.then( function ( key, value ) { - results[ key ] = value; + results[ key ] = value; - }.bind( this, type + ( type === 'mesh' ? 'es' : 's' ) ) ); + }.bind( this, type + ( type === 'mesh' ? 'es' : 's' ) ) ); - pendings.push( value ); + pendings.push( value ); - } + } - return Promise.all( pendings ).then( function () { + return Promise.all( pendings ).then( function () { - return results; + return results; - } ); + } ); - }; + }; - /** - * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views - * @param {number} bufferIndex - * @return {Promise} - */ - GLTFParser.prototype.loadBuffer = function ( bufferIndex ) { + /** + * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views + * @param {number} bufferIndex + * @return {Promise} + */ + GLTFParser.prototype.loadBuffer = function ( bufferIndex ) { - var bufferDef = this.json.buffers[ bufferIndex ]; - var loader = this.fileLoader; + var bufferDef = this.json.buffers[ bufferIndex ]; + var loader = this.fileLoader; - if ( bufferDef.type && bufferDef.type !== 'arraybuffer' ) { + if ( bufferDef.type && bufferDef.type !== 'arraybuffer' ) { - throw new Error( 'THREE.GLTFLoader: ' + bufferDef.type + ' buffer type is not supported.' ); + throw new Error( 'THREE.GLTFLoader: ' + bufferDef.type + ' buffer type is not supported.' ); - } + } - // If present, GLB container is required to be the first buffer. - if ( bufferDef.uri === undefined && bufferIndex === 0 ) { + // If present, GLB container is required to be the first buffer. + if ( bufferDef.uri === undefined && bufferIndex === 0 ) { - return Promise.resolve( this.extensions[ EXTENSIONS.KHR_BINARY_GLTF ].body ); + return Promise.resolve( this.extensions[ EXTENSIONS.KHR_BINARY_GLTF ].body ); - } + } - var options = this.options; + var options = this.options; - return new Promise( function ( resolve, reject ) { + return new Promise( function ( resolve, reject ) { - loader.load( resolveURL( bufferDef.uri, options.path ), resolve, undefined, function () { + loader.load( resolveURL( bufferDef.uri, options.path ), resolve, undefined, function () { - reject( new Error( 'THREE.GLTFLoader: Failed to load buffer "' + bufferDef.uri + '".' ) ); + reject( new Error( 'THREE.GLTFLoader: Failed to load buffer "' + bufferDef.uri + '".' ) ); - } ); + } ); - } ); + } ); - }; + }; - /** - * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views - * @param {number} bufferViewIndex - * @return {Promise} - */ - GLTFParser.prototype.loadBufferView = function ( bufferViewIndex ) { + /** + * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views + * @param {number} bufferViewIndex + * @return {Promise} + */ + GLTFParser.prototype.loadBufferView = function ( bufferViewIndex ) { - var bufferViewDef = this.json.bufferViews[ bufferViewIndex ]; + var bufferViewDef = this.json.bufferViews[ bufferViewIndex ]; - return this.getDependency( 'buffer', bufferViewDef.buffer ).then( function ( buffer ) { + return this.getDependency( 'buffer', bufferViewDef.buffer ).then( function ( buffer ) { - var byteLength = bufferViewDef.byteLength || 0; - var byteOffset = bufferViewDef.byteOffset || 0; - return buffer.slice( byteOffset, byteOffset + byteLength ); + var byteLength = bufferViewDef.byteLength || 0; + var byteOffset = bufferViewDef.byteOffset || 0; + return buffer.slice( byteOffset, byteOffset + byteLength ); - } ); + } ); - }; + }; - /** - * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors - * @param {number} accessorIndex - * @return {Promise} - */ - GLTFParser.prototype.loadAccessor = function ( accessorIndex ) { + /** + * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors + * @param {number} accessorIndex + * @return {Promise} + */ + GLTFParser.prototype.loadAccessor = function ( accessorIndex ) { - var parser = this; - var json = this.json; + var parser = this; + var json = this.json; - var accessorDef = this.json.accessors[ accessorIndex ]; + var accessorDef = this.json.accessors[ accessorIndex ]; - if ( accessorDef.bufferView === undefined && accessorDef.sparse === undefined ) { + if ( accessorDef.bufferView === undefined && accessorDef.sparse === undefined ) { - // Ignore empty accessors, which may be used to declare runtime - // information about attributes coming from another source (e.g. Draco - // compression extension). - return null; + // Ignore empty accessors, which may be used to declare runtime + // information about attributes coming from another source (e.g. Draco + // compression extension). + return null; - } + } - var pendingBufferViews = []; + var pendingBufferViews = []; - if ( accessorDef.bufferView !== undefined ) { + if ( accessorDef.bufferView !== undefined ) { - pendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.bufferView ) ); + pendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.bufferView ) ); - } else { + } else { - pendingBufferViews.push( null ); + pendingBufferViews.push( null ); - } + } - if ( accessorDef.sparse !== undefined ) { + if ( accessorDef.sparse !== undefined ) { - pendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.indices.bufferView ) ); - pendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.values.bufferView ) ); + pendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.indices.bufferView ) ); + pendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.values.bufferView ) ); - } + } - return Promise.all( pendingBufferViews ).then( function ( bufferViews ) { + return Promise.all( pendingBufferViews ).then( function ( bufferViews ) { - var bufferView = bufferViews[ 0 ]; + var bufferView = bufferViews[ 0 ]; - var itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ]; - var TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ]; + var itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ]; + var TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ]; - // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12. - var elementBytes = TypedArray.BYTES_PER_ELEMENT; - var itemBytes = elementBytes * itemSize; - var byteOffset = accessorDef.byteOffset || 0; - var byteStride = json.bufferViews[ accessorDef.bufferView ].byteStride; - var normalized = accessorDef.normalized === true; - var array, bufferAttribute; + // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12. + var elementBytes = TypedArray.BYTES_PER_ELEMENT; + var itemBytes = elementBytes * itemSize; + var byteOffset = accessorDef.byteOffset || 0; + var byteStride = json.bufferViews[ accessorDef.bufferView ].byteStride; + var normalized = accessorDef.normalized === true; + var array, bufferAttribute; - // The buffer is not interleaved if the stride is the item size in bytes. - if ( byteStride && byteStride !== itemBytes ) { + // The buffer is not interleaved if the stride is the item size in bytes. + if ( byteStride && byteStride !== itemBytes ) { - var ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType; - var ib = parser.cache.get( ibCacheKey ); + var ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType; + var ib = parser.cache.get( ibCacheKey ); - if ( ! ib ) { + if ( ! ib ) { - // Use the full buffer if it's interleaved. - array = new TypedArray( bufferView ); + // Use the full buffer if it's interleaved. + array = new TypedArray( bufferView ); - // Integer parameters to IB/IBA are in array elements, not bytes. - ib = new THREE.InterleavedBuffer( array, byteStride / elementBytes ); + // Integer parameters to IB/IBA are in array elements, not bytes. + ib = new THREE.InterleavedBuffer( array, byteStride / elementBytes ); - parser.cache.add( ibCacheKey, ib ); + parser.cache.add( ibCacheKey, ib ); - } + } - bufferAttribute = new THREE.InterleavedBufferAttribute( ib, itemSize, byteOffset / elementBytes, normalized ); + bufferAttribute = new THREE.InterleavedBufferAttribute( ib, itemSize, byteOffset / elementBytes, normalized ); - } else { + } else { - if ( bufferView === null ) { + if ( bufferView === null ) { - array = new TypedArray( accessorDef.count * itemSize ); + array = new TypedArray( accessorDef.count * itemSize ); - } else { + } else { - array = new TypedArray( bufferView, byteOffset, accessorDef.count * itemSize ); + array = new TypedArray( bufferView, byteOffset, accessorDef.count * itemSize ); - } + } - bufferAttribute = new THREE.BufferAttribute( array, itemSize, normalized ); + bufferAttribute = new THREE.BufferAttribute( array, itemSize, normalized ); - } + } - // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors - if ( accessorDef.sparse !== undefined ) { + // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors + if ( accessorDef.sparse !== undefined ) { - var itemSizeIndices = WEBGL_TYPE_SIZES.SCALAR; - var TypedArrayIndices = WEBGL_COMPONENT_TYPES[ accessorDef.sparse.indices.componentType ]; + var itemSizeIndices = WEBGL_TYPE_SIZES.SCALAR; + var TypedArrayIndices = WEBGL_COMPONENT_TYPES[ accessorDef.sparse.indices.componentType ]; - var byteOffsetIndices = accessorDef.sparse.indices.byteOffset || 0; - var byteOffsetValues = accessorDef.sparse.values.byteOffset || 0; + var byteOffsetIndices = accessorDef.sparse.indices.byteOffset || 0; + var byteOffsetValues = accessorDef.sparse.values.byteOffset || 0; - var sparseIndices = new TypedArrayIndices( bufferViews[ 1 ], byteOffsetIndices, accessorDef.sparse.count * itemSizeIndices ); - var sparseValues = new TypedArray( bufferViews[ 2 ], byteOffsetValues, accessorDef.sparse.count * itemSize ); + var sparseIndices = new TypedArrayIndices( bufferViews[ 1 ], byteOffsetIndices, accessorDef.sparse.count * itemSizeIndices ); + var sparseValues = new TypedArray( bufferViews[ 2 ], byteOffsetValues, accessorDef.sparse.count * itemSize ); - if ( bufferView !== null ) { + if ( bufferView !== null ) { - // Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes. - bufferAttribute.setArray( bufferAttribute.array.slice() ); + // Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes. + bufferAttribute.setArray( bufferAttribute.array.slice() ); - } + } - for ( var i = 0, il = sparseIndices.length; i < il; i ++ ) { + for ( var i = 0, il = sparseIndices.length; i < il; i ++ ) { - var index = sparseIndices[ i ]; + var index = sparseIndices[ i ]; - bufferAttribute.setX( index, sparseValues[ i * itemSize ] ); - if ( itemSize >= 2 ) bufferAttribute.setY( index, sparseValues[ i * itemSize + 1 ] ); - if ( itemSize >= 3 ) bufferAttribute.setZ( index, sparseValues[ i * itemSize + 2 ] ); - if ( itemSize >= 4 ) bufferAttribute.setW( index, sparseValues[ i * itemSize + 3 ] ); - if ( itemSize >= 5 ) throw new Error( 'THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.' ); + bufferAttribute.setX( index, sparseValues[ i * itemSize ] ); + if ( itemSize >= 2 ) bufferAttribute.setY( index, sparseValues[ i * itemSize + 1 ] ); + if ( itemSize >= 3 ) bufferAttribute.setZ( index, sparseValues[ i * itemSize + 2 ] ); + if ( itemSize >= 4 ) bufferAttribute.setW( index, sparseValues[ i * itemSize + 3 ] ); + if ( itemSize >= 5 ) throw new Error( 'THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.' ); - } + } - } + } - return bufferAttribute; + return bufferAttribute; - } ); + } ); - }; + }; - /** - * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures - * @param {number} textureIndex - * @return {Promise} - */ - GLTFParser.prototype.loadTexture = function ( textureIndex ) { + /** + * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures + * @param {number} textureIndex + * @return {Promise} + */ + GLTFParser.prototype.loadTexture = function ( textureIndex ) { - var parser = this; - var json = this.json; - var options = this.options; - var textureLoader = this.textureLoader; + var parser = this; + var json = this.json; + var options = this.options; + var textureLoader = this.textureLoader; - var URL = window.URL || window.webkitURL; + var URL = window.URL || window.webkitURL; - var textureDef = json.textures[ textureIndex ]; + var textureDef = json.textures[ textureIndex ]; - var textureExtensions = textureDef.extensions || {}; + var textureExtensions = textureDef.extensions || {}; - var source; + var source; - if ( textureExtensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] ) { + if ( textureExtensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] ) { - source = json.images[ textureExtensions[ EXTENSIONS.MSFT_TEXTURE_DDS ].source ]; + source = json.images[ textureExtensions[ EXTENSIONS.MSFT_TEXTURE_DDS ].source ]; - } else { + } else { - source = json.images[ textureDef.source ]; + source = json.images[ textureDef.source ]; - } + } - var sourceURI = source.uri; - var isObjectURL = false; + var sourceURI = source.uri; + var isObjectURL = false; - if ( source.bufferView !== undefined ) { + if ( source.bufferView !== undefined ) { - // Load binary image data from bufferView, if provided. + // Load binary image data from bufferView, if provided. - sourceURI = parser.getDependency( 'bufferView', source.bufferView ).then( function ( bufferView ) { + sourceURI = parser.getDependency( 'bufferView', source.bufferView ).then( function ( bufferView ) { - isObjectURL = true; - var blob = new Blob( [ bufferView ], { type: source.mimeType } ); - sourceURI = URL.createObjectURL( blob ); - return sourceURI; + isObjectURL = true; + var blob = new Blob( [ bufferView ], { type: source.mimeType } ); + sourceURI = URL.createObjectURL( blob ); + return sourceURI; - } ); + } ); - } + } - return Promise.resolve( sourceURI ).then( function ( sourceURI ) { + return Promise.resolve( sourceURI ).then( function ( sourceURI ) { - // Load Texture resource. + // Load Texture resource. - var loader = THREE.Loader.Handlers.get( sourceURI ); + var loader = THREE.Loader.Handlers.get( sourceURI ); - if ( ! loader ) { + if ( ! loader ) { - loader = textureExtensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] - ? parser.extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ].ddsLoader - : textureLoader; + loader = textureExtensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] + ? parser.extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ].ddsLoader + : textureLoader; - } + } - return new Promise( function ( resolve, reject ) { + return new Promise( function ( resolve, reject ) { - loader.load( resolveURL( sourceURI, options.path ), resolve, undefined, reject ); + loader.load( resolveURL( sourceURI, options.path ), resolve, undefined, reject ); - } ); + } ); - } ).then( function ( texture ) { + } ).then( function ( texture ) { - // Clean up resources and configure Texture. + // Clean up resources and configure Texture. - if ( isObjectURL === true ) { + if ( isObjectURL === true ) { - URL.revokeObjectURL( sourceURI ); + URL.revokeObjectURL( sourceURI ); - } + } - texture.flipY = false; + texture.flipY = false; - if ( textureDef.name !== undefined ) texture.name = textureDef.name; + if ( textureDef.name !== undefined ) texture.name = textureDef.name; - var samplers = json.samplers || {}; - var sampler = samplers[ textureDef.sampler ] || {}; + var samplers = json.samplers || {}; + var sampler = samplers[ textureDef.sampler ] || {}; - texture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || THREE.LinearFilter; - texture.minFilter = WEBGL_FILTERS[ sampler.minFilter ] || THREE.LinearMipMapLinearFilter; - texture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || THREE.RepeatWrapping; - texture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || THREE.RepeatWrapping; + texture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || THREE.LinearFilter; + texture.minFilter = WEBGL_FILTERS[ sampler.minFilter ] || THREE.LinearMipMapLinearFilter; + texture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || THREE.RepeatWrapping; + texture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || THREE.RepeatWrapping; - return texture; + return texture; - } ); + } ); - }; + }; - /** - * Asynchronously assigns a texture to the given material parameters. - * @param {Object} materialParams - * @param {string} textureName - * @param {number} textureIndex - * @return {Promise} - */ - GLTFParser.prototype.assignTexture = function ( materialParams, textureName, textureIndex ) { + /** + * Asynchronously assigns a texture to the given material parameters. + * @param {Object} materialParams + * @param {string} textureName + * @param {number} textureIndex + * @return {Promise} + */ + GLTFParser.prototype.assignTexture = function ( materialParams, textureName, textureIndex ) { - return this.getDependency( 'texture', textureIndex ).then( function ( texture ) { + return this.getDependency( 'texture', textureIndex ).then( function ( texture ) { - materialParams[ textureName ] = texture; + materialParams[ textureName ] = texture; - } ); + } ); - }; + }; - /** - * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials - * @param {number} materialIndex - * @return {Promise} - */ - GLTFParser.prototype.loadMaterial = function ( materialIndex ) { + /** + * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials + * @param {number} materialIndex + * @return {Promise} + */ + GLTFParser.prototype.loadMaterial = function ( materialIndex ) { - var parser = this; - var json = this.json; - var extensions = this.extensions; - var materialDef = this.json.materials[ materialIndex ]; + var parser = this; + var json = this.json; + var extensions = this.extensions; + var materialDef = this.json.materials[ materialIndex ]; - var materialType; - var materialParams = {}; - var materialExtensions = materialDef.extensions || {}; + var materialType; + var materialParams = {}; + var materialExtensions = materialDef.extensions || {}; - var pending = []; + var pending = []; - if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] ) { + if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] ) { - var sgExtension = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ]; - materialType = sgExtension.getMaterialType( materialDef ); - pending.push( sgExtension.extendParams( materialParams, materialDef, parser ) ); + var sgExtension = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ]; + materialType = sgExtension.getMaterialType( materialDef ); + pending.push( sgExtension.extendParams( materialParams, materialDef, parser ) ); - } else if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) { + } else if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) { - var kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ]; - materialType = kmuExtension.getMaterialType( materialDef ); - pending.push( kmuExtension.extendParams( materialParams, materialDef, parser ) ); + var kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ]; + materialType = kmuExtension.getMaterialType( materialDef ); + pending.push( kmuExtension.extendParams( materialParams, materialDef, parser ) ); - } else { + } else { - // Specification: - // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material + // Specification: + // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material - materialType = THREE.MeshStandardMaterial; + materialType = THREE.MeshStandardMaterial; - var metallicRoughness = materialDef.pbrMetallicRoughness || {}; + var metallicRoughness = materialDef.pbrMetallicRoughness || {}; - materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 ); - materialParams.opacity = 1.0; + materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 ); + materialParams.opacity = 1.0; - if ( Array.isArray( metallicRoughness.baseColorFactor ) ) { + if ( Array.isArray( metallicRoughness.baseColorFactor ) ) { - var array = metallicRoughness.baseColorFactor; + var array = metallicRoughness.baseColorFactor; - materialParams.color.fromArray( array ); - materialParams.opacity = array[ 3 ]; + materialParams.color.fromArray( array ); + materialParams.opacity = array[ 3 ]; - } + } - if ( metallicRoughness.baseColorTexture !== undefined ) { + if ( metallicRoughness.baseColorTexture !== undefined ) { - pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) ); - } + } - materialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0; - materialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0; + materialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0; + materialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0; - if ( metallicRoughness.metallicRoughnessTexture !== undefined ) { + if ( metallicRoughness.metallicRoughnessTexture !== undefined ) { - var textureIndex = metallicRoughness.metallicRoughnessTexture.index; - pending.push( parser.assignTexture( materialParams, 'metalnessMap', textureIndex ) ); - pending.push( parser.assignTexture( materialParams, 'roughnessMap', textureIndex ) ); + var textureIndex = metallicRoughness.metallicRoughnessTexture.index; + pending.push( parser.assignTexture( materialParams, 'metalnessMap', textureIndex ) ); + pending.push( parser.assignTexture( materialParams, 'roughnessMap', textureIndex ) ); - } + } - } + } - if ( materialDef.doubleSided === true ) { + if ( materialDef.doubleSided === true ) { - materialParams.side = THREE.DoubleSide; + materialParams.side = THREE.DoubleSide; - } + } - var alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE; + var alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE; - if ( alphaMode === ALPHA_MODES.BLEND ) { + if ( alphaMode === ALPHA_MODES.BLEND ) { - materialParams.transparent = true; + materialParams.transparent = true; - } else { + } else { - materialParams.transparent = false; + materialParams.transparent = false; - if ( alphaMode === ALPHA_MODES.MASK ) { + if ( alphaMode === ALPHA_MODES.MASK ) { - materialParams.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5; + materialParams.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5; - } + } - } + } - if ( materialDef.normalTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { + if ( materialDef.normalTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { - pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture.index ) ); - materialParams.normalScale = new THREE.Vector2( 1, 1 ); + materialParams.normalScale = new THREE.Vector2( 1, 1 ); - if ( materialDef.normalTexture.scale !== undefined ) { + if ( materialDef.normalTexture.scale !== undefined ) { - materialParams.normalScale.set( materialDef.normalTexture.scale, materialDef.normalTexture.scale ); + materialParams.normalScale.set( materialDef.normalTexture.scale, materialDef.normalTexture.scale ); - } + } - } + } - if ( materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { + if ( materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { - pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture.index ) ); - if ( materialDef.occlusionTexture.strength !== undefined ) { + if ( materialDef.occlusionTexture.strength !== undefined ) { - materialParams.aoMapIntensity = materialDef.occlusionTexture.strength; + materialParams.aoMapIntensity = materialDef.occlusionTexture.strength; - } + } - } + } - if ( materialDef.emissiveFactor !== undefined && materialType !== THREE.MeshBasicMaterial ) { + if ( materialDef.emissiveFactor !== undefined && materialType !== THREE.MeshBasicMaterial ) { - materialParams.emissive = new THREE.Color().fromArray( materialDef.emissiveFactor ); + materialParams.emissive = new THREE.Color().fromArray( materialDef.emissiveFactor ); - } + } - if ( materialDef.emissiveTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { + if ( materialDef.emissiveTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) { - pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture.index ) ); + pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture.index ) ); - } + } - return Promise.all( pending ).then( function () { + return Promise.all( pending ).then( function () { - var material; + var material; - if ( materialType === THREE.ShaderMaterial ) { + if ( materialType === THREE.ShaderMaterial ) { - material = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].createMaterial( materialParams ); + material = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].createMaterial( materialParams ); - } else { + } else { - material = new materialType( materialParams ); + material = new materialType( materialParams ); - } + } - if ( materialDef.name !== undefined ) material.name = materialDef.name; + if ( materialDef.name !== undefined ) material.name = materialDef.name; - // Normal map textures use OpenGL conventions: - // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#materialnormaltexture - if ( material.normalScale ) { + // Normal map textures use OpenGL conventions: + // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#materialnormaltexture + if ( material.normalScale ) { - material.normalScale.y = - material.normalScale.y; + material.normalScale.y = - material.normalScale.y; - } + } - // baseColorTexture, emissiveTexture, and specularGlossinessTexture use sRGB encoding. - if ( material.map ) material.map.encoding = THREE.sRGBEncoding; - if ( material.emissiveMap ) material.emissiveMap.encoding = THREE.sRGBEncoding; - if ( material.specularMap ) material.specularMap.encoding = THREE.sRGBEncoding; + // baseColorTexture, emissiveTexture, and specularGlossinessTexture use sRGB encoding. + if ( material.map ) material.map.encoding = THREE.sRGBEncoding; + if ( material.emissiveMap ) material.emissiveMap.encoding = THREE.sRGBEncoding; + if ( material.specularMap ) material.specularMap.encoding = THREE.sRGBEncoding; - assignExtrasToUserData( material, materialDef ); + assignExtrasToUserData( material, materialDef ); - if ( materialDef.extensions ) addUnknownExtensionsToUserData( extensions, material, materialDef ); + if ( materialDef.extensions ) addUnknownExtensionsToUserData( extensions, material, materialDef ); - return material; + return material; - } ); + } ); - }; + }; - /** - * @param {THREE.BufferGeometry} geometry - * @param {GLTF.Primitive} primitiveDef - * @param {Array} accessors - */ - function addPrimitiveAttributes( geometry, primitiveDef, accessors ) { + /** + * @param {THREE.BufferGeometry} geometry + * @param {GLTF.Primitive} primitiveDef + * @param {Array} accessors + */ + function addPrimitiveAttributes( geometry, primitiveDef, accessors ) { - var attributes = primitiveDef.attributes; + var attributes = primitiveDef.attributes; - for ( var gltfAttributeName in attributes ) { + for ( var gltfAttributeName in attributes ) { - var threeAttributeName = ATTRIBUTES[ gltfAttributeName ]; - var bufferAttribute = accessors[ attributes[ gltfAttributeName ] ]; + var threeAttributeName = ATTRIBUTES[ gltfAttributeName ]; + var bufferAttribute = accessors[ attributes[ gltfAttributeName ] ]; - // Skip attributes already provided by e.g. Draco extension. - if ( ! threeAttributeName ) continue; - if ( threeAttributeName in geometry.attributes ) continue; + // Skip attributes already provided by e.g. Draco extension. + if ( ! threeAttributeName ) continue; + if ( threeAttributeName in geometry.attributes ) continue; - geometry.addAttribute( threeAttributeName, bufferAttribute ); + geometry.addAttribute( threeAttributeName, bufferAttribute ); - } + } - if ( primitiveDef.indices !== undefined && ! geometry.index ) { + if ( primitiveDef.indices !== undefined && ! geometry.index ) { - geometry.setIndex( accessors[ primitiveDef.indices ] ); + geometry.setIndex( accessors[ primitiveDef.indices ] ); - } + } - if ( primitiveDef.targets !== undefined ) { + if ( primitiveDef.targets !== undefined ) { - addMorphTargets( geometry, primitiveDef.targets, accessors ); + addMorphTargets( geometry, primitiveDef.targets, accessors ); - } + } - assignExtrasToUserData( geometry, primitiveDef ); + assignExtrasToUserData( geometry, primitiveDef ); - } + } - /** - * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry - * - * Creates BufferGeometries from primitives. - * If we can build a single BufferGeometry with .groups from multiple primitives, returns one BufferGeometry. - * Otherwise, returns BufferGeometries without .groups as many as primitives. - * - * @param {Array} primitives - * @return {Promise>} - */ - GLTFParser.prototype.loadGeometries = function ( primitives ) { + /** + * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry + * + * Creates BufferGeometries from primitives. + * If we can build a single BufferGeometry with .groups from multiple primitives, returns one BufferGeometry. + * Otherwise, returns BufferGeometries without .groups as many as primitives. + * + * @param {Array} primitives + * @return {Promise>} + */ + GLTFParser.prototype.loadGeometries = function ( primitives ) { - var parser = this; - var extensions = this.extensions; - var cache = this.primitiveCache; + var parser = this; + var extensions = this.extensions; + var cache = this.primitiveCache; - var isMultiPass = isMultiPassGeometry( primitives ); - var originalPrimitives; + var isMultiPass = isMultiPassGeometry( primitives ); + var originalPrimitives; - if ( isMultiPass ) { + if ( isMultiPass ) { - originalPrimitives = primitives; // save original primitives and use later + originalPrimitives = primitives; // save original primitives and use later - // We build a single BufferGeometry with .groups from multiple primitives - // because all primitives share the same attributes/morph/mode and have indices. + // We build a single BufferGeometry with .groups from multiple primitives + // because all primitives share the same attributes/morph/mode and have indices. - primitives = [ primitives[ 0 ] ]; + primitives = [ primitives[ 0 ] ]; - // Sets .groups and combined indices to a geometry later in this method. + // Sets .groups and combined indices to a geometry later in this method. - } + } - return this.getDependencies( 'accessor' ).then( function ( accessors ) { + return this.getDependencies( 'accessor' ).then( function ( accessors ) { - var pending = []; + var pending = []; - for ( var i = 0, il = primitives.length; i < il; i ++ ) { + for ( var i = 0, il = primitives.length; i < il; i ++ ) { - var primitive = primitives[ i ]; + var primitive = primitives[ i ]; - // See if we've already created this geometry - var cached = getCachedGeometry( cache, primitive ); + // See if we've already created this geometry + var cached = getCachedGeometry( cache, primitive ); - if ( cached ) { + if ( cached ) { - // Use the cached geometry if it exists - pending.push( cached ); + // Use the cached geometry if it exists + pending.push( cached ); - } else if ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) { + } else if ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) { - // Use DRACO geometry if available - var geometryPromise = extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] - .decodePrimitive( primitive, parser ) - .then( function ( geometry ) { + // Use DRACO geometry if available + var geometryPromise = extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] + .decodePrimitive( primitive, parser ) + .then( function ( geometry ) { - addPrimitiveAttributes( geometry, primitive, accessors ); + addPrimitiveAttributes( geometry, primitive, accessors ); - return geometry; + return geometry; - } ); + } ); - cache.push( { primitive: primitive, promise: geometryPromise } ); + cache.push( { primitive: primitive, promise: geometryPromise } ); - pending.push( geometryPromise ); + pending.push( geometryPromise ); - } else { + } else { - // Otherwise create a new geometry - var geometry = new THREE.BufferGeometry(); + // Otherwise create a new geometry + var geometry = new THREE.BufferGeometry(); - addPrimitiveAttributes( geometry, primitive, accessors ); + addPrimitiveAttributes( geometry, primitive, accessors ); - var geometryPromise = Promise.resolve( geometry ); + var geometryPromise = Promise.resolve( geometry ); - // Cache this geometry - cache.push( { primitive: primitive, promise: geometryPromise } ); + // Cache this geometry + cache.push( { primitive: primitive, promise: geometryPromise } ); - pending.push( geometryPromise ); + pending.push( geometryPromise ); - } + } - } + } - return Promise.all( pending ).then( function ( geometries ) { + return Promise.all( pending ).then( function ( geometries ) { - if ( isMultiPass ) { + if ( isMultiPass ) { - var baseGeometry = geometries[ 0 ]; + var baseGeometry = geometries[ 0 ]; - // See if we've already created this combined geometry - var cache = parser.multiPassGeometryCache; - var cached = getCachedMultiPassGeometry( cache, baseGeometry, originalPrimitives ); + // See if we've already created this combined geometry + var cache = parser.multiPassGeometryCache; + var cached = getCachedMultiPassGeometry( cache, baseGeometry, originalPrimitives ); - if ( cached !== null ) return [ cached.geometry ]; + if ( cached !== null ) return [ cached.geometry ]; - // Cloning geometry because of index override. - // Attributes can be reused so cloning by myself here. - var geometry = new THREE.BufferGeometry(); + // Cloning geometry because of index override. + // Attributes can be reused so cloning by myself here. + var geometry = new THREE.BufferGeometry(); - geometry.name = baseGeometry.name; - geometry.userData = baseGeometry.userData; + geometry.name = baseGeometry.name; + geometry.userData = baseGeometry.userData; - for ( var key in baseGeometry.attributes ) geometry.addAttribute( key, baseGeometry.attributes[ key ] ); - for ( var key in baseGeometry.morphAttributes ) geometry.morphAttributes[ key ] = baseGeometry.morphAttributes[ key ]; + for ( var key in baseGeometry.attributes ) geometry.addAttribute( key, baseGeometry.attributes[ key ] ); + for ( var key in baseGeometry.morphAttributes ) geometry.morphAttributes[ key ] = baseGeometry.morphAttributes[ key ]; - var indices = []; - var offset = 0; + var indices = []; + var offset = 0; - for ( var i = 0, il = originalPrimitives.length; i < il; i ++ ) { + for ( var i = 0, il = originalPrimitives.length; i < il; i ++ ) { - var accessor = accessors[ originalPrimitives[ i ].indices ]; + var accessor = accessors[ originalPrimitives[ i ].indices ]; - for ( var j = 0, jl = accessor.count; j < jl; j ++ ) indices.push( accessor.array[ j ] ); + for ( var j = 0, jl = accessor.count; j < jl; j ++ ) indices.push( accessor.array[ j ] ); - geometry.addGroup( offset, accessor.count, i ); + geometry.addGroup( offset, accessor.count, i ); - offset += accessor.count; + offset += accessor.count; - } + } - geometry.setIndex( indices ); + geometry.setIndex( indices ); - cache.push( { geometry: geometry, baseGeometry: baseGeometry, primitives: originalPrimitives } ); + cache.push( { geometry: geometry, baseGeometry: baseGeometry, primitives: originalPrimitives } ); - return [ geometry ]; + return [ geometry ]; - } else if ( geometries.length > 1 && THREE.BufferGeometryUtils !== undefined ) { + } else if ( geometries.length > 1 && THREE.BufferGeometryUtils !== undefined ) { - // Tries to merge geometries with BufferGeometryUtils if possible + // Tries to merge geometries with BufferGeometryUtils if possible - for ( var i = 1, il = primitives.length; i < il; i ++ ) { + for ( var i = 1, il = primitives.length; i < il; i ++ ) { - // can't merge if draw mode is different - if ( primitives[ 0 ].mode !== primitives[ i ].mode ) return geometries; + // can't merge if draw mode is different + if ( primitives[ 0 ].mode !== primitives[ i ].mode ) return geometries; - } + } - // See if we've already created this combined geometry - var cache = parser.multiplePrimitivesCache; - var cached = getCachedCombinedGeometry( cache, geometries ); + // See if we've already created this combined geometry + var cache = parser.multiplePrimitivesCache; + var cached = getCachedCombinedGeometry( cache, geometries ); - if ( cached ) { + if ( cached ) { - if ( cached.geometry !== null ) return [ cached.geometry ]; + if ( cached.geometry !== null ) return [ cached.geometry ]; - } else { + } else { - var geometry = THREE.BufferGeometryUtils.mergeBufferGeometries( geometries, true ); + var geometry = THREE.BufferGeometryUtils.mergeBufferGeometries( geometries, true ); - cache.push( { geometry: geometry, baseGeometries: geometries } ); + cache.push( { geometry: geometry, baseGeometries: geometries } ); - if ( geometry !== null ) return [ geometry ]; + if ( geometry !== null ) return [ geometry ]; - } + } - } + } - return geometries; + return geometries; - } ); + } ); - } ); + } ); - }; + }; - /** - * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes - * @param {number} meshIndex - * @return {Promise} - */ - GLTFParser.prototype.loadMesh = function ( meshIndex ) { + /** + * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes + * @param {number} meshIndex + * @return {Promise} + */ + GLTFParser.prototype.loadMesh = function ( meshIndex ) { - var scope = this; - var json = this.json; - var extensions = this.extensions; + var scope = this; + var json = this.json; + var extensions = this.extensions; - var meshDef = this.json.meshes[ meshIndex ]; + var meshDef = this.json.meshes[ meshIndex ]; - return this.getMultiDependencies( [ + return this.getMultiDependencies( [ - 'accessor', - 'material' + 'accessor', + 'material' - ] ).then( function ( dependencies ) { + ] ).then( function ( dependencies ) { - var primitives = meshDef.primitives; - var originalMaterials = []; + var primitives = meshDef.primitives; + var originalMaterials = []; - for ( var i = 0, il = primitives.length; i < il; i ++ ) { + for ( var i = 0, il = primitives.length; i < il; i ++ ) { - originalMaterials[ i ] = primitives[ i ].material === undefined - ? createDefaultMaterial() - : dependencies.materials[ primitives[ i ].material ]; + originalMaterials[ i ] = primitives[ i ].material === undefined + ? createDefaultMaterial() + : dependencies.materials[ primitives[ i ].material ]; - } + } - return scope.loadGeometries( primitives ).then( function ( geometries ) { + return scope.loadGeometries( primitives ).then( function ( geometries ) { - var isMultiMaterial = geometries.length === 1 && geometries[ 0 ].groups.length > 0; + var isMultiMaterial = geometries.length === 1 && geometries[ 0 ].groups.length > 0; - var meshes = []; + var meshes = []; - for ( var i = 0, il = geometries.length; i < il; i ++ ) { + for ( var i = 0, il = geometries.length; i < il; i ++ ) { - var geometry = geometries[ i ]; - var primitive = primitives[ i ]; + var geometry = geometries[ i ]; + var primitive = primitives[ i ]; - // 1. create Mesh + // 1. create Mesh - var mesh; + var mesh; - var material = isMultiMaterial ? originalMaterials : originalMaterials[ i ]; + var material = isMultiMaterial ? originalMaterials : originalMaterials[ i ]; - if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES || - primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP || - primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN || - primitive.mode === undefined ) { + if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES || + primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP || + primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN || + primitive.mode === undefined ) { - // .isSkinnedMesh isn't in glTF spec. See .markDefs() - mesh = meshDef.isSkinnedMesh === true - ? new THREE.SkinnedMesh( geometry, material ) - : new THREE.Mesh( geometry, material ); + // .isSkinnedMesh isn't in glTF spec. See .markDefs() + mesh = meshDef.isSkinnedMesh === true + ? new THREE.SkinnedMesh( geometry, material ) + : new THREE.Mesh( geometry, material ); - if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) { + if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) { - mesh.drawMode = THREE.TriangleStripDrawMode; + mesh.drawMode = THREE.TriangleStripDrawMode; - } else if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ) { + } else if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ) { - mesh.drawMode = THREE.TriangleFanDrawMode; + mesh.drawMode = THREE.TriangleFanDrawMode; - } + } - } else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) { + } else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) { - mesh = new THREE.LineSegments( geometry, material ); + mesh = new THREE.LineSegments( geometry, material ); - } else if ( primitive.mode === WEBGL_CONSTANTS.LINE_STRIP ) { + } else if ( primitive.mode === WEBGL_CONSTANTS.LINE_STRIP ) { - mesh = new THREE.Line( geometry, material ); + mesh = new THREE.Line( geometry, material ); - } else if ( primitive.mode === WEBGL_CONSTANTS.LINE_LOOP ) { + } else if ( primitive.mode === WEBGL_CONSTANTS.LINE_LOOP ) { - mesh = new THREE.LineLoop( geometry, material ); + mesh = new THREE.LineLoop( geometry, material ); - } else if ( primitive.mode === WEBGL_CONSTANTS.POINTS ) { + } else if ( primitive.mode === WEBGL_CONSTANTS.POINTS ) { - mesh = new THREE.Points( geometry, material ); + mesh = new THREE.Points( geometry, material ); - } else { + } else { - throw new Error( 'THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode ); + throw new Error( 'THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode ); - } + } - if ( Object.keys( mesh.geometry.morphAttributes ).length > 0 ) { + if ( Object.keys( mesh.geometry.morphAttributes ).length > 0 ) { - updateMorphTargets( mesh, meshDef ); + updateMorphTargets( mesh, meshDef ); - } + } - mesh.name = meshDef.name || ( 'mesh_' + meshIndex ); + mesh.name = meshDef.name || ( 'mesh_' + meshIndex ); - if ( geometries.length > 1 ) mesh.name += '_' + i; + if ( geometries.length > 1 ) mesh.name += '_' + i; - assignExtrasToUserData( mesh, meshDef ); + assignExtrasToUserData( mesh, meshDef ); - meshes.push( mesh ); + meshes.push( mesh ); - // 2. update Material depending on Mesh and BufferGeometry + // 2. update Material depending on Mesh and BufferGeometry - var materials = isMultiMaterial ? mesh.material : [ mesh.material ]; + var materials = isMultiMaterial ? mesh.material : [ mesh.material ]; - var useVertexColors = geometry.attributes.color !== undefined; - var useFlatShading = geometry.attributes.normal === undefined; - var useSkinning = mesh.isSkinnedMesh === true; - var useMorphTargets = Object.keys( geometry.morphAttributes ).length > 0; - var useMorphNormals = useMorphTargets && geometry.morphAttributes.normal !== undefined; + var useVertexColors = geometry.attributes.color !== undefined; + var useFlatShading = geometry.attributes.normal === undefined; + var useSkinning = mesh.isSkinnedMesh === true; + var useMorphTargets = Object.keys( geometry.morphAttributes ).length > 0; + var useMorphNormals = useMorphTargets && geometry.morphAttributes.normal !== undefined; - for ( var j = 0, jl = materials.length; j < jl; j ++ ) { + for ( var j = 0, jl = materials.length; j < jl; j ++ ) { - var material = materials[ j ]; + var material = materials[ j ]; - if ( mesh.isPoints ) { + if ( mesh.isPoints ) { - var cacheKey = 'PointsMaterial:' + material.uuid; + var cacheKey = 'PointsMaterial:' + material.uuid; - var pointsMaterial = scope.cache.get( cacheKey ); + var pointsMaterial = scope.cache.get( cacheKey ); - if ( ! pointsMaterial ) { + if ( ! pointsMaterial ) { - pointsMaterial = new THREE.PointsMaterial(); - THREE.Material.prototype.copy.call( pointsMaterial, material ); - pointsMaterial.color.copy( material.color ); - pointsMaterial.map = material.map; - pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet + pointsMaterial = new THREE.PointsMaterial(); + THREE.Material.prototype.copy.call( pointsMaterial, material ); + pointsMaterial.color.copy( material.color ); + pointsMaterial.map = material.map; + pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet - scope.cache.add( cacheKey, pointsMaterial ); + scope.cache.add( cacheKey, pointsMaterial ); - } + } - material = pointsMaterial; + material = pointsMaterial; - } else if ( mesh.isLine ) { + } else if ( mesh.isLine ) { - var cacheKey = 'LineBasicMaterial:' + material.uuid; + var cacheKey = 'LineBasicMaterial:' + material.uuid; - var lineMaterial = scope.cache.get( cacheKey ); + var lineMaterial = scope.cache.get( cacheKey ); - if ( ! lineMaterial ) { + if ( ! lineMaterial ) { - lineMaterial = new THREE.LineBasicMaterial(); - THREE.Material.prototype.copy.call( lineMaterial, material ); - lineMaterial.color.copy( material.color ); - lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet + lineMaterial = new THREE.LineBasicMaterial(); + THREE.Material.prototype.copy.call( lineMaterial, material ); + lineMaterial.color.copy( material.color ); + lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet - scope.cache.add( cacheKey, lineMaterial ); + scope.cache.add( cacheKey, lineMaterial ); - } + } - material = lineMaterial; + material = lineMaterial; - } + } - // Clone the material if it will be modified - if ( useVertexColors || useFlatShading || useSkinning || useMorphTargets ) { + // Clone the material if it will be modified + if ( useVertexColors || useFlatShading || useSkinning || useMorphTargets ) { - var cacheKey = 'ClonedMaterial:' + material.uuid + ':'; + var cacheKey = 'ClonedMaterial:' + material.uuid + ':'; - if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:'; - if ( useSkinning ) cacheKey += 'skinning:'; - if ( useVertexColors ) cacheKey += 'vertex-colors:'; - if ( useFlatShading ) cacheKey += 'flat-shading:'; - if ( useMorphTargets ) cacheKey += 'morph-targets:'; - if ( useMorphNormals ) cacheKey += 'morph-normals:'; + if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:'; + if ( useSkinning ) cacheKey += 'skinning:'; + if ( useVertexColors ) cacheKey += 'vertex-colors:'; + if ( useFlatShading ) cacheKey += 'flat-shading:'; + if ( useMorphTargets ) cacheKey += 'morph-targets:'; + if ( useMorphNormals ) cacheKey += 'morph-normals:'; - var cachedMaterial = scope.cache.get( cacheKey ); + var cachedMaterial = scope.cache.get( cacheKey ); - if ( ! cachedMaterial ) { + if ( ! cachedMaterial ) { - cachedMaterial = material.isGLTFSpecularGlossinessMaterial - ? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( material ) - : material.clone(); + cachedMaterial = material.isGLTFSpecularGlossinessMaterial + ? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( material ) + : material.clone(); - if ( useSkinning ) cachedMaterial.skinning = true; - if ( useVertexColors ) cachedMaterial.vertexColors = THREE.VertexColors; - if ( useFlatShading ) cachedMaterial.flatShading = true; - if ( useMorphTargets ) cachedMaterial.morphTargets = true; - if ( useMorphNormals ) cachedMaterial.morphNormals = true; + if ( useSkinning ) cachedMaterial.skinning = true; + if ( useVertexColors ) cachedMaterial.vertexColors = THREE.VertexColors; + if ( useFlatShading ) cachedMaterial.flatShading = true; + if ( useMorphTargets ) cachedMaterial.morphTargets = true; + if ( useMorphNormals ) cachedMaterial.morphNormals = true; - scope.cache.add( cacheKey, cachedMaterial ); + scope.cache.add( cacheKey, cachedMaterial ); - } + } - material = cachedMaterial; + material = cachedMaterial; - } + } - materials[ j ] = material; + materials[ j ] = material; - // workarounds for mesh and geometry + // workarounds for mesh and geometry - if ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) { + if ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) { - console.log( 'THREE.GLTFLoader: Duplicating UVs to support aoMap.' ); - geometry.addAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) ); + console.log( 'THREE.GLTFLoader: Duplicating UVs to support aoMap.' ); + geometry.addAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) ); - } + } - if ( material.isGLTFSpecularGlossinessMaterial ) { + if ( material.isGLTFSpecularGlossinessMaterial ) { - // for GLTFSpecularGlossinessMaterial(ShaderMaterial) uniforms runtime update - mesh.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms; + // for GLTFSpecularGlossinessMaterial(ShaderMaterial) uniforms runtime update + mesh.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms; - } + } - } + } - mesh.material = isMultiMaterial ? materials : materials[ 0 ]; + mesh.material = isMultiMaterial ? materials : materials[ 0 ]; - } + } - if ( meshes.length === 1 ) { + if ( meshes.length === 1 ) { - return meshes[ 0 ]; + return meshes[ 0 ]; - } + } - var group = new THREE.Group(); + var group = new THREE.Group(); - for ( var i = 0, il = meshes.length; i < il; i ++ ) { + for ( var i = 0, il = meshes.length; i < il; i ++ ) { - group.add( meshes[ i ] ); + group.add( meshes[ i ] ); - } + } - return group; + return group; - } ); + } ); - } ); + } ); - }; + }; - /** - * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras - * @param {number} cameraIndex - * @return {Promise} - */ - GLTFParser.prototype.loadCamera = function ( cameraIndex ) { + /** + * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras + * @param {number} cameraIndex + * @return {Promise} + */ + GLTFParser.prototype.loadCamera = function ( cameraIndex ) { - var camera; - var cameraDef = this.json.cameras[ cameraIndex ]; - var params = cameraDef[ cameraDef.type ]; + var camera; + var cameraDef = this.json.cameras[ cameraIndex ]; + var params = cameraDef[ cameraDef.type ]; - if ( ! params ) { + if ( ! params ) { - console.warn( 'THREE.GLTFLoader: Missing camera parameters.' ); - return; + console.warn( 'THREE.GLTFLoader: Missing camera parameters.' ); + return; - } + } - if ( cameraDef.type === 'perspective' ) { + if ( cameraDef.type === 'perspective' ) { - camera = new THREE.PerspectiveCamera( THREE.Math.radToDeg( params.yfov ), params.aspectRatio || 1, params.znear || 1, params.zfar || 2e6 ); + camera = new THREE.PerspectiveCamera( THREE.Math.radToDeg( params.yfov ), params.aspectRatio || 1, params.znear || 1, params.zfar || 2e6 ); - } else if ( cameraDef.type === 'orthographic' ) { + } else if ( cameraDef.type === 'orthographic' ) { - camera = new THREE.OrthographicCamera( params.xmag / - 2, params.xmag / 2, params.ymag / 2, params.ymag / - 2, params.znear, params.zfar ); + camera = new THREE.OrthographicCamera( params.xmag / - 2, params.xmag / 2, params.ymag / 2, params.ymag / - 2, params.znear, params.zfar ); - } + } - if ( cameraDef.name !== undefined ) camera.name = cameraDef.name; + if ( cameraDef.name !== undefined ) camera.name = cameraDef.name; - assignExtrasToUserData( camera, cameraDef ); + assignExtrasToUserData( camera, cameraDef ); - return Promise.resolve( camera ); + return Promise.resolve( camera ); - }; + }; - /** - * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins - * @param {number} skinIndex - * @return {Promise} - */ - GLTFParser.prototype.loadSkin = function ( skinIndex ) { + /** + * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins + * @param {number} skinIndex + * @return {Promise} + */ + GLTFParser.prototype.loadSkin = function ( skinIndex ) { - var skinDef = this.json.skins[ skinIndex ]; + var skinDef = this.json.skins[ skinIndex ]; - var skinEntry = { joints: skinDef.joints }; + var skinEntry = { joints: skinDef.joints }; - if ( skinDef.inverseBindMatrices === undefined ) { + if ( skinDef.inverseBindMatrices === undefined ) { - return Promise.resolve( skinEntry ); + return Promise.resolve( skinEntry ); - } + } - return this.getDependency( 'accessor', skinDef.inverseBindMatrices ).then( function ( accessor ) { + return this.getDependency( 'accessor', skinDef.inverseBindMatrices ).then( function ( accessor ) { - skinEntry.inverseBindMatrices = accessor; + skinEntry.inverseBindMatrices = accessor; - return skinEntry; + return skinEntry; - } ); + } ); - }; + }; - /** - * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations - * @param {number} animationIndex - * @return {Promise} - */ - GLTFParser.prototype.loadAnimation = function ( animationIndex ) { + /** + * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations + * @param {number} animationIndex + * @return {Promise} + */ + GLTFParser.prototype.loadAnimation = function ( animationIndex ) { - var json = this.json; + var json = this.json; - var animationDef = this.json.animations[ animationIndex ]; + var animationDef = this.json.animations[ animationIndex ]; - return this.getMultiDependencies( [ + return this.getMultiDependencies( [ - 'accessor', - 'node' + 'accessor', + 'node' - ] ).then( function ( dependencies ) { + ] ).then( function ( dependencies ) { - var tracks = []; + var tracks = []; - for ( var i = 0, il = animationDef.channels.length; i < il; i ++ ) { + for ( var i = 0, il = animationDef.channels.length; i < il; i ++ ) { - var channel = animationDef.channels[ i ]; - var sampler = animationDef.samplers[ channel.sampler ]; + var channel = animationDef.channels[ i ]; + var sampler = animationDef.samplers[ channel.sampler ]; - if ( sampler ) { + if ( sampler ) { - var target = channel.target; - var name = target.node !== undefined ? target.node : target.id; // NOTE: target.id is deprecated. - var input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input; - var output = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.output ] : sampler.output; + var target = channel.target; + var name = target.node !== undefined ? target.node : target.id; // NOTE: target.id is deprecated. + var input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input; + var output = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.output ] : sampler.output; - var inputAccessor = dependencies.accessors[ input ]; - var outputAccessor = dependencies.accessors[ output ]; + var inputAccessor = dependencies.accessors[ input ]; + var outputAccessor = dependencies.accessors[ output ]; - var node = dependencies.nodes[ name ]; + var node = dependencies.nodes[ name ]; - if ( node ) { + if ( node ) { - node.updateMatrix(); - node.matrixAutoUpdate = true; + node.updateMatrix(); + node.matrixAutoUpdate = true; - var TypedKeyframeTrack; + var TypedKeyframeTrack; - switch ( PATH_PROPERTIES[ target.path ] ) { + switch ( PATH_PROPERTIES[ target.path ] ) { - case PATH_PROPERTIES.weights: + case PATH_PROPERTIES.weights: - TypedKeyframeTrack = THREE.NumberKeyframeTrack; - break; + TypedKeyframeTrack = THREE.NumberKeyframeTrack; + break; - case PATH_PROPERTIES.rotation: + case PATH_PROPERTIES.rotation: - TypedKeyframeTrack = THREE.QuaternionKeyframeTrack; - break; + TypedKeyframeTrack = THREE.QuaternionKeyframeTrack; + break; - case PATH_PROPERTIES.position: - case PATH_PROPERTIES.scale: - default: + case PATH_PROPERTIES.position: + case PATH_PROPERTIES.scale: + default: - TypedKeyframeTrack = THREE.VectorKeyframeTrack; - break; + TypedKeyframeTrack = THREE.VectorKeyframeTrack; + break; - } + } - var targetName = node.name ? node.name : node.uuid; + var targetName = node.name ? node.name : node.uuid; - var interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : THREE.InterpolateLinear; + var interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : THREE.InterpolateLinear; - var targetNames = []; + var targetNames = []; - if ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) { + if ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) { - // node can be THREE.Group here but - // PATH_PROPERTIES.weights(morphTargetInfluences) should be - // the property of a mesh object under group. + // node can be THREE.Group here but + // PATH_PROPERTIES.weights(morphTargetInfluences) should be + // the property of a mesh object under group. - node.traverse( function ( object ) { + node.traverse( function ( object ) { - if ( object.isMesh === true && object.morphTargetInfluences ) { + if ( object.isMesh === true && object.morphTargetInfluences ) { - targetNames.push( object.name ? object.name : object.uuid ); + targetNames.push( object.name ? object.name : object.uuid ); - } + } - } ); + } ); - } else { + } else { - targetNames.push( targetName ); + targetNames.push( targetName ); - } + } - // KeyframeTrack.optimize() will modify given 'times' and 'values' - // buffers before creating a truncated copy to keep. Because buffers may - // be reused by other tracks, make copies here. - for ( var j = 0, jl = targetNames.length; j < jl; j ++ ) { + // KeyframeTrack.optimize() will modify given 'times' and 'values' + // buffers before creating a truncated copy to keep. Because buffers may + // be reused by other tracks, make copies here. + for ( var j = 0, jl = targetNames.length; j < jl; j ++ ) { - var track = new TypedKeyframeTrack( - targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ], - THREE.AnimationUtils.arraySlice( inputAccessor.array, 0 ), - THREE.AnimationUtils.arraySlice( outputAccessor.array, 0 ), - interpolation - ); + var track = new TypedKeyframeTrack( + targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ], + THREE.AnimationUtils.arraySlice( inputAccessor.array, 0 ), + THREE.AnimationUtils.arraySlice( outputAccessor.array, 0 ), + interpolation + ); - // Here is the trick to enable custom interpolation. - // Overrides .createInterpolant in a factory method which creates custom interpolation. - if ( sampler.interpolation === 'CUBICSPLINE' ) { + // Here is the trick to enable custom interpolation. + // Overrides .createInterpolant in a factory method which creates custom interpolation. + if ( sampler.interpolation === 'CUBICSPLINE' ) { - track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) { + track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) { - // A CUBICSPLINE keyframe in glTF has three output values for each input value, - // representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize() - // must be divided by three to get the interpolant's sampleSize argument. + // A CUBICSPLINE keyframe in glTF has three output values for each input value, + // representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize() + // must be divided by three to get the interpolant's sampleSize argument. - return new GLTFCubicSplineInterpolant( this.times, this.values, this.getValueSize() / 3, result ); + return new GLTFCubicSplineInterpolant( this.times, this.values, this.getValueSize() / 3, result ); - }; + }; - // Workaround, provide an alternate way to know if the interpolant type is cubis spline to track. - // track.getInterpolation() doesn't return valid value for custom interpolant. - track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true; + // Workaround, provide an alternate way to know if the interpolant type is cubis spline to track. + // track.getInterpolation() doesn't return valid value for custom interpolant. + track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true; - } + } - tracks.push( track ); + tracks.push( track ); - } + } - } + } - } + } - } + } - var name = animationDef.name !== undefined ? animationDef.name : 'animation_' + animationIndex; + var name = animationDef.name !== undefined ? animationDef.name : 'animation_' + animationIndex; - return new THREE.AnimationClip( name, undefined, tracks ); + return new THREE.AnimationClip( name, undefined, tracks ); - } ); + } ); - }; + }; - /** - * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy - * @param {number} nodeIndex - * @return {Promise} - */ - GLTFParser.prototype.loadNode = function ( nodeIndex ) { + /** + * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy + * @param {number} nodeIndex + * @return {Promise} + */ + GLTFParser.prototype.loadNode = function ( nodeIndex ) { - var json = this.json; - var extensions = this.extensions; + var json = this.json; + var extensions = this.extensions; - var meshReferences = this.json.meshReferences; - var meshUses = this.json.meshUses; + var meshReferences = this.json.meshReferences; + var meshUses = this.json.meshUses; - var nodeDef = this.json.nodes[ nodeIndex ]; + var nodeDef = this.json.nodes[ nodeIndex ]; - return this.getMultiDependencies( [ + return this.getMultiDependencies( [ - 'mesh', - 'skin', - 'camera', - 'light' + 'mesh', + 'skin', + 'camera', + 'light' - ] ).then( function ( dependencies ) { + ] ).then( function ( dependencies ) { - var node; + var node; - // .isBone isn't in glTF spec. See .markDefs - if ( nodeDef.isBone === true ) { + // .isBone isn't in glTF spec. See .markDefs + if ( nodeDef.isBone === true ) { - node = new THREE.Bone(); + node = new THREE.Bone(); - } else if ( nodeDef.mesh !== undefined ) { + } else if ( nodeDef.mesh !== undefined ) { - var mesh = dependencies.meshes[ nodeDef.mesh ]; + var mesh = dependencies.meshes[ nodeDef.mesh ]; - if ( meshReferences[ nodeDef.mesh ] > 1 ) { + if ( meshReferences[ nodeDef.mesh ] > 1 ) { - var instanceNum = meshUses[ nodeDef.mesh ] ++; + var instanceNum = meshUses[ nodeDef.mesh ] ++; - node = mesh.clone(); - node.name += '_instance_' + instanceNum; + node = mesh.clone(); + node.name += '_instance_' + instanceNum; - // onBeforeRender copy for Specular-Glossiness - node.onBeforeRender = mesh.onBeforeRender; + // onBeforeRender copy for Specular-Glossiness + node.onBeforeRender = mesh.onBeforeRender; - for ( var i = 0, il = node.children.length; i < il; i ++ ) { + for ( var i = 0, il = node.children.length; i < il; i ++ ) { - node.children[ i ].name += '_instance_' + instanceNum; - node.children[ i ].onBeforeRender = mesh.children[ i ].onBeforeRender; + node.children[ i ].name += '_instance_' + instanceNum; + node.children[ i ].onBeforeRender = mesh.children[ i ].onBeforeRender; - } + } - } else { + } else { - node = mesh; + node = mesh; - } + } - } else if ( nodeDef.camera !== undefined ) { + } else if ( nodeDef.camera !== undefined ) { - node = dependencies.cameras[ nodeDef.camera ]; + node = dependencies.cameras[ nodeDef.camera ]; - } else if ( nodeDef.extensions - && nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ] - && nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light !== undefined ) { + } else if ( nodeDef.extensions + && nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ] + && nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light !== undefined ) { - var lights = extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].lights; - node = lights[ nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light ]; + var lights = extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].lights; + node = lights[ nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light ]; - } else { + } else { - node = new THREE.Object3D(); + node = new THREE.Object3D(); - } + } - if ( nodeDef.name !== undefined ) { + if ( nodeDef.name !== undefined ) { - node.name = THREE.PropertyBinding.sanitizeNodeName( nodeDef.name ); + node.name = THREE.PropertyBinding.sanitizeNodeName( nodeDef.name ); - } + } - assignExtrasToUserData( node, nodeDef ); + assignExtrasToUserData( node, nodeDef ); - if ( nodeDef.extensions ) addUnknownExtensionsToUserData( extensions, node, nodeDef ); + if ( nodeDef.extensions ) addUnknownExtensionsToUserData( extensions, node, nodeDef ); - if ( nodeDef.matrix !== undefined ) { + if ( nodeDef.matrix !== undefined ) { - var matrix = new THREE.Matrix4(); - matrix.fromArray( nodeDef.matrix ); - node.applyMatrix( matrix ); + var matrix = new THREE.Matrix4(); + matrix.fromArray( nodeDef.matrix ); + node.applyMatrix( matrix ); - } else { + } else { - if ( nodeDef.translation !== undefined ) { + if ( nodeDef.translation !== undefined ) { - node.position.fromArray( nodeDef.translation ); + node.position.fromArray( nodeDef.translation ); - } + } - if ( nodeDef.rotation !== undefined ) { + if ( nodeDef.rotation !== undefined ) { - node.quaternion.fromArray( nodeDef.rotation ); + node.quaternion.fromArray( nodeDef.rotation ); - } + } - if ( nodeDef.scale !== undefined ) { + if ( nodeDef.scale !== undefined ) { - node.scale.fromArray( nodeDef.scale ); + node.scale.fromArray( nodeDef.scale ); - } + } - } + } - return node; + return node; - } ); + } ); - }; + }; - /** - * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes - * @param {number} sceneIndex - * @return {Promise} - */ - GLTFParser.prototype.loadScene = function () { + /** + * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes + * @param {number} sceneIndex + * @return {Promise} + */ + GLTFParser.prototype.loadScene = function () { - // scene node hierachy builder + // scene node hierachy builder - function buildNodeHierachy( nodeId, parentObject, json, allNodes, skins ) { + function buildNodeHierachy( nodeId, parentObject, json, allNodes, skins ) { - var node = allNodes[ nodeId ]; - var nodeDef = json.nodes[ nodeId ]; + var node = allNodes[ nodeId ]; + var nodeDef = json.nodes[ nodeId ]; - // build skeleton here as well + // build skeleton here as well - if ( nodeDef.skin !== undefined ) { + if ( nodeDef.skin !== undefined ) { - var meshes = node.isGroup === true ? node.children : [ node ]; + var meshes = node.isGroup === true ? node.children : [ node ]; - for ( var i = 0, il = meshes.length; i < il; i ++ ) { + for ( var i = 0, il = meshes.length; i < il; i ++ ) { - var mesh = meshes[ i ]; - var skinEntry = skins[ nodeDef.skin ]; + var mesh = meshes[ i ]; + var skinEntry = skins[ nodeDef.skin ]; - var bones = []; - var boneInverses = []; + var bones = []; + var boneInverses = []; - for ( var j = 0, jl = skinEntry.joints.length; j < jl; j ++ ) { + for ( var j = 0, jl = skinEntry.joints.length; j < jl; j ++ ) { - var jointId = skinEntry.joints[ j ]; - var jointNode = allNodes[ jointId ]; + var jointId = skinEntry.joints[ j ]; + var jointNode = allNodes[ jointId ]; - if ( jointNode ) { + if ( jointNode ) { - bones.push( jointNode ); + bones.push( jointNode ); - var mat = new THREE.Matrix4(); + var mat = new THREE.Matrix4(); - if ( skinEntry.inverseBindMatrices !== undefined ) { + if ( skinEntry.inverseBindMatrices !== undefined ) { - mat.fromArray( skinEntry.inverseBindMatrices.array, j * 16 ); + mat.fromArray( skinEntry.inverseBindMatrices.array, j * 16 ); - } + } - boneInverses.push( mat ); + boneInverses.push( mat ); - } else { + } else { - console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', jointId ); + console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', jointId ); - } + } - } + } - mesh.bind( new THREE.Skeleton( bones, boneInverses ), mesh.matrixWorld ); + mesh.bind( new THREE.Skeleton( bones, boneInverses ), mesh.matrixWorld ); - } + } - } + } - // build node hierachy + // build node hierachy - parentObject.add( node ); + parentObject.add( node ); - if ( nodeDef.children ) { + if ( nodeDef.children ) { - var children = nodeDef.children; + var children = nodeDef.children; - for ( var i = 0, il = children.length; i < il; i ++ ) { + for ( var i = 0, il = children.length; i < il; i ++ ) { - var child = children[ i ]; - buildNodeHierachy( child, node, json, allNodes, skins ); + var child = children[ i ]; + buildNodeHierachy( child, node, json, allNodes, skins ); - } + } - } + } - } + } - return function loadScene( sceneIndex ) { + return function loadScene( sceneIndex ) { - var json = this.json; - var extensions = this.extensions; - var sceneDef = this.json.scenes[ sceneIndex ]; + var json = this.json; + var extensions = this.extensions; + var sceneDef = this.json.scenes[ sceneIndex ]; - return this.getMultiDependencies( [ + return this.getMultiDependencies( [ - 'node', - 'skin' + 'node', + 'skin' - ] ).then( function ( dependencies ) { + ] ).then( function ( dependencies ) { - var scene = new THREE.Scene(); - if ( sceneDef.name !== undefined ) scene.name = sceneDef.name; + var scene = new THREE.Scene(); + if ( sceneDef.name !== undefined ) scene.name = sceneDef.name; - assignExtrasToUserData( scene, sceneDef ); + assignExtrasToUserData( scene, sceneDef ); - if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef ); + if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef ); - var nodeIds = sceneDef.nodes || []; + var nodeIds = sceneDef.nodes || []; - for ( var i = 0, il = nodeIds.length; i < il; i ++ ) { + for ( var i = 0, il = nodeIds.length; i < il; i ++ ) { - buildNodeHierachy( nodeIds[ i ], scene, json, dependencies.nodes, dependencies.skins ); + buildNodeHierachy( nodeIds[ i ], scene, json, dependencies.nodes, dependencies.skins ); - } + } - return scene; + return scene; - } ); + } ); - }; + }; - }(); + }(); - return GLTFLoader; + return GLTFLoader; } )(); -},{}],43:[function(_dereq_,module,exports){ +},{}],40:[function(_dereq_,module,exports){ /** * Loads a Wavefront .mtl file specifying materials * @@ -59362,172 +59008,172 @@ THREE.GLTFLoader = ( function () { THREE.MTLLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; }; THREE.MTLLoader.prototype = { - constructor: THREE.MTLLoader, + constructor: THREE.MTLLoader, - /** - * Loads and parses a MTL asset from a URL. - * - * @param {String} url - URL to the MTL file. - * @param {Function} [onLoad] - Callback invoked with the loaded object. - * @param {Function} [onProgress] - Callback for download progress. - * @param {Function} [onError] - Callback for download errors. - * - * @see setPath setTexturePath - * - * @note In order for relative texture references to resolve correctly - * you must call setPath and/or setTexturePath explicitly prior to load. - */ - load: function ( url, onLoad, onProgress, onError ) { + /** + * Loads and parses a MTL asset from a URL. + * + * @param {String} url - URL to the MTL file. + * @param {Function} [onLoad] - Callback invoked with the loaded object. + * @param {Function} [onProgress] - Callback for download progress. + * @param {Function} [onError] - Callback for download errors. + * + * @see setPath setTexturePath + * + * @note In order for relative texture references to resolve correctly + * you must call setPath and/or setTexturePath explicitly prior to load. + */ + load: function ( url, onLoad, onProgress, onError ) { - var scope = this; + var scope = this; - var loader = new THREE.FileLoader( this.manager ); - loader.setPath( this.path ); - loader.load( url, function ( text ) { + var loader = new THREE.FileLoader( this.manager ); + loader.setPath( this.path ); + loader.load( url, function ( text ) { - onLoad( scope.parse( text ) ); + onLoad( scope.parse( text ) ); - }, onProgress, onError ); + }, onProgress, onError ); - }, + }, - /** - * Set base path for resolving references. - * If set this path will be prepended to each loaded and found reference. - * - * @see setTexturePath - * @param {String} path - * @return {THREE.MTLLoader} - * - * @example - * mtlLoader.setPath( 'assets/obj/' ); - * mtlLoader.load( 'my.mtl', ... ); - */ - setPath: function ( path ) { + /** + * Set base path for resolving references. + * If set this path will be prepended to each loaded and found reference. + * + * @see setTexturePath + * @param {String} path + * @return {THREE.MTLLoader} + * + * @example + * mtlLoader.setPath( 'assets/obj/' ); + * mtlLoader.load( 'my.mtl', ... ); + */ + setPath: function ( path ) { - this.path = path; - return this; + this.path = path; + return this; - }, + }, - /** - * Set base path for resolving texture references. - * If set this path will be prepended found texture reference. - * If not set and setPath is, it will be used as texture base path. - * - * @see setPath - * @param {String} path - * @return {THREE.MTLLoader} - * - * @example - * mtlLoader.setPath( 'assets/obj/' ); - * mtlLoader.setTexturePath( 'assets/textures/' ); - * mtlLoader.load( 'my.mtl', ... ); - */ - setTexturePath: function ( path ) { + /** + * Set base path for resolving texture references. + * If set this path will be prepended found texture reference. + * If not set and setPath is, it will be used as texture base path. + * + * @see setPath + * @param {String} path + * @return {THREE.MTLLoader} + * + * @example + * mtlLoader.setPath( 'assets/obj/' ); + * mtlLoader.setTexturePath( 'assets/textures/' ); + * mtlLoader.load( 'my.mtl', ... ); + */ + setTexturePath: function ( path ) { - this.texturePath = path; - return this; + this.texturePath = path; + return this; - }, + }, - setBaseUrl: function ( path ) { + setBaseUrl: function ( path ) { - console.warn( 'THREE.MTLLoader: .setBaseUrl() is deprecated. Use .setTexturePath( path ) for texture path or .setPath( path ) for general base path instead.' ); + console.warn( 'THREE.MTLLoader: .setBaseUrl() is deprecated. Use .setTexturePath( path ) for texture path or .setPath( path ) for general base path instead.' ); - return this.setTexturePath( path ); + return this.setTexturePath( path ); - }, + }, - setCrossOrigin: function ( value ) { + setCrossOrigin: function ( value ) { - this.crossOrigin = value; - return this; + this.crossOrigin = value; + return this; - }, + }, - setMaterialOptions: function ( value ) { + setMaterialOptions: function ( value ) { - this.materialOptions = value; - return this; + this.materialOptions = value; + return this; - }, + }, - /** - * Parses a MTL file. - * - * @param {String} text - Content of MTL file - * @return {THREE.MTLLoader.MaterialCreator} - * - * @see setPath setTexturePath - * - * @note In order for relative texture references to resolve correctly - * you must call setPath and/or setTexturePath explicitly prior to parse. - */ - parse: function ( text ) { + /** + * Parses a MTL file. + * + * @param {String} text - Content of MTL file + * @return {THREE.MTLLoader.MaterialCreator} + * + * @see setPath setTexturePath + * + * @note In order for relative texture references to resolve correctly + * you must call setPath and/or setTexturePath explicitly prior to parse. + */ + parse: function ( text ) { - var lines = text.split( '\n' ); - var info = {}; - var delimiter_pattern = /\s+/; - var materialsInfo = {}; + var lines = text.split( '\n' ); + var info = {}; + var delimiter_pattern = /\s+/; + var materialsInfo = {}; - for ( var i = 0; i < lines.length; i ++ ) { + for ( var i = 0; i < lines.length; i ++ ) { - var line = lines[ i ]; - line = line.trim(); + var line = lines[ i ]; + line = line.trim(); - if ( line.length === 0 || line.charAt( 0 ) === '#' ) { + if ( line.length === 0 || line.charAt( 0 ) === '#' ) { - // Blank line or comment ignore - continue; + // Blank line or comment ignore + continue; - } + } - var pos = line.indexOf( ' ' ); + var pos = line.indexOf( ' ' ); - var key = ( pos >= 0 ) ? line.substring( 0, pos ) : line; - key = key.toLowerCase(); + var key = ( pos >= 0 ) ? line.substring( 0, pos ) : line; + key = key.toLowerCase(); - var value = ( pos >= 0 ) ? line.substring( pos + 1 ) : ''; - value = value.trim(); + var value = ( pos >= 0 ) ? line.substring( pos + 1 ) : ''; + value = value.trim(); - if ( key === 'newmtl' ) { + if ( key === 'newmtl' ) { - // New material + // New material - info = { name: value }; - materialsInfo[ value ] = info; + info = { name: value }; + materialsInfo[ value ] = info; - } else if ( info ) { + } else if ( info ) { - if ( key === 'ka' || key === 'kd' || key === 'ks' ) { + if ( key === 'ka' || key === 'kd' || key === 'ks' ) { - var ss = value.split( delimiter_pattern, 3 ); - info[ key ] = [ parseFloat( ss[ 0 ] ), parseFloat( ss[ 1 ] ), parseFloat( ss[ 2 ] ) ]; + var ss = value.split( delimiter_pattern, 3 ); + info[ key ] = [ parseFloat( ss[ 0 ] ), parseFloat( ss[ 1 ] ), parseFloat( ss[ 2 ] ) ]; - } else { + } else { - info[ key ] = value; + info[ key ] = value; - } + } - } + } - } + } - var materialCreator = new THREE.MTLLoader.MaterialCreator( this.texturePath || this.path, this.materialOptions ); - materialCreator.setCrossOrigin( this.crossOrigin ); - materialCreator.setManager( this.manager ); - materialCreator.setMaterials( materialsInfo ); - return materialCreator; + var materialCreator = new THREE.MTLLoader.MaterialCreator( this.texturePath || this.path, this.materialOptions ); + materialCreator.setCrossOrigin( this.crossOrigin ); + materialCreator.setManager( this.manager ); + materialCreator.setMaterials( materialsInfo ); + return materialCreator; - } + } }; @@ -59548,1169 +59194,1169 @@ THREE.MTLLoader.prototype = { THREE.MTLLoader.MaterialCreator = function ( baseUrl, options ) { - this.baseUrl = baseUrl || ''; - this.options = options; - this.materialsInfo = {}; - this.materials = {}; - this.materialsArray = []; - this.nameLookup = {}; + this.baseUrl = baseUrl || ''; + this.options = options; + this.materialsInfo = {}; + this.materials = {}; + this.materialsArray = []; + this.nameLookup = {}; - this.side = ( this.options && this.options.side ) ? this.options.side : THREE.FrontSide; - this.wrap = ( this.options && this.options.wrap ) ? this.options.wrap : THREE.RepeatWrapping; + this.side = ( this.options && this.options.side ) ? this.options.side : THREE.FrontSide; + this.wrap = ( this.options && this.options.wrap ) ? this.options.wrap : THREE.RepeatWrapping; }; THREE.MTLLoader.MaterialCreator.prototype = { - constructor: THREE.MTLLoader.MaterialCreator, + constructor: THREE.MTLLoader.MaterialCreator, - crossOrigin: 'anonymous', + crossOrigin: 'anonymous', - setCrossOrigin: function ( value ) { + setCrossOrigin: function ( value ) { - this.crossOrigin = value; - return this; + this.crossOrigin = value; + return this; - }, + }, - setManager: function ( value ) { + setManager: function ( value ) { - this.manager = value; + this.manager = value; - }, + }, - setMaterials: function ( materialsInfo ) { + setMaterials: function ( materialsInfo ) { - this.materialsInfo = this.convert( materialsInfo ); - this.materials = {}; - this.materialsArray = []; - this.nameLookup = {}; + this.materialsInfo = this.convert( materialsInfo ); + this.materials = {}; + this.materialsArray = []; + this.nameLookup = {}; - }, + }, - convert: function ( materialsInfo ) { + convert: function ( materialsInfo ) { - if ( ! this.options ) return materialsInfo; + if ( ! this.options ) return materialsInfo; - var converted = {}; + var converted = {}; - for ( var mn in materialsInfo ) { + for ( var mn in materialsInfo ) { - // Convert materials info into normalized form based on options + // Convert materials info into normalized form based on options - var mat = materialsInfo[ mn ]; + var mat = materialsInfo[ mn ]; - var covmat = {}; + var covmat = {}; - converted[ mn ] = covmat; + converted[ mn ] = covmat; - for ( var prop in mat ) { + for ( var prop in mat ) { - var save = true; - var value = mat[ prop ]; - var lprop = prop.toLowerCase(); + var save = true; + var value = mat[ prop ]; + var lprop = prop.toLowerCase(); - switch ( lprop ) { + switch ( lprop ) { - case 'kd': - case 'ka': - case 'ks': + case 'kd': + case 'ka': + case 'ks': - // Diffuse color (color under white light) using RGB values + // Diffuse color (color under white light) using RGB values - if ( this.options && this.options.normalizeRGB ) { + if ( this.options && this.options.normalizeRGB ) { - value = [ value[ 0 ] / 255, value[ 1 ] / 255, value[ 2 ] / 255 ]; + value = [ value[ 0 ] / 255, value[ 1 ] / 255, value[ 2 ] / 255 ]; - } + } - if ( this.options && this.options.ignoreZeroRGBs ) { + if ( this.options && this.options.ignoreZeroRGBs ) { - if ( value[ 0 ] === 0 && value[ 1 ] === 0 && value[ 2 ] === 0 ) { + if ( value[ 0 ] === 0 && value[ 1 ] === 0 && value[ 2 ] === 0 ) { - // ignore + // ignore - save = false; + save = false; - } + } - } + } - break; + break; - default: + default: - break; + break; - } + } - if ( save ) { + if ( save ) { - covmat[ lprop ] = value; + covmat[ lprop ] = value; - } + } - } + } - } + } - return converted; + return converted; - }, + }, - preload: function () { + preload: function () { - for ( var mn in this.materialsInfo ) { + for ( var mn in this.materialsInfo ) { - this.create( mn ); + this.create( mn ); - } + } - }, + }, - getIndex: function ( materialName ) { + getIndex: function ( materialName ) { - return this.nameLookup[ materialName ]; + return this.nameLookup[ materialName ]; - }, + }, - getAsArray: function () { + getAsArray: function () { - var index = 0; + var index = 0; - for ( var mn in this.materialsInfo ) { + for ( var mn in this.materialsInfo ) { - this.materialsArray[ index ] = this.create( mn ); - this.nameLookup[ mn ] = index; - index ++; + this.materialsArray[ index ] = this.create( mn ); + this.nameLookup[ mn ] = index; + index ++; - } + } - return this.materialsArray; + return this.materialsArray; - }, + }, - create: function ( materialName ) { + create: function ( materialName ) { - if ( this.materials[ materialName ] === undefined ) { + if ( this.materials[ materialName ] === undefined ) { - this.createMaterial_( materialName ); + this.createMaterial_( materialName ); - } + } - return this.materials[ materialName ]; + return this.materials[ materialName ]; - }, + }, - createMaterial_: function ( materialName ) { + createMaterial_: function ( materialName ) { - // Create material + // Create material - var scope = this; - var mat = this.materialsInfo[ materialName ]; - var params = { + var scope = this; + var mat = this.materialsInfo[ materialName ]; + var params = { - name: materialName, - side: this.side + name: materialName, + side: this.side - }; + }; - function resolveURL( baseUrl, url ) { + function resolveURL( baseUrl, url ) { - if ( typeof url !== 'string' || url === '' ) - return ''; + if ( typeof url !== 'string' || url === '' ) + return ''; - // Absolute URL - if ( /^https?:\/\//i.test( url ) ) return url; + // Absolute URL + if ( /^https?:\/\//i.test( url ) ) return url; - return baseUrl + url; + return baseUrl + url; - } + } - function setMapForType( mapType, value ) { + function setMapForType( mapType, value ) { - if ( params[ mapType ] ) return; // Keep the first encountered texture + if ( params[ mapType ] ) return; // Keep the first encountered texture - var texParams = scope.getTextureParams( value, params ); - var map = scope.loadTexture( resolveURL( scope.baseUrl, texParams.url ) ); + var texParams = scope.getTextureParams( value, params ); + var map = scope.loadTexture( resolveURL( scope.baseUrl, texParams.url ) ); - map.repeat.copy( texParams.scale ); - map.offset.copy( texParams.offset ); + map.repeat.copy( texParams.scale ); + map.offset.copy( texParams.offset ); - map.wrapS = scope.wrap; - map.wrapT = scope.wrap; + map.wrapS = scope.wrap; + map.wrapT = scope.wrap; - params[ mapType ] = map; + params[ mapType ] = map; - } + } - for ( var prop in mat ) { + for ( var prop in mat ) { - var value = mat[ prop ]; - var n; + var value = mat[ prop ]; + var n; - if ( value === '' ) continue; + if ( value === '' ) continue; - switch ( prop.toLowerCase() ) { + switch ( prop.toLowerCase() ) { - // Ns is material specular exponent + // Ns is material specular exponent - case 'kd': + case 'kd': - // Diffuse color (color under white light) using RGB values + // Diffuse color (color under white light) using RGB values - params.color = new THREE.Color().fromArray( value ); + params.color = new THREE.Color().fromArray( value ); - break; + break; - case 'ks': + case 'ks': - // Specular color (color when light is reflected from shiny surface) using RGB values - params.specular = new THREE.Color().fromArray( value ); + // Specular color (color when light is reflected from shiny surface) using RGB values + params.specular = new THREE.Color().fromArray( value ); - break; + break; - case 'map_kd': + case 'map_kd': - // Diffuse texture map + // Diffuse texture map - setMapForType( "map", value ); + setMapForType( "map", value ); - break; + break; - case 'map_ks': + case 'map_ks': - // Specular map + // Specular map - setMapForType( "specularMap", value ); + setMapForType( "specularMap", value ); - break; + break; - case 'norm': + case 'norm': - setMapForType( "normalMap", value ); + setMapForType( "normalMap", value ); - break; + break; - case 'map_bump': - case 'bump': + case 'map_bump': + case 'bump': - // Bump texture map + // Bump texture map - setMapForType( "bumpMap", value ); + setMapForType( "bumpMap", value ); - break; + break; - case 'ns': + case 'ns': - // The specular exponent (defines the focus of the specular highlight) - // A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000. + // The specular exponent (defines the focus of the specular highlight) + // A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000. - params.shininess = parseFloat( value ); + params.shininess = parseFloat( value ); - break; + break; - case 'd': - n = parseFloat( value ); + case 'd': + n = parseFloat( value ); - if ( n < 1 ) { + if ( n < 1 ) { - params.opacity = n; - params.transparent = true; + params.opacity = n; + params.transparent = true; - } + } - break; + break; - case 'tr': - n = parseFloat( value ); + case 'tr': + n = parseFloat( value ); - if ( this.options && this.options.invertTrProperty ) n = 1 - n; + if ( this.options && this.options.invertTrProperty ) n = 1 - n; - if ( n > 0 ) { + if ( n > 0 ) { - params.opacity = 1 - n; - params.transparent = true; + params.opacity = 1 - n; + params.transparent = true; - } + } - break; + break; - default: - break; + default: + break; - } + } - } + } - this.materials[ materialName ] = new THREE.MeshPhongMaterial( params ); - return this.materials[ materialName ]; + this.materials[ materialName ] = new THREE.MeshPhongMaterial( params ); + return this.materials[ materialName ]; - }, + }, - getTextureParams: function ( value, matParams ) { + getTextureParams: function ( value, matParams ) { - var texParams = { + var texParams = { - scale: new THREE.Vector2( 1, 1 ), - offset: new THREE.Vector2( 0, 0 ) + scale: new THREE.Vector2( 1, 1 ), + offset: new THREE.Vector2( 0, 0 ) - }; + }; - var items = value.split( /\s+/ ); - var pos; + var items = value.split( /\s+/ ); + var pos; - pos = items.indexOf( '-bm' ); + pos = items.indexOf( '-bm' ); - if ( pos >= 0 ) { + if ( pos >= 0 ) { - matParams.bumpScale = parseFloat( items[ pos + 1 ] ); - items.splice( pos, 2 ); + matParams.bumpScale = parseFloat( items[ pos + 1 ] ); + items.splice( pos, 2 ); - } + } - pos = items.indexOf( '-s' ); + pos = items.indexOf( '-s' ); - if ( pos >= 0 ) { + if ( pos >= 0 ) { - texParams.scale.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) ); - items.splice( pos, 4 ); // we expect 3 parameters here! + texParams.scale.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) ); + items.splice( pos, 4 ); // we expect 3 parameters here! - } + } - pos = items.indexOf( '-o' ); + pos = items.indexOf( '-o' ); - if ( pos >= 0 ) { + if ( pos >= 0 ) { - texParams.offset.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) ); - items.splice( pos, 4 ); // we expect 3 parameters here! + texParams.offset.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) ); + items.splice( pos, 4 ); // we expect 3 parameters here! - } + } - texParams.url = items.join( ' ' ).trim(); - return texParams; + texParams.url = items.join( ' ' ).trim(); + return texParams; - }, + }, - loadTexture: function ( url, mapping, onLoad, onProgress, onError ) { + loadTexture: function ( url, mapping, onLoad, onProgress, onError ) { - var texture; - var loader = THREE.Loader.Handlers.get( url ); - var manager = ( this.manager !== undefined ) ? this.manager : THREE.DefaultLoadingManager; + var texture; + var loader = THREE.Loader.Handlers.get( url ); + var manager = ( this.manager !== undefined ) ? this.manager : THREE.DefaultLoadingManager; - if ( loader === null ) { + if ( loader === null ) { - loader = new THREE.TextureLoader( manager ); + loader = new THREE.TextureLoader( manager ); - } + } - if ( loader.setCrossOrigin ) loader.setCrossOrigin( this.crossOrigin ); - texture = loader.load( url, onLoad, onProgress, onError ); + if ( loader.setCrossOrigin ) loader.setCrossOrigin( this.crossOrigin ); + texture = loader.load( url, onLoad, onProgress, onError ); - if ( mapping !== undefined ) texture.mapping = mapping; + if ( mapping !== undefined ) texture.mapping = mapping; - return texture; + return texture; - } + } }; -},{}],44:[function(_dereq_,module,exports){ +},{}],41:[function(_dereq_,module,exports){ /** * @author mrdoob / http://mrdoob.com/ */ THREE.OBJLoader = ( function () { - // o object_name | g group_name - var object_pattern = /^[og]\s*(.+)?/; - // mtllib file_reference - var material_library_pattern = /^mtllib /; - // usemtl material_name - var material_use_pattern = /^usemtl /; + // o object_name | g group_name + var object_pattern = /^[og]\s*(.+)?/; + // mtllib file_reference + var material_library_pattern = /^mtllib /; + // usemtl material_name + var material_use_pattern = /^usemtl /; - function ParserState() { + function ParserState() { - var state = { - objects: [], - object: {}, + var state = { + objects: [], + object: {}, - vertices: [], - normals: [], - colors: [], - uvs: [], + vertices: [], + normals: [], + colors: [], + uvs: [], - materialLibraries: [], + materialLibraries: [], - startObject: function ( name, fromDeclaration ) { + startObject: function ( name, fromDeclaration ) { - // If the current object (initial from reset) is not from a g/o declaration in the parsed - // file. We need to use it for the first parsed g/o to keep things in sync. - if ( this.object && this.object.fromDeclaration === false ) { + // If the current object (initial from reset) is not from a g/o declaration in the parsed + // file. We need to use it for the first parsed g/o to keep things in sync. + if ( this.object && this.object.fromDeclaration === false ) { - this.object.name = name; - this.object.fromDeclaration = ( fromDeclaration !== false ); - return; + this.object.name = name; + this.object.fromDeclaration = ( fromDeclaration !== false ); + return; - } + } - var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined ); + var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined ); - if ( this.object && typeof this.object._finalize === 'function' ) { + if ( this.object && typeof this.object._finalize === 'function' ) { - this.object._finalize( true ); + this.object._finalize( true ); - } + } - this.object = { - name: name || '', - fromDeclaration: ( fromDeclaration !== false ), + this.object = { + name: name || '', + fromDeclaration: ( fromDeclaration !== false ), - geometry: { - vertices: [], - normals: [], - colors: [], - uvs: [] - }, - materials: [], - smooth: true, + geometry: { + vertices: [], + normals: [], + colors: [], + uvs: [] + }, + materials: [], + smooth: true, - startMaterial: function ( name, libraries ) { + startMaterial: function ( name, libraries ) { - var previous = this._finalize( false ); + var previous = this._finalize( false ); - // New usemtl declaration overwrites an inherited material, except if faces were declared - // after the material, then it must be preserved for proper MultiMaterial continuation. - if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) { + // New usemtl declaration overwrites an inherited material, except if faces were declared + // after the material, then it must be preserved for proper MultiMaterial continuation. + if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) { - this.materials.splice( previous.index, 1 ); + this.materials.splice( previous.index, 1 ); - } + } - var material = { - index: this.materials.length, - name: name || '', - mtllib: ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ), - smooth: ( previous !== undefined ? previous.smooth : this.smooth ), - groupStart: ( previous !== undefined ? previous.groupEnd : 0 ), - groupEnd: - 1, - groupCount: - 1, - inherited: false, + var material = { + index: this.materials.length, + name: name || '', + mtllib: ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ), + smooth: ( previous !== undefined ? previous.smooth : this.smooth ), + groupStart: ( previous !== undefined ? previous.groupEnd : 0 ), + groupEnd: - 1, + groupCount: - 1, + inherited: false, - clone: function ( index ) { + clone: function ( index ) { - var cloned = { - index: ( typeof index === 'number' ? index : this.index ), - name: this.name, - mtllib: this.mtllib, - smooth: this.smooth, - groupStart: 0, - groupEnd: - 1, - groupCount: - 1, - inherited: false - }; - cloned.clone = this.clone.bind( cloned ); - return cloned; + var cloned = { + index: ( typeof index === 'number' ? index : this.index ), + name: this.name, + mtllib: this.mtllib, + smooth: this.smooth, + groupStart: 0, + groupEnd: - 1, + groupCount: - 1, + inherited: false + }; + cloned.clone = this.clone.bind( cloned ); + return cloned; - } - }; + } + }; - this.materials.push( material ); + this.materials.push( material ); - return material; + return material; - }, + }, - currentMaterial: function () { + currentMaterial: function () { - if ( this.materials.length > 0 ) { + if ( this.materials.length > 0 ) { - return this.materials[ this.materials.length - 1 ]; + return this.materials[ this.materials.length - 1 ]; - } + } - return undefined; + return undefined; - }, + }, - _finalize: function ( end ) { + _finalize: function ( end ) { - var lastMultiMaterial = this.currentMaterial(); - if ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) { + var lastMultiMaterial = this.currentMaterial(); + if ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) { - lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3; - lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart; - lastMultiMaterial.inherited = false; + lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3; + lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart; + lastMultiMaterial.inherited = false; - } + } - // Ignore objects tail materials if no face declarations followed them before a new o/g started. - if ( end && this.materials.length > 1 ) { + // Ignore objects tail materials if no face declarations followed them before a new o/g started. + if ( end && this.materials.length > 1 ) { - for ( var mi = this.materials.length - 1; mi >= 0; mi -- ) { + for ( var mi = this.materials.length - 1; mi >= 0; mi -- ) { - if ( this.materials[ mi ].groupCount <= 0 ) { + if ( this.materials[ mi ].groupCount <= 0 ) { - this.materials.splice( mi, 1 ); + this.materials.splice( mi, 1 ); - } + } - } + } - } + } - // Guarantee at least one empty material, this makes the creation later more straight forward. - if ( end && this.materials.length === 0 ) { + // Guarantee at least one empty material, this makes the creation later more straight forward. + if ( end && this.materials.length === 0 ) { - this.materials.push( { - name: '', - smooth: this.smooth - } ); + this.materials.push( { + name: '', + smooth: this.smooth + } ); - } + } - return lastMultiMaterial; + return lastMultiMaterial; - } - }; + } + }; - // Inherit previous objects material. - // Spec tells us that a declared material must be set to all objects until a new material is declared. - // If a usemtl declaration is encountered while this new object is being parsed, it will - // overwrite the inherited material. Exception being that there was already face declarations - // to the inherited material, then it will be preserved for proper MultiMaterial continuation. + // Inherit previous objects material. + // Spec tells us that a declared material must be set to all objects until a new material is declared. + // If a usemtl declaration is encountered while this new object is being parsed, it will + // overwrite the inherited material. Exception being that there was already face declarations + // to the inherited material, then it will be preserved for proper MultiMaterial continuation. - if ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === 'function' ) { + if ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === 'function' ) { - var declared = previousMaterial.clone( 0 ); - declared.inherited = true; - this.object.materials.push( declared ); + var declared = previousMaterial.clone( 0 ); + declared.inherited = true; + this.object.materials.push( declared ); - } + } - this.objects.push( this.object ); + this.objects.push( this.object ); - }, + }, - finalize: function () { + finalize: function () { - if ( this.object && typeof this.object._finalize === 'function' ) { + if ( this.object && typeof this.object._finalize === 'function' ) { - this.object._finalize( true ); + this.object._finalize( true ); - } + } - }, + }, - parseVertexIndex: function ( value, len ) { + parseVertexIndex: function ( value, len ) { - var index = parseInt( value, 10 ); - return ( index >= 0 ? index - 1 : index + len / 3 ) * 3; + var index = parseInt( value, 10 ); + return ( index >= 0 ? index - 1 : index + len / 3 ) * 3; - }, + }, - parseNormalIndex: function ( value, len ) { + parseNormalIndex: function ( value, len ) { - var index = parseInt( value, 10 ); - return ( index >= 0 ? index - 1 : index + len / 3 ) * 3; + var index = parseInt( value, 10 ); + return ( index >= 0 ? index - 1 : index + len / 3 ) * 3; - }, + }, - parseUVIndex: function ( value, len ) { + parseUVIndex: function ( value, len ) { - var index = parseInt( value, 10 ); - return ( index >= 0 ? index - 1 : index + len / 2 ) * 2; + var index = parseInt( value, 10 ); + return ( index >= 0 ? index - 1 : index + len / 2 ) * 2; - }, + }, - addVertex: function ( a, b, c ) { + addVertex: function ( a, b, c ) { - var src = this.vertices; - var dst = this.object.geometry.vertices; + var src = this.vertices; + var dst = this.object.geometry.vertices; - dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); - dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] ); - dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] ); + dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); + dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] ); + dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] ); - }, + }, - addVertexPoint: function ( a ) { + addVertexPoint: function ( a ) { - var src = this.vertices; - var dst = this.object.geometry.vertices; + var src = this.vertices; + var dst = this.object.geometry.vertices; - dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); + dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); - }, + }, - addVertexLine: function ( a ) { + addVertexLine: function ( a ) { - var src = this.vertices; - var dst = this.object.geometry.vertices; + var src = this.vertices; + var dst = this.object.geometry.vertices; - dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); + dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); - }, + }, - addNormal: function ( a, b, c ) { + addNormal: function ( a, b, c ) { - var src = this.normals; - var dst = this.object.geometry.normals; + var src = this.normals; + var dst = this.object.geometry.normals; - dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); - dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] ); - dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] ); + dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); + dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] ); + dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] ); - }, + }, - addColor: function ( a, b, c ) { + addColor: function ( a, b, c ) { - var src = this.colors; - var dst = this.object.geometry.colors; + var src = this.colors; + var dst = this.object.geometry.colors; - dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); - dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] ); - dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] ); + dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); + dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] ); + dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] ); - }, + }, - addUV: function ( a, b, c ) { + addUV: function ( a, b, c ) { - var src = this.uvs; - var dst = this.object.geometry.uvs; + var src = this.uvs; + var dst = this.object.geometry.uvs; - dst.push( src[ a + 0 ], src[ a + 1 ] ); - dst.push( src[ b + 0 ], src[ b + 1 ] ); - dst.push( src[ c + 0 ], src[ c + 1 ] ); + dst.push( src[ a + 0 ], src[ a + 1 ] ); + dst.push( src[ b + 0 ], src[ b + 1 ] ); + dst.push( src[ c + 0 ], src[ c + 1 ] ); - }, + }, - addUVLine: function ( a ) { + addUVLine: function ( a ) { - var src = this.uvs; - var dst = this.object.geometry.uvs; + var src = this.uvs; + var dst = this.object.geometry.uvs; - dst.push( src[ a + 0 ], src[ a + 1 ] ); + dst.push( src[ a + 0 ], src[ a + 1 ] ); - }, + }, - addFace: function ( a, b, c, ua, ub, uc, na, nb, nc ) { + addFace: function ( a, b, c, ua, ub, uc, na, nb, nc ) { - var vLen = this.vertices.length; + var vLen = this.vertices.length; - var ia = this.parseVertexIndex( a, vLen ); - var ib = this.parseVertexIndex( b, vLen ); - var ic = this.parseVertexIndex( c, vLen ); + var ia = this.parseVertexIndex( a, vLen ); + var ib = this.parseVertexIndex( b, vLen ); + var ic = this.parseVertexIndex( c, vLen ); - this.addVertex( ia, ib, ic ); + this.addVertex( ia, ib, ic ); - if ( ua !== undefined && ua !== '' ) { + if ( ua !== undefined && ua !== '' ) { - var uvLen = this.uvs.length; - ia = this.parseUVIndex( ua, uvLen ); - ib = this.parseUVIndex( ub, uvLen ); - ic = this.parseUVIndex( uc, uvLen ); - this.addUV( ia, ib, ic ); + var uvLen = this.uvs.length; + ia = this.parseUVIndex( ua, uvLen ); + ib = this.parseUVIndex( ub, uvLen ); + ic = this.parseUVIndex( uc, uvLen ); + this.addUV( ia, ib, ic ); - } + } - if ( na !== undefined && na !== '' ) { + if ( na !== undefined && na !== '' ) { - // Normals are many times the same. If so, skip function call and parseInt. - var nLen = this.normals.length; - ia = this.parseNormalIndex( na, nLen ); + // Normals are many times the same. If so, skip function call and parseInt. + var nLen = this.normals.length; + ia = this.parseNormalIndex( na, nLen ); - ib = na === nb ? ia : this.parseNormalIndex( nb, nLen ); - ic = na === nc ? ia : this.parseNormalIndex( nc, nLen ); + ib = na === nb ? ia : this.parseNormalIndex( nb, nLen ); + ic = na === nc ? ia : this.parseNormalIndex( nc, nLen ); - this.addNormal( ia, ib, ic ); + this.addNormal( ia, ib, ic ); - } + } - if ( this.colors.length > 0 ) { + if ( this.colors.length > 0 ) { - this.addColor( ia, ib, ic ); + this.addColor( ia, ib, ic ); - } + } - }, + }, - addPointGeometry: function ( vertices ) { + addPointGeometry: function ( vertices ) { - this.object.geometry.type = 'Points'; + this.object.geometry.type = 'Points'; - var vLen = this.vertices.length; + var vLen = this.vertices.length; - for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) { + for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) { - this.addVertexPoint( this.parseVertexIndex( vertices[ vi ], vLen ) ); + this.addVertexPoint( this.parseVertexIndex( vertices[ vi ], vLen ) ); - } + } - }, + }, - addLineGeometry: function ( vertices, uvs ) { + addLineGeometry: function ( vertices, uvs ) { - this.object.geometry.type = 'Line'; + this.object.geometry.type = 'Line'; - var vLen = this.vertices.length; - var uvLen = this.uvs.length; + var vLen = this.vertices.length; + var uvLen = this.uvs.length; - for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) { + for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) { - this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) ); + this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) ); - } + } - for ( var uvi = 0, l = uvs.length; uvi < l; uvi ++ ) { + for ( var uvi = 0, l = uvs.length; uvi < l; uvi ++ ) { - this.addUVLine( this.parseUVIndex( uvs[ uvi ], uvLen ) ); + this.addUVLine( this.parseUVIndex( uvs[ uvi ], uvLen ) ); - } + } - } + } - }; + }; - state.startObject( '', false ); + state.startObject( '', false ); - return state; + return state; - } + } - // + // - function OBJLoader( manager ) { + function OBJLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - this.materials = null; + this.materials = null; - } + } - OBJLoader.prototype = { + OBJLoader.prototype = { - constructor: OBJLoader, + constructor: OBJLoader, - load: function ( url, onLoad, onProgress, onError ) { + load: function ( url, onLoad, onProgress, onError ) { - var scope = this; + var scope = this; - var loader = new THREE.FileLoader( scope.manager ); - loader.setPath( this.path ); - loader.load( url, function ( text ) { + var loader = new THREE.FileLoader( scope.manager ); + loader.setPath( this.path ); + loader.load( url, function ( text ) { - onLoad( scope.parse( text ) ); + onLoad( scope.parse( text ) ); - }, onProgress, onError ); + }, onProgress, onError ); - }, + }, - setPath: function ( value ) { + setPath: function ( value ) { - this.path = value; + this.path = value; - return this; + return this; - }, + }, - setMaterials: function ( materials ) { + setMaterials: function ( materials ) { - this.materials = materials; + this.materials = materials; - return this; + return this; - }, + }, - parse: function ( text ) { + parse: function ( text ) { - console.time( 'OBJLoader' ); + console.time( 'OBJLoader' ); - var state = new ParserState(); + var state = new ParserState(); - if ( text.indexOf( '\r\n' ) !== - 1 ) { + if ( text.indexOf( '\r\n' ) !== - 1 ) { - // This is faster than String.split with regex that splits on both - text = text.replace( /\r\n/g, '\n' ); + // This is faster than String.split with regex that splits on both + text = text.replace( /\r\n/g, '\n' ); - } + } - if ( text.indexOf( '\\\n' ) !== - 1 ) { + if ( text.indexOf( '\\\n' ) !== - 1 ) { - // join lines separated by a line continuation character (\) - text = text.replace( /\\\n/g, '' ); + // join lines separated by a line continuation character (\) + text = text.replace( /\\\n/g, '' ); - } + } - var lines = text.split( '\n' ); - var line = '', lineFirstChar = ''; - var lineLength = 0; - var result = []; + var lines = text.split( '\n' ); + var line = '', lineFirstChar = ''; + var lineLength = 0; + var result = []; - // Faster to just trim left side of the line. Use if available. - var trimLeft = ( typeof ''.trimLeft === 'function' ); + // Faster to just trim left side of the line. Use if available. + var trimLeft = ( typeof ''.trimLeft === 'function' ); - for ( var i = 0, l = lines.length; i < l; i ++ ) { + for ( var i = 0, l = lines.length; i < l; i ++ ) { - line = lines[ i ]; + line = lines[ i ]; - line = trimLeft ? line.trimLeft() : line.trim(); + line = trimLeft ? line.trimLeft() : line.trim(); - lineLength = line.length; + lineLength = line.length; - if ( lineLength === 0 ) continue; + if ( lineLength === 0 ) continue; - lineFirstChar = line.charAt( 0 ); + lineFirstChar = line.charAt( 0 ); - // @todo invoke passed in handler if any - if ( lineFirstChar === '#' ) continue; + // @todo invoke passed in handler if any + if ( lineFirstChar === '#' ) continue; - if ( lineFirstChar === 'v' ) { + if ( lineFirstChar === 'v' ) { - var data = line.split( /\s+/ ); + var data = line.split( /\s+/ ); - switch ( data[ 0 ] ) { + switch ( data[ 0 ] ) { - case 'v': - state.vertices.push( - parseFloat( data[ 1 ] ), - parseFloat( data[ 2 ] ), - parseFloat( data[ 3 ] ) - ); - if ( data.length === 8 ) { + case 'v': + state.vertices.push( + parseFloat( data[ 1 ] ), + parseFloat( data[ 2 ] ), + parseFloat( data[ 3 ] ) + ); + if ( data.length === 8 ) { - state.colors.push( - parseFloat( data[ 4 ] ), - parseFloat( data[ 5 ] ), - parseFloat( data[ 6 ] ) + state.colors.push( + parseFloat( data[ 4 ] ), + parseFloat( data[ 5 ] ), + parseFloat( data[ 6 ] ) - ); + ); - } - break; - case 'vn': - state.normals.push( - parseFloat( data[ 1 ] ), - parseFloat( data[ 2 ] ), - parseFloat( data[ 3 ] ) - ); - break; - case 'vt': - state.uvs.push( - parseFloat( data[ 1 ] ), - parseFloat( data[ 2 ] ) - ); - break; + } + break; + case 'vn': + state.normals.push( + parseFloat( data[ 1 ] ), + parseFloat( data[ 2 ] ), + parseFloat( data[ 3 ] ) + ); + break; + case 'vt': + state.uvs.push( + parseFloat( data[ 1 ] ), + parseFloat( data[ 2 ] ) + ); + break; - } + } - } else if ( lineFirstChar === 'f' ) { + } else if ( lineFirstChar === 'f' ) { - var lineData = line.substr( 1 ).trim(); - var vertexData = lineData.split( /\s+/ ); - var faceVertices = []; + var lineData = line.substr( 1 ).trim(); + var vertexData = lineData.split( /\s+/ ); + var faceVertices = []; - // Parse the face vertex data into an easy to work with format + // Parse the face vertex data into an easy to work with format - for ( var j = 0, jl = vertexData.length; j < jl; j ++ ) { + for ( var j = 0, jl = vertexData.length; j < jl; j ++ ) { - var vertex = vertexData[ j ]; + var vertex = vertexData[ j ]; - if ( vertex.length > 0 ) { + if ( vertex.length > 0 ) { - var vertexParts = vertex.split( '/' ); - faceVertices.push( vertexParts ); + var vertexParts = vertex.split( '/' ); + faceVertices.push( vertexParts ); - } + } - } + } - // Draw an edge between the first vertex and all subsequent vertices to form an n-gon + // Draw an edge between the first vertex and all subsequent vertices to form an n-gon - var v1 = faceVertices[ 0 ]; + var v1 = faceVertices[ 0 ]; - for ( var j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) { + for ( var j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) { - var v2 = faceVertices[ j ]; - var v3 = faceVertices[ j + 1 ]; + var v2 = faceVertices[ j ]; + var v3 = faceVertices[ j + 1 ]; - state.addFace( - v1[ 0 ], v2[ 0 ], v3[ 0 ], - v1[ 1 ], v2[ 1 ], v3[ 1 ], - v1[ 2 ], v2[ 2 ], v3[ 2 ] - ); + state.addFace( + v1[ 0 ], v2[ 0 ], v3[ 0 ], + v1[ 1 ], v2[ 1 ], v3[ 1 ], + v1[ 2 ], v2[ 2 ], v3[ 2 ] + ); - } + } - } else if ( lineFirstChar === 'l' ) { + } else if ( lineFirstChar === 'l' ) { - var lineParts = line.substring( 1 ).trim().split( " " ); - var lineVertices = [], lineUVs = []; + var lineParts = line.substring( 1 ).trim().split( " " ); + var lineVertices = [], lineUVs = []; - if ( line.indexOf( "/" ) === - 1 ) { + if ( line.indexOf( "/" ) === - 1 ) { - lineVertices = lineParts; + lineVertices = lineParts; - } else { + } else { - for ( var li = 0, llen = lineParts.length; li < llen; li ++ ) { + for ( var li = 0, llen = lineParts.length; li < llen; li ++ ) { - var parts = lineParts[ li ].split( "/" ); + var parts = lineParts[ li ].split( "/" ); - if ( parts[ 0 ] !== "" ) lineVertices.push( parts[ 0 ] ); - if ( parts[ 1 ] !== "" ) lineUVs.push( parts[ 1 ] ); + if ( parts[ 0 ] !== "" ) lineVertices.push( parts[ 0 ] ); + if ( parts[ 1 ] !== "" ) lineUVs.push( parts[ 1 ] ); - } + } - } - state.addLineGeometry( lineVertices, lineUVs ); + } + state.addLineGeometry( lineVertices, lineUVs ); - } else if ( lineFirstChar === 'p' ) { + } else if ( lineFirstChar === 'p' ) { - var lineData = line.substr( 1 ).trim(); - var pointData = lineData.split( " " ); + var lineData = line.substr( 1 ).trim(); + var pointData = lineData.split( " " ); - state.addPointGeometry( pointData ); + state.addPointGeometry( pointData ); - } else if ( ( result = object_pattern.exec( line ) ) !== null ) { + } else if ( ( result = object_pattern.exec( line ) ) !== null ) { - // o object_name - // or - // g group_name + // o object_name + // or + // g group_name - // WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869 - // var name = result[ 0 ].substr( 1 ).trim(); - var name = ( " " + result[ 0 ].substr( 1 ).trim() ).substr( 1 ); + // WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869 + // var name = result[ 0 ].substr( 1 ).trim(); + var name = ( " " + result[ 0 ].substr( 1 ).trim() ).substr( 1 ); - state.startObject( name ); + state.startObject( name ); - } else if ( material_use_pattern.test( line ) ) { + } else if ( material_use_pattern.test( line ) ) { - // material + // material - state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries ); + state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries ); - } else if ( material_library_pattern.test( line ) ) { + } else if ( material_library_pattern.test( line ) ) { - // mtl file + // mtl file - state.materialLibraries.push( line.substring( 7 ).trim() ); + state.materialLibraries.push( line.substring( 7 ).trim() ); - } else if ( lineFirstChar === 's' ) { + } else if ( lineFirstChar === 's' ) { - result = line.split( ' ' ); + result = line.split( ' ' ); - // smooth shading + // smooth shading - // @todo Handle files that have varying smooth values for a set of faces inside one geometry, - // but does not define a usemtl for each face set. - // This should be detected and a dummy material created (later MultiMaterial and geometry groups). - // This requires some care to not create extra material on each smooth value for "normal" obj files. - // where explicit usemtl defines geometry groups. - // Example asset: examples/models/obj/cerberus/Cerberus.obj + // @todo Handle files that have varying smooth values for a set of faces inside one geometry, + // but does not define a usemtl for each face set. + // This should be detected and a dummy material created (later MultiMaterial and geometry groups). + // This requires some care to not create extra material on each smooth value for "normal" obj files. + // where explicit usemtl defines geometry groups. + // Example asset: examples/models/obj/cerberus/Cerberus.obj - /* - * http://paulbourke.net/dataformats/obj/ - * or - * http://www.cs.utah.edu/~boulos/cs3505/obj_spec.pdf - * - * From chapter "Grouping" Syntax explanation "s group_number": - * "group_number is the smoothing group number. To turn off smoothing groups, use a value of 0 or off. - * Polygonal elements use group numbers to put elements in different smoothing groups. For free-form - * surfaces, smoothing groups are either turned on or off; there is no difference between values greater - * than 0." - */ - if ( result.length > 1 ) { + /* + * http://paulbourke.net/dataformats/obj/ + * or + * http://www.cs.utah.edu/~boulos/cs3505/obj_spec.pdf + * + * From chapter "Grouping" Syntax explanation "s group_number": + * "group_number is the smoothing group number. To turn off smoothing groups, use a value of 0 or off. + * Polygonal elements use group numbers to put elements in different smoothing groups. For free-form + * surfaces, smoothing groups are either turned on or off; there is no difference between values greater + * than 0." + */ + if ( result.length > 1 ) { - var value = result[ 1 ].trim().toLowerCase(); - state.object.smooth = ( value !== '0' && value !== 'off' ); + var value = result[ 1 ].trim().toLowerCase(); + state.object.smooth = ( value !== '0' && value !== 'off' ); - } else { + } else { - // ZBrush can produce "s" lines #11707 - state.object.smooth = true; + // ZBrush can produce "s" lines #11707 + state.object.smooth = true; - } - var material = state.object.currentMaterial(); - if ( material ) material.smooth = state.object.smooth; + } + var material = state.object.currentMaterial(); + if ( material ) material.smooth = state.object.smooth; - } else { + } else { - // Handle null terminated files without exception - if ( line === '\0' ) continue; + // Handle null terminated files without exception + if ( line === '\0' ) continue; - throw new Error( 'THREE.OBJLoader: Unexpected line: "' + line + '"' ); + throw new Error( 'THREE.OBJLoader: Unexpected line: "' + line + '"' ); - } + } - } + } - state.finalize(); + state.finalize(); - var container = new THREE.Group(); - container.materialLibraries = [].concat( state.materialLibraries ); + var container = new THREE.Group(); + container.materialLibraries = [].concat( state.materialLibraries ); - for ( var i = 0, l = state.objects.length; i < l; i ++ ) { + for ( var i = 0, l = state.objects.length; i < l; i ++ ) { - var object = state.objects[ i ]; - var geometry = object.geometry; - var materials = object.materials; - var isLine = ( geometry.type === 'Line' ); - var isPoints = ( geometry.type === 'Points' ); - var hasVertexColors = false; + var object = state.objects[ i ]; + var geometry = object.geometry; + var materials = object.materials; + var isLine = ( geometry.type === 'Line' ); + var isPoints = ( geometry.type === 'Points' ); + var hasVertexColors = false; - // Skip o/g line declarations that did not follow with any faces - if ( geometry.vertices.length === 0 ) continue; + // Skip o/g line declarations that did not follow with any faces + if ( geometry.vertices.length === 0 ) continue; - var buffergeometry = new THREE.BufferGeometry(); + var buffergeometry = new THREE.BufferGeometry(); - buffergeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) ); + buffergeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) ); - if ( geometry.normals.length > 0 ) { + if ( geometry.normals.length > 0 ) { - buffergeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) ); + buffergeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) ); - } else { + } else { - buffergeometry.computeVertexNormals(); + buffergeometry.computeVertexNormals(); - } + } - if ( geometry.colors.length > 0 ) { + if ( geometry.colors.length > 0 ) { - hasVertexColors = true; - buffergeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( geometry.colors, 3 ) ); + hasVertexColors = true; + buffergeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( geometry.colors, 3 ) ); - } + } - if ( geometry.uvs.length > 0 ) { + if ( geometry.uvs.length > 0 ) { - buffergeometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) ); + buffergeometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) ); - } + } - // Create materials + // Create materials - var createdMaterials = []; + var createdMaterials = []; - for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) { + for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) { - var sourceMaterial = materials[ mi ]; - var material = undefined; + var sourceMaterial = materials[ mi ]; + var material = undefined; - if ( this.materials !== null ) { + if ( this.materials !== null ) { - material = this.materials.create( sourceMaterial.name ); + material = this.materials.create( sourceMaterial.name ); - // mtl etc. loaders probably can't create line materials correctly, copy properties to a line material. - if ( isLine && material && ! ( material instanceof THREE.LineBasicMaterial ) ) { + // mtl etc. loaders probably can't create line materials correctly, copy properties to a line material. + if ( isLine && material && ! ( material instanceof THREE.LineBasicMaterial ) ) { - var materialLine = new THREE.LineBasicMaterial(); - materialLine.copy( material ); - materialLine.lights = false; // TOFIX - material = materialLine; + var materialLine = new THREE.LineBasicMaterial(); + materialLine.copy( material ); + materialLine.lights = false; // TOFIX + material = materialLine; - } else if ( isPoints && material && ! ( material instanceof THREE.PointsMaterial ) ) { + } else if ( isPoints && material && ! ( material instanceof THREE.PointsMaterial ) ) { - var materialPoints = new THREE.PointsMaterial( { size: 10, sizeAttenuation: false } ); - materialLine.copy( material ); - material = materialPoints; + var materialPoints = new THREE.PointsMaterial( { size: 10, sizeAttenuation: false } ); + materialLine.copy( material ); + material = materialPoints; - } + } - } + } - if ( ! material ) { + if ( ! material ) { - if ( isLine ) { + if ( isLine ) { - material = new THREE.LineBasicMaterial(); + material = new THREE.LineBasicMaterial(); - } else if ( isPoints ) { + } else if ( isPoints ) { - material = new THREE.PointsMaterial( { size: 1, sizeAttenuation: false } ); + material = new THREE.PointsMaterial( { size: 1, sizeAttenuation: false } ); - } else { + } else { - material = new THREE.MeshPhongMaterial(); + material = new THREE.MeshPhongMaterial(); - } + } - material.name = sourceMaterial.name; + material.name = sourceMaterial.name; - } + } - material.flatShading = sourceMaterial.smooth ? false : true; - material.vertexColors = hasVertexColors ? THREE.VertexColors : THREE.NoColors; + material.flatShading = sourceMaterial.smooth ? false : true; + material.vertexColors = hasVertexColors ? THREE.VertexColors : THREE.NoColors; - createdMaterials.push( material ); + createdMaterials.push( material ); - } + } - // Create mesh + // Create mesh - var mesh; + var mesh; - if ( createdMaterials.length > 1 ) { + if ( createdMaterials.length > 1 ) { - for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) { + for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) { - var sourceMaterial = materials[ mi ]; - buffergeometry.addGroup( sourceMaterial.groupStart, sourceMaterial.groupCount, mi ); + var sourceMaterial = materials[ mi ]; + buffergeometry.addGroup( sourceMaterial.groupStart, sourceMaterial.groupCount, mi ); - } + } - if ( isLine ) { + if ( isLine ) { - mesh = new THREE.LineSegments( buffergeometry, createdMaterials ); + mesh = new THREE.LineSegments( buffergeometry, createdMaterials ); - } else if ( isPoints ) { + } else if ( isPoints ) { - mesh = new THREE.Points( buffergeometry, createdMaterials ); + mesh = new THREE.Points( buffergeometry, createdMaterials ); - } else { + } else { - mesh = new THREE.Mesh( buffergeometry, createdMaterials ); + mesh = new THREE.Mesh( buffergeometry, createdMaterials ); - } + } - } else { + } else { - if ( isLine ) { + if ( isLine ) { - mesh = new THREE.LineSegments( buffergeometry, createdMaterials[ 0 ] ); + mesh = new THREE.LineSegments( buffergeometry, createdMaterials[ 0 ] ); - } else if ( isPoints ) { + } else if ( isPoints ) { - mesh = new THREE.Points( buffergeometry, createdMaterials[ 0 ] ); + mesh = new THREE.Points( buffergeometry, createdMaterials[ 0 ] ); - } else { + } else { - mesh = new THREE.Mesh( buffergeometry, createdMaterials[ 0 ] ); + mesh = new THREE.Mesh( buffergeometry, createdMaterials[ 0 ] ); - } + } - } + } - mesh.name = object.name; + mesh.name = object.name; - container.add( mesh ); + container.add( mesh ); - } + } - console.timeEnd( 'OBJLoader' ); + console.timeEnd( 'OBJLoader' ); - return container; + return container; - } + } - }; + }; - return OBJLoader; + return OBJLoader; } )(); -},{}],45:[function(_dereq_,module,exports){ +},{}],42:[function(_dereq_,module,exports){ exports = module.exports = trim; @@ -60726,7 +60372,7 @@ exports.right = function(str){ return str.replace(/\s*$/, ''); }; -},{}],46:[function(_dereq_,module,exports){ +},{}],43:[function(_dereq_,module,exports){ (function (global){ /** * @license @@ -60764,7 +60410,7 @@ exports.right = function(str){ /** * @license - * webvr-polyfill-dpdb + * webvr-polyfill-dpdb * Copyright (c) 2017 Google * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60828,9 +60474,9 @@ exports.right = function(str){ */ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.WebVRPolyfill = factory()); + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.WebVRPolyfill = factory()); }(this, (function () { 'use strict'; var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; @@ -60838,11 +60484,11 @@ var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== function unwrapExports (x) { - return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } function createCommonjsModule(fn, module) { - return module = { exports: {} }, fn(module, module.exports), module.exports; + return module = { exports: {} }, fn(module, module.exports), module.exports; } var race = function race(promises) { @@ -60954,7 +60600,7 @@ var cardboardVrDisplay = createCommonjsModule(function (module, exports) { * THE SOFTWARE. */ (function (global, factory) { - module.exports = factory(); + module.exports = factory(); }(commonjsGlobal, (function () { var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); @@ -62618,9 +62264,9 @@ var format = 1; var last_updated = "2018-02-20T22:55:10Z"; var devices = [{"type":"android","rules":[{"mdmh":"asus/*/Nexus 7/*"},{"ua":"Nexus 7"}],"dpi":[320.8,323],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"asus/*/ASUS_Z00AD/*"},{"ua":"ASUS_Z00AD"}],"dpi":[403,404.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Google/*/Pixel XL/*"},{"ua":"Pixel XL"}],"dpi":[537.9,533],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Google/*/Pixel/*"},{"ua":"Pixel"}],"dpi":[432.6,436.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"HTC/*/HTC6435LVW/*"},{"ua":"HTC6435LVW"}],"dpi":[449.7,443.3],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"HTC/*/HTC One XL/*"},{"ua":"HTC One XL"}],"dpi":[315.3,314.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"htc/*/Nexus 9/*"},{"ua":"Nexus 9"}],"dpi":289,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"HTC/*/HTC One M9/*"},{"ua":"HTC One M9"}],"dpi":[442.5,443.3],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"HTC/*/HTC One_M8/*"},{"ua":"HTC One_M8"}],"dpi":[449.7,447.4],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"HTC/*/HTC One/*"},{"ua":"HTC One"}],"dpi":472.8,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Huawei/*/Nexus 6P/*"},{"ua":"Nexus 6P"}],"dpi":[515.1,518],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LENOVO/*/Lenovo PB2-690Y/*"},{"ua":"Lenovo PB2-690Y"}],"dpi":[457.2,454.713],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"LGE/*/Nexus 5X/*"},{"ua":"Nexus 5X"}],"dpi":[422,419.9],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/LGMS345/*"},{"ua":"LGMS345"}],"dpi":[221.7,219.1],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"LGE/*/LG-D800/*"},{"ua":"LG-D800"}],"dpi":[422,424.1],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"LGE/*/LG-D850/*"},{"ua":"LG-D850"}],"dpi":[537.9,541.9],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"LGE/*/VS985 4G/*"},{"ua":"VS985 4G"}],"dpi":[537.9,535.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/Nexus 5/*"},{"ua":"Nexus 5 B"}],"dpi":[442.4,444.8],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/Nexus 4/*"},{"ua":"Nexus 4"}],"dpi":[319.8,318.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/LG-P769/*"},{"ua":"LG-P769"}],"dpi":[240.6,247.5],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/LGMS323/*"},{"ua":"LGMS323"}],"dpi":[206.6,204.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/LGLS996/*"},{"ua":"LGLS996"}],"dpi":[403.4,401.5],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Micromax/*/4560MMX/*"},{"ua":"4560MMX"}],"dpi":[240,219.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Micromax/*/A250/*"},{"ua":"Micromax A250"}],"dpi":[480,446.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Micromax/*/Micromax AQ4501/*"},{"ua":"Micromax AQ4501"}],"dpi":240,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/G5/*"},{"ua":"Moto G (5) Plus"}],"dpi":[403.4,403],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/DROID RAZR/*"},{"ua":"DROID RAZR"}],"dpi":[368.1,256.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT830C/*"},{"ua":"XT830C"}],"dpi":[254,255.9],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1021/*"},{"ua":"XT1021"}],"dpi":[254,256.7],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1023/*"},{"ua":"XT1023"}],"dpi":[254,256.7],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1028/*"},{"ua":"XT1028"}],"dpi":[326.6,327.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1034/*"},{"ua":"XT1034"}],"dpi":[326.6,328.4],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1053/*"},{"ua":"XT1053"}],"dpi":[315.3,316.1],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1562/*"},{"ua":"XT1562"}],"dpi":[403.4,402.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/Nexus 6/*"},{"ua":"Nexus 6 B"}],"dpi":[494.3,489.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1063/*"},{"ua":"XT1063"}],"dpi":[295,296.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1064/*"},{"ua":"XT1064"}],"dpi":[295,295.6],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1092/*"},{"ua":"XT1092"}],"dpi":[422,424.1],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1095/*"},{"ua":"XT1095"}],"dpi":[422,423.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/G4/*"},{"ua":"Moto G (4)"}],"dpi":401,"bw":4,"ac":1000},{"type":"android","rules":[{"mdmh":"OnePlus/*/A0001/*"},{"ua":"A0001"}],"dpi":[403.4,401],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"OnePlus/*/ONE E1005/*"},{"ua":"ONE E1005"}],"dpi":[442.4,441.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"OnePlus/*/ONE A2005/*"},{"ua":"ONE A2005"}],"dpi":[391.9,405.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"OnePlus/*/ONEPLUS A5000/*"},{"ua":"ONEPLUS A5000 "}],"dpi":[403.411,399.737],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"OnePlus/*/ONE A5010/*"},{"ua":"ONEPLUS A5010"}],"dpi":[403,400],"bw":2,"ac":1000},{"type":"android","rules":[{"mdmh":"OPPO/*/X909/*"},{"ua":"X909"}],"dpi":[442.4,444.1],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9082/*"},{"ua":"GT-I9082"}],"dpi":[184.7,185.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G360P/*"},{"ua":"SM-G360P"}],"dpi":[196.7,205.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/Nexus S/*"},{"ua":"Nexus S"}],"dpi":[234.5,229.8],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9300/*"},{"ua":"GT-I9300"}],"dpi":[304.8,303.9],"bw":5,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-T230NU/*"},{"ua":"SM-T230NU"}],"dpi":216,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SGH-T399/*"},{"ua":"SGH-T399"}],"dpi":[217.7,231.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SGH-M919/*"},{"ua":"SGH-M919"}],"dpi":[440.8,437.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N9005/*"},{"ua":"SM-N9005"}],"dpi":[386.4,387],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SAMSUNG-SM-N900A/*"},{"ua":"SAMSUNG-SM-N900A"}],"dpi":[386.4,387.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9500/*"},{"ua":"GT-I9500"}],"dpi":[442.5,443.3],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9505/*"},{"ua":"GT-I9505"}],"dpi":439.4,"bw":4,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G900F/*"},{"ua":"SM-G900F"}],"dpi":[415.6,431.6],"bw":5,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G900M/*"},{"ua":"SM-G900M"}],"dpi":[415.6,431.6],"bw":5,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G800F/*"},{"ua":"SM-G800F"}],"dpi":326.8,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G906S/*"},{"ua":"SM-G906S"}],"dpi":[562.7,572.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9300/*"},{"ua":"GT-I9300"}],"dpi":[306.7,304.8],"bw":5,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-T535/*"},{"ua":"SM-T535"}],"dpi":[142.6,136.4],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N920C/*"},{"ua":"SM-N920C"}],"dpi":[515.1,518.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N920P/*"},{"ua":"SM-N920P"}],"dpi":[386.3655,390.144],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N920W8/*"},{"ua":"SM-N920W8"}],"dpi":[515.1,518.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9300I/*"},{"ua":"GT-I9300I"}],"dpi":[304.8,305.8],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9195/*"},{"ua":"GT-I9195"}],"dpi":[249.4,256.7],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SPH-L520/*"},{"ua":"SPH-L520"}],"dpi":[249.4,255.9],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SAMSUNG-SGH-I717/*"},{"ua":"SAMSUNG-SGH-I717"}],"dpi":285.8,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SPH-D710/*"},{"ua":"SPH-D710"}],"dpi":[217.7,204.2],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-N7100/*"},{"ua":"GT-N7100"}],"dpi":265.1,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SCH-I605/*"},{"ua":"SCH-I605"}],"dpi":265.1,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/Galaxy Nexus/*"},{"ua":"Galaxy Nexus"}],"dpi":[315.3,314.2],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N910H/*"},{"ua":"SM-N910H"}],"dpi":[515.1,518],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N910C/*"},{"ua":"SM-N910C"}],"dpi":[515.2,520.2],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G130M/*"},{"ua":"SM-G130M"}],"dpi":[165.9,164.8],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G928I/*"},{"ua":"SM-G928I"}],"dpi":[515.1,518.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G920F/*"},{"ua":"SM-G920F"}],"dpi":580.6,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G920P/*"},{"ua":"SM-G920P"}],"dpi":[522.5,577],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G925F/*"},{"ua":"SM-G925F"}],"dpi":580.6,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G925V/*"},{"ua":"SM-G925V"}],"dpi":[522.5,576.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G930F/*"},{"ua":"SM-G930F"}],"dpi":576.6,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G935F/*"},{"ua":"SM-G935F"}],"dpi":533,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G950F/*"},{"ua":"SM-G950F"}],"dpi":[562.707,565.293],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G955U/*"},{"ua":"SM-G955U"}],"dpi":[522.514,525.762],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"Sony/*/C6903/*"},{"ua":"C6903"}],"dpi":[442.5,443.3],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"Sony/*/D6653/*"},{"ua":"D6653"}],"dpi":[428.6,427.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Sony/*/E6653/*"},{"ua":"E6653"}],"dpi":[428.6,425.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Sony/*/E6853/*"},{"ua":"E6853"}],"dpi":[403.4,401.9],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Sony/*/SGP321/*"},{"ua":"SGP321"}],"dpi":[224.7,224.1],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"TCT/*/ALCATEL ONE TOUCH Fierce/*"},{"ua":"ALCATEL ONE TOUCH Fierce"}],"dpi":[240,247.5],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"THL/*/thl 5000/*"},{"ua":"thl 5000"}],"dpi":[480,443.3],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Fly/*/IQ4412/*"},{"ua":"IQ4412"}],"dpi":307.9,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"ZTE/*/ZTE Blade L2/*"},{"ua":"ZTE Blade L2"}],"dpi":240,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"BENEVE/*/VR518/*"},{"ua":"VR518"}],"dpi":480,"bw":3,"ac":500},{"type":"ios","rules":[{"res":[640,960]}],"dpi":[325.1,328.4],"bw":4,"ac":1000},{"type":"ios","rules":[{"res":[640,1136]}],"dpi":[317.1,320.2],"bw":3,"ac":1000},{"type":"ios","rules":[{"res":[750,1334]}],"dpi":326.4,"bw":4,"ac":1000},{"type":"ios","rules":[{"res":[1242,2208]}],"dpi":[453.6,458.4],"bw":4,"ac":1000},{"type":"ios","rules":[{"res":[1125,2001]}],"dpi":[410.9,415.4],"bw":4,"ac":1000},{"type":"ios","rules":[{"res":[1125,2436]}],"dpi":458,"bw":4,"ac":1000}]; var DPDB_CACHE = { - format: format, - last_updated: last_updated, - devices: devices + format: format, + last_updated: last_updated, + devices: devices }; function Dpdb(url, onDeviceParamsUpdated) { this.dpdb = DPDB_CACHE; @@ -63409,51 +63055,51 @@ ViewerSelector.prototype.createButton_ = function (label, onclick) { }; var commonjsGlobal$$1 = typeof window !== 'undefined' ? window : typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : typeof self !== 'undefined' ? self : {}; function unwrapExports$$1 (x) { - return x && x.__esModule ? x['default'] : x; + return x && x.__esModule ? x['default'] : x; } function createCommonjsModule$$1(fn, module) { - return module = { exports: {} }, fn(module, module.exports), module.exports; + return module = { exports: {} }, fn(module, module.exports), module.exports; } var NoSleep = createCommonjsModule$$1(function (module, exports) { (function webpackUniversalModuleDefinition(root, factory) { - module.exports = factory(); + module.exports = factory(); })(commonjsGlobal$$1, function() { return (function(modules) { - var installedModules = {}; - function __webpack_require__(moduleId) { - if(installedModules[moduleId]) { - return installedModules[moduleId].exports; - } - var module = installedModules[moduleId] = { - i: moduleId, - l: false, - exports: {} - }; - modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); - module.l = true; - return module.exports; - } - __webpack_require__.m = modules; - __webpack_require__.c = installedModules; - __webpack_require__.d = function(exports, name, getter) { - if(!__webpack_require__.o(exports, name)) { - Object.defineProperty(exports, name, { - configurable: false, - enumerable: true, - get: getter - }); - } - }; - __webpack_require__.n = function(module) { - var getter = module && module.__esModule ? - function getDefault() { return module['default']; } : - function getModuleExports() { return module; }; - __webpack_require__.d(getter, 'a', getter); - return getter; - }; - __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; - __webpack_require__.p = ""; - return __webpack_require__(__webpack_require__.s = 0); + var installedModules = {}; + function __webpack_require__(moduleId) { + if(installedModules[moduleId]) { + return installedModules[moduleId].exports; + } + var module = installedModules[moduleId] = { + i: moduleId, + l: false, + exports: {} + }; + modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + module.l = true; + return module.exports; + } + __webpack_require__.m = modules; + __webpack_require__.c = installedModules; + __webpack_require__.d = function(exports, name, getter) { + if(!__webpack_require__.o(exports, name)) { + Object.defineProperty(exports, name, { + configurable: false, + enumerable: true, + get: getter + }); + } + }; + __webpack_require__.n = function(module) { + var getter = module && module.__esModule ? + function getDefault() { return module['default']; } : + function getModuleExports() { return module; }; + __webpack_require__.d(getter, 'a', getter); + return getter; + }; + __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; + __webpack_require__.p = ""; + return __webpack_require__(__webpack_require__.s = 0); }) ([ (function(module, exports, __webpack_require__) { @@ -64223,7 +63869,7 @@ WebVRPolyfill.VRDisplay = CardboardVRDisplay.VRDisplay; var webvrPolyfill = Object.freeze({ - default: WebVRPolyfill + default: WebVRPolyfill }); var require$$0 = ( webvrPolyfill && WebVRPolyfill ) || webvrPolyfill; @@ -64244,7 +63890,7 @@ return src; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],47:[function(_dereq_,module,exports){ +},{}],44:[function(_dereq_,module,exports){ var newline = /\n/ var newlineChar = '\n' var whitespace = /\s/ @@ -64260,7 +63906,7 @@ module.exports.lines = function wordwrap(text, opt) { opt = opt||{} //zero width results in nothing visible - if (opt.width === 0 && opt.mode !== 'nowrap') + if (opt.width === 0 && opt.mode !== 'nowrap') return [] text = text||'' @@ -64300,7 +63946,7 @@ function pre(measure, text, start, end, width) { var lineEnd = isNewline ? i : i+1 var measured = measure(text, lineStart, lineEnd, width) lines.push(measured) - + lineStart = i+1 } } @@ -64372,7 +64018,7 @@ function monospace(text, start, end, width) { end: start+glyphs } } -},{}],48:[function(_dereq_,module,exports){ +},{}],45:[function(_dereq_,module,exports){ "use strict"; var window = _dereq_("global/window") var isFunction = _dereq_("is-function") @@ -64619,7 +64265,7 @@ function getXml(xhr) { function noop() {} -},{"global/window":17,"is-function":21,"parse-headers":31,"xtend":50}],49:[function(_dereq_,module,exports){ +},{"global/window":14,"is-function":18,"parse-headers":28,"xtend":47}],46:[function(_dereq_,module,exports){ module.exports = (function xmlparser() { //common browsers if (typeof self.DOMParser !== 'undefined') { @@ -64627,7 +64273,7 @@ module.exports = (function xmlparser() { var parser = new self.DOMParser() return parser.parseFromString(str, 'application/xml') } - } + } //IE8 fallback if (typeof self.ActiveXObject !== 'undefined' @@ -64648,7 +64294,7 @@ module.exports = (function xmlparser() { } })() -},{}],50:[function(_dereq_,module,exports){ +},{}],47:[function(_dereq_,module,exports){ module.exports = extend var hasOwnProperty = Object.prototype.hasOwnProperty; @@ -64669,7 +64315,7 @@ function extend() { return target } -},{}],51:[function(_dereq_,module,exports){ +},{}],48:[function(_dereq_,module,exports){ module.exports={ "name": "aframe", "version": "0.8.2", @@ -64805,7 +64451,7 @@ module.exports={ } } -},{}],52:[function(_dereq_,module,exports){ +},{}],49:[function(_dereq_,module,exports){ var anime = _dereq_('animejs'); var components = _dereq_('../core/component').components; var registerComponent = _dereq_('../core/component').registerComponent; @@ -65421,7 +65067,7 @@ function isRawProperty (data) { data.property.startsWith(STRING_OBJECT3D); } -},{"../core/component":107,"../lib/three":157,"../utils":180,"animejs":2}],53:[function(_dereq_,module,exports){ +},{"../core/component":104,"../lib/three":154,"../utils":177,"animejs":2}],50:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; var THREE = _dereq_('../lib/three'); @@ -65513,7 +65159,7 @@ module.exports.Component = registerComponent('camera', { } }); -},{"../core/component":107,"../lib/three":157}],54:[function(_dereq_,module,exports){ +},{"../core/component":104,"../lib/three":154}],51:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; var THREE = _dereq_('../lib/three'); @@ -65547,7 +65193,7 @@ module.exports.Component = registerComponent('collada-model', { } }); -},{"../core/component":107,"../lib/three":157}],55:[function(_dereq_,module,exports){ +},{"../core/component":104,"../lib/three":154}],52:[function(_dereq_,module,exports){ /* global THREE */ var registerComponent = _dereq_('../core/component').registerComponent; var utils = _dereq_('../utils/'); @@ -65925,7 +65571,7 @@ module.exports.Component = registerComponent('cursor', { } }); -},{"../core/component":107,"../utils/":180}],56:[function(_dereq_,module,exports){ +},{"../core/component":104,"../utils/":177}],53:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; var bind = _dereq_('../utils/bind'); var checkControllerPresentAndSetup = _dereq_('../utils/tracked-controls').checkControllerPresentAndSetup; @@ -66103,7 +65749,7 @@ module.exports.Component = registerComponent('daydream-controls', { } }); -},{"../core/component":107,"../utils/bind":174,"../utils/tracked-controls":186}],57:[function(_dereq_,module,exports){ +},{"../core/component":104,"../utils/bind":171,"../utils/tracked-controls":183}],54:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; var bind = _dereq_('../utils/bind'); var trackedControlsUtils = _dereq_('../utils/tracked-controls'); @@ -66279,7 +65925,7 @@ module.exports.Component = registerComponent('gearvr-controls', { } }); -},{"../core/component":107,"../utils/bind":174,"../utils/tracked-controls":186}],58:[function(_dereq_,module,exports){ +},{"../core/component":104,"../utils/bind":171,"../utils/tracked-controls":183}],55:[function(_dereq_,module,exports){ var geometries = _dereq_('../core/geometry').geometries; var geometryNames = _dereq_('../core/geometry').geometryNames; var registerComponent = _dereq_('../core/component').registerComponent; @@ -66358,7 +66004,7 @@ module.exports.Component = registerComponent('geometry', { } }); -},{"../core/component":107,"../core/geometry":109,"../lib/three":157}],59:[function(_dereq_,module,exports){ +},{"../core/component":104,"../core/geometry":106,"../lib/three":154}],56:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; var THREE = _dereq_('../lib/three'); var utils = _dereq_('../utils/'); @@ -66406,7 +66052,7 @@ module.exports.Component = registerComponent('gltf-model', { } }); -},{"../core/component":107,"../lib/three":157,"../utils/":180}],60:[function(_dereq_,module,exports){ +},{"../core/component":104,"../lib/three":154,"../utils/":177}],57:[function(_dereq_,module,exports){ /* global THREE */ var registerComponent = _dereq_('../core/component').registerComponent; @@ -66789,7 +66435,7 @@ function isViveController (trackedControls) { return controllerId && controllerId.indexOf('OpenVR ') === 0; } -},{"../core/component":107}],61:[function(_dereq_,module,exports){ +},{"../core/component":104}],58:[function(_dereq_,module,exports){ _dereq_('./animation'); _dereq_('./camera'); _dereq_('./collada-model'); @@ -66835,7 +66481,7 @@ _dereq_('./scene/screenshot'); _dereq_('./scene/stats'); _dereq_('./scene/vr-mode-ui'); -},{"./animation":52,"./camera":53,"./collada-model":54,"./cursor":55,"./daydream-controls":56,"./gearvr-controls":57,"./geometry":58,"./gltf-model":59,"./hand-controls":60,"./laser-controls":62,"./light":63,"./line":64,"./link":65,"./look-controls":66,"./material":67,"./obj-model":68,"./oculus-go-controls":69,"./oculus-touch-controls":70,"./position":71,"./raycaster":72,"./rotation":73,"./scale":74,"./scene/background":75,"./scene/debug":76,"./scene/effects":78,"./scene/embedded":81,"./scene/fog":82,"./scene/inspector":83,"./scene/keyboard-shortcuts":84,"./scene/overlay":85,"./scene/pool":86,"./scene/renderer":87,"./scene/screenshot":88,"./scene/stats":89,"./scene/vr-mode-ui":90,"./shadow":91,"./sound":92,"./text":93,"./tracked-controls":94,"./visible":95,"./vive-controls":96,"./wasd-controls":97,"./windows-motion-controls":98}],62:[function(_dereq_,module,exports){ +},{"./animation":49,"./camera":50,"./collada-model":51,"./cursor":52,"./daydream-controls":53,"./gearvr-controls":54,"./geometry":55,"./gltf-model":56,"./hand-controls":57,"./laser-controls":59,"./light":60,"./line":61,"./link":62,"./look-controls":63,"./material":64,"./obj-model":65,"./oculus-go-controls":66,"./oculus-touch-controls":67,"./position":68,"./raycaster":69,"./rotation":70,"./scale":71,"./scene/background":72,"./scene/debug":73,"./scene/effects":75,"./scene/embedded":78,"./scene/fog":79,"./scene/inspector":80,"./scene/keyboard-shortcuts":81,"./scene/overlay":82,"./scene/pool":83,"./scene/renderer":84,"./scene/screenshot":85,"./scene/stats":86,"./scene/vr-mode-ui":87,"./shadow":88,"./sound":89,"./text":90,"./tracked-controls":91,"./visible":92,"./vive-controls":93,"./wasd-controls":94,"./windows-motion-controls":95}],59:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; var utils = _dereq_('../utils/'); @@ -66909,12 +66555,12 @@ registerComponent('laser-controls', { }, 'gearvr-controls': { - cursor: {downEvents: ['trackpaddown', 'triggerdown'], upEvents: ['trackpadup', 'triggerup']}, + cursor: {downEvents: ['triggerdown'], upEvents: ['triggerup']}, raycaster: {origin: {x: 0, y: 0.0005, z: 0}} }, 'oculus-go-controls': { - cursor: {downEvents: ['trackpaddown', 'triggerdown'], upEvents: ['trackpadup', 'triggerup']}, + cursor: {downEvents: ['triggerdown'], upEvents: ['triggerup']}, raycaster: {origin: {x: 0, y: 0.0005, z: 0}} }, @@ -66934,7 +66580,7 @@ registerComponent('laser-controls', { } }); -},{"../core/component":107,"../utils/":180}],63:[function(_dereq_,module,exports){ +},{"../core/component":104,"../utils/":177}],60:[function(_dereq_,module,exports){ var bind = _dereq_('../utils/bind'); var diff = _dereq_('../utils').diff; var debug = _dereq_('../utils/debug'); @@ -67211,7 +66857,7 @@ module.exports.Component = registerComponent('light', { } }); -},{"../core/component":107,"../lib/three":157,"../utils":180,"../utils/bind":174,"../utils/debug":176}],64:[function(_dereq_,module,exports){ +},{"../core/component":104,"../lib/three":154,"../utils":177,"../utils/bind":171,"../utils/debug":173}],61:[function(_dereq_,module,exports){ /* global THREE */ var registerComponent = _dereq_('../core/component').registerComponent; @@ -67286,7 +66932,7 @@ function isEqualVec3 (a, b) { return (a.x === b.x && a.y === b.y && a.z === b.z); } -},{"../core/component":107}],65:[function(_dereq_,module,exports){ +},{"../core/component":104}],62:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; var registerShader = _dereq_('../core/shader').registerShader; var THREE = _dereq_('../lib/three'); @@ -67658,7 +67304,7 @@ registerShader('portal', { }); /* eslint-enable */ -},{"../core/component":107,"../core/shader":118,"../lib/three":157}],66:[function(_dereq_,module,exports){ +},{"../core/component":104,"../core/shader":115,"../lib/three":154}],63:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; var THREE = _dereq_('../lib/three'); var utils = _dereq_('../utils/'); @@ -68088,7 +67734,7 @@ module.exports.Component = registerComponent('look-controls', { } }); -},{"../core/component":107,"../lib/three":157,"../utils":180,"../utils/":180}],67:[function(_dereq_,module,exports){ +},{"../core/component":104,"../lib/three":154,"../utils":177,"../utils/":177}],64:[function(_dereq_,module,exports){ /* global Promise */ var utils = _dereq_('../utils/'); var component = _dereq_('../core/component'); @@ -68357,7 +68003,7 @@ function disposeMaterial (material, system) { system.unregisterMaterial(material); } -},{"../core/component":107,"../core/shader":118,"../lib/three":157,"../utils/":180}],68:[function(_dereq_,module,exports){ +},{"../core/component":104,"../core/shader":115,"../lib/three":154,"../utils/":177}],65:[function(_dereq_,module,exports){ var debug = _dereq_('../utils/debug'); var registerComponent = _dereq_('../core/component').registerComponent; var THREE = _dereq_('../lib/three'); @@ -68437,7 +68083,7 @@ module.exports.Component = registerComponent('obj-model', { } }); -},{"../core/component":107,"../lib/three":157,"../utils/debug":176}],69:[function(_dereq_,module,exports){ +},{"../core/component":104,"../lib/three":154,"../utils/debug":173}],66:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; var bind = _dereq_('../utils/bind'); var trackedControlsUtils = _dereq_('../utils/tracked-controls'); @@ -68609,7 +68255,7 @@ module.exports.Component = registerComponent('oculus-go-controls', { } }); -},{"../core/component":107,"../utils/bind":174,"../utils/tracked-controls":186}],70:[function(_dereq_,module,exports){ +},{"../core/component":104,"../utils/bind":171,"../utils/tracked-controls":183}],67:[function(_dereq_,module,exports){ var bind = _dereq_('../utils/bind'); var registerComponent = _dereq_('../core/component').registerComponent; var trackedControlsUtils = _dereq_('../utils/tracked-controls'); @@ -68827,7 +68473,7 @@ module.exports.Component = registerComponent('oculus-touch-controls', { } }); -},{"../core/component":107,"../lib/three":157,"../utils/bind":174,"../utils/tracked-controls":186}],71:[function(_dereq_,module,exports){ +},{"../core/component":104,"../lib/three":154,"../utils/bind":171,"../utils/tracked-controls":183}],68:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; module.exports.Component = registerComponent('position', { @@ -68845,7 +68491,7 @@ module.exports.Component = registerComponent('position', { } }); -},{"../core/component":107}],72:[function(_dereq_,module,exports){ +},{"../core/component":104}],69:[function(_dereq_,module,exports){ /* global MutationObserver */ var registerComponent = _dereq_('../core/component').registerComponent; @@ -69274,7 +68920,7 @@ function copyArray (a, b) { } } -},{"../core/component":107,"../lib/three":157,"../utils/":180}],73:[function(_dereq_,module,exports){ +},{"../core/component":104,"../lib/three":154,"../utils/":177}],70:[function(_dereq_,module,exports){ var degToRad = _dereq_('../lib/three').Math.degToRad; var registerComponent = _dereq_('../core/component').registerComponent; @@ -69297,7 +68943,7 @@ module.exports.Component = registerComponent('rotation', { } }); -},{"../core/component":107,"../lib/three":157}],74:[function(_dereq_,module,exports){ +},{"../core/component":104,"../lib/three":154}],71:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; // Avoids triggering a zero-determinant which makes object3D matrix non-invertible. @@ -69324,7 +68970,7 @@ module.exports.Component = registerComponent('scale', { } }); -},{"../core/component":107}],75:[function(_dereq_,module,exports){ +},{"../core/component":104}],72:[function(_dereq_,module,exports){ /* global THREE */ var register = _dereq_('../../core/component').registerComponent; @@ -69344,14 +68990,14 @@ module.exports.Component = register('background', { } }); -},{"../../core/component":107}],76:[function(_dereq_,module,exports){ +},{"../../core/component":104}],73:[function(_dereq_,module,exports){ var register = _dereq_('../../core/component').registerComponent; module.exports.Component = register('debug', { schema: {default: true} }); -},{"../../core/component":107}],77:[function(_dereq_,module,exports){ +},{"../../core/component":104}],74:[function(_dereq_,module,exports){ /* global THREE */ var registerEffect = _dereq_('../../../core/effect').registerEffect; @@ -69381,13 +69027,13 @@ registerEffect('bloom', { } }); -},{"../../../../vendor/effects/CopyShader":189,"../../../../vendor/effects/LuminosityHighPassShader":191,"../../../../vendor/effects/ShaderPass":196,"../../../../vendor/effects/UnrealBloomPass":197,"../../../core/effect":108}],78:[function(_dereq_,module,exports){ +},{"../../../../vendor/effects/CopyShader":186,"../../../../vendor/effects/LuminosityHighPassShader":188,"../../../../vendor/effects/ShaderPass":193,"../../../../vendor/effects/UnrealBloomPass":194,"../../../core/effect":105}],75:[function(_dereq_,module,exports){ _dereq_('./bloom'); _dereq_('./sepia'); _dereq_('./ssao'); -},{"./bloom":77,"./sepia":79,"./ssao":80}],79:[function(_dereq_,module,exports){ +},{"./bloom":74,"./sepia":76,"./ssao":77}],76:[function(_dereq_,module,exports){ /* global THREE */ var registerEffect = _dereq_('../../../core/effect').registerEffect; @@ -69411,7 +69057,7 @@ registerEffect('sepia', { } }); -},{"../../../../vendor/effects/SepiaShader":195,"../../../../vendor/effects/ShaderPass":196,"../../../core/effect":108}],80:[function(_dereq_,module,exports){ +},{"../../../../vendor/effects/SepiaShader":192,"../../../../vendor/effects/ShaderPass":193,"../../../core/effect":105}],77:[function(_dereq_,module,exports){ /* global THREE */ var registerEffect = _dereq_('../../../core/effect').registerEffect; @@ -69439,7 +69085,7 @@ registerEffect('ssao', { } }); -},{"../../../../vendor/effects/SSAOPass":193,"../../../../vendor/effects/SSAOShader":194,"../../../core/effect":108}],81:[function(_dereq_,module,exports){ +},{"../../../../vendor/effects/SSAOPass":190,"../../../../vendor/effects/SSAOShader":191,"../../../core/effect":105}],78:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../../core/component').registerComponent; /** @@ -69464,7 +69110,7 @@ module.exports.Component = registerComponent('embedded', { }); -},{"../../core/component":107}],82:[function(_dereq_,module,exports){ +},{"../../core/component":104}],79:[function(_dereq_,module,exports){ var register = _dereq_('../../core/component').registerComponent; var THREE = _dereq_('../../lib/three'); var debug = _dereq_('../../utils/debug'); @@ -69537,7 +69183,7 @@ function getFog (data) { return fog; } -},{"../../core/component":107,"../../lib/three":157,"../../utils/debug":176}],83:[function(_dereq_,module,exports){ +},{"../../core/component":104,"../../lib/three":154,"../../utils/debug":173}],80:[function(_dereq_,module,exports){ (function (process){ /* global AFRAME */ var AFRAME_INJECTED = _dereq_('../../constants').AFRAME_INJECTED; @@ -69642,7 +69288,7 @@ module.exports.Component = registerComponent('inspector', { }).call(this,_dereq_('_process')) -},{"../../../package":51,"../../constants":99,"../../core/component":107,"../../utils/bind":174,"_process":6}],84:[function(_dereq_,module,exports){ +},{"../../../package":48,"../../constants":96,"../../core/component":104,"../../utils/bind":171,"_process":6}],81:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../../core/component').registerComponent; var shouldCaptureKeyEvent = _dereq_('../../utils/').shouldCaptureKeyEvent; @@ -69681,7 +69327,7 @@ module.exports.Component = registerComponent('keyboard-shortcuts', { } }); -},{"../../core/component":107,"../../utils/":180}],85:[function(_dereq_,module,exports){ +},{"../../core/component":104,"../../utils/":177}],82:[function(_dereq_,module,exports){ /* global THREE */ var register = _dereq_('../../core/component').registerComponent; @@ -69743,7 +69389,7 @@ module.exports.Component = register('overlay', { } }); -},{"../../core/component":107}],86:[function(_dereq_,module,exports){ +},{"../../core/component":104}],83:[function(_dereq_,module,exports){ var debug = _dereq_('../../utils/debug'); var registerComponent = _dereq_('../../core/component').registerComponent; @@ -69861,7 +69507,7 @@ module.exports.Component = registerComponent('pool', { } }); -},{"../../core/component":107,"../../utils/debug":176}],87:[function(_dereq_,module,exports){ +},{"../../core/component":104,"../../utils/debug":173}],84:[function(_dereq_,module,exports){ var register = _dereq_('../../core/component').registerComponent; var debug = _dereq_('../../utils/debug'); @@ -69943,7 +69589,7 @@ module.exports.Component = register('renderer', { } }); -},{"../../core/component":107,"../../utils/debug":176}],88:[function(_dereq_,module,exports){ +},{"../../core/component":104,"../../utils/debug":173}],85:[function(_dereq_,module,exports){ /* global ImageData, URL */ var registerComponent = _dereq_('../../core/component').registerComponent; var THREE = _dereq_('../../lib/three'); @@ -70202,7 +69848,7 @@ module.exports.Component = registerComponent('screenshot', { } }); -},{"../../core/component":107,"../../lib/three":157}],89:[function(_dereq_,module,exports){ +},{"../../core/component":104,"../../lib/three":154}],86:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../../core/component').registerComponent; var RStats = _dereq_('../../../vendor/rStats'); var utils = _dereq_('../../utils'); @@ -70282,7 +69928,7 @@ function createStats (scene) { }); } -},{"../../../vendor/rStats":199,"../../../vendor/rStats.extras":198,"../../core/component":107,"../../lib/rStatsAframe":156,"../../utils":180}],90:[function(_dereq_,module,exports){ +},{"../../../vendor/rStats":196,"../../../vendor/rStats.extras":195,"../../core/component":104,"../../lib/rStatsAframe":153,"../../utils":177}],87:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../../core/component').registerComponent; var constants = _dereq_('../../constants/'); var utils = _dereq_('../../utils/'); @@ -70468,7 +70114,7 @@ function createOrientationModal (onClick) { return modal; } -},{"../../constants/":99,"../../core/component":107,"../../utils/":180}],91:[function(_dereq_,module,exports){ +},{"../../constants/":96,"../../core/component":104,"../../utils/":177}],88:[function(_dereq_,module,exports){ var component = _dereq_('../core/component'); var THREE = _dereq_('../lib/three'); var bind = _dereq_('../utils/bind'); @@ -70522,7 +70168,7 @@ module.exports.Component = registerComponent('shadow', { } }); -},{"../core/component":107,"../lib/three":157,"../utils/bind":174}],92:[function(_dereq_,module,exports){ +},{"../core/component":104,"../lib/three":154,"../utils/bind":171}],89:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; var debug = _dereq_('../utils/debug'); var bind = _dereq_('../utils/bind'); @@ -70561,7 +70207,10 @@ module.exports.Component = registerComponent('sound', { update: function (oldData) { var data = this.data; + var i; + var sound; var srcChanged = data.src !== oldData.src; + // Create new sound if not yet created or changing `src`. if (srcChanged) { if (!data.src) { @@ -70571,7 +70220,8 @@ module.exports.Component = registerComponent('sound', { this.setupSound(); } - this.pool.children.forEach(function (sound) { + for (i = 0; i < this.pool.children.length; i++) { + sound = this.pool.children[i]; if (data.positional) { sound.setDistanceModel(data.distanceModel); sound.setMaxDistance(data.maxDistance); @@ -70581,7 +70231,7 @@ module.exports.Component = registerComponent('sound', { sound.setLoop(data.loop); sound.setVolume(data.volume); sound.isPaused = false; - }); + } if (data.on !== oldData.on) { this.updateEventListener(oldData.on); @@ -70593,15 +70243,16 @@ module.exports.Component = registerComponent('sound', { this.loaded = false; this.audioLoader.load(data.src, function (buffer) { - self.pool.children.forEach(function (sound) { + for (i = 0; i < self.pool.children.length; i++) { + sound = self.pool.children[i]; sound.setBuffer(buffer); - }); + } self.loaded = true; // Remove this key from cache, otherwise we can't play it again THREE.Cache.remove(data.src); if (self.data.autoplay || self.mustPlay) { self.playSound(); } - self.el.emit('sound-loaded', self.evtDetail); + self.el.emit('sound-loaded', self.evtDetail, false); }); } }, @@ -70617,12 +70268,17 @@ module.exports.Component = registerComponent('sound', { }, remove: function () { + var i; + var sound; + this.removeEventListener(); this.el.removeObject3D(this.attrName); + try { - this.pool.children.forEach(function (sound) { + for (i = 0; i < this.pool.children.length; i++) { + sound = this.pool.children[i]; sound.disconnect(); - }); + } } catch (e) { // disconnect() will throw if it was never connected initially. warn('Audio source not properly disconnected'); @@ -70650,7 +70306,9 @@ module.exports.Component = registerComponent('sound', { setupSound: function () { var self = this; var el = this.el; + var i; var sceneEl = el.sceneEl; + var sound; if (this.pool.children.length > 0) { this.stopSound(); @@ -70672,52 +70330,67 @@ module.exports.Component = registerComponent('sound', { // Create [poolSize] audio instances and attach them to pool this.pool = new THREE.Group(); - for (var i = 0; i < this.data.poolSize; i++) { - var sound = this.data.positional ? new THREE.PositionalAudio(listener) : new THREE.Audio(listener); + for (i = 0; i < this.data.poolSize; i++) { + sound = this.data.positional + ? new THREE.PositionalAudio(listener) + : new THREE.Audio(listener); this.pool.add(sound); } el.setObject3D(this.attrName, this.pool); - this.pool.children.forEach(function (sound) { + for (i = 0; i < this.pool.children.length; i++) { + sound = this.pool.children[i]; sound.onEnded = function () { sound.isPlaying = false; - el.emit('sound-ended', self.evtDetail); + el.emit('sound-ended', self.evtDetail, false); }; - }); + } }, /** * Pause all the sounds in the pool. */ pauseSound: function () { + var i; + var sound; + this.isPlaying = false; - this.pool.children.forEach(function (sound) { - if (!sound.source || !sound.source.buffer || !sound.isPlaying || sound.isPaused) { return; } + for (i = 0; i < this.pool.children.length; i++) { + sound = this.pool.children[i]; + if (!sound.source || !sound.source.buffer || !sound.isPlaying || sound.isPaused) { + continue; + } sound.isPaused = true; sound.pause(); - }); + } }, /** * Look for an unused sound in the pool and play it if found. */ - playSound: function () { + playSound: function (processSound) { + var found; + var i; + var sound; + if (!this.loaded) { warn('Sound not loaded yet. It will be played once it finished loading'); this.mustPlay = true; return; } - var found = false; + found = false; this.isPlaying = true; - this.pool.children.forEach(function (sound) { + for (i = 0; i < this.pool.children.length; i++) { + sound = this.pool.children[i]; if (!sound.isPlaying && sound.buffer && !found) { + if (processSound) { processSound(sound); } sound.play(); sound.isPaused = false; found = true; - return; + continue; } - }); + } if (!found) { warn('All the sounds are playing. If you need to play more sounds simultaneously ' + @@ -70732,15 +70405,18 @@ module.exports.Component = registerComponent('sound', { * Stop all the sounds in the pool. */ stopSound: function () { + var i; + var sound; this.isPlaying = false; - this.pool.children.forEach(function (sound) { + for (i = 0; i < this.pool.children.length; i++) { + sound = this.pool.children[i]; if (!sound.source || !sound.source.buffer) { return; } sound.stop(); - }); + } } }); -},{"../core/component":107,"../lib/three":157,"../utils/bind":174,"../utils/debug":176}],93:[function(_dereq_,module,exports){ +},{"../core/component":104,"../lib/three":154,"../utils/bind":171,"../utils/debug":173}],90:[function(_dereq_,module,exports){ var createTextGeometry = _dereq_('three-bmfont-text'); var loadBMFont = _dereq_('load-bmfont'); @@ -71225,7 +70901,7 @@ function PromiseCache () { }; } -},{"../core/component":107,"../core/shader":118,"../lib/three":157,"../utils/":180,"load-bmfont":24,"three-bmfont-text":35}],94:[function(_dereq_,module,exports){ +},{"../core/component":104,"../core/shader":115,"../lib/three":154,"../utils/":177,"load-bmfont":21,"three-bmfont-text":32}],91:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; var controllerUtils = _dereq_('../utils/tracked-controls'); var DEFAULT_CAMERA_HEIGHT = _dereq_('../constants').DEFAULT_CAMERA_HEIGHT; @@ -71559,7 +71235,7 @@ module.exports.Component = registerComponent('tracked-controls', { } }); -},{"../constants":99,"../core/component":107,"../lib/three":157,"../utils/tracked-controls":186}],95:[function(_dereq_,module,exports){ +},{"../constants":96,"../core/component":104,"../lib/three":154,"../utils/tracked-controls":183}],92:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; /** @@ -71573,7 +71249,7 @@ module.exports.Component = registerComponent('visible', { } }); -},{"../core/component":107}],96:[function(_dereq_,module,exports){ +},{"../core/component":104}],93:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../core/component').registerComponent; var utils = _dereq_('../utils/'); @@ -71802,7 +71478,7 @@ module.exports.Component = registerComponent('vive-controls', { } }); -},{"../core/component":107,"../utils/":180,"../utils/tracked-controls":186}],97:[function(_dereq_,module,exports){ +},{"../core/component":104,"../utils/":177,"../utils/tracked-controls":183}],94:[function(_dereq_,module,exports){ var KEYCODE_TO_CODE = _dereq_('../constants').keyboardevent.KEYCODE_TO_CODE; var registerComponent = _dereq_('../core/component').registerComponent; var THREE = _dereq_('../lib/three'); @@ -72011,7 +71687,7 @@ function isEmptyObject (keys) { return true; } -},{"../constants":99,"../core/component":107,"../lib/three":157,"../utils/":180}],98:[function(_dereq_,module,exports){ +},{"../constants":96,"../core/component":104,"../lib/three":154,"../utils/":177}],95:[function(_dereq_,module,exports){ /* global THREE */ var bind = _dereq_('../utils/bind'); var registerComponent = _dereq_('../core/component').registerComponent; @@ -72460,7 +72136,7 @@ module.exports.Component = registerComponent('windows-motion-controls', { } }); -},{"../constants":99,"../core/component":107,"../utils/":180,"../utils/bind":174,"../utils/tracked-controls":186}],99:[function(_dereq_,module,exports){ +},{"../constants":96,"../core/component":104,"../utils/":177,"../utils/bind":171,"../utils/tracked-controls":183}],96:[function(_dereq_,module,exports){ module.exports = { AFRAME_INJECTED: 'aframe-injected', DEFAULT_CAMERA_HEIGHT: 1.6, @@ -72468,7 +72144,7 @@ module.exports = { keyboardevent: _dereq_('./keyboardevent') }; -},{"./keyboardevent":100}],100:[function(_dereq_,module,exports){ +},{"./keyboardevent":97}],97:[function(_dereq_,module,exports){ module.exports = { // Tiny KeyboardEvent.code polyfill. KEYCODE_TO_CODE: { @@ -72483,7 +72159,7 @@ module.exports = { } }; -},{}],101:[function(_dereq_,module,exports){ +},{}],98:[function(_dereq_,module,exports){ var ANode = _dereq_('./a-node'); var bind = _dereq_('../utils/bind'); var debug = _dereq_('../utils/debug'); @@ -72748,7 +72424,7 @@ function inferResponseType (src) { } module.exports.inferResponseType = inferResponseType; -},{"../lib/three":157,"../utils/bind":174,"../utils/debug":176,"./a-node":105,"./a-register-element":106}],102:[function(_dereq_,module,exports){ +},{"../lib/three":154,"../utils/bind":171,"../utils/debug":173,"./a-node":102,"./a-register-element":103}],99:[function(_dereq_,module,exports){ var debug = _dereq_('../utils/debug'); var registerElement = _dereq_('./a-register-element').registerElement; @@ -72798,7 +72474,7 @@ module.exports = registerElement('a-cubemap', { }) }); -},{"../utils/debug":176,"./a-register-element":106}],103:[function(_dereq_,module,exports){ +},{"../utils/debug":173,"./a-register-element":103}],100:[function(_dereq_,module,exports){ var ANode = _dereq_('./a-node'); var COMPONENTS = _dereq_('./component').components; var registerElement = _dereq_('./a-register-element').registerElement; @@ -73644,7 +73320,7 @@ function getRotation (entityEl) { AEntity = registerElement('a-entity', {prototype: proto}); module.exports = AEntity; -},{"../lib/three":157,"../utils/":180,"./a-node":105,"./a-register-element":106,"./component":107}],104:[function(_dereq_,module,exports){ +},{"../lib/three":154,"../utils/":177,"./a-node":102,"./a-register-element":103,"./component":104}],101:[function(_dereq_,module,exports){ var ANode = _dereq_('./a-node'); var registerElement = _dereq_('./a-register-element').registerElement; var components = _dereq_('./component').components; @@ -73759,7 +73435,7 @@ module.exports = registerElement('a-mixin', { }) }); -},{"../utils":180,"./a-node":105,"./a-register-element":106,"./component":107}],105:[function(_dereq_,module,exports){ +},{"../utils":177,"./a-node":102,"./a-register-element":103,"./component":104}],102:[function(_dereq_,module,exports){ /* global CustomEvent, MutationObserver */ var registerElement = _dereq_('./a-register-element').registerElement; var isNode = _dereq_('./a-register-element').isNode; @@ -74067,7 +73743,7 @@ module.exports = registerElement('a-node', { }) }); -},{"../utils/":180,"./a-register-element":106}],106:[function(_dereq_,module,exports){ +},{"../utils/":177,"./a-register-element":103}],103:[function(_dereq_,module,exports){ /* ------------------------------------------------------------ ------------- WARNING WARNING WARNING WARNING -------------- @@ -74254,7 +73930,7 @@ function copyProperties (source, destination) { ANode = _dereq_('./a-node'); AEntity = _dereq_('./a-entity'); -},{"./a-entity":103,"./a-node":105,"document-register-element":13}],107:[function(_dereq_,module,exports){ +},{"./a-entity":100,"./a-node":102,"document-register-element":201}],104:[function(_dereq_,module,exports){ /* global Node */ var schema = _dereq_('./schema'); var scenes = _dereq_('./scene/scenes'); @@ -74951,7 +74627,7 @@ function isObjectOrArray (value) { return value && (value.constructor === Object || value.constructor === Array); } -},{"../utils/":180,"./scene/scenes":115,"./schema":117,"./system":119}],108:[function(_dereq_,module,exports){ +},{"../utils/":177,"./scene/scenes":112,"./schema":114,"./system":116}],105:[function(_dereq_,module,exports){ _dereq_('../../vendor/effects/EffectComposer'); _dereq_('../../vendor/effects/RenderPass'); @@ -75030,7 +74706,7 @@ module.exports.registerEffect = function (name, definition) { registerComponent('effect-' + name, proto); }; -},{"../../vendor/effects/EffectComposer":190,"../../vendor/effects/RenderPass":192,"../lib/three":157,"../utils/":180,"./component":107}],109:[function(_dereq_,module,exports){ +},{"../../vendor/effects/EffectComposer":187,"../../vendor/effects/RenderPass":189,"../lib/three":154,"../utils/":177,"./component":104}],106:[function(_dereq_,module,exports){ var schema = _dereq_('./schema'); var processSchema = schema.process; @@ -75104,7 +74780,7 @@ module.exports.registerGeometry = function (name, definition) { return NewGeometry; }; -},{"../lib/three":157,"./schema":117}],110:[function(_dereq_,module,exports){ +},{"../lib/three":154,"./schema":114}],107:[function(_dereq_,module,exports){ var coordinates = _dereq_('../utils/coordinates'); var debug = _dereq_('debug'); @@ -75328,7 +75004,7 @@ function isValidDefaultCoordinate (possibleCoordinates, dimensions) { } module.exports.isValidDefaultCoordinate = isValidDefaultCoordinate; -},{"../utils/coordinates":175,"debug":10}],111:[function(_dereq_,module,exports){ +},{"../utils/coordinates":172,"debug":199}],108:[function(_dereq_,module,exports){ /* global Promise, screen */ var initMetaTags = _dereq_('./metaTags').inject; var initWakelock = _dereq_('./wakelock'); @@ -76116,7 +75792,7 @@ function setupCanvas (sceneEl) { } module.exports.setupCanvas = setupCanvas; // For testing. -},{"../../lib/three":157,"../../utils/":180,"../a-entity":103,"../a-node":105,"../a-register-element":106,"../system":119,"./loadingScreen":112,"./metaTags":113,"./postMessage":114,"./scenes":115,"./wakelock":116}],112:[function(_dereq_,module,exports){ +},{"../../lib/three":154,"../../utils/":177,"../a-entity":100,"../a-node":102,"../a-register-element":103,"../system":116,"./loadingScreen":109,"./metaTags":110,"./postMessage":111,"./scenes":112,"./wakelock":113}],109:[function(_dereq_,module,exports){ /* global THREE */ var utils = _dereq_('../../utils/'); var styleParser = utils.styleParser; @@ -76224,7 +75900,7 @@ function setupTitle () { sceneEl.appendChild(titleEl); } -},{"../../utils/":180}],113:[function(_dereq_,module,exports){ +},{"../../utils/":177}],110:[function(_dereq_,module,exports){ var constants = _dereq_('../../constants/'); var extend = _dereq_('../../utils').extend; @@ -76305,7 +75981,7 @@ function createTag (tagObj) { return extend(meta, tagObj.attributes); } -},{"../../constants/":99,"../../utils":180}],114:[function(_dereq_,module,exports){ +},{"../../constants/":96,"../../utils":177}],111:[function(_dereq_,module,exports){ var bind = _dereq_('../../utils/bind'); var isIframed = _dereq_('../../utils/').isIframed; @@ -76338,13 +76014,13 @@ function postMessageAPIHandler (event) { } } -},{"../../utils/":180,"../../utils/bind":174}],115:[function(_dereq_,module,exports){ +},{"../../utils/":177,"../../utils/bind":171}],112:[function(_dereq_,module,exports){ /* Scene index for keeping track of created scenes. */ module.exports = []; -},{}],116:[function(_dereq_,module,exports){ +},{}],113:[function(_dereq_,module,exports){ var Wakelock = _dereq_('../../../vendor/wakelock/wakelock'); module.exports = function initWakelock (scene) { @@ -76355,7 +76031,7 @@ module.exports = function initWakelock (scene) { scene.addEventListener('exit-vr', function () { wakelock.release(); }); }; -},{"../../../vendor/wakelock/wakelock":201}],117:[function(_dereq_,module,exports){ +},{"../../../vendor/wakelock/wakelock":198}],114:[function(_dereq_,module,exports){ var utils = _dereq_('../utils/'); var PropertyTypes = _dereq_('./propertyTypes'); @@ -76556,7 +76232,7 @@ function stringifyProperty (value, propDefinition) { } module.exports.stringifyProperty = stringifyProperty; -},{"../utils/":180,"./propertyTypes":110}],118:[function(_dereq_,module,exports){ +},{"../utils/":177,"./propertyTypes":107}],115:[function(_dereq_,module,exports){ var schema = _dereq_('./schema'); var processSchema = schema.process; @@ -76745,7 +76421,7 @@ module.exports.registerShader = function (name, definition) { return NewShader; }; -},{"../lib/three":157,"../utils":180,"./schema":117}],119:[function(_dereq_,module,exports){ +},{"../lib/three":154,"../utils":177,"./schema":114}],116:[function(_dereq_,module,exports){ var components = _dereq_('./component'); var schema = _dereq_('./schema'); var utils = _dereq_('../utils/'); @@ -76903,10 +76579,10 @@ module.exports.registerSystem = function (name, definition) { for (i = 0; i < scenes.length; i++) { scenes[i].initSystem(name); } }; -},{"../utils/":180,"./component":107,"./schema":117}],120:[function(_dereq_,module,exports){ +},{"../utils/":177,"./component":104,"./schema":114}],117:[function(_dereq_,module,exports){ _dereq_('./pivot'); -},{"./pivot":121}],121:[function(_dereq_,module,exports){ +},{"./pivot":118}],118:[function(_dereq_,module,exports){ var registerComponent = _dereq_('../../core/component').registerComponent; var THREE = _dereq_('../../lib/three'); @@ -76955,7 +76631,7 @@ registerComponent('pivot', { } }); -},{"../../core/component":107,"../../lib/three":157}],122:[function(_dereq_,module,exports){ +},{"../../core/component":104,"../../lib/three":154}],119:[function(_dereq_,module,exports){ /** * Common mesh defaults, mappings, and transforms. */ @@ -76982,7 +76658,7 @@ module.exports = function getMeshMixin () { }; }; -},{"../../core/component":107,"../../core/shader":118,"../../utils/":180}],123:[function(_dereq_,module,exports){ +},{"../../core/component":104,"../../core/shader":115,"../../utils/":177}],120:[function(_dereq_,module,exports){ _dereq_('./primitives/a-camera'); _dereq_('./primitives/a-collada-model'); _dereq_('./primitives/a-cursor'); @@ -76999,7 +76675,7 @@ _dereq_('./primitives/a-video'); _dereq_('./primitives/a-videosphere'); _dereq_('./primitives/meshPrimitives'); -},{"./primitives/a-camera":125,"./primitives/a-collada-model":126,"./primitives/a-cursor":127,"./primitives/a-curvedimage":128,"./primitives/a-gltf-model":129,"./primitives/a-image":130,"./primitives/a-light":131,"./primitives/a-link":132,"./primitives/a-obj-model":133,"./primitives/a-sky":134,"./primitives/a-sound":135,"./primitives/a-text":136,"./primitives/a-video":137,"./primitives/a-videosphere":138,"./primitives/meshPrimitives":139}],124:[function(_dereq_,module,exports){ +},{"./primitives/a-camera":122,"./primitives/a-collada-model":123,"./primitives/a-cursor":124,"./primitives/a-curvedimage":125,"./primitives/a-gltf-model":126,"./primitives/a-image":127,"./primitives/a-light":128,"./primitives/a-link":129,"./primitives/a-obj-model":130,"./primitives/a-sky":131,"./primitives/a-sound":132,"./primitives/a-text":133,"./primitives/a-video":134,"./primitives/a-videosphere":135,"./primitives/meshPrimitives":136}],121:[function(_dereq_,module,exports){ var AEntity = _dereq_('../../core/a-entity'); var components = _dereq_('../../core/component').components; var registerElement = _dereq_('../../core/a-register-element').registerElement; @@ -77198,7 +76874,7 @@ function definePrimitive (tagName, defaultComponents, mappings) { } module.exports.definePrimitive = definePrimitive; -},{"../../core/a-entity":103,"../../core/a-register-element":106,"../../core/component":107,"../../utils/":180}],125:[function(_dereq_,module,exports){ +},{"../../core/a-entity":100,"../../core/a-register-element":103,"../../core/component":104,"../../utils/":177}],122:[function(_dereq_,module,exports){ var registerPrimitive = _dereq_('../primitives').registerPrimitive; registerPrimitive('a-camera', { @@ -77222,7 +76898,7 @@ registerPrimitive('a-camera', { } }); -},{"../primitives":124}],126:[function(_dereq_,module,exports){ +},{"../primitives":121}],123:[function(_dereq_,module,exports){ var registerPrimitive = _dereq_('../primitives').registerPrimitive; registerPrimitive('a-collada-model', { @@ -77231,7 +76907,7 @@ registerPrimitive('a-collada-model', { } }); -},{"../primitives":124}],127:[function(_dereq_,module,exports){ +},{"../primitives":121}],124:[function(_dereq_,module,exports){ var getMeshMixin = _dereq_('../getMeshMixin'); var registerPrimitive = _dereq_('../primitives').registerPrimitive; var utils = _dereq_('../../../utils/'); @@ -77266,7 +76942,7 @@ registerPrimitive('a-cursor', utils.extendDeep({}, getMeshMixin(), { } })); -},{"../../../utils/":180,"../getMeshMixin":122,"../primitives":124}],128:[function(_dereq_,module,exports){ +},{"../../../utils/":177,"../getMeshMixin":119,"../primitives":121}],125:[function(_dereq_,module,exports){ var getMeshMixin = _dereq_('../getMeshMixin'); var registerPrimitive = _dereq_('../primitives').registerPrimitive; var utils = _dereq_('../../../utils/'); @@ -77303,7 +76979,7 @@ registerPrimitive('a-curvedimage', utils.extendDeep({}, getMeshMixin(), { } })); -},{"../../../utils/":180,"../getMeshMixin":122,"../primitives":124}],129:[function(_dereq_,module,exports){ +},{"../../../utils/":177,"../getMeshMixin":119,"../primitives":121}],126:[function(_dereq_,module,exports){ var registerPrimitive = _dereq_('../primitives').registerPrimitive; registerPrimitive('a-gltf-model', { @@ -77312,7 +76988,7 @@ registerPrimitive('a-gltf-model', { } }); -},{"../primitives":124}],130:[function(_dereq_,module,exports){ +},{"../primitives":121}],127:[function(_dereq_,module,exports){ var getMeshMixin = _dereq_('../getMeshMixin'); var registerPrimitive = _dereq_('../primitives').registerPrimitive; var utils = _dereq_('../../../utils/'); @@ -77336,7 +77012,7 @@ registerPrimitive('a-image', utils.extendDeep({}, getMeshMixin(), { } })); -},{"../../../utils/":180,"../getMeshMixin":122,"../primitives":124}],131:[function(_dereq_,module,exports){ +},{"../../../utils/":177,"../getMeshMixin":119,"../primitives":121}],128:[function(_dereq_,module,exports){ var registerPrimitive = _dereq_('../primitives').registerPrimitive; registerPrimitive('a-light', { @@ -77357,7 +77033,7 @@ registerPrimitive('a-light', { } }); -},{"../primitives":124}],132:[function(_dereq_,module,exports){ +},{"../primitives":121}],129:[function(_dereq_,module,exports){ var registerPrimitive = _dereq_('../primitives').registerPrimitive; registerPrimitive('a-link', { @@ -77370,7 +77046,7 @@ registerPrimitive('a-link', { } }); -},{"../primitives":124}],133:[function(_dereq_,module,exports){ +},{"../primitives":121}],130:[function(_dereq_,module,exports){ var meshMixin = _dereq_('../getMeshMixin')(); var registerPrimitive = _dereq_('../primitives').registerPrimitive; var utils = _dereq_('../../../utils/'); @@ -77386,7 +77062,7 @@ registerPrimitive('a-obj-model', utils.extendDeep({}, meshMixin, { } })); -},{"../../../utils/":180,"../getMeshMixin":122,"../primitives":124}],134:[function(_dereq_,module,exports){ +},{"../../../utils/":177,"../getMeshMixin":119,"../primitives":121}],131:[function(_dereq_,module,exports){ var getMeshMixin = _dereq_('../getMeshMixin'); var registerPrimitive = _dereq_('../primitives').registerPrimitive; var utils = _dereq_('../../../utils/'); @@ -77412,7 +77088,7 @@ registerPrimitive('a-sky', utils.extendDeep({}, getMeshMixin(), { mappings: utils.extendDeep({}, meshPrimitives['a-sphere'].prototype.mappings) })); -},{"../../../utils/":180,"../getMeshMixin":122,"../primitives":124,"./meshPrimitives":139}],135:[function(_dereq_,module,exports){ +},{"../../../utils/":177,"../getMeshMixin":119,"../primitives":121,"./meshPrimitives":136}],132:[function(_dereq_,module,exports){ var registerPrimitive = _dereq_('../primitives').registerPrimitive; registerPrimitive('a-sound', { @@ -77429,12 +77105,12 @@ registerPrimitive('a-sound', { } }); -},{"../primitives":124}],136:[function(_dereq_,module,exports){ +},{"../primitives":121}],133:[function(_dereq_,module,exports){ // using `definePrimitive` helper. var definePrimitive = _dereq_('../primitives').definePrimitive; definePrimitive('a-text', {text: {anchor: 'align', width: 5}}); -},{"../primitives":124}],137:[function(_dereq_,module,exports){ +},{"../primitives":121}],134:[function(_dereq_,module,exports){ var getMeshMixin = _dereq_('../getMeshMixin'); var registerPrimitive = _dereq_('../primitives').registerPrimitive; var utils = _dereq_('../../../utils/'); @@ -77458,7 +77134,7 @@ registerPrimitive('a-video', utils.extendDeep({}, getMeshMixin(), { } })); -},{"../../../utils/":180,"../getMeshMixin":122,"../primitives":124}],138:[function(_dereq_,module,exports){ +},{"../../../utils/":177,"../getMeshMixin":119,"../primitives":121}],135:[function(_dereq_,module,exports){ var getMeshMixin = _dereq_('../getMeshMixin'); var registerPrimitive = _dereq_('../primitives').registerPrimitive; var utils = _dereq_('../../../utils/'); @@ -77487,7 +77163,7 @@ registerPrimitive('a-videosphere', utils.extendDeep({}, getMeshMixin(), { } })); -},{"../../../utils/":180,"../getMeshMixin":122,"../primitives":124}],139:[function(_dereq_,module,exports){ +},{"../../../utils/":177,"../getMeshMixin":119,"../primitives":121}],136:[function(_dereq_,module,exports){ /** * Automated mesh primitive registration. */ @@ -77527,7 +77203,7 @@ function unCamelCase (str) { return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); } -},{"../../../core/geometry":109,"../../../utils/":180,"../getMeshMixin":122,"../primitives":124}],140:[function(_dereq_,module,exports){ +},{"../../../core/geometry":106,"../../../utils/":177,"../getMeshMixin":119,"../primitives":121}],137:[function(_dereq_,module,exports){ var registerGeometry = _dereq_('../core/geometry').registerGeometry; var THREE = _dereq_('../lib/three'); @@ -77548,7 +77224,7 @@ registerGeometry('box', { } }); -},{"../core/geometry":109,"../lib/three":157}],141:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../lib/three":154}],138:[function(_dereq_,module,exports){ var registerGeometry = _dereq_('../core/geometry').registerGeometry; var THREE = _dereq_('../lib/three'); @@ -77568,7 +77244,7 @@ registerGeometry('circle', { } }); -},{"../core/geometry":109,"../lib/three":157}],142:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../lib/three":154}],139:[function(_dereq_,module,exports){ var registerGeometry = _dereq_('../core/geometry').registerGeometry; var THREE = _dereq_('../lib/three'); @@ -77594,7 +77270,7 @@ registerGeometry('cone', { } }); -},{"../core/geometry":109,"../lib/three":157}],143:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../lib/three":154}],140:[function(_dereq_,module,exports){ var registerGeometry = _dereq_('../core/geometry').registerGeometry; var THREE = _dereq_('../lib/three'); @@ -77618,7 +77294,7 @@ registerGeometry('cylinder', { } }); -},{"../core/geometry":109,"../lib/three":157}],144:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../lib/three":154}],141:[function(_dereq_,module,exports){ var registerGeometry = _dereq_('../core/geometry').registerGeometry; var THREE = _dereq_('../lib/three'); @@ -77633,7 +77309,7 @@ registerGeometry('dodecahedron', { } }); -},{"../core/geometry":109,"../lib/three":157}],145:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../lib/three":154}],142:[function(_dereq_,module,exports){ var registerGeometry = _dereq_('../core/geometry').registerGeometry; var THREE = _dereq_('../lib/three'); @@ -77648,7 +77324,7 @@ registerGeometry('icosahedron', { } }); -},{"../core/geometry":109,"../lib/three":157}],146:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../lib/three":154}],143:[function(_dereq_,module,exports){ _dereq_('./box.js'); _dereq_('./circle.js'); _dereq_('./cone.js'); @@ -77664,7 +77340,7 @@ _dereq_('./torus.js'); _dereq_('./torusKnot.js'); _dereq_('./triangle.js'); -},{"./box.js":140,"./circle.js":141,"./cone.js":142,"./cylinder.js":143,"./dodecahedron.js":144,"./icosahedron.js":145,"./octahedron.js":147,"./plane.js":148,"./ring.js":149,"./sphere.js":150,"./tetrahedron.js":151,"./torus.js":152,"./torusKnot.js":153,"./triangle.js":154}],147:[function(_dereq_,module,exports){ +},{"./box.js":137,"./circle.js":138,"./cone.js":139,"./cylinder.js":140,"./dodecahedron.js":141,"./icosahedron.js":142,"./octahedron.js":144,"./plane.js":145,"./ring.js":146,"./sphere.js":147,"./tetrahedron.js":148,"./torus.js":149,"./torusKnot.js":150,"./triangle.js":151}],144:[function(_dereq_,module,exports){ var registerGeometry = _dereq_('../core/geometry').registerGeometry; var THREE = _dereq_('../lib/three'); @@ -77679,7 +77355,7 @@ registerGeometry('octahedron', { } }); -},{"../core/geometry":109,"../lib/three":157}],148:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../lib/three":154}],145:[function(_dereq_,module,exports){ var registerGeometry = _dereq_('../core/geometry').registerGeometry; var THREE = _dereq_('../lib/three'); @@ -77696,7 +77372,7 @@ registerGeometry('plane', { } }); -},{"../core/geometry":109,"../lib/three":157}],149:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../lib/three":154}],146:[function(_dereq_,module,exports){ var registerGeometry = _dereq_('../core/geometry').registerGeometry; var THREE = _dereq_('../lib/three'); @@ -77719,7 +77395,7 @@ registerGeometry('ring', { } }); -},{"../core/geometry":109,"../lib/three":157}],150:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../lib/three":154}],147:[function(_dereq_,module,exports){ var registerGeometry = _dereq_('../core/geometry').registerGeometry; var THREE = _dereq_('../lib/three'); @@ -77743,7 +77419,7 @@ registerGeometry('sphere', { } }); -},{"../core/geometry":109,"../lib/three":157}],151:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../lib/three":154}],148:[function(_dereq_,module,exports){ var registerGeometry = _dereq_('../core/geometry').registerGeometry; var THREE = _dereq_('../lib/three'); @@ -77758,7 +77434,7 @@ registerGeometry('tetrahedron', { } }); -},{"../core/geometry":109,"../lib/three":157}],152:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../lib/three":154}],149:[function(_dereq_,module,exports){ var registerGeometry = _dereq_('../core/geometry').registerGeometry; var THREE = _dereq_('../lib/three'); @@ -77780,7 +77456,7 @@ registerGeometry('torus', { } }); -},{"../core/geometry":109,"../lib/three":157}],153:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../lib/three":154}],150:[function(_dereq_,module,exports){ var registerGeometry = _dereq_('../core/geometry').registerGeometry; var THREE = _dereq_('../lib/three'); @@ -77801,7 +77477,7 @@ registerGeometry('torusKnot', { } }); -},{"../core/geometry":109,"../lib/three":157}],154:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../lib/three":154}],151:[function(_dereq_,module,exports){ var registerGeometry = _dereq_('../core/geometry').registerGeometry; var THREE = _dereq_('../lib/three'); @@ -77856,7 +77532,7 @@ registerGeometry('triangle', { } }); -},{"../core/geometry":109,"../lib/three":157}],155:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../lib/three":154}],152:[function(_dereq_,module,exports){ // Check before the polyfill runs. window.hasNativeWebVRImplementation = !!window.navigator.getVRDisplays || !!window.navigator.getVRDevices; @@ -77937,7 +77613,7 @@ _dereq_('./core/a-mixin'); _dereq_('./extras/components/'); _dereq_('./extras/primitives/'); -console.log('A-Frame Version: 0.8.2 (Date 2018-10-10, Commit #1ab59cd99)'); +console.log('A-Frame Version: 0.8.2 (Date 2018-10-12, Commit #6849534f)'); console.log('three Version:', pkg.dependencies['three']); console.log('WebVR Polyfill Version:', pkg.dependencies['webvr-polyfill']); @@ -77968,7 +77644,7 @@ module.exports = window.AFRAME = { version: pkg.version }; -},{"../package":51,"./components/index":61,"./core/a-assets":101,"./core/a-cubemap":102,"./core/a-entity":103,"./core/a-mixin":104,"./core/a-node":105,"./core/a-register-element":106,"./core/component":107,"./core/geometry":109,"./core/scene/a-scene":111,"./core/scene/scenes":115,"./core/schema":117,"./core/shader":118,"./core/system":119,"./extras/components/":120,"./extras/primitives/":123,"./extras/primitives/getMeshMixin":122,"./extras/primitives/primitives":124,"./geometries/index":146,"./lib/three":157,"./shaders/index":159,"./style/aframe.css":164,"./style/rStats.css":165,"./systems/index":169,"./utils/":180,"animejs":2,"present":32,"promise-polyfill":33,"webvr-polyfill":46}],156:[function(_dereq_,module,exports){ +},{"../package":48,"./components/index":58,"./core/a-assets":98,"./core/a-cubemap":99,"./core/a-entity":100,"./core/a-mixin":101,"./core/a-node":102,"./core/a-register-element":103,"./core/component":104,"./core/geometry":106,"./core/scene/a-scene":108,"./core/scene/scenes":112,"./core/schema":114,"./core/shader":115,"./core/system":116,"./extras/components/":117,"./extras/primitives/":120,"./extras/primitives/getMeshMixin":119,"./extras/primitives/primitives":121,"./geometries/index":143,"./lib/three":154,"./shaders/index":156,"./style/aframe.css":161,"./style/rStats.css":162,"./systems/index":166,"./utils/":177,"animejs":2,"present":29,"promise-polyfill":30,"webvr-polyfill":43}],153:[function(_dereq_,module,exports){ window.aframeStats = function (scene) { var _rS = null; var _scene = scene; @@ -78025,7 +77701,7 @@ if (typeof module === 'object') { }; } -},{}],157:[function(_dereq_,module,exports){ +},{}],154:[function(_dereq_,module,exports){ (function (global){ var THREE = global.THREE = _dereq_('three'); @@ -78065,7 +77741,7 @@ module.exports = THREE; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../../vendor/VRControls":187,"../../vendor/VREffect":188,"three":39,"three/examples/js/loaders/ColladaLoader":40,"three/examples/js/loaders/DRACOLoader":41,"three/examples/js/loaders/GLTFLoader":42,"three/examples/js/loaders/MTLLoader":43,"three/examples/js/loaders/OBJLoader":44}],158:[function(_dereq_,module,exports){ +},{"../../vendor/VRControls":184,"../../vendor/VREffect":185,"three":36,"three/examples/js/loaders/ColladaLoader":37,"three/examples/js/loaders/DRACOLoader":38,"three/examples/js/loaders/GLTFLoader":39,"three/examples/js/loaders/MTLLoader":40,"three/examples/js/loaders/OBJLoader":41}],155:[function(_dereq_,module,exports){ var registerShader = _dereq_('../core/shader').registerShader; var THREE = _dereq_('../lib/three'); var utils = _dereq_('../utils/'); @@ -78132,14 +77808,14 @@ function getMaterialData (data, materialData) { return materialData; } -},{"../core/shader":118,"../lib/three":157,"../utils/":180}],159:[function(_dereq_,module,exports){ +},{"../core/shader":115,"../lib/three":154,"../utils/":177}],156:[function(_dereq_,module,exports){ _dereq_('./flat'); _dereq_('./standard'); _dereq_('./sdf'); _dereq_('./msdf'); _dereq_('./ios10hls'); -},{"./flat":158,"./ios10hls":160,"./msdf":161,"./sdf":162,"./standard":163}],160:[function(_dereq_,module,exports){ +},{"./flat":155,"./ios10hls":157,"./msdf":158,"./sdf":159,"./standard":160}],157:[function(_dereq_,module,exports){ var registerShader = _dereq_('../core/shader').registerShader; /** @@ -78174,7 +77850,7 @@ module.exports.Shader = registerShader('ios10hls', { }); -},{"../core/shader":118}],161:[function(_dereq_,module,exports){ +},{"../core/shader":115}],158:[function(_dereq_,module,exports){ var registerShader = _dereq_('../core/shader').registerShader; /** @@ -78242,7 +77918,7 @@ module.exports.Shader = registerShader('msdf', { ].join('\n') }); -},{"../core/shader":118}],162:[function(_dereq_,module,exports){ +},{"../core/shader":115}],159:[function(_dereq_,module,exports){ var registerShader = _dereq_('../core/shader').registerShader; /** @@ -78349,7 +78025,7 @@ module.exports.Shader = registerShader('sdf', { ].join('\n') }); -},{"../core/shader":118}],163:[function(_dereq_,module,exports){ +},{"../core/shader":115}],160:[function(_dereq_,module,exports){ var registerShader = _dereq_('../core/shader').registerShader; var THREE = _dereq_('../lib/three'); var utils = _dereq_('../utils/'); @@ -78536,11 +78212,11 @@ function getMaterialData (data, materialData) { return materialData; } -},{"../core/shader":118,"../lib/three":157,"../utils/":180}],164:[function(_dereq_,module,exports){ -var css = ".a-html{bottom:0;left:0;position:fixed;right:0;top:0}.a-body{height:100%;margin:0;overflow:hidden;padding:0;width:100%}:-webkit-full-screen{background-color:transparent}.a-hidden{display:none!important}.a-canvas{height:100%;left:0;position:absolute;top:0;width:100%}.a-canvas.a-grab-cursor:hover{cursor:grab;cursor:-moz-grab;cursor:-webkit-grab}.a-canvas.a-grab-cursor:active,.a-grabbing{cursor:grabbing;cursor:-moz-grabbing;cursor:-webkit-grabbing}a-scene.fullscreen .a-canvas{width:100%!important;height:100%!important;top:0!important;left:0!important;right:0!important;bottom:0!important;position:fixed!important}.a-inspector-loader{background-color:#ed3160;position:fixed;left:3px;top:3px;padding:6px 10px;color:#fff;text-decoration:none;font-size:12px;font-family:Roboto,sans-serif;text-align:center;z-index:99999;width:204px}@keyframes dots-1{from{opacity:0}25%{opacity:1}}@keyframes dots-2{from{opacity:0}50%{opacity:1}}@keyframes dots-3{from{opacity:0}75%{opacity:1}}@-webkit-keyframes dots-1{from{opacity:0}25%{opacity:1}}@-webkit-keyframes dots-2{from{opacity:0}50%{opacity:1}}@-webkit-keyframes dots-3{from{opacity:0}75%{opacity:1}}.a-inspector-loader .dots span{animation:dots-1 2s infinite steps(1);-webkit-animation:dots-1 2s infinite steps(1)}.a-inspector-loader .dots span:first-child+span{animation-name:dots-2;-webkit-animation-name:dots-2}.a-inspector-loader .dots span:first-child+span+span{animation-name:dots-3;-webkit-animation-name:dots-3}a-scene{display:block;position:relative;height:100%;width:100%}a-assets,a-scene audio,a-scene img,a-scene video{display:none}.a-enter-vr-modal,.a-orientation-modal{font-family:Consolas,Andale Mono,Courier New,monospace}.a-enter-vr-modal a{border-bottom:1px solid #fff;padding:2px 0;text-decoration:none;transition:.1s color ease-in}.a-enter-vr-modal a:hover{background-color:#fff;color:#111;padding:2px 4px;position:relative;left:-4px}.a-enter-vr{font-family:sans-serif,monospace;font-size:13px;width:100%;font-weight:200;line-height:16px;position:absolute;right:20px;bottom:20px}.a-enter-vr.embedded{right:5px;bottom:5px}.a-enter-vr-button,.a-enter-vr-modal,.a-enter-vr-modal a{color:#fff}.a-enter-vr-button{background:url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20245.82%20141.73%22%3E%3Cdefs%3E%3Cstyle%3E.a%7Bfill%3A%23fff%3Bfill-rule%3Aevenodd%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Emask%3C%2Ftitle%3E%3Cpath%20class%3D%22a%22%20d%3D%22M175.56%2C111.37c-22.52%2C0-40.77-18.84-40.77-42.07S153%2C27.24%2C175.56%2C27.24s40.77%2C18.84%2C40.77%2C42.07S198.08%2C111.37%2C175.56%2C111.37ZM26.84%2C69.31c0-23.23%2C18.25-42.07%2C40.77-42.07s40.77%2C18.84%2C40.77%2C42.07-18.26%2C42.07-40.77%2C42.07S26.84%2C92.54%2C26.84%2C69.31ZM27.27%2C0C11.54%2C0%2C0%2C12.34%2C0%2C28.58V110.9c0%2C16.24%2C11.54%2C30.83%2C27.27%2C30.83H99.57c2.17%2C0%2C4.19-1.83%2C5.4-3.7L116.47%2C118a8%2C8%2C0%2C0%2C1%2C12.52-.18l11.51%2C20.34c1.2%2C1.86%2C3.22%2C3.61%2C5.39%2C3.61h72.29c15.74%2C0%2C27.63-14.6%2C27.63-30.83V28.58C245.82%2C12.34%2C233.93%2C0%2C218.19%2C0H27.27Z%22%2F%3E%3C%2Fsvg%3E) 50% 50%/70% 70% no-repeat rgba(0,0,0,.35);border:0;bottom:0;cursor:pointer;min-width:50px;min-height:30px;padding-right:5%;padding-top:4%;position:absolute;right:0;transition:background-color .05s ease;-webkit-transition:background-color .05s ease;z-index:9999}.a-enter-vr-button:active,.a-enter-vr-button:hover{background-color:#666}[data-a-enter-vr-no-webvr] .a-enter-vr-button{border-color:#666;opacity:.65}[data-a-enter-vr-no-webvr] .a-enter-vr-button:active,[data-a-enter-vr-no-webvr] .a-enter-vr-button:hover{background-color:rgba(0,0,0,.35);cursor:not-allowed}.a-enter-vr-modal{background-color:#666;border-radius:0;display:none;min-height:32px;margin-right:70px;padding:9px;width:280px;right:2%;position:absolute}.a-enter-vr-modal:after{border-bottom:10px solid transparent;border-left:10px solid #666;border-top:10px solid transparent;display:inline-block;content:'';position:absolute;right:-5px;top:5px;width:0;height:0}.a-enter-vr-modal a,.a-enter-vr-modal p{display:inline}.a-enter-vr-modal p{margin:0}.a-enter-vr-modal p:after{content:' '}[data-a-enter-vr-no-headset].a-enter-vr:hover .a-enter-vr-modal,[data-a-enter-vr-no-webvr].a-enter-vr:hover .a-enter-vr-modal{display:block}.a-orientation-modal{background:url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20version%3D%221.1%22%20x%3D%220px%22%20y%3D%220px%22%20viewBox%3D%220%200%2090%2090%22%20enable-background%3D%22new%200%200%2090%2090%22%20xml%3Aspace%3D%22preserve%22%3E%3Cpolygon%20points%3D%220%2C0%200%2C0%200%2C0%20%22%3E%3C/polygon%3E%3Cg%3E%3Cpath%20d%3D%22M71.545%2C48.145h-31.98V20.743c0-2.627-2.138-4.765-4.765-4.765H18.456c-2.628%2C0-4.767%2C2.138-4.767%2C4.765v42.789%20%20%20c0%2C2.628%2C2.138%2C4.766%2C4.767%2C4.766h5.535v0.959c0%2C2.628%2C2.138%2C4.765%2C4.766%2C4.765h42.788c2.628%2C0%2C4.766-2.137%2C4.766-4.765V52.914%20%20%20C76.311%2C50.284%2C74.173%2C48.145%2C71.545%2C48.145z%20M18.455%2C16.935h16.344c2.1%2C0%2C3.808%2C1.708%2C3.808%2C3.808v27.401H37.25V22.636%20%20%20c0-0.264-0.215-0.478-0.479-0.478H16.482c-0.264%2C0-0.479%2C0.214-0.479%2C0.478v36.585c0%2C0.264%2C0.215%2C0.478%2C0.479%2C0.478h7.507v7.644%20%20%20h-5.534c-2.101%2C0-3.81-1.709-3.81-3.81V20.743C14.645%2C18.643%2C16.354%2C16.935%2C18.455%2C16.935z%20M16.96%2C23.116h19.331v25.031h-7.535%20%20%20c-2.628%2C0-4.766%2C2.139-4.766%2C4.768v5.828h-7.03V23.116z%20M71.545%2C73.064H28.757c-2.101%2C0-3.81-1.708-3.81-3.808V52.914%20%20%20c0-2.102%2C1.709-3.812%2C3.81-3.812h42.788c2.1%2C0%2C3.809%2C1.71%2C3.809%2C3.812v16.343C75.354%2C71.356%2C73.645%2C73.064%2C71.545%2C73.064z%22%3E%3C/path%3E%3Cpath%20d%3D%22M28.919%2C58.424c-1.466%2C0-2.659%2C1.193-2.659%2C2.66c0%2C1.466%2C1.193%2C2.658%2C2.659%2C2.658c1.468%2C0%2C2.662-1.192%2C2.662-2.658%20%20%20C31.581%2C59.617%2C30.387%2C58.424%2C28.919%2C58.424z%20M28.919%2C62.786c-0.939%2C0-1.703-0.764-1.703-1.702c0-0.939%2C0.764-1.704%2C1.703-1.704%20%20%20c0.94%2C0%2C1.705%2C0.765%2C1.705%2C1.704C30.623%2C62.022%2C29.858%2C62.786%2C28.919%2C62.786z%22%3E%3C/path%3E%3Cpath%20d%3D%22M69.654%2C50.461H33.069c-0.264%2C0-0.479%2C0.215-0.479%2C0.479v20.288c0%2C0.264%2C0.215%2C0.478%2C0.479%2C0.478h36.585%20%20%20c0.263%2C0%2C0.477-0.214%2C0.477-0.478V50.939C70.131%2C50.676%2C69.917%2C50.461%2C69.654%2C50.461z%20M69.174%2C51.417V70.75H33.548V51.417H69.174z%22%3E%3C/path%3E%3Cpath%20d%3D%22M45.201%2C30.296c6.651%2C0%2C12.233%2C5.351%2C12.551%2C11.977l-3.033-2.638c-0.193-0.165-0.507-0.142-0.675%2C0.048%20%20%20c-0.174%2C0.198-0.153%2C0.501%2C0.045%2C0.676l3.883%2C3.375c0.09%2C0.075%2C0.198%2C0.115%2C0.312%2C0.115c0.141%2C0%2C0.273-0.061%2C0.362-0.166%20%20%20l3.371-3.877c0.173-0.2%2C0.151-0.502-0.047-0.675c-0.194-0.166-0.508-0.144-0.676%2C0.048l-2.592%2C2.979%20%20%20c-0.18-3.417-1.629-6.605-4.099-9.001c-2.538-2.461-5.877-3.817-9.404-3.817c-0.264%2C0-0.479%2C0.215-0.479%2C0.479%20%20%20C44.72%2C30.083%2C44.936%2C30.296%2C45.201%2C30.296z%22%3E%3C/path%3E%3C/g%3E%3C/svg%3E) center/50% 50% no-repeat rgba(244,244,244,1);bottom:0;font-size:14px;font-weight:600;left:0;line-height:20px;right:0;position:fixed;top:0;z-index:9999999}.a-orientation-modal:after{color:#666;content:\"Insert phone into Cardboard holder.\";display:block;position:absolute;text-align:center;top:70%;transform:translateY(-70%);width:100%}.a-orientation-modal button{background:url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20version%3D%221.1%22%20x%3D%220px%22%20y%3D%220px%22%20viewBox%3D%220%200%20100%20100%22%20enable-background%3D%22new%200%200%20100%20100%22%20xml%3Aspace%3D%22preserve%22%3E%3Cpath%20fill%3D%22%23000000%22%20d%3D%22M55.209%2C50l17.803-17.803c1.416-1.416%2C1.416-3.713%2C0-5.129c-1.416-1.417-3.713-1.417-5.129%2C0L50.08%2C44.872%20%20L32.278%2C27.069c-1.416-1.417-3.714-1.417-5.129%2C0c-1.417%2C1.416-1.417%2C3.713%2C0%2C5.129L44.951%2C50L27.149%2C67.803%20%20c-1.417%2C1.416-1.417%2C3.713%2C0%2C5.129c0.708%2C0.708%2C1.636%2C1.062%2C2.564%2C1.062c0.928%2C0%2C1.856-0.354%2C2.564-1.062L50.08%2C55.13l17.803%2C17.802%20%20c0.708%2C0.708%2C1.637%2C1.062%2C2.564%2C1.062s1.856-0.354%2C2.564-1.062c1.416-1.416%2C1.416-3.713%2C0-5.129L55.209%2C50z%22%3E%3C/path%3E%3C/svg%3E) no-repeat;border:none;height:50px;text-indent:-9999px;width:50px}.a-loader-title{background-color:rgba(0,0,0,.6);font-family:sans-serif,monospace;text-align:center;font-size:20px;height:50px;font-weight:300;line-height:50px;position:absolute;right:0;left:0;top:0;color:#fff}"; (_dereq_("browserify-css").createStyle(css, { "href": "src\\style\\aframe.css"})); module.exports = css; -},{"browserify-css":5}],165:[function(_dereq_,module,exports){ -var css = ".rs-base{background-color:#333;color:#fafafa;border-radius:0;font:10px monospace;left:5px;line-height:1em;opacity:.85;overflow:hidden;padding:10px;position:fixed;top:5px;width:300px;z-index:10000}.rs-base div.hidden{display:none}.rs-base h1{color:#fff;cursor:pointer;font-size:1.4em;font-weight:300;margin:0 0 5px;padding:0}.rs-group{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-direction:column-reverse;flex-direction:column-reverse;margin-bottom:5px}.rs-group:last-child{margin-bottom:0}.rs-counter-base{align-items:center;display:-webkit-box;display:-webkit-flex;display:flex;height:10px;-webkit-justify-content:space-between;justify-content:space-between;margin:2px 0}.rs-counter-base.alarm{color:#b70000;text-shadow:0 0 0 #b70000,0 0 1px #fff,0 0 1px #fff,0 0 2px #fff,0 0 2px #fff,0 0 3px #fff,0 0 3px #fff,0 0 4px #fff,0 0 4px #fff}.rs-counter-id{font-weight:300;-webkit-box-ordinal-group:0;-webkit-order:0;order:0;width:54px}.rs-counter-value{font-weight:300;-webkit-box-ordinal-group:1;-webkit-order:1;order:1;text-align:right;width:35px}.rs-canvas{-webkit-box-ordinal-group:2;-webkit-order:2;order:2}@media (min-width:480px){.rs-base{left:20px;top:20px}}"; (_dereq_("browserify-css").createStyle(css, { "href": "src\\style\\rStats.css"})); module.exports = css; -},{"browserify-css":5}],166:[function(_dereq_,module,exports){ +},{"../core/shader":115,"../lib/three":154,"../utils/":177}],161:[function(_dereq_,module,exports){ +var css = ".a-html{bottom:0;left:0;position:fixed;right:0;top:0}.a-body{height:100%;margin:0;overflow:hidden;padding:0;width:100%}:-webkit-full-screen{background-color:transparent}.a-hidden{display:none!important}.a-canvas{height:100%;left:0;position:absolute;top:0;width:100%}.a-canvas.a-grab-cursor:hover{cursor:grab;cursor:-moz-grab;cursor:-webkit-grab}.a-canvas.a-grab-cursor:active,.a-grabbing{cursor:grabbing;cursor:-moz-grabbing;cursor:-webkit-grabbing}a-scene.fullscreen .a-canvas{width:100%!important;height:100%!important;top:0!important;left:0!important;right:0!important;bottom:0!important;position:fixed!important}.a-inspector-loader{background-color:#ed3160;position:fixed;left:3px;top:3px;padding:6px 10px;color:#fff;text-decoration:none;font-size:12px;font-family:Roboto,sans-serif;text-align:center;z-index:99999;width:204px}@keyframes dots-1{from{opacity:0}25%{opacity:1}}@keyframes dots-2{from{opacity:0}50%{opacity:1}}@keyframes dots-3{from{opacity:0}75%{opacity:1}}@-webkit-keyframes dots-1{from{opacity:0}25%{opacity:1}}@-webkit-keyframes dots-2{from{opacity:0}50%{opacity:1}}@-webkit-keyframes dots-3{from{opacity:0}75%{opacity:1}}.a-inspector-loader .dots span{animation:dots-1 2s infinite steps(1);-webkit-animation:dots-1 2s infinite steps(1)}.a-inspector-loader .dots span:first-child+span{animation-name:dots-2;-webkit-animation-name:dots-2}.a-inspector-loader .dots span:first-child+span+span{animation-name:dots-3;-webkit-animation-name:dots-3}a-scene{display:block;position:relative;height:100%;width:100%}a-assets,a-scene audio,a-scene img,a-scene video{display:none}.a-enter-vr-modal,.a-orientation-modal{font-family:Consolas,Andale Mono,Courier New,monospace}.a-enter-vr-modal a{border-bottom:1px solid #fff;padding:2px 0;text-decoration:none;transition:.1s color ease-in}.a-enter-vr-modal a:hover{background-color:#fff;color:#111;padding:2px 4px;position:relative;left:-4px}.a-enter-vr{font-family:sans-serif,monospace;font-size:13px;width:100%;font-weight:200;line-height:16px;position:absolute;right:20px;bottom:20px}.a-enter-vr.embedded{right:5px;bottom:5px}.a-enter-vr-button,.a-enter-vr-modal,.a-enter-vr-modal a{color:#fff}.a-enter-vr-button{background:url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20245.82%20141.73%22%3E%3Cdefs%3E%3Cstyle%3E.a%7Bfill%3A%23fff%3Bfill-rule%3Aevenodd%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Emask%3C%2Ftitle%3E%3Cpath%20class%3D%22a%22%20d%3D%22M175.56%2C111.37c-22.52%2C0-40.77-18.84-40.77-42.07S153%2C27.24%2C175.56%2C27.24s40.77%2C18.84%2C40.77%2C42.07S198.08%2C111.37%2C175.56%2C111.37ZM26.84%2C69.31c0-23.23%2C18.25-42.07%2C40.77-42.07s40.77%2C18.84%2C40.77%2C42.07-18.26%2C42.07-40.77%2C42.07S26.84%2C92.54%2C26.84%2C69.31ZM27.27%2C0C11.54%2C0%2C0%2C12.34%2C0%2C28.58V110.9c0%2C16.24%2C11.54%2C30.83%2C27.27%2C30.83H99.57c2.17%2C0%2C4.19-1.83%2C5.4-3.7L116.47%2C118a8%2C8%2C0%2C0%2C1%2C12.52-.18l11.51%2C20.34c1.2%2C1.86%2C3.22%2C3.61%2C5.39%2C3.61h72.29c15.74%2C0%2C27.63-14.6%2C27.63-30.83V28.58C245.82%2C12.34%2C233.93%2C0%2C218.19%2C0H27.27Z%22%2F%3E%3C%2Fsvg%3E) 50% 50%/70% 70% no-repeat rgba(0,0,0,.35);border:0;bottom:0;cursor:pointer;min-width:50px;min-height:30px;padding-right:5%;padding-top:4%;position:absolute;right:0;transition:background-color .05s ease;-webkit-transition:background-color .05s ease;z-index:9999}.a-enter-vr-button:active,.a-enter-vr-button:hover{background-color:#666}[data-a-enter-vr-no-webvr] .a-enter-vr-button{border-color:#666;opacity:.65}[data-a-enter-vr-no-webvr] .a-enter-vr-button:active,[data-a-enter-vr-no-webvr] .a-enter-vr-button:hover{background-color:rgba(0,0,0,.35);cursor:not-allowed}.a-enter-vr-modal{background-color:#666;border-radius:0;display:none;min-height:32px;margin-right:70px;padding:9px;width:280px;right:2%;position:absolute}.a-enter-vr-modal:after{border-bottom:10px solid transparent;border-left:10px solid #666;border-top:10px solid transparent;display:inline-block;content:'';position:absolute;right:-5px;top:5px;width:0;height:0}.a-enter-vr-modal a,.a-enter-vr-modal p{display:inline}.a-enter-vr-modal p{margin:0}.a-enter-vr-modal p:after{content:' '}[data-a-enter-vr-no-headset].a-enter-vr:hover .a-enter-vr-modal,[data-a-enter-vr-no-webvr].a-enter-vr:hover .a-enter-vr-modal{display:block}.a-orientation-modal{background:url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20version%3D%221.1%22%20x%3D%220px%22%20y%3D%220px%22%20viewBox%3D%220%200%2090%2090%22%20enable-background%3D%22new%200%200%2090%2090%22%20xml%3Aspace%3D%22preserve%22%3E%3Cpolygon%20points%3D%220%2C0%200%2C0%200%2C0%20%22%3E%3C/polygon%3E%3Cg%3E%3Cpath%20d%3D%22M71.545%2C48.145h-31.98V20.743c0-2.627-2.138-4.765-4.765-4.765H18.456c-2.628%2C0-4.767%2C2.138-4.767%2C4.765v42.789%20%20%20c0%2C2.628%2C2.138%2C4.766%2C4.767%2C4.766h5.535v0.959c0%2C2.628%2C2.138%2C4.765%2C4.766%2C4.765h42.788c2.628%2C0%2C4.766-2.137%2C4.766-4.765V52.914%20%20%20C76.311%2C50.284%2C74.173%2C48.145%2C71.545%2C48.145z%20M18.455%2C16.935h16.344c2.1%2C0%2C3.808%2C1.708%2C3.808%2C3.808v27.401H37.25V22.636%20%20%20c0-0.264-0.215-0.478-0.479-0.478H16.482c-0.264%2C0-0.479%2C0.214-0.479%2C0.478v36.585c0%2C0.264%2C0.215%2C0.478%2C0.479%2C0.478h7.507v7.644%20%20%20h-5.534c-2.101%2C0-3.81-1.709-3.81-3.81V20.743C14.645%2C18.643%2C16.354%2C16.935%2C18.455%2C16.935z%20M16.96%2C23.116h19.331v25.031h-7.535%20%20%20c-2.628%2C0-4.766%2C2.139-4.766%2C4.768v5.828h-7.03V23.116z%20M71.545%2C73.064H28.757c-2.101%2C0-3.81-1.708-3.81-3.808V52.914%20%20%20c0-2.102%2C1.709-3.812%2C3.81-3.812h42.788c2.1%2C0%2C3.809%2C1.71%2C3.809%2C3.812v16.343C75.354%2C71.356%2C73.645%2C73.064%2C71.545%2C73.064z%22%3E%3C/path%3E%3Cpath%20d%3D%22M28.919%2C58.424c-1.466%2C0-2.659%2C1.193-2.659%2C2.66c0%2C1.466%2C1.193%2C2.658%2C2.659%2C2.658c1.468%2C0%2C2.662-1.192%2C2.662-2.658%20%20%20C31.581%2C59.617%2C30.387%2C58.424%2C28.919%2C58.424z%20M28.919%2C62.786c-0.939%2C0-1.703-0.764-1.703-1.702c0-0.939%2C0.764-1.704%2C1.703-1.704%20%20%20c0.94%2C0%2C1.705%2C0.765%2C1.705%2C1.704C30.623%2C62.022%2C29.858%2C62.786%2C28.919%2C62.786z%22%3E%3C/path%3E%3Cpath%20d%3D%22M69.654%2C50.461H33.069c-0.264%2C0-0.479%2C0.215-0.479%2C0.479v20.288c0%2C0.264%2C0.215%2C0.478%2C0.479%2C0.478h36.585%20%20%20c0.263%2C0%2C0.477-0.214%2C0.477-0.478V50.939C70.131%2C50.676%2C69.917%2C50.461%2C69.654%2C50.461z%20M69.174%2C51.417V70.75H33.548V51.417H69.174z%22%3E%3C/path%3E%3Cpath%20d%3D%22M45.201%2C30.296c6.651%2C0%2C12.233%2C5.351%2C12.551%2C11.977l-3.033-2.638c-0.193-0.165-0.507-0.142-0.675%2C0.048%20%20%20c-0.174%2C0.198-0.153%2C0.501%2C0.045%2C0.676l3.883%2C3.375c0.09%2C0.075%2C0.198%2C0.115%2C0.312%2C0.115c0.141%2C0%2C0.273-0.061%2C0.362-0.166%20%20%20l3.371-3.877c0.173-0.2%2C0.151-0.502-0.047-0.675c-0.194-0.166-0.508-0.144-0.676%2C0.048l-2.592%2C2.979%20%20%20c-0.18-3.417-1.629-6.605-4.099-9.001c-2.538-2.461-5.877-3.817-9.404-3.817c-0.264%2C0-0.479%2C0.215-0.479%2C0.479%20%20%20C44.72%2C30.083%2C44.936%2C30.296%2C45.201%2C30.296z%22%3E%3C/path%3E%3C/g%3E%3C/svg%3E) center/50% 50% no-repeat rgba(244,244,244,1);bottom:0;font-size:14px;font-weight:600;left:0;line-height:20px;right:0;position:fixed;top:0;z-index:9999999}.a-orientation-modal:after{color:#666;content:\"Insert phone into Cardboard holder.\";display:block;position:absolute;text-align:center;top:70%;transform:translateY(-70%);width:100%}.a-orientation-modal button{background:url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20version%3D%221.1%22%20x%3D%220px%22%20y%3D%220px%22%20viewBox%3D%220%200%20100%20100%22%20enable-background%3D%22new%200%200%20100%20100%22%20xml%3Aspace%3D%22preserve%22%3E%3Cpath%20fill%3D%22%23000000%22%20d%3D%22M55.209%2C50l17.803-17.803c1.416-1.416%2C1.416-3.713%2C0-5.129c-1.416-1.417-3.713-1.417-5.129%2C0L50.08%2C44.872%20%20L32.278%2C27.069c-1.416-1.417-3.714-1.417-5.129%2C0c-1.417%2C1.416-1.417%2C3.713%2C0%2C5.129L44.951%2C50L27.149%2C67.803%20%20c-1.417%2C1.416-1.417%2C3.713%2C0%2C5.129c0.708%2C0.708%2C1.636%2C1.062%2C2.564%2C1.062c0.928%2C0%2C1.856-0.354%2C2.564-1.062L50.08%2C55.13l17.803%2C17.802%20%20c0.708%2C0.708%2C1.637%2C1.062%2C2.564%2C1.062s1.856-0.354%2C2.564-1.062c1.416-1.416%2C1.416-3.713%2C0-5.129L55.209%2C50z%22%3E%3C/path%3E%3C/svg%3E) no-repeat;border:none;height:50px;text-indent:-9999px;width:50px}.a-loader-title{background-color:rgba(0,0,0,.6);font-family:sans-serif,monospace;text-align:center;font-size:20px;height:50px;font-weight:300;line-height:50px;position:absolute;right:0;left:0;top:0;color:#fff}"; (_dereq_("browserify-css").createStyle(css, { "href": "src/style/aframe.css"})); module.exports = css; +},{"browserify-css":5}],162:[function(_dereq_,module,exports){ +var css = ".rs-base{background-color:#333;color:#fafafa;border-radius:0;font:10px monospace;left:5px;line-height:1em;opacity:.85;overflow:hidden;padding:10px;position:fixed;top:5px;width:300px;z-index:10000}.rs-base div.hidden{display:none}.rs-base h1{color:#fff;cursor:pointer;font-size:1.4em;font-weight:300;margin:0 0 5px;padding:0}.rs-group{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-direction:column-reverse;flex-direction:column-reverse;margin-bottom:5px}.rs-group:last-child{margin-bottom:0}.rs-counter-base{align-items:center;display:-webkit-box;display:-webkit-flex;display:flex;height:10px;-webkit-justify-content:space-between;justify-content:space-between;margin:2px 0}.rs-counter-base.alarm{color:#b70000;text-shadow:0 0 0 #b70000,0 0 1px #fff,0 0 1px #fff,0 0 2px #fff,0 0 2px #fff,0 0 3px #fff,0 0 3px #fff,0 0 4px #fff,0 0 4px #fff}.rs-counter-id{font-weight:300;-webkit-box-ordinal-group:0;-webkit-order:0;order:0;width:54px}.rs-counter-value{font-weight:300;-webkit-box-ordinal-group:1;-webkit-order:1;order:1;text-align:right;width:35px}.rs-canvas{-webkit-box-ordinal-group:2;-webkit-order:2;order:2}@media (min-width:480px){.rs-base{left:20px;top:20px}}"; (_dereq_("browserify-css").createStyle(css, { "href": "src/style/rStats.css"})); module.exports = css; +},{"browserify-css":5}],163:[function(_dereq_,module,exports){ var constants = _dereq_('../constants/'); var registerSystem = _dereq_('../core/system').registerSystem; @@ -78814,7 +78490,7 @@ function removeDefaultCamera (sceneEl) { sceneEl.removeChild(defaultCamera); } -},{"../constants/":99,"../core/system":119}],167:[function(_dereq_,module,exports){ +},{"../constants/":96,"../core/system":116}],164:[function(_dereq_,module,exports){ var geometries = _dereq_('../core/geometry').geometries; var registerSystem = _dereq_('../core/system').registerSystem; var THREE = _dereq_('../lib/three'); @@ -78954,7 +78630,7 @@ function toBufferGeometry (geometry, doBuffer) { return bufferGeometry; } -},{"../core/geometry":109,"../core/system":119,"../lib/three":157}],168:[function(_dereq_,module,exports){ +},{"../core/geometry":106,"../core/system":116,"../lib/three":154}],165:[function(_dereq_,module,exports){ var registerSystem = _dereq_('../core/system').registerSystem; var THREE = _dereq_('../lib/three'); @@ -78982,7 +78658,7 @@ module.exports.System = registerSystem('gltf-model', { } }); -},{"../core/system":119,"../lib/three":157}],169:[function(_dereq_,module,exports){ +},{"../core/system":116,"../lib/three":154}],166:[function(_dereq_,module,exports){ _dereq_('./camera'); _dereq_('./geometry'); _dereq_('./gltf-model'); @@ -78991,7 +78667,7 @@ _dereq_('./material'); _dereq_('./shadow'); _dereq_('./tracked-controls'); -},{"./camera":166,"./geometry":167,"./gltf-model":168,"./light":170,"./material":171,"./shadow":172,"./tracked-controls":173}],170:[function(_dereq_,module,exports){ +},{"./camera":163,"./geometry":164,"./gltf-model":165,"./light":167,"./material":168,"./shadow":169,"./tracked-controls":170}],167:[function(_dereq_,module,exports){ var registerSystem = _dereq_('../core/system').registerSystem; var bind = _dereq_('../utils/bind'); var constants = _dereq_('../constants/'); @@ -79077,7 +78753,7 @@ module.exports.System = registerSystem('light', { } }); -},{"../constants/":99,"../core/system":119,"../utils/bind":174}],171:[function(_dereq_,module,exports){ +},{"../constants/":96,"../core/system":116,"../utils/bind":171}],168:[function(_dereq_,module,exports){ var registerSystem = _dereq_('../core/system').registerSystem; var THREE = _dereq_('../lib/three'); var utils = _dereq_('../utils/'); @@ -79482,7 +79158,7 @@ function fixVideoAttributes (videoEl) { return videoEl; } -},{"../core/system":119,"../lib/three":157,"../utils/":180,"../utils/material":181}],172:[function(_dereq_,module,exports){ +},{"../core/system":116,"../lib/three":154,"../utils/":177,"../utils/material":178}],169:[function(_dereq_,module,exports){ var registerSystem = _dereq_('../core/system').registerSystem; var THREE = _dereq_('../lib/three'); @@ -79530,7 +79206,7 @@ module.exports.System = registerSystem('shadow', { } }); -},{"../core/system":119,"../lib/three":157}],173:[function(_dereq_,module,exports){ +},{"../core/system":116,"../lib/three":154}],170:[function(_dereq_,module,exports){ var registerSystem = _dereq_('../core/system').registerSystem; var utils = _dereq_('../utils'); @@ -79589,7 +79265,7 @@ module.exports.System = registerSystem('tracked-controls', { } }); -},{"../core/system":119,"../utils":180}],174:[function(_dereq_,module,exports){ +},{"../core/system":116,"../utils":177}],171:[function(_dereq_,module,exports){ /** * Faster version of Function.prototype.bind * @param {Function} fn - Function to wrap. @@ -79606,7 +79282,7 @@ module.exports = function bind (fn, ctx/* , arg1, arg2 */) { })(Array.prototype.slice.call(arguments, 2)); }; -},{}],175:[function(_dereq_,module,exports){ +},{}],172:[function(_dereq_,module,exports){ /* global THREE */ var debug = _dereq_('./debug'); var extend = _dereq_('object-assign'); @@ -79704,7 +79380,7 @@ module.exports.toVector3 = function (vec3) { return new THREE.Vector3(vec3.x, vec3.y, vec3.z); }; -},{"./debug":176,"object-assign":26}],176:[function(_dereq_,module,exports){ +},{"./debug":173,"object-assign":23}],173:[function(_dereq_,module,exports){ (function (process){ var debugLib = _dereq_('debug'); var extend = _dereq_('object-assign'); @@ -79801,7 +79477,7 @@ module.exports = debug; }).call(this,_dereq_('_process')) -},{"_process":6,"debug":10,"object-assign":26}],177:[function(_dereq_,module,exports){ +},{"_process":6,"debug":199,"object-assign":23}],174:[function(_dereq_,module,exports){ (function (process){ var vrDisplay; @@ -79940,7 +79616,7 @@ module.exports.PolyfillControls = function PolyfillControls (object) { }).call(this,_dereq_('_process')) -},{"_process":6}],178:[function(_dereq_,module,exports){ +},{"_process":6}],175:[function(_dereq_,module,exports){ /** * Split a delimited component property string (e.g., `material.color`) to an object * containing `component` name and `property` name. If there is no delimiter, just return the @@ -80002,7 +79678,7 @@ module.exports.setComponentProperty = function (el, name, value, delimiter) { el.setAttribute(name, value); }; -},{}],179:[function(_dereq_,module,exports){ +},{}],176:[function(_dereq_,module,exports){ module.exports = function forceCanvasResizeSafariMobile (canvasEl) { var width = canvasEl.style.width; var height = canvasEl.style.height; @@ -80018,7 +79694,7 @@ module.exports = function forceCanvasResizeSafariMobile (canvasEl) { }, 200); }; -},{}],180:[function(_dereq_,module,exports){ +},{}],177:[function(_dereq_,module,exports){ /* global location */ /* Centralized place to reference utilities since utils is exposed to the user. */ @@ -80345,7 +80021,7 @@ module.exports.findAllScenes = function (el) { // Must be at bottom to avoid circular dependency. module.exports.srcLoader = _dereq_('./src-loader'); -},{"./bind":174,"./coordinates":175,"./debug":176,"./device":177,"./entity":178,"./forceCanvasResizeSafariMobile":179,"./material":181,"./object-pool":182,"./split":183,"./src-loader":184,"./styleParser":185,"./tracked-controls":186,"deep-assign":12,"object-assign":26}],181:[function(_dereq_,module,exports){ +},{"./bind":171,"./coordinates":172,"./debug":173,"./device":174,"./entity":175,"./forceCanvasResizeSafariMobile":176,"./material":178,"./object-pool":179,"./split":180,"./src-loader":181,"./styleParser":182,"./tracked-controls":183,"deep-assign":10,"object-assign":23}],178:[function(_dereq_,module,exports){ var THREE = _dereq_('../lib/three'); var HLS_MIMETYPES = ['application/x-mpegurl', 'application/vnd.apple.mpegurl']; @@ -80500,7 +80176,7 @@ module.exports.isHLS = function (src, type) { return false; }; -},{"../lib/three":157}],182:[function(_dereq_,module,exports){ +},{"../lib/three":154}],179:[function(_dereq_,module,exports){ /* Adapted deePool by Kyle Simpson. MIT License: http://getify.mit-license.org @@ -80580,7 +80256,7 @@ function clearObject (obj) { } module.exports.clearObject = clearObject; -},{}],183:[function(_dereq_,module,exports){ +},{}],180:[function(_dereq_,module,exports){ /** * String split with cached result. */ @@ -80597,7 +80273,7 @@ module.exports.split = (function () { }; })(); -},{}],184:[function(_dereq_,module,exports){ +},{}],181:[function(_dereq_,module,exports){ /* global Image, XMLHttpRequest */ var debug = _dereq_('./debug'); @@ -80756,7 +80432,7 @@ module.exports = { validateCubemapSrc: validateCubemapSrc }; -},{"./debug":176}],185:[function(_dereq_,module,exports){ +},{"./debug":173}],182:[function(_dereq_,module,exports){ /** * Utils for parsing style-like strings (e.g., "primitive: box; width: 5; height: 4.5"). * Some code adapted from `style-attr` (https://github.com/joshwnj/style-attr) @@ -80909,7 +80585,7 @@ function styleStringify (obj) { function upperCase (str) { return str[1].toUpperCase(); } -},{}],186:[function(_dereq_,module,exports){ +},{}],183:[function(_dereq_,module,exports){ var DEFAULT_HANDEDNESS = _dereq_('../constants').DEFAULT_HANDEDNESS; var AXIS_LABELS = ['x', 'y', 'z', 'w']; var NUM_HANDS = 2; // Number of hands in a pair. Should always be 2. @@ -81089,7 +80765,7 @@ module.exports.onButtonEvent = function (id, evtName, component, hand) { } }; -},{"../constants":99}],187:[function(_dereq_,module,exports){ +},{"../constants":96}],184:[function(_dereq_,module,exports){ /** * @author dmarcos / https://github.com/dmarcos * @author mrdoob / http://mrdoob.com @@ -81267,7 +80943,7 @@ THREE.VRControls = function ( object, onError ) { }; -},{}],188:[function(_dereq_,module,exports){ +},{}],185:[function(_dereq_,module,exports){ /** * @author dmarcos / https://github.com/dmarcos * @author mrdoob / http://mrdoob.com @@ -81297,7 +80973,7 @@ THREE.VREffect = function( renderer, onError ) { window.addEventListener('vrdisplayconnect', function (evt) { vrDisplay = evt.display; }); window.addEventListener('vrdisplaydisconnect', function (evt) { var f; - + scope.exitPresent(); // Cancels current request animation frame. f = scope.cancelAnimationFrame(); @@ -81786,7 +81462,7 @@ THREE.VREffect = function( renderer, onError ) { }; -},{}],189:[function(_dereq_,module,exports){ +},{}],186:[function(_dereq_,module,exports){ /** * @author alteredq / http://alteredqualia.com/ * @@ -81834,7 +81510,7 @@ THREE.CopyShader = { }; -},{}],190:[function(_dereq_,module,exports){ +},{}],187:[function(_dereq_,module,exports){ /** * @author alteredq / http://alteredqualia.com/ */ @@ -82039,7 +81715,7 @@ Object.assign( THREE.Pass.prototype, { } ); -},{}],191:[function(_dereq_,module,exports){ +},{}],188:[function(_dereq_,module,exports){ /** * @author bhouston / http://clara.io/ * @@ -82105,7 +81781,7 @@ THREE.LuminosityHighPassShader = { }; -},{}],192:[function(_dereq_,module,exports){ +},{}],189:[function(_dereq_,module,exports){ /** * @author alteredq / http://alteredqualia.com/ */ @@ -82170,7 +81846,7 @@ THREE.RenderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype } ); -},{}],193:[function(_dereq_,module,exports){ +},{}],190:[function(_dereq_,module,exports){ 'use strict'; /** @@ -82185,7 +81861,7 @@ THREE.RenderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype * - Ambient occlusion clamp (numeric value). * - lumInfluence * - Pixel luminosity influence in AO calculation (numeric value). - * + * * To output to screen set renderToScreens true * * @author alteredq / http://alteredqualia.com/ @@ -82219,7 +81895,7 @@ THREE.SSAOPass = function ( scene, camera, width, height ) { //Depth render target this.depthRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter } ); //this.depthRenderTarget.texture.name = 'SSAOShader.rt'; - + //Shader uniforms this.uniforms[ 'tDepth' ].value = this.depthRenderTarget.texture; this.uniforms[ 'size' ].value.set( this.width, this.height ); @@ -82262,7 +81938,7 @@ THREE.SSAOPass.prototype = Object.create( THREE.ShaderPass.prototype ); /** * Render using this pass. - * + * * @method render * @param {WebGLRenderer} renderer * @param {WebGLRenderTarget} writeBuffer Buffer to write output. @@ -82274,9 +81950,9 @@ THREE.SSAOPass.prototype.render = function( renderer, writeBuffer, readBuffer, d //Render depth into depthRenderTarget this.scene2.overrideMaterial = this.depthMaterial; - + renderer.render( this.scene2, this.camera2, this.depthRenderTarget, true ); - + this.scene2.overrideMaterial = null; @@ -82292,7 +81968,7 @@ THREE.SSAOPass.prototype.render = function( renderer, writeBuffer, readBuffer, d * @param {Scene} scene */ THREE.SSAOPass.prototype.setScene = function(scene) { - + this.scene2 = scene; }; @@ -82314,7 +81990,7 @@ THREE.SSAOPass.prototype.setCamera = function( camera ) { /** * Set resolution of this render pass. - * + * * @method setSize * @param {Number} width * @param {Number} height @@ -82329,7 +82005,7 @@ THREE.SSAOPass.prototype.setSize = function( width, height ) { }; -},{}],194:[function(_dereq_,module,exports){ +},{}],191:[function(_dereq_,module,exports){ /** * @author alteredq / http://alteredqualia.com/ * @@ -82564,7 +82240,7 @@ THREE.SSAOShader = { }; -},{}],195:[function(_dereq_,module,exports){ +},{}],192:[function(_dereq_,module,exports){ /** * @author alteredq / http://alteredqualia.com/ * @@ -82620,7 +82296,7 @@ THREE.SepiaShader = { }; -},{}],196:[function(_dereq_,module,exports){ +},{}],193:[function(_dereq_,module,exports){ /** * @author alteredq / http://alteredqualia.com/ */ @@ -82689,10 +82365,10 @@ THREE.ShaderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype } ); -},{}],197:[function(_dereq_,module,exports){ +},{}],194:[function(_dereq_,module,exports){ /** * @author spidersharma / http://eduperiment.com/ - * + * * Inspired from Unreal Engine * https://docs.unrealengine.com/latest/INT/Engine/Rendering/PostProcessEffects/Bloom/ */ @@ -83072,7 +82748,7 @@ THREE.UnrealBloomPass.prototype = Object.assign( Object.create( THREE.Pass.proto THREE.UnrealBloomPass.BlurDirectionX = new THREE.Vector2( 1.0, 0.0 ); THREE.UnrealBloomPass.BlurDirectionY = new THREE.Vector2( 0.0, 1.0 ); -},{}],198:[function(_dereq_,module,exports){ +},{}],195:[function(_dereq_,module,exports){ window.glStats = function () { var _rS = null; @@ -83333,7 +83009,7 @@ if (typeof module === 'object') { }; } -},{}],199:[function(_dereq_,module,exports){ +},{}],196:[function(_dereq_,module,exports){ // performance.now() polyfill from https://gist.github.com/paulirish/5438650 'use strict'; @@ -83788,7 +83464,7 @@ if (typeof module === 'object') { module.exports = window.rStats; } -},{}],200:[function(_dereq_,module,exports){ +},{}],197:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -83850,7 +83526,7 @@ Util.isLandscapeMode = function() { module.exports = Util; -},{}],201:[function(_dereq_,module,exports){ +},{}],198:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -83926,6 +83602,362 @@ function getWakeLock() { module.exports = getWakeLock(); -},{"./util.js":200}]},{},[155])(155) +},{"./util.js":197}],199:[function(_dereq_,module,exports){ + +/** + * This is the web browser implementation of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = _dereq_('./debug'); +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.storage = 'undefined' != typeof chrome + && 'undefined' != typeof chrome.storage + ? chrome.storage.local + : localstorage(); + +/** + * Colors. + */ + +exports.colors = [ + 'lightseagreen', + 'forestgreen', + 'goldenrod', + 'dodgerblue', + 'darkorchid', + 'crimson' +]; + +/** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ + +function useColors() { + // is webkit? http://stackoverflow.com/a/16459606/376773 + return ('WebkitAppearance' in document.documentElement.style) || + // is firebug? http://stackoverflow.com/a/398120/376773 + (window.console && (console.firebug || (console.exception && console.table))) || + // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); +} + +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +exports.formatters.j = function(v) { + return JSON.stringify(v); +}; + + +/** + * Colorize log arguments if enabled. + * + * @api public + */ + +function formatArgs() { + var args = arguments; + var useColors = this.useColors; + + args[0] = (useColors ? '%c' : '') + + this.namespace + + (useColors ? ' %c' : ' ') + + args[0] + + (useColors ? '%c ' : ' '); + + if (!useColors) return args; + + var c = 'color: ' + this.color; + args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); + + // the final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + var index = 0; + var lastC = 0; + args[0].replace(/%[a-z%]/g, function(match) { + if ('%%' === match) return; + index++; + if ('%c' === match) { + // we only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + + args.splice(lastC, 0, c); + return args; +} + +/** + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". + * + * @api public + */ + +function log() { + // this hackery is required for IE8/9, where + // the `console.log` function doesn't have 'apply' + return 'object' === typeof console + && console.log + && Function.prototype.apply.call(console.log, console, arguments); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + +function save(namespaces) { + try { + if (null == namespaces) { + exports.storage.removeItem('debug'); + } else { + exports.storage.debug = namespaces; + } + } catch(e) {} +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + var r; + try { + r = exports.storage.debug; + } catch(e) {} + return r; +} + +/** + * Enable namespaces listed in `localStorage.debug` initially. + */ + +exports.enable(load()); + +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ + +function localstorage(){ + try { + return window.localStorage; + } catch (e) {} +} + +},{"./debug":200}],200:[function(_dereq_,module,exports){ + +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = debug; +exports.coerce = coerce; +exports.disable = disable; +exports.enable = enable; +exports.enabled = enabled; + +/** + * The currently active debug mode names, and names to skip. + */ + +exports.names = []; +exports.skips = []; + +/** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lowercased letter, i.e. "n". + */ + +exports.formatters = {}; + +/** + * Previously assigned color. + */ + +var prevColor = 0; + +/** + * Select a color. + * + * @return {Number} + * @api private + */ + +function selectColor() { + return exports.colors[prevColor++ % exports.colors.length]; +} + +/** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + +function debug(namespace) { + + // define the `disabled` version + function disabled() { + } + disabled.enabled = false; + + // define the `enabled` version + function enabled() { + + var self = enabled; + + // add the `color` if not set + if (null == self.useColors) self.useColors = exports.useColors(); + if (null == self.color && self.useColors) self.color = selectColor(); + + var args = Array.prototype.slice.call(arguments); + + args[0] = exports.coerce(args[0]); + + if ('string' !== typeof args[0]) { + // anything else let's inspect with %o + args = ['%o'].concat(args); + } + + // apply any `formatters` transformations + var index = 0; + args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { + // if we encounter an escaped % then don't increase the array index + if (match === '%%') return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); + + // now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); + + if ('function' === typeof exports.formatArgs) { + args = exports.formatArgs.apply(self, args); + } + var logFn = enabled.log || exports.log || console.log.bind(console); + logFn.apply(self, args); + } + enabled.enabled = true; + + var fn = exports.enabled(namespace) ? enabled : disabled; + + fn.namespace = namespace; + + return fn; +} + +/** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + +function enable(namespaces) { + exports.save(namespaces); + + var split = (namespaces || '').split(/[\s,]+/); + var len = split.length; + + for (var i = 0; i < len; i++) { + if (!split[i]) continue; // ignore empty strings + namespaces = split[i].replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + exports.names.push(new RegExp('^' + namespaces + '$')); + } + } +} + +/** + * Disable debug output. + * + * @api public + */ + +function disable() { + exports.enable(''); +} + +/** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + +function enabled(name) { + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { + return true; + } + } + return false; +} + +/** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} + +},{}],201:[function(_dereq_,module,exports){ +/*! (C) WebReflection Mit Style License */ +(function(t,n,r,i){"use strict";function st(e,t){for(var n=0,r=e.length;n>0),o="attached",u="detached",a="extends",f="ADDITION",l="MODIFICATION",c="REMOVAL",h="DOMAttrModified",p="DOMContentLoaded",d="DOMSubtreeModified",v="<",m="=",g=/^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/,y=["ANNOTATION-XML","COLOR-PROFILE","FONT-FACE","FONT-FACE-SRC","FONT-FACE-URI","FONT-FACE-FORMAT","FONT-FACE-NAME","MISSING-GLYPH"],b=[],w=[],E="",S=n.documentElement,x=b.indexOf||function(e){for(var t=this.length;t--&&this[t]!==e;);return t},T=r.prototype,N=T.hasOwnProperty,C=T.isPrototypeOf,k=r.defineProperty,L=r.getOwnPropertyDescriptor,A=r.getOwnPropertyNames,O=r.getPrototypeOf,M=r.setPrototypeOf,_=!!r.__proto__,D=r.create||function yt(e){return e?(yt.prototype=e,new yt):this},P=M||(_?function(e,t){return e.__proto__=t,e}:A&&L?function(){function e(e,t){for(var n,r=A(t),i=0,s=r.length;ib&&(b+=1);1b?c:b<2/3?a+(c-a)*(2/3-b)*6:a}var d=/hsl\\((\\d+),\\s*([\\d.]+)%,\\s*([\\d.]+)%\\)/g.exec(a)||/hsla\\((\\d+),\\s*([\\d.]+)%,\\s*([\\d.]+)%,\\s*([\\d.]+)\\)/g.exec(a);a=parseInt(d[1])/360;var b=parseInt(d[2])/100,f=parseInt(d[3])/100,d=d[4]||1;if(0==b)f=b=a=f;else{var n=.5>f?f*(1+b):f+b-f*b,k=2*f-n,f=c(k,n,a+1/3),b=c(k,n,a);a=c(k,n,a-1/3)}return\"rgba(\"+\n255*f+\",\"+255*b+\",\"+255*a+\",\"+d+\")\"}function y(a){if(a=/([\\+\\-]?[0-9#\\.]+)(%|px|pt|em|rem|in|cm|mm|ex|ch|pc|vw|vh|vmin|vmax|deg|rad|turn)?$/.exec(a))return a[2]}function V(a){if(-1=g.currentTime)for(var G=0;G=w||!k)g.began||(g.began=!0,f(\"begin\")),f(\"run\");if(q>n&&q=k&&r!==k||!k)b(k),x||e();f(\"update\");a>=k&&(g.remaining?(t=h,\"alternate\"===g.direction&&(g.reversed=!g.reversed)):(g.pause(),g.completed||(g.completed=!0,f(\"complete\"),\"Promise\"in window&&(p(),m=c()))),l=0)}a=void 0===a?{}:a;var h,t,l=0,p=null,m=c(),g=fa(a);g.reset=function(){var a=g.direction,c=g.loop;g.currentTime=\n0;g.progress=0;g.paused=!0;g.began=!1;g.completed=!1;g.reversed=\"reverse\"===a;g.remaining=\"alternate\"===a&&1===c?2:c;b(0);for(a=g.children.length;a--;)g.children[a].reset()};g.tick=function(a){h=a;t||(t=h);k((l+h-t)*q.speed)};g.seek=function(a){k(d(a))};g.pause=function(){var a=v.indexOf(g);-1=c&&0<=b&&1>=b){var e=new Float32Array(11);if(c!==d||b!==f)for(var k=0;11>k;++k)e[k]=a(.1*k,c,b);return function(k){if(c===d&&b===f)return k;if(0===k)return 0;if(1===k)return 1;for(var h=0,l=1;10!==l&&e[l]<=k;++l)h+=.1;--l;var l=h+(k-e[l])/(e[l+1]-e[l])*.1,n=3*(1-3*b+3*c)*l*l+2*(3*b-6*c)*l+3*c;if(.001<=n){for(h=0;4>h;++h){n=3*(1-3*b+3*c)*l*l+2*(3*b-6*c)*l+3*c;if(0===n)break;var m=a(l,c,b)-k,l=l-m/n}k=l}else if(0===\nn)k=l;else{var l=h,h=h+.1,g=0;do m=l+(h-l)/2,n=a(m,c,b)-k,0++g);k=m}return a(k,d,f)}}}}(),Q=function(){function a(a,b){return 0===a||1===a?a:-Math.pow(2,10*(a-1))*Math.sin(2*(a-1-b/(2*Math.PI)*Math.asin(1))*Math.PI/b)}var c=\"Quad Cubic Quart Quint Sine Expo Circ Back Elastic\".split(\" \"),d={In:[[.55,.085,.68,.53],[.55,.055,.675,.19],[.895,.03,.685,.22],[.755,.05,.855,.06],[.47,0,.745,.715],[.95,.05,.795,.035],[.6,.04,.98,.335],[.6,-.28,.735,.045],a],Out:[[.25,\n.46,.45,.94],[.215,.61,.355,1],[.165,.84,.44,1],[.23,1,.32,1],[.39,.575,.565,1],[.19,1,.22,1],[.075,.82,.165,1],[.175,.885,.32,1.275],function(b,c){return 1-a(1-b,c)}],InOut:[[.455,.03,.515,.955],[.645,.045,.355,1],[.77,0,.175,1],[.86,0,.07,1],[.445,.05,.55,.95],[1,0,0,1],[.785,.135,.15,.86],[.68,-.55,.265,1.55],function(b,c){return.5>b?a(2*b,c)/2:1-a(-2*b+2,c)/2}]},b={linear:A(.25,.25,.75,.75)},f={},e;for(e in d)f.type=e,d[f.type].forEach(function(a){return function(d,f){b[\"ease\"+a.type+c[f]]=h.fnc(d)?\nd:A.apply($jscomp$this,d)}}(f)),f={type:f.type};return b}(),ha={css:function(a,c,d){return a.style[c]=d},attribute:function(a,c,d){return a.setAttribute(c,d)},object:function(a,c,d){return a[c]=d},transform:function(a,c,d,b,f){b[f]||(b[f]=[]);b[f].push(c+\"(\"+d+\")\")}},v=[],B=0,ia=function(){function a(){B=requestAnimationFrame(c)}function c(c){var b=v.length;if(b){for(var d=0;db&&(c.duration=d.duration);c.children.push(d)});c.seek(0);c.reset();c.autoplay&&c.restart();return c};return c};q.random=function(a,c){return Math.floor(Math.random()*(c-a+1))+a};return q});", - "module.exports = function numtype(num, def) {\n\treturn typeof num === 'number'\n\t\t? num \n\t\t: (typeof def === 'number' ? def : 0)\n}", - "'use strict'\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i]\n revLookup[code.charCodeAt(i)] = i\n}\n\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction placeHoldersCount (b64) {\n var len = b64.length\n if (len % 4 > 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // the number of equal signs (place holders)\n // if there are two placeholders, than the two characters before it\n // represent one byte\n // if there is only one, then the three characters before it represent 2 bytes\n // this is just a cheap hack to not do indexOf twice\n return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0\n}\n\nfunction byteLength (b64) {\n // base64 is 4/3 + up to two characters of the original data\n return (b64.length * 3 / 4) - placeHoldersCount(b64)\n}\n\nfunction toByteArray (b64) {\n var i, l, tmp, placeHolders, arr\n var len = b64.length\n placeHolders = placeHoldersCount(b64)\n\n arr = new Arr((len * 3 / 4) - placeHolders)\n\n // if there are placeholders, only get up to the last complete 4 chars\n l = placeHolders > 0 ? len - 4 : len\n\n var L = 0\n\n for (i = 0; i < l; i += 4) {\n tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]\n arr[L++] = (tmp >> 16) & 0xFF\n arr[L++] = (tmp >> 8) & 0xFF\n arr[L++] = tmp & 0xFF\n }\n\n if (placeHolders === 2) {\n tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)\n arr[L++] = tmp & 0xFF\n } else if (placeHolders === 1) {\n tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)\n arr[L++] = (tmp >> 8) & 0xFF\n arr[L++] = tmp & 0xFF\n }\n\n return arr\n}\n\nfunction tripletToBase64 (num) {\n return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n var tmp\n var output = []\n for (var i = start; i < end; i += 3) {\n tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\n output.push(tripletToBase64(tmp))\n }\n return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n var tmp\n var len = uint8.length\n var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n var output = ''\n var parts = []\n var maxChunkLength = 16383 // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1]\n output += lookup[tmp >> 2]\n output += lookup[(tmp << 4) & 0x3F]\n output += '=='\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + (uint8[len - 1])\n output += lookup[tmp >> 10]\n output += lookup[(tmp >> 4) & 0x3F]\n output += lookup[(tmp << 2) & 0x3F]\n output += '='\n }\n\n parts.push(output)\n\n return parts.join('')\n}\n", - "'use strict';\n// For more information about browser field, check out the browser field at https://github.com/substack/browserify-handbook#browser-field.\n\nmodule.exports = {\n // Create a tag with optional data attributes\n createLink: function(href, attributes) {\n var head = document.head || document.getElementsByTagName('head')[0];\n var link = document.createElement('link');\n\n link.href = href;\n link.rel = 'stylesheet';\n\n for (var key in attributes) {\n if ( ! attributes.hasOwnProperty(key)) {\n continue;\n }\n var value = attributes[key];\n link.setAttribute('data-' + key, value);\n }\n\n head.appendChild(link);\n },\n // Create a