three.js 579 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  4. (factory((global.THREE = global.THREE || {})));
  5. }(this, (function (exports) { 'use strict';
  6. // Polyfills
  7. if ( Number.EPSILON === undefined ) {
  8. Number.EPSILON = Math.pow( 2, - 52 );
  9. }
  10. //
  11. if ( Math.sign === undefined ) {
  12. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign
  13. Math.sign = function ( x ) {
  14. return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;
  15. };
  16. }
  17. if ( Function.prototype.name === undefined ) {
  18. // Missing in IE9-11.
  19. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
  20. Object.defineProperty( Function.prototype, 'name', {
  21. get: function () {
  22. return this.toString().match( /^\s*function\s*([^\(\s]*)/ )[ 1 ];
  23. }
  24. } );
  25. }
  26. if ( Object.assign === undefined ) {
  27. // Missing in IE.
  28. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
  29. ( function () {
  30. Object.assign = function ( target ) {
  31. 'use strict';
  32. if ( target === undefined || target === null ) {
  33. throw new TypeError( 'Cannot convert undefined or null to object' );
  34. }
  35. var output = Object( target );
  36. for ( var index = 1; index < arguments.length; index ++ ) {
  37. var source = arguments[ index ];
  38. if ( source !== undefined && source !== null ) {
  39. for ( var nextKey in source ) {
  40. if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {
  41. output[ nextKey ] = source[ nextKey ];
  42. }
  43. }
  44. }
  45. }
  46. return output;
  47. };
  48. } )();
  49. }
  50. var REVISION = '84';
  51. var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
  52. var CullFaceNone = 0;
  53. var CullFaceBack = 1;
  54. var CullFaceFront = 2;
  55. var CullFaceFrontBack = 3;
  56. var FrontFaceDirectionCW = 0;
  57. var FrontFaceDirectionCCW = 1;
  58. var BasicShadowMap = 0;
  59. var PCFShadowMap = 1;
  60. var PCFSoftShadowMap = 2;
  61. var FrontSide = 0;
  62. var BackSide = 1;
  63. var DoubleSide = 2;
  64. var FlatShading = 1;
  65. var SmoothShading = 2;
  66. var NoColors = 0;
  67. var FaceColors = 1;
  68. var VertexColors = 2;
  69. var NoBlending = 0;
  70. var NormalBlending = 1;
  71. var AdditiveBlending = 2;
  72. var SubtractiveBlending = 3;
  73. var MultiplyBlending = 4;
  74. var CustomBlending = 5;
  75. var AddEquation = 100;
  76. var SubtractEquation = 101;
  77. var ReverseSubtractEquation = 102;
  78. var MinEquation = 103;
  79. var MaxEquation = 104;
  80. var ZeroFactor = 200;
  81. var OneFactor = 201;
  82. var SrcColorFactor = 202;
  83. var OneMinusSrcColorFactor = 203;
  84. var SrcAlphaFactor = 204;
  85. var OneMinusSrcAlphaFactor = 205;
  86. var DstAlphaFactor = 206;
  87. var OneMinusDstAlphaFactor = 207;
  88. var DstColorFactor = 208;
  89. var OneMinusDstColorFactor = 209;
  90. var SrcAlphaSaturateFactor = 210;
  91. var NeverDepth = 0;
  92. var AlwaysDepth = 1;
  93. var LessDepth = 2;
  94. var LessEqualDepth = 3;
  95. var EqualDepth = 4;
  96. var GreaterEqualDepth = 5;
  97. var GreaterDepth = 6;
  98. var NotEqualDepth = 7;
  99. var MultiplyOperation = 0;
  100. var MixOperation = 1;
  101. var AddOperation = 2;
  102. var NoToneMapping = 0;
  103. var LinearToneMapping = 1;
  104. var ReinhardToneMapping = 2;
  105. var Uncharted2ToneMapping = 3;
  106. var CineonToneMapping = 4;
  107. var UVMapping = 300;
  108. var CubeReflectionMapping = 301;
  109. var CubeRefractionMapping = 302;
  110. var EquirectangularReflectionMapping = 303;
  111. var EquirectangularRefractionMapping = 304;
  112. var SphericalReflectionMapping = 305;
  113. var CubeUVReflectionMapping = 306;
  114. var CubeUVRefractionMapping = 307;
  115. var RepeatWrapping = 1000;
  116. var ClampToEdgeWrapping = 1001;
  117. var MirroredRepeatWrapping = 1002;
  118. var NearestFilter = 1003;
  119. var NearestMipMapNearestFilter = 1004;
  120. var NearestMipMapLinearFilter = 1005;
  121. var LinearFilter = 1006;
  122. var LinearMipMapNearestFilter = 1007;
  123. var LinearMipMapLinearFilter = 1008;
  124. var UnsignedByteType = 1009;
  125. var ByteType = 1010;
  126. var ShortType = 1011;
  127. var UnsignedShortType = 1012;
  128. var IntType = 1013;
  129. var UnsignedIntType = 1014;
  130. var FloatType = 1015;
  131. var HalfFloatType = 1016;
  132. var UnsignedShort4444Type = 1017;
  133. var UnsignedShort5551Type = 1018;
  134. var UnsignedShort565Type = 1019;
  135. var UnsignedInt248Type = 1020;
  136. var AlphaFormat = 1021;
  137. var RGBFormat = 1022;
  138. var RGBAFormat = 1023;
  139. var LuminanceFormat = 1024;
  140. var LuminanceAlphaFormat = 1025;
  141. var RGBEFormat = RGBAFormat;
  142. var DepthFormat = 1026;
  143. var DepthStencilFormat = 1027;
  144. var RGB_S3TC_DXT1_Format = 2001;
  145. var RGBA_S3TC_DXT1_Format = 2002;
  146. var RGBA_S3TC_DXT3_Format = 2003;
  147. var RGBA_S3TC_DXT5_Format = 2004;
  148. var RGB_PVRTC_4BPPV1_Format = 2100;
  149. var RGB_PVRTC_2BPPV1_Format = 2101;
  150. var RGBA_PVRTC_4BPPV1_Format = 2102;
  151. var RGBA_PVRTC_2BPPV1_Format = 2103;
  152. var RGB_ETC1_Format = 2151;
  153. var LoopOnce = 2200;
  154. var LoopRepeat = 2201;
  155. var LoopPingPong = 2202;
  156. var InterpolateDiscrete = 2300;
  157. var InterpolateLinear = 2301;
  158. var InterpolateSmooth = 2302;
  159. var ZeroCurvatureEnding = 2400;
  160. var ZeroSlopeEnding = 2401;
  161. var WrapAroundEnding = 2402;
  162. var TrianglesDrawMode = 0;
  163. var TriangleStripDrawMode = 1;
  164. var TriangleFanDrawMode = 2;
  165. var LinearEncoding = 3000;
  166. var sRGBEncoding = 3001;
  167. var GammaEncoding = 3007;
  168. var RGBEEncoding = 3002;
  169. var LogLuvEncoding = 3003;
  170. var RGBM7Encoding = 3004;
  171. var RGBM16Encoding = 3005;
  172. var RGBDEncoding = 3006;
  173. var BasicDepthPacking = 3200;
  174. var RGBADepthPacking = 3201;
  175. /**
  176. * @author alteredq / http://alteredqualia.com/
  177. * @author mrdoob / http://mrdoob.com/
  178. */
  179. var _Math = {
  180. DEG2RAD: Math.PI / 180,
  181. RAD2DEG: 180 / Math.PI,
  182. generateUUID: function () {
  183. // http://www.broofa.com/Tools/Math.uuid.htm
  184. var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );
  185. var uuid = new Array( 36 );
  186. var rnd = 0, r;
  187. return function generateUUID() {
  188. for ( var i = 0; i < 36; i ++ ) {
  189. if ( i === 8 || i === 13 || i === 18 || i === 23 ) {
  190. uuid[ i ] = '-';
  191. } else if ( i === 14 ) {
  192. uuid[ i ] = '4';
  193. } else {
  194. if ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;
  195. r = rnd & 0xf;
  196. rnd = rnd >> 4;
  197. uuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];
  198. }
  199. }
  200. return uuid.join( '' );
  201. };
  202. }(),
  203. clamp: function ( value, min, max ) {
  204. return Math.max( min, Math.min( max, value ) );
  205. },
  206. // compute euclidian modulo of m % n
  207. // https://en.wikipedia.org/wiki/Modulo_operation
  208. euclideanModulo: function ( n, m ) {
  209. return ( ( n % m ) + m ) % m;
  210. },
  211. // Linear mapping from range <a1, a2> to range <b1, b2>
  212. mapLinear: function ( x, a1, a2, b1, b2 ) {
  213. return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
  214. },
  215. // https://en.wikipedia.org/wiki/Linear_interpolation
  216. lerp: function ( x, y, t ) {
  217. return ( 1 - t ) * x + t * y;
  218. },
  219. // http://en.wikipedia.org/wiki/Smoothstep
  220. smoothstep: function ( x, min, max ) {
  221. if ( x <= min ) return 0;
  222. if ( x >= max ) return 1;
  223. x = ( x - min ) / ( max - min );
  224. return x * x * ( 3 - 2 * x );
  225. },
  226. smootherstep: function ( x, min, max ) {
  227. if ( x <= min ) return 0;
  228. if ( x >= max ) return 1;
  229. x = ( x - min ) / ( max - min );
  230. return x * x * x * ( x * ( x * 6 - 15 ) + 10 );
  231. },
  232. // Random integer from <low, high> interval
  233. randInt: function ( low, high ) {
  234. return low + Math.floor( Math.random() * ( high - low + 1 ) );
  235. },
  236. // Random float from <low, high> interval
  237. randFloat: function ( low, high ) {
  238. return low + Math.random() * ( high - low );
  239. },
  240. // Random float from <-range/2, range/2> interval
  241. randFloatSpread: function ( range ) {
  242. return range * ( 0.5 - Math.random() );
  243. },
  244. degToRad: function ( degrees ) {
  245. return degrees * _Math.DEG2RAD;
  246. },
  247. radToDeg: function ( radians ) {
  248. return radians * _Math.RAD2DEG;
  249. },
  250. isPowerOfTwo: function ( value ) {
  251. return ( value & ( value - 1 ) ) === 0 && value !== 0;
  252. },
  253. nearestPowerOfTwo: function ( value ) {
  254. return Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );
  255. },
  256. nextPowerOfTwo: function ( value ) {
  257. value --;
  258. value |= value >> 1;
  259. value |= value >> 2;
  260. value |= value >> 4;
  261. value |= value >> 8;
  262. value |= value >> 16;
  263. value ++;
  264. return value;
  265. }
  266. };
  267. /**
  268. * @author mikael emtinger / http://gomo.se/
  269. * @author alteredq / http://alteredqualia.com/
  270. * @author WestLangley / http://github.com/WestLangley
  271. * @author bhouston / http://clara.io
  272. */
  273. function Quaternion( x, y, z, w ) {
  274. this._x = x || 0;
  275. this._y = y || 0;
  276. this._z = z || 0;
  277. this._w = ( w !== undefined ) ? w : 1;
  278. }
  279. Quaternion.prototype = {
  280. constructor: Quaternion,
  281. get x () {
  282. return this._x;
  283. },
  284. set x ( value ) {
  285. this._x = value;
  286. this.onChangeCallback();
  287. },
  288. get y () {
  289. return this._y;
  290. },
  291. set y ( value ) {
  292. this._y = value;
  293. this.onChangeCallback();
  294. },
  295. get z () {
  296. return this._z;
  297. },
  298. set z ( value ) {
  299. this._z = value;
  300. this.onChangeCallback();
  301. },
  302. get w () {
  303. return this._w;
  304. },
  305. set w ( value ) {
  306. this._w = value;
  307. this.onChangeCallback();
  308. },
  309. set: function ( x, y, z, w ) {
  310. this._x = x;
  311. this._y = y;
  312. this._z = z;
  313. this._w = w;
  314. this.onChangeCallback();
  315. return this;
  316. },
  317. clone: function () {
  318. return new this.constructor( this._x, this._y, this._z, this._w );
  319. },
  320. copy: function ( quaternion ) {
  321. this._x = quaternion.x;
  322. this._y = quaternion.y;
  323. this._z = quaternion.z;
  324. this._w = quaternion.w;
  325. this.onChangeCallback();
  326. return this;
  327. },
  328. setFromEuler: function ( euler, update ) {
  329. if ( (euler && euler.isEuler) === false ) {
  330. throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );
  331. }
  332. // http://www.mathworks.com/matlabcentral/fileexchange/
  333. // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
  334. // content/SpinCalc.m
  335. var c1 = Math.cos( euler._x / 2 );
  336. var c2 = Math.cos( euler._y / 2 );
  337. var c3 = Math.cos( euler._z / 2 );
  338. var s1 = Math.sin( euler._x / 2 );
  339. var s2 = Math.sin( euler._y / 2 );
  340. var s3 = Math.sin( euler._z / 2 );
  341. var order = euler.order;
  342. if ( order === 'XYZ' ) {
  343. this._x = s1 * c2 * c3 + c1 * s2 * s3;
  344. this._y = c1 * s2 * c3 - s1 * c2 * s3;
  345. this._z = c1 * c2 * s3 + s1 * s2 * c3;
  346. this._w = c1 * c2 * c3 - s1 * s2 * s3;
  347. } else if ( order === 'YXZ' ) {
  348. this._x = s1 * c2 * c3 + c1 * s2 * s3;
  349. this._y = c1 * s2 * c3 - s1 * c2 * s3;
  350. this._z = c1 * c2 * s3 - s1 * s2 * c3;
  351. this._w = c1 * c2 * c3 + s1 * s2 * s3;
  352. } else if ( order === 'ZXY' ) {
  353. this._x = s1 * c2 * c3 - c1 * s2 * s3;
  354. this._y = c1 * s2 * c3 + s1 * c2 * s3;
  355. this._z = c1 * c2 * s3 + s1 * s2 * c3;
  356. this._w = c1 * c2 * c3 - s1 * s2 * s3;
  357. } else if ( order === 'ZYX' ) {
  358. this._x = s1 * c2 * c3 - c1 * s2 * s3;
  359. this._y = c1 * s2 * c3 + s1 * c2 * s3;
  360. this._z = c1 * c2 * s3 - s1 * s2 * c3;
  361. this._w = c1 * c2 * c3 + s1 * s2 * s3;
  362. } else if ( order === 'YZX' ) {
  363. this._x = s1 * c2 * c3 + c1 * s2 * s3;
  364. this._y = c1 * s2 * c3 + s1 * c2 * s3;
  365. this._z = c1 * c2 * s3 - s1 * s2 * c3;
  366. this._w = c1 * c2 * c3 - s1 * s2 * s3;
  367. } else if ( order === 'XZY' ) {
  368. this._x = s1 * c2 * c3 - c1 * s2 * s3;
  369. this._y = c1 * s2 * c3 - s1 * c2 * s3;
  370. this._z = c1 * c2 * s3 + s1 * s2 * c3;
  371. this._w = c1 * c2 * c3 + s1 * s2 * s3;
  372. }
  373. if ( update !== false ) this.onChangeCallback();
  374. return this;
  375. },
  376. setFromAxisAngle: function ( axis, angle ) {
  377. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
  378. // assumes axis is normalized
  379. var halfAngle = angle / 2, s = Math.sin( halfAngle );
  380. this._x = axis.x * s;
  381. this._y = axis.y * s;
  382. this._z = axis.z * s;
  383. this._w = Math.cos( halfAngle );
  384. this.onChangeCallback();
  385. return this;
  386. },
  387. setFromRotationMatrix: function ( m ) {
  388. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
  389. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  390. var te = m.elements,
  391. m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
  392. m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
  393. m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],
  394. trace = m11 + m22 + m33,
  395. s;
  396. if ( trace > 0 ) {
  397. s = 0.5 / Math.sqrt( trace + 1.0 );
  398. this._w = 0.25 / s;
  399. this._x = ( m32 - m23 ) * s;
  400. this._y = ( m13 - m31 ) * s;
  401. this._z = ( m21 - m12 ) * s;
  402. } else if ( m11 > m22 && m11 > m33 ) {
  403. s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );
  404. this._w = ( m32 - m23 ) / s;
  405. this._x = 0.25 * s;
  406. this._y = ( m12 + m21 ) / s;
  407. this._z = ( m13 + m31 ) / s;
  408. } else if ( m22 > m33 ) {
  409. s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );
  410. this._w = ( m13 - m31 ) / s;
  411. this._x = ( m12 + m21 ) / s;
  412. this._y = 0.25 * s;
  413. this._z = ( m23 + m32 ) / s;
  414. } else {
  415. s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );
  416. this._w = ( m21 - m12 ) / s;
  417. this._x = ( m13 + m31 ) / s;
  418. this._y = ( m23 + m32 ) / s;
  419. this._z = 0.25 * s;
  420. }
  421. this.onChangeCallback();
  422. return this;
  423. },
  424. setFromUnitVectors: function () {
  425. // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final
  426. // assumes direction vectors vFrom and vTo are normalized
  427. var v1, r;
  428. var EPS = 0.000001;
  429. return function setFromUnitVectors( vFrom, vTo ) {
  430. if ( v1 === undefined ) v1 = new Vector3();
  431. r = vFrom.dot( vTo ) + 1;
  432. if ( r < EPS ) {
  433. r = 0;
  434. if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {
  435. v1.set( - vFrom.y, vFrom.x, 0 );
  436. } else {
  437. v1.set( 0, - vFrom.z, vFrom.y );
  438. }
  439. } else {
  440. v1.crossVectors( vFrom, vTo );
  441. }
  442. this._x = v1.x;
  443. this._y = v1.y;
  444. this._z = v1.z;
  445. this._w = r;
  446. return this.normalize();
  447. };
  448. }(),
  449. inverse: function () {
  450. return this.conjugate().normalize();
  451. },
  452. conjugate: function () {
  453. this._x *= - 1;
  454. this._y *= - 1;
  455. this._z *= - 1;
  456. this.onChangeCallback();
  457. return this;
  458. },
  459. dot: function ( v ) {
  460. return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
  461. },
  462. lengthSq: function () {
  463. return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
  464. },
  465. length: function () {
  466. return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );
  467. },
  468. normalize: function () {
  469. var l = this.length();
  470. if ( l === 0 ) {
  471. this._x = 0;
  472. this._y = 0;
  473. this._z = 0;
  474. this._w = 1;
  475. } else {
  476. l = 1 / l;
  477. this._x = this._x * l;
  478. this._y = this._y * l;
  479. this._z = this._z * l;
  480. this._w = this._w * l;
  481. }
  482. this.onChangeCallback();
  483. return this;
  484. },
  485. multiply: function ( q, p ) {
  486. if ( p !== undefined ) {
  487. console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );
  488. return this.multiplyQuaternions( q, p );
  489. }
  490. return this.multiplyQuaternions( this, q );
  491. },
  492. premultiply: function ( q ) {
  493. return this.multiplyQuaternions( q, this );
  494. },
  495. multiplyQuaternions: function ( a, b ) {
  496. // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
  497. var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;
  498. var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;
  499. this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
  500. this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
  501. this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
  502. this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
  503. this.onChangeCallback();
  504. return this;
  505. },
  506. slerp: function ( qb, t ) {
  507. if ( t === 0 ) return this;
  508. if ( t === 1 ) return this.copy( qb );
  509. var x = this._x, y = this._y, z = this._z, w = this._w;
  510. // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
  511. var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
  512. if ( cosHalfTheta < 0 ) {
  513. this._w = - qb._w;
  514. this._x = - qb._x;
  515. this._y = - qb._y;
  516. this._z = - qb._z;
  517. cosHalfTheta = - cosHalfTheta;
  518. } else {
  519. this.copy( qb );
  520. }
  521. if ( cosHalfTheta >= 1.0 ) {
  522. this._w = w;
  523. this._x = x;
  524. this._y = y;
  525. this._z = z;
  526. return this;
  527. }
  528. var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
  529. if ( Math.abs( sinHalfTheta ) < 0.001 ) {
  530. this._w = 0.5 * ( w + this._w );
  531. this._x = 0.5 * ( x + this._x );
  532. this._y = 0.5 * ( y + this._y );
  533. this._z = 0.5 * ( z + this._z );
  534. return this;
  535. }
  536. var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );
  537. var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
  538. ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
  539. this._w = ( w * ratioA + this._w * ratioB );
  540. this._x = ( x * ratioA + this._x * ratioB );
  541. this._y = ( y * ratioA + this._y * ratioB );
  542. this._z = ( z * ratioA + this._z * ratioB );
  543. this.onChangeCallback();
  544. return this;
  545. },
  546. equals: function ( quaternion ) {
  547. return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );
  548. },
  549. fromArray: function ( array, offset ) {
  550. if ( offset === undefined ) offset = 0;
  551. this._x = array[ offset ];
  552. this._y = array[ offset + 1 ];
  553. this._z = array[ offset + 2 ];
  554. this._w = array[ offset + 3 ];
  555. this.onChangeCallback();
  556. return this;
  557. },
  558. toArray: function ( array, offset ) {
  559. if ( array === undefined ) array = [];
  560. if ( offset === undefined ) offset = 0;
  561. array[ offset ] = this._x;
  562. array[ offset + 1 ] = this._y;
  563. array[ offset + 2 ] = this._z;
  564. array[ offset + 3 ] = this._w;
  565. return array;
  566. },
  567. onChange: function ( callback ) {
  568. this.onChangeCallback = callback;
  569. return this;
  570. },
  571. onChangeCallback: function () {}
  572. };
  573. Object.assign( Quaternion, {
  574. slerp: function( qa, qb, qm, t ) {
  575. return qm.copy( qa ).slerp( qb, t );
  576. },
  577. slerpFlat: function(
  578. dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {
  579. // fuzz-free, array-based Quaternion SLERP operation
  580. var x0 = src0[ srcOffset0 + 0 ],
  581. y0 = src0[ srcOffset0 + 1 ],
  582. z0 = src0[ srcOffset0 + 2 ],
  583. w0 = src0[ srcOffset0 + 3 ],
  584. x1 = src1[ srcOffset1 + 0 ],
  585. y1 = src1[ srcOffset1 + 1 ],
  586. z1 = src1[ srcOffset1 + 2 ],
  587. w1 = src1[ srcOffset1 + 3 ];
  588. if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {
  589. var s = 1 - t,
  590. cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,
  591. dir = ( cos >= 0 ? 1 : - 1 ),
  592. sqrSin = 1 - cos * cos;
  593. // Skip the Slerp for tiny steps to avoid numeric problems:
  594. if ( sqrSin > Number.EPSILON ) {
  595. var sin = Math.sqrt( sqrSin ),
  596. len = Math.atan2( sin, cos * dir );
  597. s = Math.sin( s * len ) / sin;
  598. t = Math.sin( t * len ) / sin;
  599. }
  600. var tDir = t * dir;
  601. x0 = x0 * s + x1 * tDir;
  602. y0 = y0 * s + y1 * tDir;
  603. z0 = z0 * s + z1 * tDir;
  604. w0 = w0 * s + w1 * tDir;
  605. // Normalize in case we just did a lerp:
  606. if ( s === 1 - t ) {
  607. var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );
  608. x0 *= f;
  609. y0 *= f;
  610. z0 *= f;
  611. w0 *= f;
  612. }
  613. }
  614. dst[ dstOffset ] = x0;
  615. dst[ dstOffset + 1 ] = y0;
  616. dst[ dstOffset + 2 ] = z0;
  617. dst[ dstOffset + 3 ] = w0;
  618. }
  619. } );
  620. /**
  621. * @author mrdoob / http://mrdoob.com/
  622. * @author *kile / http://kile.stravaganza.org/
  623. * @author philogb / http://blog.thejit.org/
  624. * @author mikael emtinger / http://gomo.se/
  625. * @author egraether / http://egraether.com/
  626. * @author WestLangley / http://github.com/WestLangley
  627. */
  628. function Vector3( x, y, z ) {
  629. this.x = x || 0;
  630. this.y = y || 0;
  631. this.z = z || 0;
  632. }
  633. Vector3.prototype = {
  634. constructor: Vector3,
  635. isVector3: true,
  636. set: function ( x, y, z ) {
  637. this.x = x;
  638. this.y = y;
  639. this.z = z;
  640. return this;
  641. },
  642. setScalar: function ( scalar ) {
  643. this.x = scalar;
  644. this.y = scalar;
  645. this.z = scalar;
  646. return this;
  647. },
  648. setX: function ( x ) {
  649. this.x = x;
  650. return this;
  651. },
  652. setY: function ( y ) {
  653. this.y = y;
  654. return this;
  655. },
  656. setZ: function ( z ) {
  657. this.z = z;
  658. return this;
  659. },
  660. setComponent: function ( index, value ) {
  661. switch ( index ) {
  662. case 0: this.x = value; break;
  663. case 1: this.y = value; break;
  664. case 2: this.z = value; break;
  665. default: throw new Error( 'index is out of range: ' + index );
  666. }
  667. return this;
  668. },
  669. getComponent: function ( index ) {
  670. switch ( index ) {
  671. case 0: return this.x;
  672. case 1: return this.y;
  673. case 2: return this.z;
  674. default: throw new Error( 'index is out of range: ' + index );
  675. }
  676. },
  677. clone: function () {
  678. return new this.constructor( this.x, this.y, this.z );
  679. },
  680. copy: function ( v ) {
  681. this.x = v.x;
  682. this.y = v.y;
  683. this.z = v.z;
  684. return this;
  685. },
  686. add: function ( v, w ) {
  687. if ( w !== undefined ) {
  688. console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
  689. return this.addVectors( v, w );
  690. }
  691. this.x += v.x;
  692. this.y += v.y;
  693. this.z += v.z;
  694. return this;
  695. },
  696. addScalar: function ( s ) {
  697. this.x += s;
  698. this.y += s;
  699. this.z += s;
  700. return this;
  701. },
  702. addVectors: function ( a, b ) {
  703. this.x = a.x + b.x;
  704. this.y = a.y + b.y;
  705. this.z = a.z + b.z;
  706. return this;
  707. },
  708. addScaledVector: function ( v, s ) {
  709. this.x += v.x * s;
  710. this.y += v.y * s;
  711. this.z += v.z * s;
  712. return this;
  713. },
  714. sub: function ( v, w ) {
  715. if ( w !== undefined ) {
  716. console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
  717. return this.subVectors( v, w );
  718. }
  719. this.x -= v.x;
  720. this.y -= v.y;
  721. this.z -= v.z;
  722. return this;
  723. },
  724. subScalar: function ( s ) {
  725. this.x -= s;
  726. this.y -= s;
  727. this.z -= s;
  728. return this;
  729. },
  730. subVectors: function ( a, b ) {
  731. this.x = a.x - b.x;
  732. this.y = a.y - b.y;
  733. this.z = a.z - b.z;
  734. return this;
  735. },
  736. multiply: function ( v, w ) {
  737. if ( w !== undefined ) {
  738. console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );
  739. return this.multiplyVectors( v, w );
  740. }
  741. this.x *= v.x;
  742. this.y *= v.y;
  743. this.z *= v.z;
  744. return this;
  745. },
  746. multiplyScalar: function ( scalar ) {
  747. if ( isFinite( scalar ) ) {
  748. this.x *= scalar;
  749. this.y *= scalar;
  750. this.z *= scalar;
  751. } else {
  752. this.x = 0;
  753. this.y = 0;
  754. this.z = 0;
  755. }
  756. return this;
  757. },
  758. multiplyVectors: function ( a, b ) {
  759. this.x = a.x * b.x;
  760. this.y = a.y * b.y;
  761. this.z = a.z * b.z;
  762. return this;
  763. },
  764. applyEuler: function () {
  765. var quaternion;
  766. return function applyEuler( euler ) {
  767. if ( (euler && euler.isEuler) === false ) {
  768. console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );
  769. }
  770. if ( quaternion === undefined ) quaternion = new Quaternion();
  771. return this.applyQuaternion( quaternion.setFromEuler( euler ) );
  772. };
  773. }(),
  774. applyAxisAngle: function () {
  775. var quaternion;
  776. return function applyAxisAngle( axis, angle ) {
  777. if ( quaternion === undefined ) quaternion = new Quaternion();
  778. return this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );
  779. };
  780. }(),
  781. applyMatrix3: function ( m ) {
  782. var x = this.x, y = this.y, z = this.z;
  783. var e = m.elements;
  784. this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;
  785. this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;
  786. this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;
  787. return this;
  788. },
  789. applyMatrix4: function ( m ) {
  790. var x = this.x, y = this.y, z = this.z;
  791. var e = m.elements;
  792. this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];
  793. this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];
  794. this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];
  795. var w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ];
  796. return this.divideScalar( w );
  797. },
  798. applyQuaternion: function ( q ) {
  799. var x = this.x, y = this.y, z = this.z;
  800. var qx = q.x, qy = q.y, qz = q.z, qw = q.w;
  801. // calculate quat * vector
  802. var ix = qw * x + qy * z - qz * y;
  803. var iy = qw * y + qz * x - qx * z;
  804. var iz = qw * z + qx * y - qy * x;
  805. var iw = - qx * x - qy * y - qz * z;
  806. // calculate result * inverse quat
  807. this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
  808. this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
  809. this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
  810. return this;
  811. },
  812. project: function () {
  813. var matrix;
  814. return function project( camera ) {
  815. if ( matrix === undefined ) matrix = new Matrix4();
  816. matrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );
  817. return this.applyMatrix4( matrix );
  818. };
  819. }(),
  820. unproject: function () {
  821. var matrix;
  822. return function unproject( camera ) {
  823. if ( matrix === undefined ) matrix = new Matrix4();
  824. matrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );
  825. return this.applyMatrix4( matrix );
  826. };
  827. }(),
  828. transformDirection: function ( m ) {
  829. // input: THREE.Matrix4 affine matrix
  830. // vector interpreted as a direction
  831. var x = this.x, y = this.y, z = this.z;
  832. var e = m.elements;
  833. this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;
  834. this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;
  835. this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;
  836. return this.normalize();
  837. },
  838. divide: function ( v ) {
  839. this.x /= v.x;
  840. this.y /= v.y;
  841. this.z /= v.z;
  842. return this;
  843. },
  844. divideScalar: function ( scalar ) {
  845. return this.multiplyScalar( 1 / scalar );
  846. },
  847. min: function ( v ) {
  848. this.x = Math.min( this.x, v.x );
  849. this.y = Math.min( this.y, v.y );
  850. this.z = Math.min( this.z, v.z );
  851. return this;
  852. },
  853. max: function ( v ) {
  854. this.x = Math.max( this.x, v.x );
  855. this.y = Math.max( this.y, v.y );
  856. this.z = Math.max( this.z, v.z );
  857. return this;
  858. },
  859. clamp: function ( min, max ) {
  860. // This function assumes min < max, if this assumption isn't true it will not operate correctly
  861. this.x = Math.max( min.x, Math.min( max.x, this.x ) );
  862. this.y = Math.max( min.y, Math.min( max.y, this.y ) );
  863. this.z = Math.max( min.z, Math.min( max.z, this.z ) );
  864. return this;
  865. },
  866. clampScalar: function () {
  867. var min, max;
  868. return function clampScalar( minVal, maxVal ) {
  869. if ( min === undefined ) {
  870. min = new Vector3();
  871. max = new Vector3();
  872. }
  873. min.set( minVal, minVal, minVal );
  874. max.set( maxVal, maxVal, maxVal );
  875. return this.clamp( min, max );
  876. };
  877. }(),
  878. clampLength: function ( min, max ) {
  879. var length = this.length();
  880. return this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );
  881. },
  882. floor: function () {
  883. this.x = Math.floor( this.x );
  884. this.y = Math.floor( this.y );
  885. this.z = Math.floor( this.z );
  886. return this;
  887. },
  888. ceil: function () {
  889. this.x = Math.ceil( this.x );
  890. this.y = Math.ceil( this.y );
  891. this.z = Math.ceil( this.z );
  892. return this;
  893. },
  894. round: function () {
  895. this.x = Math.round( this.x );
  896. this.y = Math.round( this.y );
  897. this.z = Math.round( this.z );
  898. return this;
  899. },
  900. roundToZero: function () {
  901. this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
  902. this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
  903. this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
  904. return this;
  905. },
  906. negate: function () {
  907. this.x = - this.x;
  908. this.y = - this.y;
  909. this.z = - this.z;
  910. return this;
  911. },
  912. dot: function ( v ) {
  913. return this.x * v.x + this.y * v.y + this.z * v.z;
  914. },
  915. lengthSq: function () {
  916. return this.x * this.x + this.y * this.y + this.z * this.z;
  917. },
  918. length: function () {
  919. return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
  920. },
  921. lengthManhattan: function () {
  922. return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
  923. },
  924. normalize: function () {
  925. return this.divideScalar( this.length() );
  926. },
  927. setLength: function ( length ) {
  928. return this.multiplyScalar( length / this.length() );
  929. },
  930. lerp: function ( v, alpha ) {
  931. this.x += ( v.x - this.x ) * alpha;
  932. this.y += ( v.y - this.y ) * alpha;
  933. this.z += ( v.z - this.z ) * alpha;
  934. return this;
  935. },
  936. lerpVectors: function ( v1, v2, alpha ) {
  937. return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );
  938. },
  939. cross: function ( v, w ) {
  940. if ( w !== undefined ) {
  941. console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );
  942. return this.crossVectors( v, w );
  943. }
  944. var x = this.x, y = this.y, z = this.z;
  945. this.x = y * v.z - z * v.y;
  946. this.y = z * v.x - x * v.z;
  947. this.z = x * v.y - y * v.x;
  948. return this;
  949. },
  950. crossVectors: function ( a, b ) {
  951. var ax = a.x, ay = a.y, az = a.z;
  952. var bx = b.x, by = b.y, bz = b.z;
  953. this.x = ay * bz - az * by;
  954. this.y = az * bx - ax * bz;
  955. this.z = ax * by - ay * bx;
  956. return this;
  957. },
  958. projectOnVector: function ( vector ) {
  959. var scalar = vector.dot( this ) / vector.lengthSq();
  960. return this.copy( vector ).multiplyScalar( scalar );
  961. },
  962. projectOnPlane: function () {
  963. var v1;
  964. return function projectOnPlane( planeNormal ) {
  965. if ( v1 === undefined ) v1 = new Vector3();
  966. v1.copy( this ).projectOnVector( planeNormal );
  967. return this.sub( v1 );
  968. };
  969. }(),
  970. reflect: function () {
  971. // reflect incident vector off plane orthogonal to normal
  972. // normal is assumed to have unit length
  973. var v1;
  974. return function reflect( normal ) {
  975. if ( v1 === undefined ) v1 = new Vector3();
  976. return this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );
  977. };
  978. }(),
  979. angleTo: function ( v ) {
  980. var theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );
  981. // clamp, to handle numerical problems
  982. return Math.acos( _Math.clamp( theta, - 1, 1 ) );
  983. },
  984. distanceTo: function ( v ) {
  985. return Math.sqrt( this.distanceToSquared( v ) );
  986. },
  987. distanceToSquared: function ( v ) {
  988. var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
  989. return dx * dx + dy * dy + dz * dz;
  990. },
  991. distanceToManhattan: function ( v ) {
  992. return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );
  993. },
  994. setFromSpherical: function( s ) {
  995. var sinPhiRadius = Math.sin( s.phi ) * s.radius;
  996. this.x = sinPhiRadius * Math.sin( s.theta );
  997. this.y = Math.cos( s.phi ) * s.radius;
  998. this.z = sinPhiRadius * Math.cos( s.theta );
  999. return this;
  1000. },
  1001. setFromCylindrical: function( c ) {
  1002. this.x = c.radius * Math.sin( c.theta );
  1003. this.y = c.y;
  1004. this.z = c.radius * Math.cos( c.theta );
  1005. return this;
  1006. },
  1007. setFromMatrixPosition: function ( m ) {
  1008. return this.setFromMatrixColumn( m, 3 );
  1009. },
  1010. setFromMatrixScale: function ( m ) {
  1011. var sx = this.setFromMatrixColumn( m, 0 ).length();
  1012. var sy = this.setFromMatrixColumn( m, 1 ).length();
  1013. var sz = this.setFromMatrixColumn( m, 2 ).length();
  1014. this.x = sx;
  1015. this.y = sy;
  1016. this.z = sz;
  1017. return this;
  1018. },
  1019. setFromMatrixColumn: function ( m, index ) {
  1020. if ( typeof m === 'number' ) {
  1021. console.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );
  1022. var temp = m;
  1023. m = index;
  1024. index = temp;
  1025. }
  1026. return this.fromArray( m.elements, index * 4 );
  1027. },
  1028. equals: function ( v ) {
  1029. return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );
  1030. },
  1031. fromArray: function ( array, offset ) {
  1032. if ( offset === undefined ) offset = 0;
  1033. this.x = array[ offset ];
  1034. this.y = array[ offset + 1 ];
  1035. this.z = array[ offset + 2 ];
  1036. return this;
  1037. },
  1038. toArray: function ( array, offset ) {
  1039. if ( array === undefined ) array = [];
  1040. if ( offset === undefined ) offset = 0;
  1041. array[ offset ] = this.x;
  1042. array[ offset + 1 ] = this.y;
  1043. array[ offset + 2 ] = this.z;
  1044. return array;
  1045. },
  1046. fromBufferAttribute: function ( attribute, index, offset ) {
  1047. if ( offset !== undefined ) {
  1048. console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );
  1049. }
  1050. this.x = attribute.getX( index );
  1051. this.y = attribute.getY( index );
  1052. this.z = attribute.getZ( index );
  1053. return this;
  1054. }
  1055. };
  1056. /**
  1057. * @author mrdoob / http://mrdoob.com/
  1058. * @author supereggbert / http://www.paulbrunt.co.uk/
  1059. * @author philogb / http://blog.thejit.org/
  1060. * @author jordi_ros / http://plattsoft.com
  1061. * @author D1plo1d / http://github.com/D1plo1d
  1062. * @author alteredq / http://alteredqualia.com/
  1063. * @author mikael emtinger / http://gomo.se/
  1064. * @author timknip / http://www.floorplanner.com/
  1065. * @author bhouston / http://clara.io
  1066. * @author WestLangley / http://github.com/WestLangley
  1067. */
  1068. function Matrix4() {
  1069. this.elements = new Float32Array( [
  1070. 1, 0, 0, 0,
  1071. 0, 1, 0, 0,
  1072. 0, 0, 1, 0,
  1073. 0, 0, 0, 1
  1074. ] );
  1075. if ( arguments.length > 0 ) {
  1076. console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );
  1077. }
  1078. }
  1079. Matrix4.prototype = {
  1080. constructor: Matrix4,
  1081. isMatrix4: true,
  1082. set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
  1083. var te = this.elements;
  1084. te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;
  1085. te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;
  1086. te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;
  1087. te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;
  1088. return this;
  1089. },
  1090. identity: function () {
  1091. this.set(
  1092. 1, 0, 0, 0,
  1093. 0, 1, 0, 0,
  1094. 0, 0, 1, 0,
  1095. 0, 0, 0, 1
  1096. );
  1097. return this;
  1098. },
  1099. clone: function () {
  1100. return new Matrix4().fromArray( this.elements );
  1101. },
  1102. copy: function ( m ) {
  1103. this.elements.set( m.elements );
  1104. return this;
  1105. },
  1106. copyPosition: function ( m ) {
  1107. var te = this.elements;
  1108. var me = m.elements;
  1109. te[ 12 ] = me[ 12 ];
  1110. te[ 13 ] = me[ 13 ];
  1111. te[ 14 ] = me[ 14 ];
  1112. return this;
  1113. },
  1114. extractBasis: function ( xAxis, yAxis, zAxis ) {
  1115. xAxis.setFromMatrixColumn( this, 0 );
  1116. yAxis.setFromMatrixColumn( this, 1 );
  1117. zAxis.setFromMatrixColumn( this, 2 );
  1118. return this;
  1119. },
  1120. makeBasis: function ( xAxis, yAxis, zAxis ) {
  1121. this.set(
  1122. xAxis.x, yAxis.x, zAxis.x, 0,
  1123. xAxis.y, yAxis.y, zAxis.y, 0,
  1124. xAxis.z, yAxis.z, zAxis.z, 0,
  1125. 0, 0, 0, 1
  1126. );
  1127. return this;
  1128. },
  1129. extractRotation: function () {
  1130. var v1;
  1131. return function extractRotation( m ) {
  1132. if ( v1 === undefined ) v1 = new Vector3();
  1133. var te = this.elements;
  1134. var me = m.elements;
  1135. var scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();
  1136. var scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();
  1137. var scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();
  1138. te[ 0 ] = me[ 0 ] * scaleX;
  1139. te[ 1 ] = me[ 1 ] * scaleX;
  1140. te[ 2 ] = me[ 2 ] * scaleX;
  1141. te[ 4 ] = me[ 4 ] * scaleY;
  1142. te[ 5 ] = me[ 5 ] * scaleY;
  1143. te[ 6 ] = me[ 6 ] * scaleY;
  1144. te[ 8 ] = me[ 8 ] * scaleZ;
  1145. te[ 9 ] = me[ 9 ] * scaleZ;
  1146. te[ 10 ] = me[ 10 ] * scaleZ;
  1147. return this;
  1148. };
  1149. }(),
  1150. makeRotationFromEuler: function ( euler ) {
  1151. if ( (euler && euler.isEuler) === false ) {
  1152. console.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );
  1153. }
  1154. var te = this.elements;
  1155. var x = euler.x, y = euler.y, z = euler.z;
  1156. var a = Math.cos( x ), b = Math.sin( x );
  1157. var c = Math.cos( y ), d = Math.sin( y );
  1158. var e = Math.cos( z ), f = Math.sin( z );
  1159. if ( euler.order === 'XYZ' ) {
  1160. var ae = a * e, af = a * f, be = b * e, bf = b * f;
  1161. te[ 0 ] = c * e;
  1162. te[ 4 ] = - c * f;
  1163. te[ 8 ] = d;
  1164. te[ 1 ] = af + be * d;
  1165. te[ 5 ] = ae - bf * d;
  1166. te[ 9 ] = - b * c;
  1167. te[ 2 ] = bf - ae * d;
  1168. te[ 6 ] = be + af * d;
  1169. te[ 10 ] = a * c;
  1170. } else if ( euler.order === 'YXZ' ) {
  1171. var ce = c * e, cf = c * f, de = d * e, df = d * f;
  1172. te[ 0 ] = ce + df * b;
  1173. te[ 4 ] = de * b - cf;
  1174. te[ 8 ] = a * d;
  1175. te[ 1 ] = a * f;
  1176. te[ 5 ] = a * e;
  1177. te[ 9 ] = - b;
  1178. te[ 2 ] = cf * b - de;
  1179. te[ 6 ] = df + ce * b;
  1180. te[ 10 ] = a * c;
  1181. } else if ( euler.order === 'ZXY' ) {
  1182. var ce = c * e, cf = c * f, de = d * e, df = d * f;
  1183. te[ 0 ] = ce - df * b;
  1184. te[ 4 ] = - a * f;
  1185. te[ 8 ] = de + cf * b;
  1186. te[ 1 ] = cf + de * b;
  1187. te[ 5 ] = a * e;
  1188. te[ 9 ] = df - ce * b;
  1189. te[ 2 ] = - a * d;
  1190. te[ 6 ] = b;
  1191. te[ 10 ] = a * c;
  1192. } else if ( euler.order === 'ZYX' ) {
  1193. var ae = a * e, af = a * f, be = b * e, bf = b * f;
  1194. te[ 0 ] = c * e;
  1195. te[ 4 ] = be * d - af;
  1196. te[ 8 ] = ae * d + bf;
  1197. te[ 1 ] = c * f;
  1198. te[ 5 ] = bf * d + ae;
  1199. te[ 9 ] = af * d - be;
  1200. te[ 2 ] = - d;
  1201. te[ 6 ] = b * c;
  1202. te[ 10 ] = a * c;
  1203. } else if ( euler.order === 'YZX' ) {
  1204. var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
  1205. te[ 0 ] = c * e;
  1206. te[ 4 ] = bd - ac * f;
  1207. te[ 8 ] = bc * f + ad;
  1208. te[ 1 ] = f;
  1209. te[ 5 ] = a * e;
  1210. te[ 9 ] = - b * e;
  1211. te[ 2 ] = - d * e;
  1212. te[ 6 ] = ad * f + bc;
  1213. te[ 10 ] = ac - bd * f;
  1214. } else if ( euler.order === 'XZY' ) {
  1215. var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
  1216. te[ 0 ] = c * e;
  1217. te[ 4 ] = - f;
  1218. te[ 8 ] = d * e;
  1219. te[ 1 ] = ac * f + bd;
  1220. te[ 5 ] = a * e;
  1221. te[ 9 ] = ad * f - bc;
  1222. te[ 2 ] = bc * f - ad;
  1223. te[ 6 ] = b * e;
  1224. te[ 10 ] = bd * f + ac;
  1225. }
  1226. // last column
  1227. te[ 3 ] = 0;
  1228. te[ 7 ] = 0;
  1229. te[ 11 ] = 0;
  1230. // bottom row
  1231. te[ 12 ] = 0;
  1232. te[ 13 ] = 0;
  1233. te[ 14 ] = 0;
  1234. te[ 15 ] = 1;
  1235. return this;
  1236. },
  1237. makeRotationFromQuaternion: function ( q ) {
  1238. var te = this.elements;
  1239. var x = q.x, y = q.y, z = q.z, w = q.w;
  1240. var x2 = x + x, y2 = y + y, z2 = z + z;
  1241. var xx = x * x2, xy = x * y2, xz = x * z2;
  1242. var yy = y * y2, yz = y * z2, zz = z * z2;
  1243. var wx = w * x2, wy = w * y2, wz = w * z2;
  1244. te[ 0 ] = 1 - ( yy + zz );
  1245. te[ 4 ] = xy - wz;
  1246. te[ 8 ] = xz + wy;
  1247. te[ 1 ] = xy + wz;
  1248. te[ 5 ] = 1 - ( xx + zz );
  1249. te[ 9 ] = yz - wx;
  1250. te[ 2 ] = xz - wy;
  1251. te[ 6 ] = yz + wx;
  1252. te[ 10 ] = 1 - ( xx + yy );
  1253. // last column
  1254. te[ 3 ] = 0;
  1255. te[ 7 ] = 0;
  1256. te[ 11 ] = 0;
  1257. // bottom row
  1258. te[ 12 ] = 0;
  1259. te[ 13 ] = 0;
  1260. te[ 14 ] = 0;
  1261. te[ 15 ] = 1;
  1262. return this;
  1263. },
  1264. lookAt: function () {
  1265. var x, y, z;
  1266. return function lookAt( eye, target, up ) {
  1267. if ( x === undefined ) {
  1268. x = new Vector3();
  1269. y = new Vector3();
  1270. z = new Vector3();
  1271. }
  1272. var te = this.elements;
  1273. z.subVectors( eye, target ).normalize();
  1274. if ( z.lengthSq() === 0 ) {
  1275. z.z = 1;
  1276. }
  1277. x.crossVectors( up, z ).normalize();
  1278. if ( x.lengthSq() === 0 ) {
  1279. z.z += 0.0001;
  1280. x.crossVectors( up, z ).normalize();
  1281. }
  1282. y.crossVectors( z, x );
  1283. te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;
  1284. te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;
  1285. te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;
  1286. return this;
  1287. };
  1288. }(),
  1289. multiply: function ( m, n ) {
  1290. if ( n !== undefined ) {
  1291. console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );
  1292. return this.multiplyMatrices( m, n );
  1293. }
  1294. return this.multiplyMatrices( this, m );
  1295. },
  1296. premultiply: function ( m ) {
  1297. return this.multiplyMatrices( m, this );
  1298. },
  1299. multiplyMatrices: function ( a, b ) {
  1300. var ae = a.elements;
  1301. var be = b.elements;
  1302. var te = this.elements;
  1303. var a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];
  1304. var a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];
  1305. var a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];
  1306. var a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];
  1307. var b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];
  1308. var b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];
  1309. var b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];
  1310. var b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];
  1311. te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
  1312. te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
  1313. te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
  1314. te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
  1315. te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
  1316. te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
  1317. te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
  1318. te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
  1319. te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
  1320. te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
  1321. te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
  1322. te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
  1323. te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
  1324. te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
  1325. te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
  1326. te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
  1327. return this;
  1328. },
  1329. multiplyToArray: function ( a, b, r ) {
  1330. var te = this.elements;
  1331. this.multiplyMatrices( a, b );
  1332. r[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];
  1333. r[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];
  1334. r[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];
  1335. r[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];
  1336. return this;
  1337. },
  1338. multiplyScalar: function ( s ) {
  1339. var te = this.elements;
  1340. te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;
  1341. te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;
  1342. te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;
  1343. te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;
  1344. return this;
  1345. },
  1346. applyToBufferAttribute: function () {
  1347. var v1;
  1348. return function applyToBufferAttribute( attribute ) {
  1349. if ( v1 === undefined ) v1 = new Vector3();
  1350. for ( var i = 0, l = attribute.count; i < l; i ++ ) {
  1351. v1.x = attribute.getX( i );
  1352. v1.y = attribute.getY( i );
  1353. v1.z = attribute.getZ( i );
  1354. v1.applyMatrix4( this );
  1355. attribute.setXYZ( i, v1.x, v1.y, v1.z );
  1356. }
  1357. return attribute;
  1358. };
  1359. }(),
  1360. determinant: function () {
  1361. var te = this.elements;
  1362. var n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];
  1363. var n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];
  1364. var n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];
  1365. var n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];
  1366. //TODO: make this more efficient
  1367. //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
  1368. return (
  1369. n41 * (
  1370. + n14 * n23 * n32
  1371. - n13 * n24 * n32
  1372. - n14 * n22 * n33
  1373. + n12 * n24 * n33
  1374. + n13 * n22 * n34
  1375. - n12 * n23 * n34
  1376. ) +
  1377. n42 * (
  1378. + n11 * n23 * n34
  1379. - n11 * n24 * n33
  1380. + n14 * n21 * n33
  1381. - n13 * n21 * n34
  1382. + n13 * n24 * n31
  1383. - n14 * n23 * n31
  1384. ) +
  1385. n43 * (
  1386. + n11 * n24 * n32
  1387. - n11 * n22 * n34
  1388. - n14 * n21 * n32
  1389. + n12 * n21 * n34
  1390. + n14 * n22 * n31
  1391. - n12 * n24 * n31
  1392. ) +
  1393. n44 * (
  1394. - n13 * n22 * n31
  1395. - n11 * n23 * n32
  1396. + n11 * n22 * n33
  1397. + n13 * n21 * n32
  1398. - n12 * n21 * n33
  1399. + n12 * n23 * n31
  1400. )
  1401. );
  1402. },
  1403. transpose: function () {
  1404. var te = this.elements;
  1405. var tmp;
  1406. tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;
  1407. tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;
  1408. tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;
  1409. tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;
  1410. tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;
  1411. tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;
  1412. return this;
  1413. },
  1414. setPosition: function ( v ) {
  1415. var te = this.elements;
  1416. te[ 12 ] = v.x;
  1417. te[ 13 ] = v.y;
  1418. te[ 14 ] = v.z;
  1419. return this;
  1420. },
  1421. getInverse: function ( m, throwOnDegenerate ) {
  1422. // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
  1423. var te = this.elements,
  1424. me = m.elements,
  1425. n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],
  1426. n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],
  1427. n13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],
  1428. n14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],
  1429. t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,
  1430. t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,
  1431. t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,
  1432. t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
  1433. var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
  1434. if ( det === 0 ) {
  1435. var msg = "THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0";
  1436. if ( throwOnDegenerate === true ) {
  1437. throw new Error( msg );
  1438. } else {
  1439. console.warn( msg );
  1440. }
  1441. return this.identity();
  1442. }
  1443. var detInv = 1 / det;
  1444. te[ 0 ] = t11 * detInv;
  1445. te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;
  1446. te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;
  1447. te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;
  1448. te[ 4 ] = t12 * detInv;
  1449. te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;
  1450. te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;
  1451. te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;
  1452. te[ 8 ] = t13 * detInv;
  1453. te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;
  1454. te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;
  1455. te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;
  1456. te[ 12 ] = t14 * detInv;
  1457. te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;
  1458. te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;
  1459. te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;
  1460. return this;
  1461. },
  1462. scale: function ( v ) {
  1463. var te = this.elements;
  1464. var x = v.x, y = v.y, z = v.z;
  1465. te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;
  1466. te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;
  1467. te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;
  1468. te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;
  1469. return this;
  1470. },
  1471. getMaxScaleOnAxis: function () {
  1472. var te = this.elements;
  1473. var scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];
  1474. var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];
  1475. var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];
  1476. return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );
  1477. },
  1478. makeTranslation: function ( x, y, z ) {
  1479. this.set(
  1480. 1, 0, 0, x,
  1481. 0, 1, 0, y,
  1482. 0, 0, 1, z,
  1483. 0, 0, 0, 1
  1484. );
  1485. return this;
  1486. },
  1487. makeRotationX: function ( theta ) {
  1488. var c = Math.cos( theta ), s = Math.sin( theta );
  1489. this.set(
  1490. 1, 0, 0, 0,
  1491. 0, c, - s, 0,
  1492. 0, s, c, 0,
  1493. 0, 0, 0, 1
  1494. );
  1495. return this;
  1496. },
  1497. makeRotationY: function ( theta ) {
  1498. var c = Math.cos( theta ), s = Math.sin( theta );
  1499. this.set(
  1500. c, 0, s, 0,
  1501. 0, 1, 0, 0,
  1502. - s, 0, c, 0,
  1503. 0, 0, 0, 1
  1504. );
  1505. return this;
  1506. },
  1507. makeRotationZ: function ( theta ) {
  1508. var c = Math.cos( theta ), s = Math.sin( theta );
  1509. this.set(
  1510. c, - s, 0, 0,
  1511. s, c, 0, 0,
  1512. 0, 0, 1, 0,
  1513. 0, 0, 0, 1
  1514. );
  1515. return this;
  1516. },
  1517. makeRotationAxis: function ( axis, angle ) {
  1518. // Based on http://www.gamedev.net/reference/articles/article1199.asp
  1519. var c = Math.cos( angle );
  1520. var s = Math.sin( angle );
  1521. var t = 1 - c;
  1522. var x = axis.x, y = axis.y, z = axis.z;
  1523. var tx = t * x, ty = t * y;
  1524. this.set(
  1525. tx * x + c, tx * y - s * z, tx * z + s * y, 0,
  1526. tx * y + s * z, ty * y + c, ty * z - s * x, 0,
  1527. tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
  1528. 0, 0, 0, 1
  1529. );
  1530. return this;
  1531. },
  1532. makeScale: function ( x, y, z ) {
  1533. this.set(
  1534. x, 0, 0, 0,
  1535. 0, y, 0, 0,
  1536. 0, 0, z, 0,
  1537. 0, 0, 0, 1
  1538. );
  1539. return this;
  1540. },
  1541. makeShear: function ( x, y, z ) {
  1542. this.set(
  1543. 1, y, z, 0,
  1544. x, 1, z, 0,
  1545. x, y, 1, 0,
  1546. 0, 0, 0, 1
  1547. );
  1548. return this;
  1549. },
  1550. compose: function ( position, quaternion, scale ) {
  1551. this.makeRotationFromQuaternion( quaternion );
  1552. this.scale( scale );
  1553. this.setPosition( position );
  1554. return this;
  1555. },
  1556. decompose: function () {
  1557. var vector, matrix;
  1558. return function decompose( position, quaternion, scale ) {
  1559. if ( vector === undefined ) {
  1560. vector = new Vector3();
  1561. matrix = new Matrix4();
  1562. }
  1563. var te = this.elements;
  1564. var sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();
  1565. var sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();
  1566. var sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();
  1567. // if determine is negative, we need to invert one scale
  1568. var det = this.determinant();
  1569. if ( det < 0 ) {
  1570. sx = - sx;
  1571. }
  1572. position.x = te[ 12 ];
  1573. position.y = te[ 13 ];
  1574. position.z = te[ 14 ];
  1575. // scale the rotation part
  1576. matrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()
  1577. var invSX = 1 / sx;
  1578. var invSY = 1 / sy;
  1579. var invSZ = 1 / sz;
  1580. matrix.elements[ 0 ] *= invSX;
  1581. matrix.elements[ 1 ] *= invSX;
  1582. matrix.elements[ 2 ] *= invSX;
  1583. matrix.elements[ 4 ] *= invSY;
  1584. matrix.elements[ 5 ] *= invSY;
  1585. matrix.elements[ 6 ] *= invSY;
  1586. matrix.elements[ 8 ] *= invSZ;
  1587. matrix.elements[ 9 ] *= invSZ;
  1588. matrix.elements[ 10 ] *= invSZ;
  1589. quaternion.setFromRotationMatrix( matrix );
  1590. scale.x = sx;
  1591. scale.y = sy;
  1592. scale.z = sz;
  1593. return this;
  1594. };
  1595. }(),
  1596. makePerspective: function ( left, right, top, bottom, near, far ) {
  1597. if ( far === undefined ) {
  1598. console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );
  1599. }
  1600. var te = this.elements;
  1601. var x = 2 * near / ( right - left );
  1602. var y = 2 * near / ( top - bottom );
  1603. var a = ( right + left ) / ( right - left );
  1604. var b = ( top + bottom ) / ( top - bottom );
  1605. var c = - ( far + near ) / ( far - near );
  1606. var d = - 2 * far * near / ( far - near );
  1607. te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0;
  1608. te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0;
  1609. te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d;
  1610. te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0;
  1611. return this;
  1612. },
  1613. makeOrthographic: function ( left, right, top, bottom, near, far ) {
  1614. var te = this.elements;
  1615. var w = 1.0 / ( right - left );
  1616. var h = 1.0 / ( top - bottom );
  1617. var p = 1.0 / ( far - near );
  1618. var x = ( right + left ) * w;
  1619. var y = ( top + bottom ) * h;
  1620. var z = ( far + near ) * p;
  1621. te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x;
  1622. te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y;
  1623. te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z;
  1624. te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1;
  1625. return this;
  1626. },
  1627. equals: function ( matrix ) {
  1628. var te = this.elements;
  1629. var me = matrix.elements;
  1630. for ( var i = 0; i < 16; i ++ ) {
  1631. if ( te[ i ] !== me[ i ] ) return false;
  1632. }
  1633. return true;
  1634. },
  1635. fromArray: function ( array, offset ) {
  1636. if ( offset === undefined ) offset = 0;
  1637. for( var i = 0; i < 16; i ++ ) {
  1638. this.elements[ i ] = array[ i + offset ];
  1639. }
  1640. return this;
  1641. },
  1642. toArray: function ( array, offset ) {
  1643. if ( array === undefined ) array = [];
  1644. if ( offset === undefined ) offset = 0;
  1645. var te = this.elements;
  1646. array[ offset ] = te[ 0 ];
  1647. array[ offset + 1 ] = te[ 1 ];
  1648. array[ offset + 2 ] = te[ 2 ];
  1649. array[ offset + 3 ] = te[ 3 ];
  1650. array[ offset + 4 ] = te[ 4 ];
  1651. array[ offset + 5 ] = te[ 5 ];
  1652. array[ offset + 6 ] = te[ 6 ];
  1653. array[ offset + 7 ] = te[ 7 ];
  1654. array[ offset + 8 ] = te[ 8 ];
  1655. array[ offset + 9 ] = te[ 9 ];
  1656. array[ offset + 10 ] = te[ 10 ];
  1657. array[ offset + 11 ] = te[ 11 ];
  1658. array[ offset + 12 ] = te[ 12 ];
  1659. array[ offset + 13 ] = te[ 13 ];
  1660. array[ offset + 14 ] = te[ 14 ];
  1661. array[ offset + 15 ] = te[ 15 ];
  1662. return array;
  1663. }
  1664. };
  1665. /**
  1666. * https://github.com/mrdoob/eventdispatcher.js/
  1667. */
  1668. function EventDispatcher() {}
  1669. EventDispatcher.prototype = {
  1670. addEventListener: function ( type, listener ) {
  1671. if ( this._listeners === undefined ) this._listeners = {};
  1672. var listeners = this._listeners;
  1673. if ( listeners[ type ] === undefined ) {
  1674. listeners[ type ] = [];
  1675. }
  1676. if ( listeners[ type ].indexOf( listener ) === - 1 ) {
  1677. listeners[ type ].push( listener );
  1678. }
  1679. },
  1680. hasEventListener: function ( type, listener ) {
  1681. if ( this._listeners === undefined ) return false;
  1682. var listeners = this._listeners;
  1683. return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;
  1684. },
  1685. removeEventListener: function ( type, listener ) {
  1686. if ( this._listeners === undefined ) return;
  1687. var listeners = this._listeners;
  1688. var listenerArray = listeners[ type ];
  1689. if ( listenerArray !== undefined ) {
  1690. var index = listenerArray.indexOf( listener );
  1691. if ( index !== - 1 ) {
  1692. listenerArray.splice( index, 1 );
  1693. }
  1694. }
  1695. },
  1696. dispatchEvent: function ( event ) {
  1697. if ( this._listeners === undefined ) return;
  1698. var listeners = this._listeners;
  1699. var listenerArray = listeners[ event.type ];
  1700. if ( listenerArray !== undefined ) {
  1701. event.target = this;
  1702. var array = [], i = 0;
  1703. var length = listenerArray.length;
  1704. for ( i = 0; i < length; i ++ ) {
  1705. array[ i ] = listenerArray[ i ];
  1706. }
  1707. for ( i = 0; i < length; i ++ ) {
  1708. array[ i ].call( this, event );
  1709. }
  1710. }
  1711. }
  1712. };
  1713. /**
  1714. * @author mrdoob / http://mrdoob.com/
  1715. * @author philogb / http://blog.thejit.org/
  1716. * @author egraether / http://egraether.com/
  1717. * @author zz85 / http://www.lab4games.net/zz85/blog
  1718. */
  1719. function Vector2( x, y ) {
  1720. this.x = x || 0;
  1721. this.y = y || 0;
  1722. }
  1723. Vector2.prototype = {
  1724. constructor: Vector2,
  1725. isVector2: true,
  1726. get width() {
  1727. return this.x;
  1728. },
  1729. set width( value ) {
  1730. this.x = value;
  1731. },
  1732. get height() {
  1733. return this.y;
  1734. },
  1735. set height( value ) {
  1736. this.y = value;
  1737. },
  1738. //
  1739. set: function ( x, y ) {
  1740. this.x = x;
  1741. this.y = y;
  1742. return this;
  1743. },
  1744. setScalar: function ( scalar ) {
  1745. this.x = scalar;
  1746. this.y = scalar;
  1747. return this;
  1748. },
  1749. setX: function ( x ) {
  1750. this.x = x;
  1751. return this;
  1752. },
  1753. setY: function ( y ) {
  1754. this.y = y;
  1755. return this;
  1756. },
  1757. setComponent: function ( index, value ) {
  1758. switch ( index ) {
  1759. case 0: this.x = value; break;
  1760. case 1: this.y = value; break;
  1761. default: throw new Error( 'index is out of range: ' + index );
  1762. }
  1763. return this;
  1764. },
  1765. getComponent: function ( index ) {
  1766. switch ( index ) {
  1767. case 0: return this.x;
  1768. case 1: return this.y;
  1769. default: throw new Error( 'index is out of range: ' + index );
  1770. }
  1771. },
  1772. clone: function () {
  1773. return new this.constructor( this.x, this.y );
  1774. },
  1775. copy: function ( v ) {
  1776. this.x = v.x;
  1777. this.y = v.y;
  1778. return this;
  1779. },
  1780. add: function ( v, w ) {
  1781. if ( w !== undefined ) {
  1782. console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
  1783. return this.addVectors( v, w );
  1784. }
  1785. this.x += v.x;
  1786. this.y += v.y;
  1787. return this;
  1788. },
  1789. addScalar: function ( s ) {
  1790. this.x += s;
  1791. this.y += s;
  1792. return this;
  1793. },
  1794. addVectors: function ( a, b ) {
  1795. this.x = a.x + b.x;
  1796. this.y = a.y + b.y;
  1797. return this;
  1798. },
  1799. addScaledVector: function ( v, s ) {
  1800. this.x += v.x * s;
  1801. this.y += v.y * s;
  1802. return this;
  1803. },
  1804. sub: function ( v, w ) {
  1805. if ( w !== undefined ) {
  1806. console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
  1807. return this.subVectors( v, w );
  1808. }
  1809. this.x -= v.x;
  1810. this.y -= v.y;
  1811. return this;
  1812. },
  1813. subScalar: function ( s ) {
  1814. this.x -= s;
  1815. this.y -= s;
  1816. return this;
  1817. },
  1818. subVectors: function ( a, b ) {
  1819. this.x = a.x - b.x;
  1820. this.y = a.y - b.y;
  1821. return this;
  1822. },
  1823. multiply: function ( v ) {
  1824. this.x *= v.x;
  1825. this.y *= v.y;
  1826. return this;
  1827. },
  1828. multiplyScalar: function ( scalar ) {
  1829. if ( isFinite( scalar ) ) {
  1830. this.x *= scalar;
  1831. this.y *= scalar;
  1832. } else {
  1833. this.x = 0;
  1834. this.y = 0;
  1835. }
  1836. return this;
  1837. },
  1838. divide: function ( v ) {
  1839. this.x /= v.x;
  1840. this.y /= v.y;
  1841. return this;
  1842. },
  1843. divideScalar: function ( scalar ) {
  1844. return this.multiplyScalar( 1 / scalar );
  1845. },
  1846. min: function ( v ) {
  1847. this.x = Math.min( this.x, v.x );
  1848. this.y = Math.min( this.y, v.y );
  1849. return this;
  1850. },
  1851. max: function ( v ) {
  1852. this.x = Math.max( this.x, v.x );
  1853. this.y = Math.max( this.y, v.y );
  1854. return this;
  1855. },
  1856. clamp: function ( min, max ) {
  1857. // This function assumes min < max, if this assumption isn't true it will not operate correctly
  1858. this.x = Math.max( min.x, Math.min( max.x, this.x ) );
  1859. this.y = Math.max( min.y, Math.min( max.y, this.y ) );
  1860. return this;
  1861. },
  1862. clampScalar: function () {
  1863. var min, max;
  1864. return function clampScalar( minVal, maxVal ) {
  1865. if ( min === undefined ) {
  1866. min = new Vector2();
  1867. max = new Vector2();
  1868. }
  1869. min.set( minVal, minVal );
  1870. max.set( maxVal, maxVal );
  1871. return this.clamp( min, max );
  1872. };
  1873. }(),
  1874. clampLength: function ( min, max ) {
  1875. var length = this.length();
  1876. return this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );
  1877. },
  1878. floor: function () {
  1879. this.x = Math.floor( this.x );
  1880. this.y = Math.floor( this.y );
  1881. return this;
  1882. },
  1883. ceil: function () {
  1884. this.x = Math.ceil( this.x );
  1885. this.y = Math.ceil( this.y );
  1886. return this;
  1887. },
  1888. round: function () {
  1889. this.x = Math.round( this.x );
  1890. this.y = Math.round( this.y );
  1891. return this;
  1892. },
  1893. roundToZero: function () {
  1894. this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
  1895. this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
  1896. return this;
  1897. },
  1898. negate: function () {
  1899. this.x = - this.x;
  1900. this.y = - this.y;
  1901. return this;
  1902. },
  1903. dot: function ( v ) {
  1904. return this.x * v.x + this.y * v.y;
  1905. },
  1906. lengthSq: function () {
  1907. return this.x * this.x + this.y * this.y;
  1908. },
  1909. length: function () {
  1910. return Math.sqrt( this.x * this.x + this.y * this.y );
  1911. },
  1912. lengthManhattan: function() {
  1913. return Math.abs( this.x ) + Math.abs( this.y );
  1914. },
  1915. normalize: function () {
  1916. return this.divideScalar( this.length() );
  1917. },
  1918. angle: function () {
  1919. // computes the angle in radians with respect to the positive x-axis
  1920. var angle = Math.atan2( this.y, this.x );
  1921. if ( angle < 0 ) angle += 2 * Math.PI;
  1922. return angle;
  1923. },
  1924. distanceTo: function ( v ) {
  1925. return Math.sqrt( this.distanceToSquared( v ) );
  1926. },
  1927. distanceToSquared: function ( v ) {
  1928. var dx = this.x - v.x, dy = this.y - v.y;
  1929. return dx * dx + dy * dy;
  1930. },
  1931. distanceToManhattan: function ( v ) {
  1932. return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );
  1933. },
  1934. setLength: function ( length ) {
  1935. return this.multiplyScalar( length / this.length() );
  1936. },
  1937. lerp: function ( v, alpha ) {
  1938. this.x += ( v.x - this.x ) * alpha;
  1939. this.y += ( v.y - this.y ) * alpha;
  1940. return this;
  1941. },
  1942. lerpVectors: function ( v1, v2, alpha ) {
  1943. return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );
  1944. },
  1945. equals: function ( v ) {
  1946. return ( ( v.x === this.x ) && ( v.y === this.y ) );
  1947. },
  1948. fromArray: function ( array, offset ) {
  1949. if ( offset === undefined ) offset = 0;
  1950. this.x = array[ offset ];
  1951. this.y = array[ offset + 1 ];
  1952. return this;
  1953. },
  1954. toArray: function ( array, offset ) {
  1955. if ( array === undefined ) array = [];
  1956. if ( offset === undefined ) offset = 0;
  1957. array[ offset ] = this.x;
  1958. array[ offset + 1 ] = this.y;
  1959. return array;
  1960. },
  1961. fromBufferAttribute: function ( attribute, index, offset ) {
  1962. if ( offset !== undefined ) {
  1963. console.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );
  1964. }
  1965. this.x = attribute.getX( index );
  1966. this.y = attribute.getY( index );
  1967. return this;
  1968. },
  1969. rotateAround: function ( center, angle ) {
  1970. var c = Math.cos( angle ), s = Math.sin( angle );
  1971. var x = this.x - center.x;
  1972. var y = this.y - center.y;
  1973. this.x = x * c - y * s + center.x;
  1974. this.y = x * s + y * c + center.y;
  1975. return this;
  1976. }
  1977. };
  1978. /**
  1979. * @author mrdoob / http://mrdoob.com/
  1980. * @author alteredq / http://alteredqualia.com/
  1981. * @author szimek / https://github.com/szimek/
  1982. */
  1983. var textureId = 0;
  1984. function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
  1985. Object.defineProperty( this, 'id', { value: textureId ++ } );
  1986. this.uuid = _Math.generateUUID();
  1987. this.name = '';
  1988. this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;
  1989. this.mipmaps = [];
  1990. this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;
  1991. this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;
  1992. this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;
  1993. this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
  1994. this.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;
  1995. this.anisotropy = anisotropy !== undefined ? anisotropy : 1;
  1996. this.format = format !== undefined ? format : RGBAFormat;
  1997. this.type = type !== undefined ? type : UnsignedByteType;
  1998. this.offset = new Vector2( 0, 0 );
  1999. this.repeat = new Vector2( 1, 1 );
  2000. this.generateMipmaps = true;
  2001. this.premultiplyAlpha = false;
  2002. this.flipY = true;
  2003. this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
  2004. // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.
  2005. //
  2006. // Also changing the encoding after already used by a Material will not automatically make the Material
  2007. // update. You need to explicitly call Material.needsUpdate to trigger it to recompile.
  2008. this.encoding = encoding !== undefined ? encoding : LinearEncoding;
  2009. this.version = 0;
  2010. this.onUpdate = null;
  2011. }
  2012. Texture.DEFAULT_IMAGE = undefined;
  2013. Texture.DEFAULT_MAPPING = UVMapping;
  2014. Texture.prototype = {
  2015. constructor: Texture,
  2016. isTexture: true,
  2017. set needsUpdate( value ) {
  2018. if ( value === true ) this.version ++;
  2019. },
  2020. clone: function () {
  2021. return new this.constructor().copy( this );
  2022. },
  2023. copy: function ( source ) {
  2024. this.image = source.image;
  2025. this.mipmaps = source.mipmaps.slice( 0 );
  2026. this.mapping = source.mapping;
  2027. this.wrapS = source.wrapS;
  2028. this.wrapT = source.wrapT;
  2029. this.magFilter = source.magFilter;
  2030. this.minFilter = source.minFilter;
  2031. this.anisotropy = source.anisotropy;
  2032. this.format = source.format;
  2033. this.type = source.type;
  2034. this.offset.copy( source.offset );
  2035. this.repeat.copy( source.repeat );
  2036. this.generateMipmaps = source.generateMipmaps;
  2037. this.premultiplyAlpha = source.premultiplyAlpha;
  2038. this.flipY = source.flipY;
  2039. this.unpackAlignment = source.unpackAlignment;
  2040. this.encoding = source.encoding;
  2041. return this;
  2042. },
  2043. toJSON: function ( meta ) {
  2044. if ( meta.textures[ this.uuid ] !== undefined ) {
  2045. return meta.textures[ this.uuid ];
  2046. }
  2047. function getDataURL( image ) {
  2048. var canvas;
  2049. if ( image.toDataURL !== undefined ) {
  2050. canvas = image;
  2051. } else {
  2052. canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
  2053. canvas.width = image.width;
  2054. canvas.height = image.height;
  2055. canvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );
  2056. }
  2057. if ( canvas.width > 2048 || canvas.height > 2048 ) {
  2058. return canvas.toDataURL( 'image/jpeg', 0.6 );
  2059. } else {
  2060. return canvas.toDataURL( 'image/png' );
  2061. }
  2062. }
  2063. var output = {
  2064. metadata: {
  2065. version: 4.4,
  2066. type: 'Texture',
  2067. generator: 'Texture.toJSON'
  2068. },
  2069. uuid: this.uuid,
  2070. name: this.name,
  2071. mapping: this.mapping,
  2072. repeat: [ this.repeat.x, this.repeat.y ],
  2073. offset: [ this.offset.x, this.offset.y ],
  2074. wrap: [ this.wrapS, this.wrapT ],
  2075. minFilter: this.minFilter,
  2076. magFilter: this.magFilter,
  2077. anisotropy: this.anisotropy,
  2078. flipY: this.flipY
  2079. };
  2080. if ( this.image !== undefined ) {
  2081. // TODO: Move to THREE.Image
  2082. var image = this.image;
  2083. if ( image.uuid === undefined ) {
  2084. image.uuid = _Math.generateUUID(); // UGH
  2085. }
  2086. if ( meta.images[ image.uuid ] === undefined ) {
  2087. meta.images[ image.uuid ] = {
  2088. uuid: image.uuid,
  2089. url: getDataURL( image )
  2090. };
  2091. }
  2092. output.image = image.uuid;
  2093. }
  2094. meta.textures[ this.uuid ] = output;
  2095. return output;
  2096. },
  2097. dispose: function () {
  2098. this.dispatchEvent( { type: 'dispose' } );
  2099. },
  2100. transformUv: function ( uv ) {
  2101. if ( this.mapping !== UVMapping ) return;
  2102. uv.multiply( this.repeat );
  2103. uv.add( this.offset );
  2104. if ( uv.x < 0 || uv.x > 1 ) {
  2105. switch ( this.wrapS ) {
  2106. case RepeatWrapping:
  2107. uv.x = uv.x - Math.floor( uv.x );
  2108. break;
  2109. case ClampToEdgeWrapping:
  2110. uv.x = uv.x < 0 ? 0 : 1;
  2111. break;
  2112. case MirroredRepeatWrapping:
  2113. if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {
  2114. uv.x = Math.ceil( uv.x ) - uv.x;
  2115. } else {
  2116. uv.x = uv.x - Math.floor( uv.x );
  2117. }
  2118. break;
  2119. }
  2120. }
  2121. if ( uv.y < 0 || uv.y > 1 ) {
  2122. switch ( this.wrapT ) {
  2123. case RepeatWrapping:
  2124. uv.y = uv.y - Math.floor( uv.y );
  2125. break;
  2126. case ClampToEdgeWrapping:
  2127. uv.y = uv.y < 0 ? 0 : 1;
  2128. break;
  2129. case MirroredRepeatWrapping:
  2130. if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {
  2131. uv.y = Math.ceil( uv.y ) - uv.y;
  2132. } else {
  2133. uv.y = uv.y - Math.floor( uv.y );
  2134. }
  2135. break;
  2136. }
  2137. }
  2138. if ( this.flipY ) {
  2139. uv.y = 1 - uv.y;
  2140. }
  2141. }
  2142. };
  2143. Object.assign( Texture.prototype, EventDispatcher.prototype );
  2144. /**
  2145. * @author mrdoob / http://mrdoob.com/
  2146. */
  2147. function CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
  2148. images = images !== undefined ? images : [];
  2149. mapping = mapping !== undefined ? mapping : CubeReflectionMapping;
  2150. Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
  2151. this.flipY = false;
  2152. }
  2153. CubeTexture.prototype = Object.create( Texture.prototype );
  2154. CubeTexture.prototype.constructor = CubeTexture;
  2155. CubeTexture.prototype.isCubeTexture = true;
  2156. Object.defineProperty( CubeTexture.prototype, 'images', {
  2157. get: function () {
  2158. return this.image;
  2159. },
  2160. set: function ( value ) {
  2161. this.image = value;
  2162. }
  2163. } );
  2164. /**
  2165. * @author tschw
  2166. *
  2167. * Uniforms of a program.
  2168. * Those form a tree structure with a special top-level container for the root,
  2169. * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.
  2170. *
  2171. *
  2172. * Properties of inner nodes including the top-level container:
  2173. *
  2174. * .seq - array of nested uniforms
  2175. * .map - nested uniforms by name
  2176. *
  2177. *
  2178. * Methods of all nodes except the top-level container:
  2179. *
  2180. * .setValue( gl, value, [renderer] )
  2181. *
  2182. * uploads a uniform value(s)
  2183. * the 'renderer' parameter is needed for sampler uniforms
  2184. *
  2185. *
  2186. * Static methods of the top-level container (renderer factorizations):
  2187. *
  2188. * .upload( gl, seq, values, renderer )
  2189. *
  2190. * sets uniforms in 'seq' to 'values[id].value'
  2191. *
  2192. * .seqWithValue( seq, values ) : filteredSeq
  2193. *
  2194. * filters 'seq' entries with corresponding entry in values
  2195. *
  2196. *
  2197. * Methods of the top-level container (renderer factorizations):
  2198. *
  2199. * .setValue( gl, name, value )
  2200. *
  2201. * sets uniform with name 'name' to 'value'
  2202. *
  2203. * .set( gl, obj, prop )
  2204. *
  2205. * sets uniform from object and property with same name than uniform
  2206. *
  2207. * .setOptional( gl, obj, prop )
  2208. *
  2209. * like .set for an optional property of the object
  2210. *
  2211. */
  2212. var emptyTexture = new Texture();
  2213. var emptyCubeTexture = new CubeTexture();
  2214. // --- Base for inner nodes (including the root) ---
  2215. function UniformContainer() {
  2216. this.seq = [];
  2217. this.map = {};
  2218. }
  2219. // --- Utilities ---
  2220. // Array Caches (provide typed arrays for temporary by size)
  2221. var arrayCacheF32 = [];
  2222. var arrayCacheI32 = [];
  2223. // Flattening for arrays of vectors and matrices
  2224. function flatten( array, nBlocks, blockSize ) {
  2225. var firstElem = array[ 0 ];
  2226. if ( firstElem <= 0 || firstElem > 0 ) return array;
  2227. // unoptimized: ! isNaN( firstElem )
  2228. // see http://jacksondunstan.com/articles/983
  2229. var n = nBlocks * blockSize,
  2230. r = arrayCacheF32[ n ];
  2231. if ( r === undefined ) {
  2232. r = new Float32Array( n );
  2233. arrayCacheF32[ n ] = r;
  2234. }
  2235. if ( nBlocks !== 0 ) {
  2236. firstElem.toArray( r, 0 );
  2237. for ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {
  2238. offset += blockSize;
  2239. array[ i ].toArray( r, offset );
  2240. }
  2241. }
  2242. return r;
  2243. }
  2244. // Texture unit allocation
  2245. function allocTexUnits( renderer, n ) {
  2246. var r = arrayCacheI32[ n ];
  2247. if ( r === undefined ) {
  2248. r = new Int32Array( n );
  2249. arrayCacheI32[ n ] = r;
  2250. }
  2251. for ( var i = 0; i !== n; ++ i )
  2252. r[ i ] = renderer.allocTextureUnit();
  2253. return r;
  2254. }
  2255. // --- Setters ---
  2256. // Note: Defining these methods externally, because they come in a bunch
  2257. // and this way their names minify.
  2258. // Single scalar
  2259. function setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }
  2260. function setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }
  2261. // Single float vector (from flat array or THREE.VectorN)
  2262. function setValue2fv( gl, v ) {
  2263. if ( v.x === undefined ) gl.uniform2fv( this.addr, v );
  2264. else gl.uniform2f( this.addr, v.x, v.y );
  2265. }
  2266. function setValue3fv( gl, v ) {
  2267. if ( v.x !== undefined )
  2268. gl.uniform3f( this.addr, v.x, v.y, v.z );
  2269. else if ( v.r !== undefined )
  2270. gl.uniform3f( this.addr, v.r, v.g, v.b );
  2271. else
  2272. gl.uniform3fv( this.addr, v );
  2273. }
  2274. function setValue4fv( gl, v ) {
  2275. if ( v.x === undefined ) gl.uniform4fv( this.addr, v );
  2276. else gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );
  2277. }
  2278. // Single matrix (from flat array or MatrixN)
  2279. function setValue2fm( gl, v ) {
  2280. gl.uniformMatrix2fv( this.addr, false, v.elements || v );
  2281. }
  2282. function setValue3fm( gl, v ) {
  2283. gl.uniformMatrix3fv( this.addr, false, v.elements || v );
  2284. }
  2285. function setValue4fm( gl, v ) {
  2286. gl.uniformMatrix4fv( this.addr, false, v.elements || v );
  2287. }
  2288. // Single texture (2D / Cube)
  2289. function setValueT1( gl, v, renderer ) {
  2290. var unit = renderer.allocTextureUnit();
  2291. gl.uniform1i( this.addr, unit );
  2292. renderer.setTexture2D( v || emptyTexture, unit );
  2293. }
  2294. function setValueT6( gl, v, renderer ) {
  2295. var unit = renderer.allocTextureUnit();
  2296. gl.uniform1i( this.addr, unit );
  2297. renderer.setTextureCube( v || emptyCubeTexture, unit );
  2298. }
  2299. // Integer / Boolean vectors or arrays thereof (always flat arrays)
  2300. function setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }
  2301. function setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }
  2302. function setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }
  2303. // Helper to pick the right setter for the singular case
  2304. function getSingularSetter( type ) {
  2305. switch ( type ) {
  2306. case 0x1406: return setValue1f; // FLOAT
  2307. case 0x8b50: return setValue2fv; // _VEC2
  2308. case 0x8b51: return setValue3fv; // _VEC3
  2309. case 0x8b52: return setValue4fv; // _VEC4
  2310. case 0x8b5a: return setValue2fm; // _MAT2
  2311. case 0x8b5b: return setValue3fm; // _MAT3
  2312. case 0x8b5c: return setValue4fm; // _MAT4
  2313. case 0x8b5e: return setValueT1; // SAMPLER_2D
  2314. case 0x8b60: return setValueT6; // SAMPLER_CUBE
  2315. case 0x1404: case 0x8b56: return setValue1i; // INT, BOOL
  2316. case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2
  2317. case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3
  2318. case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4
  2319. }
  2320. }
  2321. // Array of scalars
  2322. function setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }
  2323. function setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }
  2324. // Array of vectors (flat or from THREE classes)
  2325. function setValueV2a( gl, v ) {
  2326. gl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );
  2327. }
  2328. function setValueV3a( gl, v ) {
  2329. gl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );
  2330. }
  2331. function setValueV4a( gl, v ) {
  2332. gl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );
  2333. }
  2334. // Array of matrices (flat or from THREE clases)
  2335. function setValueM2a( gl, v ) {
  2336. gl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );
  2337. }
  2338. function setValueM3a( gl, v ) {
  2339. gl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );
  2340. }
  2341. function setValueM4a( gl, v ) {
  2342. gl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );
  2343. }
  2344. // Array of textures (2D / Cube)
  2345. function setValueT1a( gl, v, renderer ) {
  2346. var n = v.length,
  2347. units = allocTexUnits( renderer, n );
  2348. gl.uniform1iv( this.addr, units );
  2349. for ( var i = 0; i !== n; ++ i ) {
  2350. renderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );
  2351. }
  2352. }
  2353. function setValueT6a( gl, v, renderer ) {
  2354. var n = v.length,
  2355. units = allocTexUnits( renderer, n );
  2356. gl.uniform1iv( this.addr, units );
  2357. for ( var i = 0; i !== n; ++ i ) {
  2358. renderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );
  2359. }
  2360. }
  2361. // Helper to pick the right setter for a pure (bottom-level) array
  2362. function getPureArraySetter( type ) {
  2363. switch ( type ) {
  2364. case 0x1406: return setValue1fv; // FLOAT
  2365. case 0x8b50: return setValueV2a; // _VEC2
  2366. case 0x8b51: return setValueV3a; // _VEC3
  2367. case 0x8b52: return setValueV4a; // _VEC4
  2368. case 0x8b5a: return setValueM2a; // _MAT2
  2369. case 0x8b5b: return setValueM3a; // _MAT3
  2370. case 0x8b5c: return setValueM4a; // _MAT4
  2371. case 0x8b5e: return setValueT1a; // SAMPLER_2D
  2372. case 0x8b60: return setValueT6a; // SAMPLER_CUBE
  2373. case 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL
  2374. case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2
  2375. case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3
  2376. case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4
  2377. }
  2378. }
  2379. // --- Uniform Classes ---
  2380. function SingleUniform( id, activeInfo, addr ) {
  2381. this.id = id;
  2382. this.addr = addr;
  2383. this.setValue = getSingularSetter( activeInfo.type );
  2384. // this.path = activeInfo.name; // DEBUG
  2385. }
  2386. function PureArrayUniform( id, activeInfo, addr ) {
  2387. this.id = id;
  2388. this.addr = addr;
  2389. this.size = activeInfo.size;
  2390. this.setValue = getPureArraySetter( activeInfo.type );
  2391. // this.path = activeInfo.name; // DEBUG
  2392. }
  2393. function StructuredUniform( id ) {
  2394. this.id = id;
  2395. UniformContainer.call( this ); // mix-in
  2396. }
  2397. StructuredUniform.prototype.setValue = function( gl, value ) {
  2398. // Note: Don't need an extra 'renderer' parameter, since samplers
  2399. // are not allowed in structured uniforms.
  2400. var seq = this.seq;
  2401. for ( var i = 0, n = seq.length; i !== n; ++ i ) {
  2402. var u = seq[ i ];
  2403. u.setValue( gl, value[ u.id ] );
  2404. }
  2405. };
  2406. // --- Top-level ---
  2407. // Parser - builds up the property tree from the path strings
  2408. var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g;
  2409. // extracts
  2410. // - the identifier (member name or array index)
  2411. // - followed by an optional right bracket (found when array index)
  2412. // - followed by an optional left bracket or dot (type of subscript)
  2413. //
  2414. // Note: These portions can be read in a non-overlapping fashion and
  2415. // allow straightforward parsing of the hierarchy that WebGL encodes
  2416. // in the uniform names.
  2417. function addUniform( container, uniformObject ) {
  2418. container.seq.push( uniformObject );
  2419. container.map[ uniformObject.id ] = uniformObject;
  2420. }
  2421. function parseUniform( activeInfo, addr, container ) {
  2422. var path = activeInfo.name,
  2423. pathLength = path.length;
  2424. // reset RegExp object, because of the early exit of a previous run
  2425. RePathPart.lastIndex = 0;
  2426. for (; ;) {
  2427. var match = RePathPart.exec( path ),
  2428. matchEnd = RePathPart.lastIndex,
  2429. id = match[ 1 ],
  2430. idIsIndex = match[ 2 ] === ']',
  2431. subscript = match[ 3 ];
  2432. if ( idIsIndex ) id = id | 0; // convert to integer
  2433. if ( subscript === undefined ||
  2434. subscript === '[' && matchEnd + 2 === pathLength ) {
  2435. // bare name or "pure" bottom-level array "[0]" suffix
  2436. addUniform( container, subscript === undefined ?
  2437. new SingleUniform( id, activeInfo, addr ) :
  2438. new PureArrayUniform( id, activeInfo, addr ) );
  2439. break;
  2440. } else {
  2441. // step into inner node / create it in case it doesn't exist
  2442. var map = container.map,
  2443. next = map[ id ];
  2444. if ( next === undefined ) {
  2445. next = new StructuredUniform( id );
  2446. addUniform( container, next );
  2447. }
  2448. container = next;
  2449. }
  2450. }
  2451. }
  2452. // Root Container
  2453. function WebGLUniforms( gl, program, renderer ) {
  2454. UniformContainer.call( this );
  2455. this.renderer = renderer;
  2456. var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );
  2457. for ( var i = 0; i < n; ++ i ) {
  2458. var info = gl.getActiveUniform( program, i ),
  2459. path = info.name,
  2460. addr = gl.getUniformLocation( program, path );
  2461. parseUniform( info, addr, this );
  2462. }
  2463. }
  2464. WebGLUniforms.prototype.setValue = function( gl, name, value ) {
  2465. var u = this.map[ name ];
  2466. if ( u !== undefined ) u.setValue( gl, value, this.renderer );
  2467. };
  2468. WebGLUniforms.prototype.set = function( gl, object, name ) {
  2469. var u = this.map[ name ];
  2470. if ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );
  2471. };
  2472. WebGLUniforms.prototype.setOptional = function( gl, object, name ) {
  2473. var v = object[ name ];
  2474. if ( v !== undefined ) this.setValue( gl, name, v );
  2475. };
  2476. // Static interface
  2477. WebGLUniforms.upload = function( gl, seq, values, renderer ) {
  2478. for ( var i = 0, n = seq.length; i !== n; ++ i ) {
  2479. var u = seq[ i ],
  2480. v = values[ u.id ];
  2481. if ( v.needsUpdate !== false ) {
  2482. // note: always updating when .needsUpdate is undefined
  2483. u.setValue( gl, v.value, renderer );
  2484. }
  2485. }
  2486. };
  2487. WebGLUniforms.seqWithValue = function( seq, values ) {
  2488. var r = [];
  2489. for ( var i = 0, n = seq.length; i !== n; ++ i ) {
  2490. var u = seq[ i ];
  2491. if ( u.id in values ) r.push( u );
  2492. }
  2493. return r;
  2494. };
  2495. /**
  2496. * Uniform Utilities
  2497. */
  2498. var UniformsUtils = {
  2499. merge: function ( uniforms ) {
  2500. var merged = {};
  2501. for ( var u = 0; u < uniforms.length; u ++ ) {
  2502. var tmp = this.clone( uniforms[ u ] );
  2503. for ( var p in tmp ) {
  2504. merged[ p ] = tmp[ p ];
  2505. }
  2506. }
  2507. return merged;
  2508. },
  2509. clone: function ( uniforms_src ) {
  2510. var uniforms_dst = {};
  2511. for ( var u in uniforms_src ) {
  2512. uniforms_dst[ u ] = {};
  2513. for ( var p in uniforms_src[ u ] ) {
  2514. var parameter_src = uniforms_src[ u ][ p ];
  2515. if ( parameter_src && ( parameter_src.isColor ||
  2516. parameter_src.isMatrix3 || parameter_src.isMatrix4 ||
  2517. parameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||
  2518. parameter_src.isTexture ) ) {
  2519. uniforms_dst[ u ][ p ] = parameter_src.clone();
  2520. } else if ( Array.isArray( parameter_src ) ) {
  2521. uniforms_dst[ u ][ p ] = parameter_src.slice();
  2522. } else {
  2523. uniforms_dst[ u ][ p ] = parameter_src;
  2524. }
  2525. }
  2526. }
  2527. return uniforms_dst;
  2528. }
  2529. };
  2530. var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif\n";
  2531. var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif\n";
  2532. var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif\n";
  2533. 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";
  2534. var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif";
  2535. var begin_vertex = "\nvec3 transformed = vec3( position );\n";
  2536. var beginnormal_vertex = "\nvec3 objectNormal = vec3( normal );\n";
  2537. var bsdfs = "float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\t\tif( decayExponent > 0.0 ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\t\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\t\treturn distanceFalloff * maxDistanceCutoffFactor;\n#else\n\t\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n#endif\n\t\t}\n\t\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 ltcTextureCoords( const in GeometricContext geometry, 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\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 P = geometry.position;\n\tfloat theta = acos( dot( N, V ) );\n\tvec2 uv = vec2(\n\t\tsqrt( saturate( roughness ) ),\n\t\tsaturate( theta / ( 0.5 * PI ) ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nvoid clipQuadToHorizon( inout vec3 L[5], out int n ) {\n\tint config = 0;\n\tif ( L[0].z > 0.0 ) config += 1;\n\tif ( L[1].z > 0.0 ) config += 2;\n\tif ( L[2].z > 0.0 ) config += 4;\n\tif ( L[3].z > 0.0 ) config += 8;\n\tn = 0;\n\tif ( config == 0 ) {\n\t} else if ( config == 1 ) {\n\t\tn = 3;\n\t\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\n\t\tL[2] = -L[3].z * L[0] + L[0].z * L[3];\n\t} else if ( config == 2 ) {\n\t\tn = 3;\n\t\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\n\t\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\n\t} else if ( config == 3 ) {\n\t\tn = 4;\n\t\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\n\t\tL[3] = -L[3].z * L[0] + L[0].z * L[3];\n\t} else if ( config == 4 ) {\n\t\tn = 3;\n\t\tL[0] = -L[3].z * L[2] + L[2].z * L[3];\n\t\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\n\t} else if ( config == 5 ) {\n\t\tn = 0;\n\t} else if ( config == 6 ) {\n\t\tn = 4;\n\t\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\n\t\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\n\t} else if ( config == 7 ) {\n\t\tn = 5;\n\t\tL[4] = -L[3].z * L[0] + L[0].z * L[3];\n\t\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\n\t} else if ( config == 8 ) {\n\t\tn = 3;\n\t\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\n\t\tL[1] = -L[2].z * L[3] + L[3].z * L[2];\n\t\tL[2] = L[3];\n\t} else if ( config == 9 ) {\n\t\tn = 4;\n\t\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\n\t\tL[2] = -L[2].z * L[3] + L[3].z * L[2];\n\t} else if ( config == 10 ) {\n\t\tn = 0;\n\t} else if ( config == 11 ) {\n\t\tn = 5;\n\t\tL[4] = L[3];\n\t\tL[3] = -L[2].z * L[3] + L[3].z * L[2];\n\t\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\n\t} else if ( config == 12 ) {\n\t\tn = 4;\n\t\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\n\t\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\n\t} else if ( config == 13 ) {\n\t\tn = 5;\n\t\tL[4] = L[3];\n\t\tL[3] = L[2];\n\t\tL[2] = -L[1].z * L[2] + L[2].z * L[1];\n\t\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\n\t} else if ( config == 14 ) {\n\t\tn = 5;\n\t\tL[4] = -L[0].z * L[3] + L[3].z * L[0];\n\t\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\n\t} else if ( config == 15 ) {\n\t\tn = 4;\n\t}\n\tif ( n == 3 )\n\t\tL[3] = L[0];\n\tif ( n == 4 )\n\t\tL[4] = L[0];\n}\nfloat integrateLtcBrdfOverRectEdge( vec3 v1, vec3 v2 ) {\n\tfloat cosTheta = dot( v1, v2 );\n\tfloat theta = acos( cosTheta );\n\tfloat res = cross( v1, v2 ).z * ( ( theta > 0.001 ) ? theta / sin( theta ) : 1.0 );\n\treturn res;\n}\nvoid initRectPoints( const in vec3 pos, const in vec3 halfWidth, const in vec3 halfHeight, out vec3 rectPoints[4] ) {\n\trectPoints[0] = pos - halfWidth - halfHeight;\n\trectPoints[1] = pos + halfWidth - halfHeight;\n\trectPoints[2] = pos + halfWidth + halfHeight;\n\trectPoints[3] = pos - halfWidth + halfHeight;\n}\nvec3 integrateLtcBrdfOverRect( const in GeometricContext geometry, const in mat3 brdfMat, const in vec3 rectPoints[4] ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 P = geometry.position;\n\tvec3 T1, T2;\n\tT1 = normalize(V - N * dot( V, N ));\n\tT2 = - cross( N, T1 );\n\tmat3 brdfWrtSurface = brdfMat * transpose( mat3( T1, T2, N ) );\n\tvec3 clippedRect[5];\n\tclippedRect[0] = brdfWrtSurface * ( rectPoints[0] - P );\n\tclippedRect[1] = brdfWrtSurface * ( rectPoints[1] - P );\n\tclippedRect[2] = brdfWrtSurface * ( rectPoints[2] - P );\n\tclippedRect[3] = brdfWrtSurface * ( rectPoints[3] - P );\n\tint n;\n\tclipQuadToHorizon(clippedRect, n);\n\tif ( n == 0 )\n\t\treturn vec3( 0, 0, 0 );\n\tclippedRect[0] = normalize( clippedRect[0] );\n\tclippedRect[1] = normalize( clippedRect[1] );\n\tclippedRect[2] = normalize( clippedRect[2] );\n\tclippedRect[3] = normalize( clippedRect[3] );\n\tclippedRect[4] = normalize( clippedRect[4] );\n\tfloat sum = 0.0;\n\tsum += integrateLtcBrdfOverRectEdge( clippedRect[0], clippedRect[1] );\n\tsum += integrateLtcBrdfOverRectEdge( clippedRect[1], clippedRect[2] );\n\tsum += integrateLtcBrdfOverRectEdge( clippedRect[2], clippedRect[3] );\n\tif (n >= 4)\n\t\tsum += integrateLtcBrdfOverRectEdge( clippedRect[3], clippedRect[4] );\n\tif (n == 5)\n\t\tsum += integrateLtcBrdfOverRectEdge( clippedRect[4], clippedRect[0] );\n\tsum = max( 0.0, sum );\n\tvec3 Lo_i = vec3( sum, sum, sum );\n\treturn Lo_i;\n}\nvec3 Rect_Area_Light_Specular_Reflectance(\n\t\tconst in GeometricContext geometry,\n\t\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight,\n\t\tconst in float roughness,\n\t\tconst in sampler2D ltcMat, const in sampler2D ltcMag ) {\n\tvec3 rectPoints[4];\n\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\n\tvec2 uv = ltcTextureCoords( geometry, roughness );\n\tvec4 brdfLtcApproxParams, t;\n\tbrdfLtcApproxParams = texture2D( ltcMat, uv );\n\tt = texture2D( ltcMat, uv );\n\tfloat brdfLtcScalar = texture2D( ltcMag, uv ).a;\n\tmat3 brdfLtcApproxMat = mat3(\n\t\tvec3( 1, 0, t.y ),\n\t\tvec3( 0, t.z, 0 ),\n\t\tvec3( t.w, 0, t.x )\n\t);\n\tvec3 specularReflectance = integrateLtcBrdfOverRect( geometry, brdfLtcApproxMat, rectPoints );\n\tspecularReflectance *= brdfLtcScalar;\n\treturn specularReflectance;\n}\nvec3 Rect_Area_Light_Diffuse_Reflectance(\n\t\tconst in GeometricContext geometry,\n\t\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight ) {\n\tvec3 rectPoints[4];\n\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\n\tmat3 diffuseBrdfMat = mat3(1);\n\tvec3 diffuseReflectance = integrateLtcBrdfOverRect( geometry, diffuseBrdfMat, rectPoints );\n\treturn diffuseReflectance;\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";
  2538. 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 = dFdx( surf_pos );\n\t\tvec3 vSigmaY = dFdy( surf_pos );\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\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif\n";
  2539. var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\n\t\tvec4 plane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t\t\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\n\t\t\tvec4 plane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t\n\t#endif\n#endif\n";
  2540. 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";
  2541. var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvarying vec3 vViewPosition;\n#endif\n";
  2542. var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n";
  2543. var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif";
  2544. var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif\n";
  2545. var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif";
  2546. var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif";
  2547. 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 transpose( const in mat3 v ) {\n\tmat3 tmp;\n\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\n\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\n\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\n\treturn tmp;\n}\n";
  2548. 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(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";
  2549. var defaultnormal_vertex = "#ifdef FLIP_SIDED\n\tobjectNormal = -objectNormal;\n#endif\nvec3 transformedNormal = normalMatrix * objectNormal;\n";
  2550. var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif\n";
  2551. var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif\n";
  2552. 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";
  2553. var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif\n";
  2554. var encodings_fragment = " gl_FragColor = linearToOutputTexel( gl_FragColor );\n";
  2555. 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";
  2556. 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, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n\t\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\tvec3 reflectView = flipNormal * 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";
  2557. 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\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";
  2558. 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";
  2559. 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";
  2560. var fog_vertex = "\n#ifdef USE_FOG\nfogDepth = -mvPosition.z;\n#endif";
  2561. var fog_pars_vertex = "#ifdef USE_FOG\n varying float fogDepth;\n#endif\n";
  2562. 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";
  2563. 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";
  2564. 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";
  2565. var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif\n";
  2566. var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif";
  2567. 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\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\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\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\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";
  2568. var lights_pars = "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};\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 ltcMat;\tuniform sampler2D ltcMag;\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#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( 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(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = saturate( reflectVec.y * 0.5 + 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";
  2569. var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;\n";
  2570. 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};\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_BlinnPhong( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 matDiffColor = material.diffuseColor;\n\t\tvec3 matSpecColor = material.specularColor;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = BlinnExponentToGGXRoughness( material.specularShininess );\n\t\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\n\t\t\t\tgeometry,\n\t\t\t\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\n\t\t\t\troughness,\n\t\t\t\tltcMat, ltcMag );\n\t\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\n\t\t\t\tgeometry,\n\t\t\t\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\n\t\treflectedLight.directSpecular += lightColor * matSpecColor * spec / PI2;\n\t\treflectedLight.directDiffuse += lightColor * matDiffColor * diff / PI2;\n\t}\n#endif\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_Direct_RectArea\t\tRE_Direct_RectArea_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)\n";
  2571. 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";
  2572. 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 matDiffColor = material.diffuseColor;\n\t\tvec3 matSpecColor = material.specularColor;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\n\t\t\t\tgeometry,\n\t\t\t\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\n\t\t\t\troughness,\n\t\t\t\tltcMat, ltcMag );\n\t\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\n\t\t\t\tgeometry,\n\t\t\t\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\n\t\treflectedLight.directSpecular += lightColor * matSpecColor * spec;\n\t\treflectedLight.directDiffuse += lightColor * matDiffColor * diff;\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";
  2573. var lights_template = "\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\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 ] ) : 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\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\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\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#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 ( NUM_HEMI_LIGHTS > 0 )\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\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\n\t#endif\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\n\t#ifndef STANDARD\n\t\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\n\t#else\n\t\tvec3 clearCoatRadiance = vec3( 0.0 );\n\t#endif\n\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif\n";
  2574. var logdepthbuf_fragment = "#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\n\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\n#endif";
  2575. 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";
  2576. 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";
  2577. var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\n\t#endif\n#endif\n";
  2578. var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif\n";
  2579. var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n";
  2580. var map_particle_fragment = "#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n";
  2581. var map_particle_pars_fragment = "#ifdef USE_MAP\n\tuniform vec4 offsetRepeat;\n\tuniform sampler2D map;\n#endif\n";
  2582. var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.r;\n#endif\n";
  2583. var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif";
  2584. 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";
  2585. 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";
  2586. 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";
  2587. var normal_flip = "#ifdef DOUBLE_SIDED\n\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n#else\n\tfloat flipNormal = 1.0;\n#endif\n";
  2588. var normal_fragment = "#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 ) * flipNormal;\n#endif\n#ifdef USE_NORMALMAP\n\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n";
  2589. var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\n\t\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif\n";
  2590. 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 1.0 - 2.0 * rgb.xyz;\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";
  2591. var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif\n";
  2592. var project_vertex = "#ifdef USE_SKINNING\n\tvec4 mvPosition = modelViewMatrix * skinned;\n#else\n\tvec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\n#endif\ngl_Position = projectionMatrix * mvPosition;\n";
  2593. var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.r;\n#endif\n";
  2594. var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif";
  2595. 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\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\treturn (\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\treturn (\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\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn 1.0;\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 ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\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";
  2596. 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";
  2597. var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\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\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\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif\n";
  2598. 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\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\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\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 ] ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}\n";
  2599. 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";
  2600. 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 boneTextureWidth;\n\t\tuniform int boneTextureHeight;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureWidth ) );\n\t\t\tfloat y = floor( j / float( boneTextureWidth ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureWidth );\n\t\t\tfloat dy = 1.0 / float( boneTextureHeight );\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";
  2601. 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\tskinned = bindMatrixInverse * skinned;\n#endif\n";
  2602. 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";
  2603. 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";
  2604. var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif";
  2605. var tonemapping_fragment = "#if defined( TONE_MAPPING )\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif\n";
  2606. var tonemapping_pars_fragment = "#define saturate(a) clamp( a, 0.0, 1.0 )\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";
  2607. 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";
  2608. 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 vec4 offsetRepeat;\n#endif\n";
  2609. 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 = uv * offsetRepeat.zw + offsetRepeat.xy;\n#endif";
  2610. var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif";
  2611. var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif";
  2612. var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif";
  2613. var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\n\t#ifdef USE_SKINNING\n\t\tvec4 worldPosition = modelMatrix * skinned;\n\t#else\n\t\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n\t#endif\n#endif\n";
  2614. var cube_frag = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\tgl_FragColor.a *= opacity;\n}\n";
  2615. var cube_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n";
  2616. var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n";
  2617. var depth_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#include <begin_vertex>\n\t#include <displacementmap_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n}\n";
  2618. var distanceRGBA_frag = "uniform vec3 lightPos;\nvarying vec4 vWorldPosition;\n#include <common>\n#include <packing>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\t#include <clipping_planes_fragment>\n\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\n}\n";
  2619. var distanceRGBA_vert = "varying vec4 vWorldPosition;\n#include <common>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <skinbase_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition;\n}\n";
  2620. var equirect_frag = "uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}\n";
  2621. var equirect_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n";
  2622. var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\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 <logdepthbuf_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n";
  2623. var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}\n";
  2624. var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\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 <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <normal_flip>\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n";
  2625. var meshbasic_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_ENVMAP\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}\n";
  2626. 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 <common>\n#include <packing>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <bsdfs>\n#include <lights_pars>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\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 <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <emissivemap_fragment>\n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#include <lightmap_fragment>\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 <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <normal_flip>\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n";
  2627. var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <bsdfs>\n#include <lights_pars>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <lights_lambert_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n";
  2628. var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\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 <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_template>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n";
  2629. var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <displacementmap_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n";
  2630. 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 <common>\n#include <packing>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\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 <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_template>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n";
  2631. var meshphysical_vert = "#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <displacementmap_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n";
  2632. var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\nvoid main() {\n\t#include <logdepthbuf_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}\n";
  2633. var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <displacementmap_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}\n";
  2634. var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n";
  2635. var points_vert = "uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <project_vertex>\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 <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n";
  2636. var shadow_frag = "uniform float opacity;\n#include <common>\n#include <packing>\n#include <bsdfs>\n#include <lights_pars>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\n}\n";
  2637. var shadow_vert = "#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n}\n";
  2638. var ShaderChunk = {
  2639. alphamap_fragment: alphamap_fragment,
  2640. alphamap_pars_fragment: alphamap_pars_fragment,
  2641. alphatest_fragment: alphatest_fragment,
  2642. aomap_fragment: aomap_fragment,
  2643. aomap_pars_fragment: aomap_pars_fragment,
  2644. begin_vertex: begin_vertex,
  2645. beginnormal_vertex: beginnormal_vertex,
  2646. bsdfs: bsdfs,
  2647. bumpmap_pars_fragment: bumpmap_pars_fragment,
  2648. clipping_planes_fragment: clipping_planes_fragment,
  2649. clipping_planes_pars_fragment: clipping_planes_pars_fragment,
  2650. clipping_planes_pars_vertex: clipping_planes_pars_vertex,
  2651. clipping_planes_vertex: clipping_planes_vertex,
  2652. color_fragment: color_fragment,
  2653. color_pars_fragment: color_pars_fragment,
  2654. color_pars_vertex: color_pars_vertex,
  2655. color_vertex: color_vertex,
  2656. common: common,
  2657. cube_uv_reflection_fragment: cube_uv_reflection_fragment,
  2658. defaultnormal_vertex: defaultnormal_vertex,
  2659. displacementmap_pars_vertex: displacementmap_pars_vertex,
  2660. displacementmap_vertex: displacementmap_vertex,
  2661. emissivemap_fragment: emissivemap_fragment,
  2662. emissivemap_pars_fragment: emissivemap_pars_fragment,
  2663. encodings_fragment: encodings_fragment,
  2664. encodings_pars_fragment: encodings_pars_fragment,
  2665. envmap_fragment: envmap_fragment,
  2666. envmap_pars_fragment: envmap_pars_fragment,
  2667. envmap_pars_vertex: envmap_pars_vertex,
  2668. envmap_vertex: envmap_vertex,
  2669. fog_vertex: fog_vertex,
  2670. fog_pars_vertex: fog_pars_vertex,
  2671. fog_fragment: fog_fragment,
  2672. fog_pars_fragment: fog_pars_fragment,
  2673. gradientmap_pars_fragment: gradientmap_pars_fragment,
  2674. lightmap_fragment: lightmap_fragment,
  2675. lightmap_pars_fragment: lightmap_pars_fragment,
  2676. lights_lambert_vertex: lights_lambert_vertex,
  2677. lights_pars: lights_pars,
  2678. lights_phong_fragment: lights_phong_fragment,
  2679. lights_phong_pars_fragment: lights_phong_pars_fragment,
  2680. lights_physical_fragment: lights_physical_fragment,
  2681. lights_physical_pars_fragment: lights_physical_pars_fragment,
  2682. lights_template: lights_template,
  2683. logdepthbuf_fragment: logdepthbuf_fragment,
  2684. logdepthbuf_pars_fragment: logdepthbuf_pars_fragment,
  2685. logdepthbuf_pars_vertex: logdepthbuf_pars_vertex,
  2686. logdepthbuf_vertex: logdepthbuf_vertex,
  2687. map_fragment: map_fragment,
  2688. map_pars_fragment: map_pars_fragment,
  2689. map_particle_fragment: map_particle_fragment,
  2690. map_particle_pars_fragment: map_particle_pars_fragment,
  2691. metalnessmap_fragment: metalnessmap_fragment,
  2692. metalnessmap_pars_fragment: metalnessmap_pars_fragment,
  2693. morphnormal_vertex: morphnormal_vertex,
  2694. morphtarget_pars_vertex: morphtarget_pars_vertex,
  2695. morphtarget_vertex: morphtarget_vertex,
  2696. normal_flip: normal_flip,
  2697. normal_fragment: normal_fragment,
  2698. normalmap_pars_fragment: normalmap_pars_fragment,
  2699. packing: packing,
  2700. premultiplied_alpha_fragment: premultiplied_alpha_fragment,
  2701. project_vertex: project_vertex,
  2702. roughnessmap_fragment: roughnessmap_fragment,
  2703. roughnessmap_pars_fragment: roughnessmap_pars_fragment,
  2704. shadowmap_pars_fragment: shadowmap_pars_fragment,
  2705. shadowmap_pars_vertex: shadowmap_pars_vertex,
  2706. shadowmap_vertex: shadowmap_vertex,
  2707. shadowmask_pars_fragment: shadowmask_pars_fragment,
  2708. skinbase_vertex: skinbase_vertex,
  2709. skinning_pars_vertex: skinning_pars_vertex,
  2710. skinning_vertex: skinning_vertex,
  2711. skinnormal_vertex: skinnormal_vertex,
  2712. specularmap_fragment: specularmap_fragment,
  2713. specularmap_pars_fragment: specularmap_pars_fragment,
  2714. tonemapping_fragment: tonemapping_fragment,
  2715. tonemapping_pars_fragment: tonemapping_pars_fragment,
  2716. uv_pars_fragment: uv_pars_fragment,
  2717. uv_pars_vertex: uv_pars_vertex,
  2718. uv_vertex: uv_vertex,
  2719. uv2_pars_fragment: uv2_pars_fragment,
  2720. uv2_pars_vertex: uv2_pars_vertex,
  2721. uv2_vertex: uv2_vertex,
  2722. worldpos_vertex: worldpos_vertex,
  2723. cube_frag: cube_frag,
  2724. cube_vert: cube_vert,
  2725. depth_frag: depth_frag,
  2726. depth_vert: depth_vert,
  2727. distanceRGBA_frag: distanceRGBA_frag,
  2728. distanceRGBA_vert: distanceRGBA_vert,
  2729. equirect_frag: equirect_frag,
  2730. equirect_vert: equirect_vert,
  2731. linedashed_frag: linedashed_frag,
  2732. linedashed_vert: linedashed_vert,
  2733. meshbasic_frag: meshbasic_frag,
  2734. meshbasic_vert: meshbasic_vert,
  2735. meshlambert_frag: meshlambert_frag,
  2736. meshlambert_vert: meshlambert_vert,
  2737. meshphong_frag: meshphong_frag,
  2738. meshphong_vert: meshphong_vert,
  2739. meshphysical_frag: meshphysical_frag,
  2740. meshphysical_vert: meshphysical_vert,
  2741. normal_frag: normal_frag,
  2742. normal_vert: normal_vert,
  2743. points_frag: points_frag,
  2744. points_vert: points_vert,
  2745. shadow_frag: shadow_frag,
  2746. shadow_vert: shadow_vert
  2747. };
  2748. /**
  2749. * @author supereggbert / http://www.paulbrunt.co.uk/
  2750. * @author philogb / http://blog.thejit.org/
  2751. * @author mikael emtinger / http://gomo.se/
  2752. * @author egraether / http://egraether.com/
  2753. * @author WestLangley / http://github.com/WestLangley
  2754. */
  2755. function Vector4( x, y, z, w ) {
  2756. this.x = x || 0;
  2757. this.y = y || 0;
  2758. this.z = z || 0;
  2759. this.w = ( w !== undefined ) ? w : 1;
  2760. }
  2761. Vector4.prototype = {
  2762. constructor: Vector4,
  2763. isVector4: true,
  2764. set: function ( x, y, z, w ) {
  2765. this.x = x;
  2766. this.y = y;
  2767. this.z = z;
  2768. this.w = w;
  2769. return this;
  2770. },
  2771. setScalar: function ( scalar ) {
  2772. this.x = scalar;
  2773. this.y = scalar;
  2774. this.z = scalar;
  2775. this.w = scalar;
  2776. return this;
  2777. },
  2778. setX: function ( x ) {
  2779. this.x = x;
  2780. return this;
  2781. },
  2782. setY: function ( y ) {
  2783. this.y = y;
  2784. return this;
  2785. },
  2786. setZ: function ( z ) {
  2787. this.z = z;
  2788. return this;
  2789. },
  2790. setW: function ( w ) {
  2791. this.w = w;
  2792. return this;
  2793. },
  2794. setComponent: function ( index, value ) {
  2795. switch ( index ) {
  2796. case 0: this.x = value; break;
  2797. case 1: this.y = value; break;
  2798. case 2: this.z = value; break;
  2799. case 3: this.w = value; break;
  2800. default: throw new Error( 'index is out of range: ' + index );
  2801. }
  2802. return this;
  2803. },
  2804. getComponent: function ( index ) {
  2805. switch ( index ) {
  2806. case 0: return this.x;
  2807. case 1: return this.y;
  2808. case 2: return this.z;
  2809. case 3: return this.w;
  2810. default: throw new Error( 'index is out of range: ' + index );
  2811. }
  2812. },
  2813. clone: function () {
  2814. return new this.constructor( this.x, this.y, this.z, this.w );
  2815. },
  2816. copy: function ( v ) {
  2817. this.x = v.x;
  2818. this.y = v.y;
  2819. this.z = v.z;
  2820. this.w = ( v.w !== undefined ) ? v.w : 1;
  2821. return this;
  2822. },
  2823. add: function ( v, w ) {
  2824. if ( w !== undefined ) {
  2825. console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
  2826. return this.addVectors( v, w );
  2827. }
  2828. this.x += v.x;
  2829. this.y += v.y;
  2830. this.z += v.z;
  2831. this.w += v.w;
  2832. return this;
  2833. },
  2834. addScalar: function ( s ) {
  2835. this.x += s;
  2836. this.y += s;
  2837. this.z += s;
  2838. this.w += s;
  2839. return this;
  2840. },
  2841. addVectors: function ( a, b ) {
  2842. this.x = a.x + b.x;
  2843. this.y = a.y + b.y;
  2844. this.z = a.z + b.z;
  2845. this.w = a.w + b.w;
  2846. return this;
  2847. },
  2848. addScaledVector: function ( v, s ) {
  2849. this.x += v.x * s;
  2850. this.y += v.y * s;
  2851. this.z += v.z * s;
  2852. this.w += v.w * s;
  2853. return this;
  2854. },
  2855. sub: function ( v, w ) {
  2856. if ( w !== undefined ) {
  2857. console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
  2858. return this.subVectors( v, w );
  2859. }
  2860. this.x -= v.x;
  2861. this.y -= v.y;
  2862. this.z -= v.z;
  2863. this.w -= v.w;
  2864. return this;
  2865. },
  2866. subScalar: function ( s ) {
  2867. this.x -= s;
  2868. this.y -= s;
  2869. this.z -= s;
  2870. this.w -= s;
  2871. return this;
  2872. },
  2873. subVectors: function ( a, b ) {
  2874. this.x = a.x - b.x;
  2875. this.y = a.y - b.y;
  2876. this.z = a.z - b.z;
  2877. this.w = a.w - b.w;
  2878. return this;
  2879. },
  2880. multiplyScalar: function ( scalar ) {
  2881. if ( isFinite( scalar ) ) {
  2882. this.x *= scalar;
  2883. this.y *= scalar;
  2884. this.z *= scalar;
  2885. this.w *= scalar;
  2886. } else {
  2887. this.x = 0;
  2888. this.y = 0;
  2889. this.z = 0;
  2890. this.w = 0;
  2891. }
  2892. return this;
  2893. },
  2894. applyMatrix4: function ( m ) {
  2895. var x = this.x, y = this.y, z = this.z, w = this.w;
  2896. var e = m.elements;
  2897. this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;
  2898. this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;
  2899. this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;
  2900. this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;
  2901. return this;
  2902. },
  2903. divideScalar: function ( scalar ) {
  2904. return this.multiplyScalar( 1 / scalar );
  2905. },
  2906. setAxisAngleFromQuaternion: function ( q ) {
  2907. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
  2908. // q is assumed to be normalized
  2909. this.w = 2 * Math.acos( q.w );
  2910. var s = Math.sqrt( 1 - q.w * q.w );
  2911. if ( s < 0.0001 ) {
  2912. this.x = 1;
  2913. this.y = 0;
  2914. this.z = 0;
  2915. } else {
  2916. this.x = q.x / s;
  2917. this.y = q.y / s;
  2918. this.z = q.z / s;
  2919. }
  2920. return this;
  2921. },
  2922. setAxisAngleFromRotationMatrix: function ( m ) {
  2923. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
  2924. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  2925. var angle, x, y, z, // variables for result
  2926. epsilon = 0.01, // margin to allow for rounding errors
  2927. epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees
  2928. te = m.elements,
  2929. m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
  2930. m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
  2931. m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
  2932. if ( ( Math.abs( m12 - m21 ) < epsilon ) &&
  2933. ( Math.abs( m13 - m31 ) < epsilon ) &&
  2934. ( Math.abs( m23 - m32 ) < epsilon ) ) {
  2935. // singularity found
  2936. // first check for identity matrix which must have +1 for all terms
  2937. // in leading diagonal and zero in other terms
  2938. if ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&
  2939. ( Math.abs( m13 + m31 ) < epsilon2 ) &&
  2940. ( Math.abs( m23 + m32 ) < epsilon2 ) &&
  2941. ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {
  2942. // this singularity is identity matrix so angle = 0
  2943. this.set( 1, 0, 0, 0 );
  2944. return this; // zero angle, arbitrary axis
  2945. }
  2946. // otherwise this singularity is angle = 180
  2947. angle = Math.PI;
  2948. var xx = ( m11 + 1 ) / 2;
  2949. var yy = ( m22 + 1 ) / 2;
  2950. var zz = ( m33 + 1 ) / 2;
  2951. var xy = ( m12 + m21 ) / 4;
  2952. var xz = ( m13 + m31 ) / 4;
  2953. var yz = ( m23 + m32 ) / 4;
  2954. if ( ( xx > yy ) && ( xx > zz ) ) {
  2955. // m11 is the largest diagonal term
  2956. if ( xx < epsilon ) {
  2957. x = 0;
  2958. y = 0.707106781;
  2959. z = 0.707106781;
  2960. } else {
  2961. x = Math.sqrt( xx );
  2962. y = xy / x;
  2963. z = xz / x;
  2964. }
  2965. } else if ( yy > zz ) {
  2966. // m22 is the largest diagonal term
  2967. if ( yy < epsilon ) {
  2968. x = 0.707106781;
  2969. y = 0;
  2970. z = 0.707106781;
  2971. } else {
  2972. y = Math.sqrt( yy );
  2973. x = xy / y;
  2974. z = yz / y;
  2975. }
  2976. } else {
  2977. // m33 is the largest diagonal term so base result on this
  2978. if ( zz < epsilon ) {
  2979. x = 0.707106781;
  2980. y = 0.707106781;
  2981. z = 0;
  2982. } else {
  2983. z = Math.sqrt( zz );
  2984. x = xz / z;
  2985. y = yz / z;
  2986. }
  2987. }
  2988. this.set( x, y, z, angle );
  2989. return this; // return 180 deg rotation
  2990. }
  2991. // as we have reached here there are no singularities so we can handle normally
  2992. var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +
  2993. ( m13 - m31 ) * ( m13 - m31 ) +
  2994. ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize
  2995. if ( Math.abs( s ) < 0.001 ) s = 1;
  2996. // prevent divide by zero, should not happen if matrix is orthogonal and should be
  2997. // caught by singularity test above, but I've left it in just in case
  2998. this.x = ( m32 - m23 ) / s;
  2999. this.y = ( m13 - m31 ) / s;
  3000. this.z = ( m21 - m12 ) / s;
  3001. this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );
  3002. return this;
  3003. },
  3004. min: function ( v ) {
  3005. this.x = Math.min( this.x, v.x );
  3006. this.y = Math.min( this.y, v.y );
  3007. this.z = Math.min( this.z, v.z );
  3008. this.w = Math.min( this.w, v.w );
  3009. return this;
  3010. },
  3011. max: function ( v ) {
  3012. this.x = Math.max( this.x, v.x );
  3013. this.y = Math.max( this.y, v.y );
  3014. this.z = Math.max( this.z, v.z );
  3015. this.w = Math.max( this.w, v.w );
  3016. return this;
  3017. },
  3018. clamp: function ( min, max ) {
  3019. // This function assumes min < max, if this assumption isn't true it will not operate correctly
  3020. this.x = Math.max( min.x, Math.min( max.x, this.x ) );
  3021. this.y = Math.max( min.y, Math.min( max.y, this.y ) );
  3022. this.z = Math.max( min.z, Math.min( max.z, this.z ) );
  3023. this.w = Math.max( min.w, Math.min( max.w, this.w ) );
  3024. return this;
  3025. },
  3026. clampScalar: function () {
  3027. var min, max;
  3028. return function clampScalar( minVal, maxVal ) {
  3029. if ( min === undefined ) {
  3030. min = new Vector4();
  3031. max = new Vector4();
  3032. }
  3033. min.set( minVal, minVal, minVal, minVal );
  3034. max.set( maxVal, maxVal, maxVal, maxVal );
  3035. return this.clamp( min, max );
  3036. };
  3037. }(),
  3038. floor: function () {
  3039. this.x = Math.floor( this.x );
  3040. this.y = Math.floor( this.y );
  3041. this.z = Math.floor( this.z );
  3042. this.w = Math.floor( this.w );
  3043. return this;
  3044. },
  3045. ceil: function () {
  3046. this.x = Math.ceil( this.x );
  3047. this.y = Math.ceil( this.y );
  3048. this.z = Math.ceil( this.z );
  3049. this.w = Math.ceil( this.w );
  3050. return this;
  3051. },
  3052. round: function () {
  3053. this.x = Math.round( this.x );
  3054. this.y = Math.round( this.y );
  3055. this.z = Math.round( this.z );
  3056. this.w = Math.round( this.w );
  3057. return this;
  3058. },
  3059. roundToZero: function () {
  3060. this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
  3061. this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
  3062. this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
  3063. this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );
  3064. return this;
  3065. },
  3066. negate: function () {
  3067. this.x = - this.x;
  3068. this.y = - this.y;
  3069. this.z = - this.z;
  3070. this.w = - this.w;
  3071. return this;
  3072. },
  3073. dot: function ( v ) {
  3074. return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
  3075. },
  3076. lengthSq: function () {
  3077. return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
  3078. },
  3079. length: function () {
  3080. return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
  3081. },
  3082. lengthManhattan: function () {
  3083. return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );
  3084. },
  3085. normalize: function () {
  3086. return this.divideScalar( this.length() );
  3087. },
  3088. setLength: function ( length ) {
  3089. return this.multiplyScalar( length / this.length() );
  3090. },
  3091. lerp: function ( v, alpha ) {
  3092. this.x += ( v.x - this.x ) * alpha;
  3093. this.y += ( v.y - this.y ) * alpha;
  3094. this.z += ( v.z - this.z ) * alpha;
  3095. this.w += ( v.w - this.w ) * alpha;
  3096. return this;
  3097. },
  3098. lerpVectors: function ( v1, v2, alpha ) {
  3099. return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );
  3100. },
  3101. equals: function ( v ) {
  3102. return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );
  3103. },
  3104. fromArray: function ( array, offset ) {
  3105. if ( offset === undefined ) offset = 0;
  3106. this.x = array[ offset ];
  3107. this.y = array[ offset + 1 ];
  3108. this.z = array[ offset + 2 ];
  3109. this.w = array[ offset + 3 ];
  3110. return this;
  3111. },
  3112. toArray: function ( array, offset ) {
  3113. if ( array === undefined ) array = [];
  3114. if ( offset === undefined ) offset = 0;
  3115. array[ offset ] = this.x;
  3116. array[ offset + 1 ] = this.y;
  3117. array[ offset + 2 ] = this.z;
  3118. array[ offset + 3 ] = this.w;
  3119. return array;
  3120. },
  3121. fromBufferAttribute: function ( attribute, index, offset ) {
  3122. if ( offset !== undefined ) {
  3123. console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );
  3124. }
  3125. this.x = attribute.getX( index );
  3126. this.y = attribute.getY( index );
  3127. this.z = attribute.getZ( index );
  3128. this.w = attribute.getW( index );
  3129. return this;
  3130. }
  3131. };
  3132. /**
  3133. * @author mrdoob / http://mrdoob.com/
  3134. */
  3135. function Color( r, g, b ) {
  3136. if ( g === undefined && b === undefined ) {
  3137. // r is THREE.Color, hex or string
  3138. return this.set( r );
  3139. }
  3140. return this.setRGB( r, g, b );
  3141. }
  3142. Color.prototype = {
  3143. constructor: Color,
  3144. isColor: true,
  3145. r: 1, g: 1, b: 1,
  3146. set: function ( value ) {
  3147. if ( value && value.isColor ) {
  3148. this.copy( value );
  3149. } else if ( typeof value === 'number' ) {
  3150. this.setHex( value );
  3151. } else if ( typeof value === 'string' ) {
  3152. this.setStyle( value );
  3153. }
  3154. return this;
  3155. },
  3156. setScalar: function ( scalar ) {
  3157. this.r = scalar;
  3158. this.g = scalar;
  3159. this.b = scalar;
  3160. return this;
  3161. },
  3162. setHex: function ( hex ) {
  3163. hex = Math.floor( hex );
  3164. this.r = ( hex >> 16 & 255 ) / 255;
  3165. this.g = ( hex >> 8 & 255 ) / 255;
  3166. this.b = ( hex & 255 ) / 255;
  3167. return this;
  3168. },
  3169. setRGB: function ( r, g, b ) {
  3170. this.r = r;
  3171. this.g = g;
  3172. this.b = b;
  3173. return this;
  3174. },
  3175. setHSL: function () {
  3176. function hue2rgb( p, q, t ) {
  3177. if ( t < 0 ) t += 1;
  3178. if ( t > 1 ) t -= 1;
  3179. if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;
  3180. if ( t < 1 / 2 ) return q;
  3181. if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );
  3182. return p;
  3183. }
  3184. return function setHSL( h, s, l ) {
  3185. // h,s,l ranges are in 0.0 - 1.0
  3186. h = _Math.euclideanModulo( h, 1 );
  3187. s = _Math.clamp( s, 0, 1 );
  3188. l = _Math.clamp( l, 0, 1 );
  3189. if ( s === 0 ) {
  3190. this.r = this.g = this.b = l;
  3191. } else {
  3192. var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );
  3193. var q = ( 2 * l ) - p;
  3194. this.r = hue2rgb( q, p, h + 1 / 3 );
  3195. this.g = hue2rgb( q, p, h );
  3196. this.b = hue2rgb( q, p, h - 1 / 3 );
  3197. }
  3198. return this;
  3199. };
  3200. }(),
  3201. setStyle: function ( style ) {
  3202. function handleAlpha( string ) {
  3203. if ( string === undefined ) return;
  3204. if ( parseFloat( string ) < 1 ) {
  3205. console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );
  3206. }
  3207. }
  3208. var m;
  3209. if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) {
  3210. // rgb / hsl
  3211. var color;
  3212. var name = m[ 1 ];
  3213. var components = m[ 2 ];
  3214. switch ( name ) {
  3215. case 'rgb':
  3216. case 'rgba':
  3217. if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
  3218. // rgb(255,0,0) rgba(255,0,0,0.5)
  3219. this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;
  3220. this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;
  3221. this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;
  3222. handleAlpha( color[ 5 ] );
  3223. return this;
  3224. }
  3225. if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
  3226. // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
  3227. this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;
  3228. this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;
  3229. this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;
  3230. handleAlpha( color[ 5 ] );
  3231. return this;
  3232. }
  3233. break;
  3234. case 'hsl':
  3235. case 'hsla':
  3236. if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
  3237. // hsl(120,50%,50%) hsla(120,50%,50%,0.5)
  3238. var h = parseFloat( color[ 1 ] ) / 360;
  3239. var s = parseInt( color[ 2 ], 10 ) / 100;
  3240. var l = parseInt( color[ 3 ], 10 ) / 100;
  3241. handleAlpha( color[ 5 ] );
  3242. return this.setHSL( h, s, l );
  3243. }
  3244. break;
  3245. }
  3246. } else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) {
  3247. // hex color
  3248. var hex = m[ 1 ];
  3249. var size = hex.length;
  3250. if ( size === 3 ) {
  3251. // #ff0
  3252. this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;
  3253. this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;
  3254. this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;
  3255. return this;
  3256. } else if ( size === 6 ) {
  3257. // #ff0000
  3258. this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;
  3259. this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;
  3260. this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;
  3261. return this;
  3262. }
  3263. }
  3264. if ( style && style.length > 0 ) {
  3265. // color keywords
  3266. var hex = ColorKeywords[ style ];
  3267. if ( hex !== undefined ) {
  3268. // red
  3269. this.setHex( hex );
  3270. } else {
  3271. // unknown color
  3272. console.warn( 'THREE.Color: Unknown color ' + style );
  3273. }
  3274. }
  3275. return this;
  3276. },
  3277. clone: function () {
  3278. return new this.constructor( this.r, this.g, this.b );
  3279. },
  3280. copy: function ( color ) {
  3281. this.r = color.r;
  3282. this.g = color.g;
  3283. this.b = color.b;
  3284. return this;
  3285. },
  3286. copyGammaToLinear: function ( color, gammaFactor ) {
  3287. if ( gammaFactor === undefined ) gammaFactor = 2.0;
  3288. this.r = Math.pow( color.r, gammaFactor );
  3289. this.g = Math.pow( color.g, gammaFactor );
  3290. this.b = Math.pow( color.b, gammaFactor );
  3291. return this;
  3292. },
  3293. copyLinearToGamma: function ( color, gammaFactor ) {
  3294. if ( gammaFactor === undefined ) gammaFactor = 2.0;
  3295. var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;
  3296. this.r = Math.pow( color.r, safeInverse );
  3297. this.g = Math.pow( color.g, safeInverse );
  3298. this.b = Math.pow( color.b, safeInverse );
  3299. return this;
  3300. },
  3301. convertGammaToLinear: function () {
  3302. var r = this.r, g = this.g, b = this.b;
  3303. this.r = r * r;
  3304. this.g = g * g;
  3305. this.b = b * b;
  3306. return this;
  3307. },
  3308. convertLinearToGamma: function () {
  3309. this.r = Math.sqrt( this.r );
  3310. this.g = Math.sqrt( this.g );
  3311. this.b = Math.sqrt( this.b );
  3312. return this;
  3313. },
  3314. getHex: function () {
  3315. return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;
  3316. },
  3317. getHexString: function () {
  3318. return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );
  3319. },
  3320. getHSL: function ( optionalTarget ) {
  3321. // h,s,l ranges are in 0.0 - 1.0
  3322. var hsl = optionalTarget || { h: 0, s: 0, l: 0 };
  3323. var r = this.r, g = this.g, b = this.b;
  3324. var max = Math.max( r, g, b );
  3325. var min = Math.min( r, g, b );
  3326. var hue, saturation;
  3327. var lightness = ( min + max ) / 2.0;
  3328. if ( min === max ) {
  3329. hue = 0;
  3330. saturation = 0;
  3331. } else {
  3332. var delta = max - min;
  3333. saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );
  3334. switch ( max ) {
  3335. case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;
  3336. case g: hue = ( b - r ) / delta + 2; break;
  3337. case b: hue = ( r - g ) / delta + 4; break;
  3338. }
  3339. hue /= 6;
  3340. }
  3341. hsl.h = hue;
  3342. hsl.s = saturation;
  3343. hsl.l = lightness;
  3344. return hsl;
  3345. },
  3346. getStyle: function () {
  3347. return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';
  3348. },
  3349. offsetHSL: function ( h, s, l ) {
  3350. var hsl = this.getHSL();
  3351. hsl.h += h; hsl.s += s; hsl.l += l;
  3352. this.setHSL( hsl.h, hsl.s, hsl.l );
  3353. return this;
  3354. },
  3355. add: function ( color ) {
  3356. this.r += color.r;
  3357. this.g += color.g;
  3358. this.b += color.b;
  3359. return this;
  3360. },
  3361. addColors: function ( color1, color2 ) {
  3362. this.r = color1.r + color2.r;
  3363. this.g = color1.g + color2.g;
  3364. this.b = color1.b + color2.b;
  3365. return this;
  3366. },
  3367. addScalar: function ( s ) {
  3368. this.r += s;
  3369. this.g += s;
  3370. this.b += s;
  3371. return this;
  3372. },
  3373. sub: function( color ) {
  3374. this.r = Math.max( 0, this.r - color.r );
  3375. this.g = Math.max( 0, this.g - color.g );
  3376. this.b = Math.max( 0, this.b - color.b );
  3377. return this;
  3378. },
  3379. multiply: function ( color ) {
  3380. this.r *= color.r;
  3381. this.g *= color.g;
  3382. this.b *= color.b;
  3383. return this;
  3384. },
  3385. multiplyScalar: function ( s ) {
  3386. this.r *= s;
  3387. this.g *= s;
  3388. this.b *= s;
  3389. return this;
  3390. },
  3391. lerp: function ( color, alpha ) {
  3392. this.r += ( color.r - this.r ) * alpha;
  3393. this.g += ( color.g - this.g ) * alpha;
  3394. this.b += ( color.b - this.b ) * alpha;
  3395. return this;
  3396. },
  3397. equals: function ( c ) {
  3398. return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );
  3399. },
  3400. fromArray: function ( array, offset ) {
  3401. if ( offset === undefined ) offset = 0;
  3402. this.r = array[ offset ];
  3403. this.g = array[ offset + 1 ];
  3404. this.b = array[ offset + 2 ];
  3405. return this;
  3406. },
  3407. toArray: function ( array, offset ) {
  3408. if ( array === undefined ) array = [];
  3409. if ( offset === undefined ) offset = 0;
  3410. array[ offset ] = this.r;
  3411. array[ offset + 1 ] = this.g;
  3412. array[ offset + 2 ] = this.b;
  3413. return array;
  3414. },
  3415. toJSON: function () {
  3416. return this.getHex();
  3417. }
  3418. };
  3419. var ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,
  3420. 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,
  3421. 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,
  3422. 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,
  3423. 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,
  3424. 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,
  3425. 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,
  3426. 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,
  3427. 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,
  3428. 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,
  3429. 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,
  3430. 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,
  3431. 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,
  3432. 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,
  3433. 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,
  3434. 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,
  3435. 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,
  3436. 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,
  3437. 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,
  3438. 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,
  3439. 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,
  3440. 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,
  3441. 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,
  3442. 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };
  3443. /**
  3444. * Uniforms library for shared webgl shaders
  3445. */
  3446. var UniformsLib = {
  3447. common: {
  3448. diffuse: { value: new Color( 0xeeeeee ) },
  3449. opacity: { value: 1.0 },
  3450. map: { value: null },
  3451. offsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },
  3452. specularMap: { value: null },
  3453. alphaMap: { value: null },
  3454. envMap: { value: null },
  3455. flipEnvMap: { value: - 1 },
  3456. reflectivity: { value: 1.0 },
  3457. refractionRatio: { value: 0.98 }
  3458. },
  3459. aomap: {
  3460. aoMap: { value: null },
  3461. aoMapIntensity: { value: 1 }
  3462. },
  3463. lightmap: {
  3464. lightMap: { value: null },
  3465. lightMapIntensity: { value: 1 }
  3466. },
  3467. emissivemap: {
  3468. emissiveMap: { value: null }
  3469. },
  3470. bumpmap: {
  3471. bumpMap: { value: null },
  3472. bumpScale: { value: 1 }
  3473. },
  3474. normalmap: {
  3475. normalMap: { value: null },
  3476. normalScale: { value: new Vector2( 1, 1 ) }
  3477. },
  3478. displacementmap: {
  3479. displacementMap: { value: null },
  3480. displacementScale: { value: 1 },
  3481. displacementBias: { value: 0 }
  3482. },
  3483. roughnessmap: {
  3484. roughnessMap: { value: null }
  3485. },
  3486. metalnessmap: {
  3487. metalnessMap: { value: null }
  3488. },
  3489. gradientmap: {
  3490. gradientMap: { value: null }
  3491. },
  3492. fog: {
  3493. fogDensity: { value: 0.00025 },
  3494. fogNear: { value: 1 },
  3495. fogFar: { value: 2000 },
  3496. fogColor: { value: new Color( 0xffffff ) }
  3497. },
  3498. lights: {
  3499. ambientLightColor: { value: [] },
  3500. directionalLights: { value: [], properties: {
  3501. direction: {},
  3502. color: {},
  3503. shadow: {},
  3504. shadowBias: {},
  3505. shadowRadius: {},
  3506. shadowMapSize: {}
  3507. } },
  3508. directionalShadowMap: { value: [] },
  3509. directionalShadowMatrix: { value: [] },
  3510. spotLights: { value: [], properties: {
  3511. color: {},
  3512. position: {},
  3513. direction: {},
  3514. distance: {},
  3515. coneCos: {},
  3516. penumbraCos: {},
  3517. decay: {},
  3518. shadow: {},
  3519. shadowBias: {},
  3520. shadowRadius: {},
  3521. shadowMapSize: {}
  3522. } },
  3523. spotShadowMap: { value: [] },
  3524. spotShadowMatrix: { value: [] },
  3525. pointLights: { value: [], properties: {
  3526. color: {},
  3527. position: {},
  3528. decay: {},
  3529. distance: {},
  3530. shadow: {},
  3531. shadowBias: {},
  3532. shadowRadius: {},
  3533. shadowMapSize: {}
  3534. } },
  3535. pointShadowMap: { value: [] },
  3536. pointShadowMatrix: { value: [] },
  3537. hemisphereLights: { value: [], properties: {
  3538. direction: {},
  3539. skyColor: {},
  3540. groundColor: {}
  3541. } },
  3542. // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src
  3543. rectAreaLights: { value: [], properties: {
  3544. color: {},
  3545. position: {},
  3546. width: {},
  3547. height: {}
  3548. } }
  3549. },
  3550. points: {
  3551. diffuse: { value: new Color( 0xeeeeee ) },
  3552. opacity: { value: 1.0 },
  3553. size: { value: 1.0 },
  3554. scale: { value: 1.0 },
  3555. map: { value: null },
  3556. offsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }
  3557. }
  3558. };
  3559. /**
  3560. * @author alteredq / http://alteredqualia.com/
  3561. * @author mrdoob / http://mrdoob.com/
  3562. * @author mikael emtinger / http://gomo.se/
  3563. */
  3564. var ShaderLib = {
  3565. basic: {
  3566. uniforms: UniformsUtils.merge( [
  3567. UniformsLib.common,
  3568. UniformsLib.aomap,
  3569. UniformsLib.lightmap,
  3570. UniformsLib.fog
  3571. ] ),
  3572. vertexShader: ShaderChunk.meshbasic_vert,
  3573. fragmentShader: ShaderChunk.meshbasic_frag
  3574. },
  3575. lambert: {
  3576. uniforms: UniformsUtils.merge( [
  3577. UniformsLib.common,
  3578. UniformsLib.aomap,
  3579. UniformsLib.lightmap,
  3580. UniformsLib.emissivemap,
  3581. UniformsLib.fog,
  3582. UniformsLib.lights,
  3583. {
  3584. emissive: { value: new Color( 0x000000 ) }
  3585. }
  3586. ] ),
  3587. vertexShader: ShaderChunk.meshlambert_vert,
  3588. fragmentShader: ShaderChunk.meshlambert_frag
  3589. },
  3590. phong: {
  3591. uniforms: UniformsUtils.merge( [
  3592. UniformsLib.common,
  3593. UniformsLib.aomap,
  3594. UniformsLib.lightmap,
  3595. UniformsLib.emissivemap,
  3596. UniformsLib.bumpmap,
  3597. UniformsLib.normalmap,
  3598. UniformsLib.displacementmap,
  3599. UniformsLib.gradientmap,
  3600. UniformsLib.fog,
  3601. UniformsLib.lights,
  3602. {
  3603. emissive: { value: new Color( 0x000000 ) },
  3604. specular: { value: new Color( 0x111111 ) },
  3605. shininess: { value: 30 }
  3606. }
  3607. ] ),
  3608. vertexShader: ShaderChunk.meshphong_vert,
  3609. fragmentShader: ShaderChunk.meshphong_frag
  3610. },
  3611. standard: {
  3612. uniforms: UniformsUtils.merge( [
  3613. UniformsLib.common,
  3614. UniformsLib.aomap,
  3615. UniformsLib.lightmap,
  3616. UniformsLib.emissivemap,
  3617. UniformsLib.bumpmap,
  3618. UniformsLib.normalmap,
  3619. UniformsLib.displacementmap,
  3620. UniformsLib.roughnessmap,
  3621. UniformsLib.metalnessmap,
  3622. UniformsLib.fog,
  3623. UniformsLib.lights,
  3624. {
  3625. emissive: { value: new Color( 0x000000 ) },
  3626. roughness: { value: 0.5 },
  3627. metalness: { value: 0 },
  3628. envMapIntensity: { value: 1 } // temporary
  3629. }
  3630. ] ),
  3631. vertexShader: ShaderChunk.meshphysical_vert,
  3632. fragmentShader: ShaderChunk.meshphysical_frag
  3633. },
  3634. points: {
  3635. uniforms: UniformsUtils.merge( [
  3636. UniformsLib.points,
  3637. UniformsLib.fog
  3638. ] ),
  3639. vertexShader: ShaderChunk.points_vert,
  3640. fragmentShader: ShaderChunk.points_frag
  3641. },
  3642. dashed: {
  3643. uniforms: UniformsUtils.merge( [
  3644. UniformsLib.common,
  3645. UniformsLib.fog,
  3646. {
  3647. scale: { value: 1 },
  3648. dashSize: { value: 1 },
  3649. totalSize: { value: 2 }
  3650. }
  3651. ] ),
  3652. vertexShader: ShaderChunk.linedashed_vert,
  3653. fragmentShader: ShaderChunk.linedashed_frag
  3654. },
  3655. depth: {
  3656. uniforms: UniformsUtils.merge( [
  3657. UniformsLib.common,
  3658. UniformsLib.displacementmap
  3659. ] ),
  3660. vertexShader: ShaderChunk.depth_vert,
  3661. fragmentShader: ShaderChunk.depth_frag
  3662. },
  3663. normal: {
  3664. uniforms: UniformsUtils.merge( [
  3665. UniformsLib.common,
  3666. UniformsLib.bumpmap,
  3667. UniformsLib.normalmap,
  3668. UniformsLib.displacementmap,
  3669. {
  3670. opacity: { value: 1.0 }
  3671. }
  3672. ] ),
  3673. vertexShader: ShaderChunk.normal_vert,
  3674. fragmentShader: ShaderChunk.normal_frag
  3675. },
  3676. /* -------------------------------------------------------------------------
  3677. // Cube map shader
  3678. ------------------------------------------------------------------------- */
  3679. cube: {
  3680. uniforms: {
  3681. tCube: { value: null },
  3682. tFlip: { value: - 1 },
  3683. opacity: { value: 1.0 }
  3684. },
  3685. vertexShader: ShaderChunk.cube_vert,
  3686. fragmentShader: ShaderChunk.cube_frag
  3687. },
  3688. /* -------------------------------------------------------------------------
  3689. // Cube map shader
  3690. ------------------------------------------------------------------------- */
  3691. equirect: {
  3692. uniforms: {
  3693. tEquirect: { value: null },
  3694. tFlip: { value: - 1 }
  3695. },
  3696. vertexShader: ShaderChunk.equirect_vert,
  3697. fragmentShader: ShaderChunk.equirect_frag
  3698. },
  3699. distanceRGBA: {
  3700. uniforms: {
  3701. lightPos: { value: new Vector3() }
  3702. },
  3703. vertexShader: ShaderChunk.distanceRGBA_vert,
  3704. fragmentShader: ShaderChunk.distanceRGBA_frag
  3705. }
  3706. };
  3707. ShaderLib.physical = {
  3708. uniforms: UniformsUtils.merge( [
  3709. ShaderLib.standard.uniforms,
  3710. {
  3711. clearCoat: { value: 0 },
  3712. clearCoatRoughness: { value: 0 }
  3713. }
  3714. ] ),
  3715. vertexShader: ShaderChunk.meshphysical_vert,
  3716. fragmentShader: ShaderChunk.meshphysical_frag
  3717. };
  3718. /**
  3719. * @author bhouston / http://clara.io
  3720. */
  3721. function Box2( min, max ) {
  3722. this.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );
  3723. this.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );
  3724. }
  3725. Box2.prototype = {
  3726. constructor: Box2,
  3727. set: function ( min, max ) {
  3728. this.min.copy( min );
  3729. this.max.copy( max );
  3730. return this;
  3731. },
  3732. setFromPoints: function ( points ) {
  3733. this.makeEmpty();
  3734. for ( var i = 0, il = points.length; i < il; i ++ ) {
  3735. this.expandByPoint( points[ i ] );
  3736. }
  3737. return this;
  3738. },
  3739. setFromCenterAndSize: function () {
  3740. var v1 = new Vector2();
  3741. return function setFromCenterAndSize( center, size ) {
  3742. var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
  3743. this.min.copy( center ).sub( halfSize );
  3744. this.max.copy( center ).add( halfSize );
  3745. return this;
  3746. };
  3747. }(),
  3748. clone: function () {
  3749. return new this.constructor().copy( this );
  3750. },
  3751. copy: function ( box ) {
  3752. this.min.copy( box.min );
  3753. this.max.copy( box.max );
  3754. return this;
  3755. },
  3756. makeEmpty: function () {
  3757. this.min.x = this.min.y = + Infinity;
  3758. this.max.x = this.max.y = - Infinity;
  3759. return this;
  3760. },
  3761. isEmpty: function () {
  3762. // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
  3763. return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );
  3764. },
  3765. getCenter: function ( optionalTarget ) {
  3766. var result = optionalTarget || new Vector2();
  3767. return this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
  3768. },
  3769. getSize: function ( optionalTarget ) {
  3770. var result = optionalTarget || new Vector2();
  3771. return this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );
  3772. },
  3773. expandByPoint: function ( point ) {
  3774. this.min.min( point );
  3775. this.max.max( point );
  3776. return this;
  3777. },
  3778. expandByVector: function ( vector ) {
  3779. this.min.sub( vector );
  3780. this.max.add( vector );
  3781. return this;
  3782. },
  3783. expandByScalar: function ( scalar ) {
  3784. this.min.addScalar( - scalar );
  3785. this.max.addScalar( scalar );
  3786. return this;
  3787. },
  3788. containsPoint: function ( point ) {
  3789. return point.x < this.min.x || point.x > this.max.x ||
  3790. point.y < this.min.y || point.y > this.max.y ? false : true;
  3791. },
  3792. containsBox: function ( box ) {
  3793. return this.min.x <= box.min.x && box.max.x <= this.max.x &&
  3794. this.min.y <= box.min.y && box.max.y <= this.max.y;
  3795. },
  3796. getParameter: function ( point, optionalTarget ) {
  3797. // This can potentially have a divide by zero if the box
  3798. // has a size dimension of 0.
  3799. var result = optionalTarget || new Vector2();
  3800. return result.set(
  3801. ( point.x - this.min.x ) / ( this.max.x - this.min.x ),
  3802. ( point.y - this.min.y ) / ( this.max.y - this.min.y )
  3803. );
  3804. },
  3805. intersectsBox: function ( box ) {
  3806. // using 6 splitting planes to rule out intersections.
  3807. return box.max.x < this.min.x || box.min.x > this.max.x ||
  3808. box.max.y < this.min.y || box.min.y > this.max.y ? false : true;
  3809. },
  3810. clampPoint: function ( point, optionalTarget ) {
  3811. var result = optionalTarget || new Vector2();
  3812. return result.copy( point ).clamp( this.min, this.max );
  3813. },
  3814. distanceToPoint: function () {
  3815. var v1 = new Vector2();
  3816. return function distanceToPoint( point ) {
  3817. var clampedPoint = v1.copy( point ).clamp( this.min, this.max );
  3818. return clampedPoint.sub( point ).length();
  3819. };
  3820. }(),
  3821. intersect: function ( box ) {
  3822. this.min.max( box.min );
  3823. this.max.min( box.max );
  3824. return this;
  3825. },
  3826. union: function ( box ) {
  3827. this.min.min( box.min );
  3828. this.max.max( box.max );
  3829. return this;
  3830. },
  3831. translate: function ( offset ) {
  3832. this.min.add( offset );
  3833. this.max.add( offset );
  3834. return this;
  3835. },
  3836. equals: function ( box ) {
  3837. return box.min.equals( this.min ) && box.max.equals( this.max );
  3838. }
  3839. };
  3840. /**
  3841. * @author mikael emtinger / http://gomo.se/
  3842. * @author alteredq / http://alteredqualia.com/
  3843. */
  3844. function LensFlarePlugin( renderer, flares ) {
  3845. var gl = renderer.context;
  3846. var state = renderer.state;
  3847. var vertexBuffer, elementBuffer;
  3848. var shader, program, attributes, uniforms;
  3849. var tempTexture, occlusionTexture;
  3850. function init() {
  3851. var vertices = new Float32Array( [
  3852. - 1, - 1, 0, 0,
  3853. 1, - 1, 1, 0,
  3854. 1, 1, 1, 1,
  3855. - 1, 1, 0, 1
  3856. ] );
  3857. var faces = new Uint16Array( [
  3858. 0, 1, 2,
  3859. 0, 2, 3
  3860. ] );
  3861. // buffers
  3862. vertexBuffer = gl.createBuffer();
  3863. elementBuffer = gl.createBuffer();
  3864. gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
  3865. gl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );
  3866. gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
  3867. gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );
  3868. // textures
  3869. tempTexture = gl.createTexture();
  3870. occlusionTexture = gl.createTexture();
  3871. state.bindTexture( gl.TEXTURE_2D, tempTexture );
  3872. gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );
  3873. gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );
  3874. gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );
  3875. gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
  3876. gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
  3877. state.bindTexture( gl.TEXTURE_2D, occlusionTexture );
  3878. gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );
  3879. gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );
  3880. gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );
  3881. gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
  3882. gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
  3883. shader = {
  3884. vertexShader: [
  3885. "uniform lowp int renderType;",
  3886. "uniform vec3 screenPosition;",
  3887. "uniform vec2 scale;",
  3888. "uniform float rotation;",
  3889. "uniform sampler2D occlusionMap;",
  3890. "attribute vec2 position;",
  3891. "attribute vec2 uv;",
  3892. "varying vec2 vUV;",
  3893. "varying float vVisibility;",
  3894. "void main() {",
  3895. "vUV = uv;",
  3896. "vec2 pos = position;",
  3897. "if ( renderType == 2 ) {",
  3898. "vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );",
  3899. "visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );",
  3900. "visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );",
  3901. "visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );",
  3902. "visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );",
  3903. "visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );",
  3904. "visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );",
  3905. "visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );",
  3906. "visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );",
  3907. "vVisibility = visibility.r / 9.0;",
  3908. "vVisibility *= 1.0 - visibility.g / 9.0;",
  3909. "vVisibility *= visibility.b / 9.0;",
  3910. "vVisibility *= 1.0 - visibility.a / 9.0;",
  3911. "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
  3912. "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
  3913. "}",
  3914. "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
  3915. "}"
  3916. ].join( "\n" ),
  3917. fragmentShader: [
  3918. "uniform lowp int renderType;",
  3919. "uniform sampler2D map;",
  3920. "uniform float opacity;",
  3921. "uniform vec3 color;",
  3922. "varying vec2 vUV;",
  3923. "varying float vVisibility;",
  3924. "void main() {",
  3925. // pink square
  3926. "if ( renderType == 0 ) {",
  3927. "gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );",
  3928. // restore
  3929. "} else if ( renderType == 1 ) {",
  3930. "gl_FragColor = texture2D( map, vUV );",
  3931. // flare
  3932. "} else {",
  3933. "vec4 texture = texture2D( map, vUV );",
  3934. "texture.a *= opacity * vVisibility;",
  3935. "gl_FragColor = texture;",
  3936. "gl_FragColor.rgb *= color;",
  3937. "}",
  3938. "}"
  3939. ].join( "\n" )
  3940. };
  3941. program = createProgram( shader );
  3942. attributes = {
  3943. vertex: gl.getAttribLocation ( program, "position" ),
  3944. uv: gl.getAttribLocation ( program, "uv" )
  3945. };
  3946. uniforms = {
  3947. renderType: gl.getUniformLocation( program, "renderType" ),
  3948. map: gl.getUniformLocation( program, "map" ),
  3949. occlusionMap: gl.getUniformLocation( program, "occlusionMap" ),
  3950. opacity: gl.getUniformLocation( program, "opacity" ),
  3951. color: gl.getUniformLocation( program, "color" ),
  3952. scale: gl.getUniformLocation( program, "scale" ),
  3953. rotation: gl.getUniformLocation( program, "rotation" ),
  3954. screenPosition: gl.getUniformLocation( program, "screenPosition" )
  3955. };
  3956. }
  3957. /*
  3958. * Render lens flares
  3959. * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,
  3960. * reads these back and calculates occlusion.
  3961. */
  3962. this.render = function ( scene, camera, viewport ) {
  3963. if ( flares.length === 0 ) return;
  3964. var tempPosition = new Vector3();
  3965. var invAspect = viewport.w / viewport.z,
  3966. halfViewportWidth = viewport.z * 0.5,
  3967. halfViewportHeight = viewport.w * 0.5;
  3968. var size = 16 / viewport.w,
  3969. scale = new Vector2( size * invAspect, size );
  3970. var screenPosition = new Vector3( 1, 1, 0 ),
  3971. screenPositionPixels = new Vector2( 1, 1 );
  3972. var validArea = new Box2();
  3973. validArea.min.set( viewport.x, viewport.y );
  3974. validArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );
  3975. if ( program === undefined ) {
  3976. init();
  3977. }
  3978. gl.useProgram( program );
  3979. state.initAttributes();
  3980. state.enableAttribute( attributes.vertex );
  3981. state.enableAttribute( attributes.uv );
  3982. state.disableUnusedAttributes();
  3983. // loop through all lens flares to update their occlusion and positions
  3984. // setup gl and common used attribs/uniforms
  3985. gl.uniform1i( uniforms.occlusionMap, 0 );
  3986. gl.uniform1i( uniforms.map, 1 );
  3987. gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
  3988. gl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );
  3989. gl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );
  3990. gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
  3991. state.disable( gl.CULL_FACE );
  3992. state.setDepthWrite( false );
  3993. for ( var i = 0, l = flares.length; i < l; i ++ ) {
  3994. size = 16 / viewport.w;
  3995. scale.set( size * invAspect, size );
  3996. // calc object screen position
  3997. var flare = flares[ i ];
  3998. tempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );
  3999. tempPosition.applyMatrix4( camera.matrixWorldInverse );
  4000. tempPosition.applyMatrix4( camera.projectionMatrix );
  4001. // setup arrays for gl programs
  4002. screenPosition.copy( tempPosition );
  4003. // horizontal and vertical coordinate of the lower left corner of the pixels to copy
  4004. screenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;
  4005. screenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;
  4006. // screen cull
  4007. if ( validArea.containsPoint( screenPositionPixels ) === true ) {
  4008. // save current RGB to temp texture
  4009. state.activeTexture( gl.TEXTURE0 );
  4010. state.bindTexture( gl.TEXTURE_2D, null );
  4011. state.activeTexture( gl.TEXTURE1 );
  4012. state.bindTexture( gl.TEXTURE_2D, tempTexture );
  4013. gl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );
  4014. // render pink quad
  4015. gl.uniform1i( uniforms.renderType, 0 );
  4016. gl.uniform2f( uniforms.scale, scale.x, scale.y );
  4017. gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
  4018. state.disable( gl.BLEND );
  4019. state.enable( gl.DEPTH_TEST );
  4020. gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
  4021. // copy result to occlusionMap
  4022. state.activeTexture( gl.TEXTURE0 );
  4023. state.bindTexture( gl.TEXTURE_2D, occlusionTexture );
  4024. gl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );
  4025. // restore graphics
  4026. gl.uniform1i( uniforms.renderType, 1 );
  4027. state.disable( gl.DEPTH_TEST );
  4028. state.activeTexture( gl.TEXTURE1 );
  4029. state.bindTexture( gl.TEXTURE_2D, tempTexture );
  4030. gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
  4031. // update object positions
  4032. flare.positionScreen.copy( screenPosition );
  4033. if ( flare.customUpdateCallback ) {
  4034. flare.customUpdateCallback( flare );
  4035. } else {
  4036. flare.updateLensFlares();
  4037. }
  4038. // render flares
  4039. gl.uniform1i( uniforms.renderType, 2 );
  4040. state.enable( gl.BLEND );
  4041. for ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {
  4042. var sprite = flare.lensFlares[ j ];
  4043. if ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {
  4044. screenPosition.x = sprite.x;
  4045. screenPosition.y = sprite.y;
  4046. screenPosition.z = sprite.z;
  4047. size = sprite.size * sprite.scale / viewport.w;
  4048. scale.x = size * invAspect;
  4049. scale.y = size;
  4050. gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
  4051. gl.uniform2f( uniforms.scale, scale.x, scale.y );
  4052. gl.uniform1f( uniforms.rotation, sprite.rotation );
  4053. gl.uniform1f( uniforms.opacity, sprite.opacity );
  4054. gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );
  4055. state.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );
  4056. renderer.setTexture2D( sprite.texture, 1 );
  4057. gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
  4058. }
  4059. }
  4060. }
  4061. }
  4062. // restore gl
  4063. state.enable( gl.CULL_FACE );
  4064. state.enable( gl.DEPTH_TEST );
  4065. state.setDepthWrite( true );
  4066. renderer.resetGLState();
  4067. };
  4068. function createProgram( shader ) {
  4069. var program = gl.createProgram();
  4070. var fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );
  4071. var vertexShader = gl.createShader( gl.VERTEX_SHADER );
  4072. var prefix = "precision " + renderer.getPrecision() + " float;\n";
  4073. gl.shaderSource( fragmentShader, prefix + shader.fragmentShader );
  4074. gl.shaderSource( vertexShader, prefix + shader.vertexShader );
  4075. gl.compileShader( fragmentShader );
  4076. gl.compileShader( vertexShader );
  4077. gl.attachShader( program, fragmentShader );
  4078. gl.attachShader( program, vertexShader );
  4079. gl.linkProgram( program );
  4080. return program;
  4081. }
  4082. }
  4083. /**
  4084. * @author mikael emtinger / http://gomo.se/
  4085. * @author alteredq / http://alteredqualia.com/
  4086. */
  4087. function SpritePlugin( renderer, sprites ) {
  4088. var gl = renderer.context;
  4089. var state = renderer.state;
  4090. var vertexBuffer, elementBuffer;
  4091. var program, attributes, uniforms;
  4092. var texture;
  4093. // decompose matrixWorld
  4094. var spritePosition = new Vector3();
  4095. var spriteRotation = new Quaternion();
  4096. var spriteScale = new Vector3();
  4097. function init() {
  4098. var vertices = new Float32Array( [
  4099. - 0.5, - 0.5, 0, 0,
  4100. 0.5, - 0.5, 1, 0,
  4101. 0.5, 0.5, 1, 1,
  4102. - 0.5, 0.5, 0, 1
  4103. ] );
  4104. var faces = new Uint16Array( [
  4105. 0, 1, 2,
  4106. 0, 2, 3
  4107. ] );
  4108. vertexBuffer = gl.createBuffer();
  4109. elementBuffer = gl.createBuffer();
  4110. gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
  4111. gl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );
  4112. gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
  4113. gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );
  4114. program = createProgram();
  4115. attributes = {
  4116. position: gl.getAttribLocation ( program, 'position' ),
  4117. uv: gl.getAttribLocation ( program, 'uv' )
  4118. };
  4119. uniforms = {
  4120. uvOffset: gl.getUniformLocation( program, 'uvOffset' ),
  4121. uvScale: gl.getUniformLocation( program, 'uvScale' ),
  4122. rotation: gl.getUniformLocation( program, 'rotation' ),
  4123. scale: gl.getUniformLocation( program, 'scale' ),
  4124. color: gl.getUniformLocation( program, 'color' ),
  4125. map: gl.getUniformLocation( program, 'map' ),
  4126. opacity: gl.getUniformLocation( program, 'opacity' ),
  4127. modelViewMatrix: gl.getUniformLocation( program, 'modelViewMatrix' ),
  4128. projectionMatrix: gl.getUniformLocation( program, 'projectionMatrix' ),
  4129. fogType: gl.getUniformLocation( program, 'fogType' ),
  4130. fogDensity: gl.getUniformLocation( program, 'fogDensity' ),
  4131. fogNear: gl.getUniformLocation( program, 'fogNear' ),
  4132. fogFar: gl.getUniformLocation( program, 'fogFar' ),
  4133. fogColor: gl.getUniformLocation( program, 'fogColor' ),
  4134. alphaTest: gl.getUniformLocation( program, 'alphaTest' )
  4135. };
  4136. var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
  4137. canvas.width = 8;
  4138. canvas.height = 8;
  4139. var context = canvas.getContext( '2d' );
  4140. context.fillStyle = 'white';
  4141. context.fillRect( 0, 0, 8, 8 );
  4142. texture = new Texture( canvas );
  4143. texture.needsUpdate = true;
  4144. }
  4145. this.render = function ( scene, camera ) {
  4146. if ( sprites.length === 0 ) return;
  4147. // setup gl
  4148. if ( program === undefined ) {
  4149. init();
  4150. }
  4151. gl.useProgram( program );
  4152. state.initAttributes();
  4153. state.enableAttribute( attributes.position );
  4154. state.enableAttribute( attributes.uv );
  4155. state.disableUnusedAttributes();
  4156. state.disable( gl.CULL_FACE );
  4157. state.enable( gl.BLEND );
  4158. gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
  4159. gl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );
  4160. gl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );
  4161. gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
  4162. gl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );
  4163. state.activeTexture( gl.TEXTURE0 );
  4164. gl.uniform1i( uniforms.map, 0 );
  4165. var oldFogType = 0;
  4166. var sceneFogType = 0;
  4167. var fog = scene.fog;
  4168. if ( fog ) {
  4169. gl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );
  4170. if ( fog.isFog ) {
  4171. gl.uniform1f( uniforms.fogNear, fog.near );
  4172. gl.uniform1f( uniforms.fogFar, fog.far );
  4173. gl.uniform1i( uniforms.fogType, 1 );
  4174. oldFogType = 1;
  4175. sceneFogType = 1;
  4176. } else if ( fog.isFogExp2 ) {
  4177. gl.uniform1f( uniforms.fogDensity, fog.density );
  4178. gl.uniform1i( uniforms.fogType, 2 );
  4179. oldFogType = 2;
  4180. sceneFogType = 2;
  4181. }
  4182. } else {
  4183. gl.uniform1i( uniforms.fogType, 0 );
  4184. oldFogType = 0;
  4185. sceneFogType = 0;
  4186. }
  4187. // update positions and sort
  4188. for ( var i = 0, l = sprites.length; i < l; i ++ ) {
  4189. var sprite = sprites[ i ];
  4190. sprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );
  4191. sprite.z = - sprite.modelViewMatrix.elements[ 14 ];
  4192. }
  4193. sprites.sort( painterSortStable );
  4194. // render all sprites
  4195. var scale = [];
  4196. for ( var i = 0, l = sprites.length; i < l; i ++ ) {
  4197. var sprite = sprites[ i ];
  4198. var material = sprite.material;
  4199. if ( material.visible === false ) continue;
  4200. gl.uniform1f( uniforms.alphaTest, material.alphaTest );
  4201. gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );
  4202. sprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );
  4203. scale[ 0 ] = spriteScale.x;
  4204. scale[ 1 ] = spriteScale.y;
  4205. var fogType = 0;
  4206. if ( scene.fog && material.fog ) {
  4207. fogType = sceneFogType;
  4208. }
  4209. if ( oldFogType !== fogType ) {
  4210. gl.uniform1i( uniforms.fogType, fogType );
  4211. oldFogType = fogType;
  4212. }
  4213. if ( material.map !== null ) {
  4214. gl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );
  4215. gl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );
  4216. } else {
  4217. gl.uniform2f( uniforms.uvOffset, 0, 0 );
  4218. gl.uniform2f( uniforms.uvScale, 1, 1 );
  4219. }
  4220. gl.uniform1f( uniforms.opacity, material.opacity );
  4221. gl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );
  4222. gl.uniform1f( uniforms.rotation, material.rotation );
  4223. gl.uniform2fv( uniforms.scale, scale );
  4224. state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
  4225. state.setDepthTest( material.depthTest );
  4226. state.setDepthWrite( material.depthWrite );
  4227. if ( material.map ) {
  4228. renderer.setTexture2D( material.map, 0 );
  4229. } else {
  4230. renderer.setTexture2D( texture, 0 );
  4231. }
  4232. gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
  4233. }
  4234. // restore gl
  4235. state.enable( gl.CULL_FACE );
  4236. renderer.resetGLState();
  4237. };
  4238. function createProgram() {
  4239. var program = gl.createProgram();
  4240. var vertexShader = gl.createShader( gl.VERTEX_SHADER );
  4241. var fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );
  4242. gl.shaderSource( vertexShader, [
  4243. 'precision ' + renderer.getPrecision() + ' float;',
  4244. 'uniform mat4 modelViewMatrix;',
  4245. 'uniform mat4 projectionMatrix;',
  4246. 'uniform float rotation;',
  4247. 'uniform vec2 scale;',
  4248. 'uniform vec2 uvOffset;',
  4249. 'uniform vec2 uvScale;',
  4250. 'attribute vec2 position;',
  4251. 'attribute vec2 uv;',
  4252. 'varying vec2 vUV;',
  4253. 'void main() {',
  4254. 'vUV = uvOffset + uv * uvScale;',
  4255. 'vec2 alignedPosition = position * scale;',
  4256. 'vec2 rotatedPosition;',
  4257. 'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',
  4258. 'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',
  4259. 'vec4 finalPosition;',
  4260. 'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',
  4261. 'finalPosition.xy += rotatedPosition;',
  4262. 'finalPosition = projectionMatrix * finalPosition;',
  4263. 'gl_Position = finalPosition;',
  4264. '}'
  4265. ].join( '\n' ) );
  4266. gl.shaderSource( fragmentShader, [
  4267. 'precision ' + renderer.getPrecision() + ' float;',
  4268. 'uniform vec3 color;',
  4269. 'uniform sampler2D map;',
  4270. 'uniform float opacity;',
  4271. 'uniform int fogType;',
  4272. 'uniform vec3 fogColor;',
  4273. 'uniform float fogDensity;',
  4274. 'uniform float fogNear;',
  4275. 'uniform float fogFar;',
  4276. 'uniform float alphaTest;',
  4277. 'varying vec2 vUV;',
  4278. 'void main() {',
  4279. 'vec4 texture = texture2D( map, vUV );',
  4280. 'if ( texture.a < alphaTest ) discard;',
  4281. 'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',
  4282. 'if ( fogType > 0 ) {',
  4283. 'float depth = gl_FragCoord.z / gl_FragCoord.w;',
  4284. 'float fogFactor = 0.0;',
  4285. 'if ( fogType == 1 ) {',
  4286. 'fogFactor = smoothstep( fogNear, fogFar, depth );',
  4287. '} else {',
  4288. 'const float LOG2 = 1.442695;',
  4289. 'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',
  4290. 'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',
  4291. '}',
  4292. 'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',
  4293. '}',
  4294. '}'
  4295. ].join( '\n' ) );
  4296. gl.compileShader( vertexShader );
  4297. gl.compileShader( fragmentShader );
  4298. gl.attachShader( program, vertexShader );
  4299. gl.attachShader( program, fragmentShader );
  4300. gl.linkProgram( program );
  4301. return program;
  4302. }
  4303. function painterSortStable( a, b ) {
  4304. if ( a.renderOrder !== b.renderOrder ) {
  4305. return a.renderOrder - b.renderOrder;
  4306. } else if ( a.z !== b.z ) {
  4307. return b.z - a.z;
  4308. } else {
  4309. return b.id - a.id;
  4310. }
  4311. }
  4312. }
  4313. /**
  4314. * @author szimek / https://github.com/szimek/
  4315. * @author alteredq / http://alteredqualia.com/
  4316. * @author Marius Kintel / https://github.com/kintel
  4317. */
  4318. /*
  4319. In options, we can specify:
  4320. * Texture parameters for an auto-generated target texture
  4321. * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers
  4322. */
  4323. function WebGLRenderTarget( width, height, options ) {
  4324. this.uuid = _Math.generateUUID();
  4325. this.width = width;
  4326. this.height = height;
  4327. this.scissor = new Vector4( 0, 0, width, height );
  4328. this.scissorTest = false;
  4329. this.viewport = new Vector4( 0, 0, width, height );
  4330. options = options || {};
  4331. if ( options.minFilter === undefined ) options.minFilter = LinearFilter;
  4332. this.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );
  4333. this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
  4334. this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;
  4335. this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;
  4336. }
  4337. WebGLRenderTarget.prototype = {
  4338. constructor: WebGLRenderTarget,
  4339. isWebGLRenderTarget: true,
  4340. setSize: function ( width, height ) {
  4341. if ( this.width !== width || this.height !== height ) {
  4342. this.width = width;
  4343. this.height = height;
  4344. this.dispose();
  4345. }
  4346. this.viewport.set( 0, 0, width, height );
  4347. this.scissor.set( 0, 0, width, height );
  4348. },
  4349. clone: function () {
  4350. return new this.constructor().copy( this );
  4351. },
  4352. copy: function ( source ) {
  4353. this.width = source.width;
  4354. this.height = source.height;
  4355. this.viewport.copy( source.viewport );
  4356. this.texture = source.texture.clone();
  4357. this.depthBuffer = source.depthBuffer;
  4358. this.stencilBuffer = source.stencilBuffer;
  4359. this.depthTexture = source.depthTexture;
  4360. return this;
  4361. },
  4362. dispose: function () {
  4363. this.dispatchEvent( { type: 'dispose' } );
  4364. }
  4365. };
  4366. Object.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype );
  4367. /**
  4368. * @author mrdoob / http://mrdoob.com/
  4369. * @author alteredq / http://alteredqualia.com/
  4370. */
  4371. var materialId = 0;
  4372. function Material() {
  4373. Object.defineProperty( this, 'id', { value: materialId ++ } );
  4374. this.uuid = _Math.generateUUID();
  4375. this.name = '';
  4376. this.type = 'Material';
  4377. this.fog = true;
  4378. this.lights = true;
  4379. this.blending = NormalBlending;
  4380. this.side = FrontSide;
  4381. this.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading
  4382. this.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors
  4383. this.opacity = 1;
  4384. this.transparent = false;
  4385. this.blendSrc = SrcAlphaFactor;
  4386. this.blendDst = OneMinusSrcAlphaFactor;
  4387. this.blendEquation = AddEquation;
  4388. this.blendSrcAlpha = null;
  4389. this.blendDstAlpha = null;
  4390. this.blendEquationAlpha = null;
  4391. this.depthFunc = LessEqualDepth;
  4392. this.depthTest = true;
  4393. this.depthWrite = true;
  4394. this.clippingPlanes = null;
  4395. this.clipIntersection = false;
  4396. this.clipShadows = false;
  4397. this.colorWrite = true;
  4398. this.precision = null; // override the renderer's default precision for this material
  4399. this.polygonOffset = false;
  4400. this.polygonOffsetFactor = 0;
  4401. this.polygonOffsetUnits = 0;
  4402. this.alphaTest = 0;
  4403. this.premultipliedAlpha = false;
  4404. this.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer
  4405. this.visible = true;
  4406. this._needsUpdate = true;
  4407. }
  4408. Material.prototype = {
  4409. constructor: Material,
  4410. isMaterial: true,
  4411. get needsUpdate() {
  4412. return this._needsUpdate;
  4413. },
  4414. set needsUpdate( value ) {
  4415. if ( value === true ) this.update();
  4416. this._needsUpdate = value;
  4417. },
  4418. setValues: function ( values ) {
  4419. if ( values === undefined ) return;
  4420. for ( var key in values ) {
  4421. var newValue = values[ key ];
  4422. if ( newValue === undefined ) {
  4423. console.warn( "THREE.Material: '" + key + "' parameter is undefined." );
  4424. continue;
  4425. }
  4426. var currentValue = this[ key ];
  4427. if ( currentValue === undefined ) {
  4428. console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." );
  4429. continue;
  4430. }
  4431. if ( currentValue && currentValue.isColor ) {
  4432. currentValue.set( newValue );
  4433. } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {
  4434. currentValue.copy( newValue );
  4435. } else if ( key === 'overdraw' ) {
  4436. // ensure overdraw is backwards-compatible with legacy boolean type
  4437. this[ key ] = Number( newValue );
  4438. } else {
  4439. this[ key ] = newValue;
  4440. }
  4441. }
  4442. },
  4443. toJSON: function ( meta ) {
  4444. var isRoot = meta === undefined;
  4445. if ( isRoot ) {
  4446. meta = {
  4447. textures: {},
  4448. images: {}
  4449. };
  4450. }
  4451. var data = {
  4452. metadata: {
  4453. version: 4.4,
  4454. type: 'Material',
  4455. generator: 'Material.toJSON'
  4456. }
  4457. };
  4458. // standard Material serialization
  4459. data.uuid = this.uuid;
  4460. data.type = this.type;
  4461. if ( this.name !== '' ) data.name = this.name;
  4462. if ( this.color && this.color.isColor ) data.color = this.color.getHex();
  4463. if ( this.roughness !== undefined ) data.roughness = this.roughness;
  4464. if ( this.metalness !== undefined ) data.metalness = this.metalness;
  4465. if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();
  4466. if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();
  4467. if ( this.shininess !== undefined ) data.shininess = this.shininess;
  4468. if ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;
  4469. if ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;
  4470. if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;
  4471. if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;
  4472. if ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;
  4473. if ( this.bumpMap && this.bumpMap.isTexture ) {
  4474. data.bumpMap = this.bumpMap.toJSON( meta ).uuid;
  4475. data.bumpScale = this.bumpScale;
  4476. }
  4477. if ( this.normalMap && this.normalMap.isTexture ) {
  4478. data.normalMap = this.normalMap.toJSON( meta ).uuid;
  4479. data.normalScale = this.normalScale.toArray();
  4480. }
  4481. if ( this.displacementMap && this.displacementMap.isTexture ) {
  4482. data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
  4483. data.displacementScale = this.displacementScale;
  4484. data.displacementBias = this.displacementBias;
  4485. }
  4486. if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;
  4487. if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;
  4488. if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;
  4489. if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;
  4490. if ( this.envMap && this.envMap.isTexture ) {
  4491. data.envMap = this.envMap.toJSON( meta ).uuid;
  4492. data.reflectivity = this.reflectivity; // Scale behind envMap
  4493. }
  4494. if ( this.gradientMap && this.gradientMap.isTexture ) {
  4495. data.gradientMap = this.gradientMap.toJSON( meta ).uuid;
  4496. }
  4497. if ( this.size !== undefined ) data.size = this.size;
  4498. if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;
  4499. if ( this.blending !== NormalBlending ) data.blending = this.blending;
  4500. if ( this.shading !== SmoothShading ) data.shading = this.shading;
  4501. if ( this.side !== FrontSide ) data.side = this.side;
  4502. if ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;
  4503. if ( this.opacity < 1 ) data.opacity = this.opacity;
  4504. if ( this.transparent === true ) data.transparent = this.transparent;
  4505. data.depthFunc = this.depthFunc;
  4506. data.depthTest = this.depthTest;
  4507. data.depthWrite = this.depthWrite;
  4508. if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;
  4509. if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;
  4510. if ( this.wireframe === true ) data.wireframe = this.wireframe;
  4511. if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;
  4512. if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;
  4513. if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;
  4514. data.skinning = this.skinning;
  4515. data.morphTargets = this.morphTargets;
  4516. // TODO: Copied from Object3D.toJSON
  4517. function extractFromCache( cache ) {
  4518. var values = [];
  4519. for ( var key in cache ) {
  4520. var data = cache[ key ];
  4521. delete data.metadata;
  4522. values.push( data );
  4523. }
  4524. return values;
  4525. }
  4526. if ( isRoot ) {
  4527. var textures = extractFromCache( meta.textures );
  4528. var images = extractFromCache( meta.images );
  4529. if ( textures.length > 0 ) data.textures = textures;
  4530. if ( images.length > 0 ) data.images = images;
  4531. }
  4532. return data;
  4533. },
  4534. clone: function () {
  4535. return new this.constructor().copy( this );
  4536. },
  4537. copy: function ( source ) {
  4538. this.name = source.name;
  4539. this.fog = source.fog;
  4540. this.lights = source.lights;
  4541. this.blending = source.blending;
  4542. this.side = source.side;
  4543. this.shading = source.shading;
  4544. this.vertexColors = source.vertexColors;
  4545. this.opacity = source.opacity;
  4546. this.transparent = source.transparent;
  4547. this.blendSrc = source.blendSrc;
  4548. this.blendDst = source.blendDst;
  4549. this.blendEquation = source.blendEquation;
  4550. this.blendSrcAlpha = source.blendSrcAlpha;
  4551. this.blendDstAlpha = source.blendDstAlpha;
  4552. this.blendEquationAlpha = source.blendEquationAlpha;
  4553. this.depthFunc = source.depthFunc;
  4554. this.depthTest = source.depthTest;
  4555. this.depthWrite = source.depthWrite;
  4556. this.colorWrite = source.colorWrite;
  4557. this.precision = source.precision;
  4558. this.polygonOffset = source.polygonOffset;
  4559. this.polygonOffsetFactor = source.polygonOffsetFactor;
  4560. this.polygonOffsetUnits = source.polygonOffsetUnits;
  4561. this.alphaTest = source.alphaTest;
  4562. this.premultipliedAlpha = source.premultipliedAlpha;
  4563. this.overdraw = source.overdraw;
  4564. this.visible = source.visible;
  4565. this.clipShadows = source.clipShadows;
  4566. this.clipIntersection = source.clipIntersection;
  4567. var srcPlanes = source.clippingPlanes,
  4568. dstPlanes = null;
  4569. if ( srcPlanes !== null ) {
  4570. var n = srcPlanes.length;
  4571. dstPlanes = new Array( n );
  4572. for ( var i = 0; i !== n; ++ i )
  4573. dstPlanes[ i ] = srcPlanes[ i ].clone();
  4574. }
  4575. this.clippingPlanes = dstPlanes;
  4576. return this;
  4577. },
  4578. update: function () {
  4579. this.dispatchEvent( { type: 'update' } );
  4580. },
  4581. dispose: function () {
  4582. this.dispatchEvent( { type: 'dispose' } );
  4583. }
  4584. };
  4585. Object.assign( Material.prototype, EventDispatcher.prototype );
  4586. /**
  4587. * @author alteredq / http://alteredqualia.com/
  4588. *
  4589. * parameters = {
  4590. * defines: { "label" : "value" },
  4591. * uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } },
  4592. *
  4593. * fragmentShader: <string>,
  4594. * vertexShader: <string>,
  4595. *
  4596. * wireframe: <boolean>,
  4597. * wireframeLinewidth: <float>,
  4598. *
  4599. * lights: <bool>,
  4600. *
  4601. * skinning: <bool>,
  4602. * morphTargets: <bool>,
  4603. * morphNormals: <bool>
  4604. * }
  4605. */
  4606. function ShaderMaterial( parameters ) {
  4607. Material.call( this );
  4608. this.type = 'ShaderMaterial';
  4609. this.defines = {};
  4610. this.uniforms = {};
  4611. this.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}';
  4612. this.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}';
  4613. this.linewidth = 1;
  4614. this.wireframe = false;
  4615. this.wireframeLinewidth = 1;
  4616. this.fog = false; // set to use scene fog
  4617. this.lights = false; // set to use scene lights
  4618. this.clipping = false; // set to use user-defined clipping planes
  4619. this.skinning = false; // set to use skinning attribute streams
  4620. this.morphTargets = false; // set to use morph targets
  4621. this.morphNormals = false; // set to use morph normals
  4622. this.extensions = {
  4623. derivatives: false, // set to use derivatives
  4624. fragDepth: false, // set to use fragment depth values
  4625. drawBuffers: false, // set to use draw buffers
  4626. shaderTextureLOD: false // set to use shader texture LOD
  4627. };
  4628. // When rendered geometry doesn't include these attributes but the material does,
  4629. // use these default values in WebGL. This avoids errors when buffer data is missing.
  4630. this.defaultAttributeValues = {
  4631. 'color': [ 1, 1, 1 ],
  4632. 'uv': [ 0, 0 ],
  4633. 'uv2': [ 0, 0 ]
  4634. };
  4635. this.index0AttributeName = undefined;
  4636. if ( parameters !== undefined ) {
  4637. if ( parameters.attributes !== undefined ) {
  4638. console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );
  4639. }
  4640. this.setValues( parameters );
  4641. }
  4642. }
  4643. ShaderMaterial.prototype = Object.create( Material.prototype );
  4644. ShaderMaterial.prototype.constructor = ShaderMaterial;
  4645. ShaderMaterial.prototype.isShaderMaterial = true;
  4646. ShaderMaterial.prototype.copy = function ( source ) {
  4647. Material.prototype.copy.call( this, source );
  4648. this.fragmentShader = source.fragmentShader;
  4649. this.vertexShader = source.vertexShader;
  4650. this.uniforms = UniformsUtils.clone( source.uniforms );
  4651. this.defines = source.defines;
  4652. this.wireframe = source.wireframe;
  4653. this.wireframeLinewidth = source.wireframeLinewidth;
  4654. this.lights = source.lights;
  4655. this.clipping = source.clipping;
  4656. this.skinning = source.skinning;
  4657. this.morphTargets = source.morphTargets;
  4658. this.morphNormals = source.morphNormals;
  4659. this.extensions = source.extensions;
  4660. return this;
  4661. };
  4662. ShaderMaterial.prototype.toJSON = function ( meta ) {
  4663. var data = Material.prototype.toJSON.call( this, meta );
  4664. data.uniforms = this.uniforms;
  4665. data.vertexShader = this.vertexShader;
  4666. data.fragmentShader = this.fragmentShader;
  4667. return data;
  4668. };
  4669. /**
  4670. * @author mrdoob / http://mrdoob.com/
  4671. * @author alteredq / http://alteredqualia.com/
  4672. * @author bhouston / https://clara.io
  4673. * @author WestLangley / http://github.com/WestLangley
  4674. *
  4675. * parameters = {
  4676. *
  4677. * opacity: <float>,
  4678. *
  4679. * map: new THREE.Texture( <Image> ),
  4680. *
  4681. * alphaMap: new THREE.Texture( <Image> ),
  4682. *
  4683. * displacementMap: new THREE.Texture( <Image> ),
  4684. * displacementScale: <float>,
  4685. * displacementBias: <float>,
  4686. *
  4687. * wireframe: <boolean>,
  4688. * wireframeLinewidth: <float>
  4689. * }
  4690. */
  4691. function MeshDepthMaterial( parameters ) {
  4692. Material.call( this );
  4693. this.type = 'MeshDepthMaterial';
  4694. this.depthPacking = BasicDepthPacking;
  4695. this.skinning = false;
  4696. this.morphTargets = false;
  4697. this.map = null;
  4698. this.alphaMap = null;
  4699. this.displacementMap = null;
  4700. this.displacementScale = 1;
  4701. this.displacementBias = 0;
  4702. this.wireframe = false;
  4703. this.wireframeLinewidth = 1;
  4704. this.fog = false;
  4705. this.lights = false;
  4706. this.setValues( parameters );
  4707. }
  4708. MeshDepthMaterial.prototype = Object.create( Material.prototype );
  4709. MeshDepthMaterial.prototype.constructor = MeshDepthMaterial;
  4710. MeshDepthMaterial.prototype.isMeshDepthMaterial = true;
  4711. MeshDepthMaterial.prototype.copy = function ( source ) {
  4712. Material.prototype.copy.call( this, source );
  4713. this.depthPacking = source.depthPacking;
  4714. this.skinning = source.skinning;
  4715. this.morphTargets = source.morphTargets;
  4716. this.map = source.map;
  4717. this.alphaMap = source.alphaMap;
  4718. this.displacementMap = source.displacementMap;
  4719. this.displacementScale = source.displacementScale;
  4720. this.displacementBias = source.displacementBias;
  4721. this.wireframe = source.wireframe;
  4722. this.wireframeLinewidth = source.wireframeLinewidth;
  4723. return this;
  4724. };
  4725. /**
  4726. * @author bhouston / http://clara.io
  4727. * @author WestLangley / http://github.com/WestLangley
  4728. */
  4729. function Box3( min, max ) {
  4730. this.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );
  4731. this.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );
  4732. }
  4733. Box3.prototype = {
  4734. constructor: Box3,
  4735. isBox3: true,
  4736. set: function ( min, max ) {
  4737. this.min.copy( min );
  4738. this.max.copy( max );
  4739. return this;
  4740. },
  4741. setFromArray: function ( array ) {
  4742. var minX = + Infinity;
  4743. var minY = + Infinity;
  4744. var minZ = + Infinity;
  4745. var maxX = - Infinity;
  4746. var maxY = - Infinity;
  4747. var maxZ = - Infinity;
  4748. for ( var i = 0, l = array.length; i < l; i += 3 ) {
  4749. var x = array[ i ];
  4750. var y = array[ i + 1 ];
  4751. var z = array[ i + 2 ];
  4752. if ( x < minX ) minX = x;
  4753. if ( y < minY ) minY = y;
  4754. if ( z < minZ ) minZ = z;
  4755. if ( x > maxX ) maxX = x;
  4756. if ( y > maxY ) maxY = y;
  4757. if ( z > maxZ ) maxZ = z;
  4758. }
  4759. this.min.set( minX, minY, minZ );
  4760. this.max.set( maxX, maxY, maxZ );
  4761. return this;
  4762. },
  4763. setFromBufferAttribute: function ( attribute ) {
  4764. var minX = + Infinity;
  4765. var minY = + Infinity;
  4766. var minZ = + Infinity;
  4767. var maxX = - Infinity;
  4768. var maxY = - Infinity;
  4769. var maxZ = - Infinity;
  4770. for ( var i = 0, l = attribute.count; i < l; i ++ ) {
  4771. var x = attribute.getX( i );
  4772. var y = attribute.getY( i );
  4773. var z = attribute.getZ( i );
  4774. if ( x < minX ) minX = x;
  4775. if ( y < minY ) minY = y;
  4776. if ( z < minZ ) minZ = z;
  4777. if ( x > maxX ) maxX = x;
  4778. if ( y > maxY ) maxY = y;
  4779. if ( z > maxZ ) maxZ = z;
  4780. }
  4781. this.min.set( minX, minY, minZ );
  4782. this.max.set( maxX, maxY, maxZ );
  4783. return this;
  4784. },
  4785. setFromPoints: function ( points ) {
  4786. this.makeEmpty();
  4787. for ( var i = 0, il = points.length; i < il; i ++ ) {
  4788. this.expandByPoint( points[ i ] );
  4789. }
  4790. return this;
  4791. },
  4792. setFromCenterAndSize: function () {
  4793. var v1 = new Vector3();
  4794. return function setFromCenterAndSize( center, size ) {
  4795. var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
  4796. this.min.copy( center ).sub( halfSize );
  4797. this.max.copy( center ).add( halfSize );
  4798. return this;
  4799. };
  4800. }(),
  4801. setFromObject: function ( object ) {
  4802. this.makeEmpty();
  4803. return this.expandByObject( object );
  4804. },
  4805. clone: function () {
  4806. return new this.constructor().copy( this );
  4807. },
  4808. copy: function ( box ) {
  4809. this.min.copy( box.min );
  4810. this.max.copy( box.max );
  4811. return this;
  4812. },
  4813. makeEmpty: function () {
  4814. this.min.x = this.min.y = this.min.z = + Infinity;
  4815. this.max.x = this.max.y = this.max.z = - Infinity;
  4816. return this;
  4817. },
  4818. isEmpty: function () {
  4819. // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
  4820. return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );
  4821. },
  4822. getCenter: function ( optionalTarget ) {
  4823. var result = optionalTarget || new Vector3();
  4824. return this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
  4825. },
  4826. getSize: function ( optionalTarget ) {
  4827. var result = optionalTarget || new Vector3();
  4828. return this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );
  4829. },
  4830. expandByPoint: function ( point ) {
  4831. this.min.min( point );
  4832. this.max.max( point );
  4833. return this;
  4834. },
  4835. expandByVector: function ( vector ) {
  4836. this.min.sub( vector );
  4837. this.max.add( vector );
  4838. return this;
  4839. },
  4840. expandByScalar: function ( scalar ) {
  4841. this.min.addScalar( - scalar );
  4842. this.max.addScalar( scalar );
  4843. return this;
  4844. },
  4845. expandByObject: function () {
  4846. // Computes the world-axis-aligned bounding box of an object (including its children),
  4847. // accounting for both the object's, and children's, world transforms
  4848. var v1 = new Vector3();
  4849. return function expandByObject( object ) {
  4850. var scope = this;
  4851. object.updateMatrixWorld( true );
  4852. object.traverse( function ( node ) {
  4853. var i, l;
  4854. var geometry = node.geometry;
  4855. if ( geometry !== undefined ) {
  4856. if ( geometry.isGeometry ) {
  4857. var vertices = geometry.vertices;
  4858. for ( i = 0, l = vertices.length; i < l; i ++ ) {
  4859. v1.copy( vertices[ i ] );
  4860. v1.applyMatrix4( node.matrixWorld );
  4861. scope.expandByPoint( v1 );
  4862. }
  4863. } else if ( geometry.isBufferGeometry ) {
  4864. var attribute = geometry.attributes.position;
  4865. if ( attribute !== undefined ) {
  4866. for ( i = 0, l = attribute.count; i < l; i ++ ) {
  4867. v1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );
  4868. scope.expandByPoint( v1 );
  4869. }
  4870. }
  4871. }
  4872. }
  4873. } );
  4874. return this;
  4875. };
  4876. }(),
  4877. containsPoint: function ( point ) {
  4878. return point.x < this.min.x || point.x > this.max.x ||
  4879. point.y < this.min.y || point.y > this.max.y ||
  4880. point.z < this.min.z || point.z > this.max.z ? false : true;
  4881. },
  4882. containsBox: function ( box ) {
  4883. return this.min.x <= box.min.x && box.max.x <= this.max.x &&
  4884. this.min.y <= box.min.y && box.max.y <= this.max.y &&
  4885. this.min.z <= box.min.z && box.max.z <= this.max.z;
  4886. },
  4887. getParameter: function ( point, optionalTarget ) {
  4888. // This can potentially have a divide by zero if the box
  4889. // has a size dimension of 0.
  4890. var result = optionalTarget || new Vector3();
  4891. return result.set(
  4892. ( point.x - this.min.x ) / ( this.max.x - this.min.x ),
  4893. ( point.y - this.min.y ) / ( this.max.y - this.min.y ),
  4894. ( point.z - this.min.z ) / ( this.max.z - this.min.z )
  4895. );
  4896. },
  4897. intersectsBox: function ( box ) {
  4898. // using 6 splitting planes to rule out intersections.
  4899. return box.max.x < this.min.x || box.min.x > this.max.x ||
  4900. box.max.y < this.min.y || box.min.y > this.max.y ||
  4901. box.max.z < this.min.z || box.min.z > this.max.z ? false : true;
  4902. },
  4903. intersectsSphere: ( function () {
  4904. var closestPoint;
  4905. return function intersectsSphere( sphere ) {
  4906. if ( closestPoint === undefined ) closestPoint = new Vector3();
  4907. // Find the point on the AABB closest to the sphere center.
  4908. this.clampPoint( sphere.center, closestPoint );
  4909. // If that point is inside the sphere, the AABB and sphere intersect.
  4910. return closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );
  4911. };
  4912. } )(),
  4913. intersectsPlane: function ( plane ) {
  4914. // We compute the minimum and maximum dot product values. If those values
  4915. // are on the same side (back or front) of the plane, then there is no intersection.
  4916. var min, max;
  4917. if ( plane.normal.x > 0 ) {
  4918. min = plane.normal.x * this.min.x;
  4919. max = plane.normal.x * this.max.x;
  4920. } else {
  4921. min = plane.normal.x * this.max.x;
  4922. max = plane.normal.x * this.min.x;
  4923. }
  4924. if ( plane.normal.y > 0 ) {
  4925. min += plane.normal.y * this.min.y;
  4926. max += plane.normal.y * this.max.y;
  4927. } else {
  4928. min += plane.normal.y * this.max.y;
  4929. max += plane.normal.y * this.min.y;
  4930. }
  4931. if ( plane.normal.z > 0 ) {
  4932. min += plane.normal.z * this.min.z;
  4933. max += plane.normal.z * this.max.z;
  4934. } else {
  4935. min += plane.normal.z * this.max.z;
  4936. max += plane.normal.z * this.min.z;
  4937. }
  4938. return ( min <= plane.constant && max >= plane.constant );
  4939. },
  4940. clampPoint: function ( point, optionalTarget ) {
  4941. var result = optionalTarget || new Vector3();
  4942. return result.copy( point ).clamp( this.min, this.max );
  4943. },
  4944. distanceToPoint: function () {
  4945. var v1 = new Vector3();
  4946. return function distanceToPoint( point ) {
  4947. var clampedPoint = v1.copy( point ).clamp( this.min, this.max );
  4948. return clampedPoint.sub( point ).length();
  4949. };
  4950. }(),
  4951. getBoundingSphere: function () {
  4952. var v1 = new Vector3();
  4953. return function getBoundingSphere( optionalTarget ) {
  4954. var result = optionalTarget || new Sphere();
  4955. this.getCenter( result.center );
  4956. result.radius = this.getSize( v1 ).length() * 0.5;
  4957. return result;
  4958. };
  4959. }(),
  4960. intersect: function ( box ) {
  4961. this.min.max( box.min );
  4962. this.max.min( box.max );
  4963. // 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.
  4964. if( this.isEmpty() ) this.makeEmpty();
  4965. return this;
  4966. },
  4967. union: function ( box ) {
  4968. this.min.min( box.min );
  4969. this.max.max( box.max );
  4970. return this;
  4971. },
  4972. applyMatrix4: function () {
  4973. var points = [
  4974. new Vector3(),
  4975. new Vector3(),
  4976. new Vector3(),
  4977. new Vector3(),
  4978. new Vector3(),
  4979. new Vector3(),
  4980. new Vector3(),
  4981. new Vector3()
  4982. ];
  4983. return function applyMatrix4( matrix ) {
  4984. // transform of empty box is an empty box.
  4985. if( this.isEmpty() ) return this;
  4986. // NOTE: I am using a binary pattern to specify all 2^3 combinations below
  4987. points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000
  4988. points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001
  4989. points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010
  4990. points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011
  4991. points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100
  4992. points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101
  4993. points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110
  4994. points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111
  4995. this.setFromPoints( points );
  4996. return this;
  4997. };
  4998. }(),
  4999. translate: function ( offset ) {
  5000. this.min.add( offset );
  5001. this.max.add( offset );
  5002. return this;
  5003. },
  5004. equals: function ( box ) {
  5005. return box.min.equals( this.min ) && box.max.equals( this.max );
  5006. }
  5007. };
  5008. /**
  5009. * @author bhouston / http://clara.io
  5010. * @author mrdoob / http://mrdoob.com/
  5011. */
  5012. function Sphere( center, radius ) {
  5013. this.center = ( center !== undefined ) ? center : new Vector3();
  5014. this.radius = ( radius !== undefined ) ? radius : 0;
  5015. }
  5016. Sphere.prototype = {
  5017. constructor: Sphere,
  5018. set: function ( center, radius ) {
  5019. this.center.copy( center );
  5020. this.radius = radius;
  5021. return this;
  5022. },
  5023. setFromPoints: function () {
  5024. var box;
  5025. return function setFromPoints( points, optionalCenter ) {
  5026. if ( box === undefined ) box = new Box3(); // see #10547
  5027. var center = this.center;
  5028. if ( optionalCenter !== undefined ) {
  5029. center.copy( optionalCenter );
  5030. } else {
  5031. box.setFromPoints( points ).getCenter( center );
  5032. }
  5033. var maxRadiusSq = 0;
  5034. for ( var i = 0, il = points.length; i < il; i ++ ) {
  5035. maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );
  5036. }
  5037. this.radius = Math.sqrt( maxRadiusSq );
  5038. return this;
  5039. };
  5040. }(),
  5041. clone: function () {
  5042. return new this.constructor().copy( this );
  5043. },
  5044. copy: function ( sphere ) {
  5045. this.center.copy( sphere.center );
  5046. this.radius = sphere.radius;
  5047. return this;
  5048. },
  5049. empty: function () {
  5050. return ( this.radius <= 0 );
  5051. },
  5052. containsPoint: function ( point ) {
  5053. return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );
  5054. },
  5055. distanceToPoint: function ( point ) {
  5056. return ( point.distanceTo( this.center ) - this.radius );
  5057. },
  5058. intersectsSphere: function ( sphere ) {
  5059. var radiusSum = this.radius + sphere.radius;
  5060. return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );
  5061. },
  5062. intersectsBox: function ( box ) {
  5063. return box.intersectsSphere( this );
  5064. },
  5065. intersectsPlane: function ( plane ) {
  5066. // We use the following equation to compute the signed distance from
  5067. // the center of the sphere to the plane.
  5068. //
  5069. // distance = q * n - d
  5070. //
  5071. // If this distance is greater than the radius of the sphere,
  5072. // then there is no intersection.
  5073. return Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;
  5074. },
  5075. clampPoint: function ( point, optionalTarget ) {
  5076. var deltaLengthSq = this.center.distanceToSquared( point );
  5077. var result = optionalTarget || new Vector3();
  5078. result.copy( point );
  5079. if ( deltaLengthSq > ( this.radius * this.radius ) ) {
  5080. result.sub( this.center ).normalize();
  5081. result.multiplyScalar( this.radius ).add( this.center );
  5082. }
  5083. return result;
  5084. },
  5085. getBoundingBox: function ( optionalTarget ) {
  5086. var box = optionalTarget || new Box3();
  5087. box.set( this.center, this.center );
  5088. box.expandByScalar( this.radius );
  5089. return box;
  5090. },
  5091. applyMatrix4: function ( matrix ) {
  5092. this.center.applyMatrix4( matrix );
  5093. this.radius = this.radius * matrix.getMaxScaleOnAxis();
  5094. return this;
  5095. },
  5096. translate: function ( offset ) {
  5097. this.center.add( offset );
  5098. return this;
  5099. },
  5100. equals: function ( sphere ) {
  5101. return sphere.center.equals( this.center ) && ( sphere.radius === this.radius );
  5102. }
  5103. };
  5104. /**
  5105. * @author alteredq / http://alteredqualia.com/
  5106. * @author WestLangley / http://github.com/WestLangley
  5107. * @author bhouston / http://clara.io
  5108. * @author tschw
  5109. */
  5110. function Matrix3() {
  5111. this.elements = new Float32Array( [
  5112. 1, 0, 0,
  5113. 0, 1, 0,
  5114. 0, 0, 1
  5115. ] );
  5116. if ( arguments.length > 0 ) {
  5117. console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );
  5118. }
  5119. }
  5120. Matrix3.prototype = {
  5121. constructor: Matrix3,
  5122. isMatrix3: true,
  5123. set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
  5124. var te = this.elements;
  5125. te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;
  5126. te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;
  5127. te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;
  5128. return this;
  5129. },
  5130. identity: function () {
  5131. this.set(
  5132. 1, 0, 0,
  5133. 0, 1, 0,
  5134. 0, 0, 1
  5135. );
  5136. return this;
  5137. },
  5138. clone: function () {
  5139. return new this.constructor().fromArray( this.elements );
  5140. },
  5141. copy: function ( m ) {
  5142. var me = m.elements;
  5143. this.set(
  5144. me[ 0 ], me[ 3 ], me[ 6 ],
  5145. me[ 1 ], me[ 4 ], me[ 7 ],
  5146. me[ 2 ], me[ 5 ], me[ 8 ]
  5147. );
  5148. return this;
  5149. },
  5150. setFromMatrix4: function( m ) {
  5151. var me = m.elements;
  5152. this.set(
  5153. me[ 0 ], me[ 4 ], me[ 8 ],
  5154. me[ 1 ], me[ 5 ], me[ 9 ],
  5155. me[ 2 ], me[ 6 ], me[ 10 ]
  5156. );
  5157. return this;
  5158. },
  5159. applyToBufferAttribute: function () {
  5160. var v1;
  5161. return function applyToBufferAttribute( attribute ) {
  5162. if ( v1 === undefined ) v1 = new Vector3();
  5163. for ( var i = 0, l = attribute.count; i < l; i ++ ) {
  5164. v1.x = attribute.getX( i );
  5165. v1.y = attribute.getY( i );
  5166. v1.z = attribute.getZ( i );
  5167. v1.applyMatrix3( this );
  5168. attribute.setXYZ( i, v1.x, v1.y, v1.z );
  5169. }
  5170. return attribute;
  5171. };
  5172. }(),
  5173. multiplyScalar: function ( s ) {
  5174. var te = this.elements;
  5175. te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;
  5176. te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;
  5177. te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;
  5178. return this;
  5179. },
  5180. determinant: function () {
  5181. var te = this.elements;
  5182. var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],
  5183. d = te[ 3 ], e = te[ 4 ], f = te[ 5 ],
  5184. g = te[ 6 ], h = te[ 7 ], i = te[ 8 ];
  5185. return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;
  5186. },
  5187. getInverse: function ( matrix, throwOnDegenerate ) {
  5188. if ( matrix && matrix.isMatrix4 ) {
  5189. console.error( "THREE.Matrix3.getInverse no longer takes a Matrix4 argument." );
  5190. }
  5191. var me = matrix.elements,
  5192. te = this.elements,
  5193. n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],
  5194. n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],
  5195. n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],
  5196. t11 = n33 * n22 - n32 * n23,
  5197. t12 = n32 * n13 - n33 * n12,
  5198. t13 = n23 * n12 - n22 * n13,
  5199. det = n11 * t11 + n21 * t12 + n31 * t13;
  5200. if ( det === 0 ) {
  5201. var msg = "THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0";
  5202. if ( throwOnDegenerate === true ) {
  5203. throw new Error( msg );
  5204. } else {
  5205. console.warn( msg );
  5206. }
  5207. return this.identity();
  5208. }
  5209. var detInv = 1 / det;
  5210. te[ 0 ] = t11 * detInv;
  5211. te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;
  5212. te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;
  5213. te[ 3 ] = t12 * detInv;
  5214. te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;
  5215. te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;
  5216. te[ 6 ] = t13 * detInv;
  5217. te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;
  5218. te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;
  5219. return this;
  5220. },
  5221. transpose: function () {
  5222. var tmp, m = this.elements;
  5223. tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;
  5224. tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;
  5225. tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;
  5226. return this;
  5227. },
  5228. getNormalMatrix: function ( matrix4 ) {
  5229. return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();
  5230. },
  5231. transposeIntoArray: function ( r ) {
  5232. var m = this.elements;
  5233. r[ 0 ] = m[ 0 ];
  5234. r[ 1 ] = m[ 3 ];
  5235. r[ 2 ] = m[ 6 ];
  5236. r[ 3 ] = m[ 1 ];
  5237. r[ 4 ] = m[ 4 ];
  5238. r[ 5 ] = m[ 7 ];
  5239. r[ 6 ] = m[ 2 ];
  5240. r[ 7 ] = m[ 5 ];
  5241. r[ 8 ] = m[ 8 ];
  5242. return this;
  5243. },
  5244. fromArray: function ( array, offset ) {
  5245. if ( offset === undefined ) offset = 0;
  5246. for( var i = 0; i < 9; i ++ ) {
  5247. this.elements[ i ] = array[ i + offset ];
  5248. }
  5249. return this;
  5250. },
  5251. toArray: function ( array, offset ) {
  5252. if ( array === undefined ) array = [];
  5253. if ( offset === undefined ) offset = 0;
  5254. var te = this.elements;
  5255. array[ offset ] = te[ 0 ];
  5256. array[ offset + 1 ] = te[ 1 ];
  5257. array[ offset + 2 ] = te[ 2 ];
  5258. array[ offset + 3 ] = te[ 3 ];
  5259. array[ offset + 4 ] = te[ 4 ];
  5260. array[ offset + 5 ] = te[ 5 ];
  5261. array[ offset + 6 ] = te[ 6 ];
  5262. array[ offset + 7 ] = te[ 7 ];
  5263. array[ offset + 8 ] = te[ 8 ];
  5264. return array;
  5265. }
  5266. };
  5267. /**
  5268. * @author bhouston / http://clara.io
  5269. */
  5270. function Plane( normal, constant ) {
  5271. this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );
  5272. this.constant = ( constant !== undefined ) ? constant : 0;
  5273. }
  5274. Plane.prototype = {
  5275. constructor: Plane,
  5276. set: function ( normal, constant ) {
  5277. this.normal.copy( normal );
  5278. this.constant = constant;
  5279. return this;
  5280. },
  5281. setComponents: function ( x, y, z, w ) {
  5282. this.normal.set( x, y, z );
  5283. this.constant = w;
  5284. return this;
  5285. },
  5286. setFromNormalAndCoplanarPoint: function ( normal, point ) {
  5287. this.normal.copy( normal );
  5288. this.constant = - point.dot( this.normal ); // must be this.normal, not normal, as this.normal is normalized
  5289. return this;
  5290. },
  5291. setFromCoplanarPoints: function () {
  5292. var v1 = new Vector3();
  5293. var v2 = new Vector3();
  5294. return function setFromCoplanarPoints( a, b, c ) {
  5295. var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();
  5296. // Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
  5297. this.setFromNormalAndCoplanarPoint( normal, a );
  5298. return this;
  5299. };
  5300. }(),
  5301. clone: function () {
  5302. return new this.constructor().copy( this );
  5303. },
  5304. copy: function ( plane ) {
  5305. this.normal.copy( plane.normal );
  5306. this.constant = plane.constant;
  5307. return this;
  5308. },
  5309. normalize: function () {
  5310. // Note: will lead to a divide by zero if the plane is invalid.
  5311. var inverseNormalLength = 1.0 / this.normal.length();
  5312. this.normal.multiplyScalar( inverseNormalLength );
  5313. this.constant *= inverseNormalLength;
  5314. return this;
  5315. },
  5316. negate: function () {
  5317. this.constant *= - 1;
  5318. this.normal.negate();
  5319. return this;
  5320. },
  5321. distanceToPoint: function ( point ) {
  5322. return this.normal.dot( point ) + this.constant;
  5323. },
  5324. distanceToSphere: function ( sphere ) {
  5325. return this.distanceToPoint( sphere.center ) - sphere.radius;
  5326. },
  5327. projectPoint: function ( point, optionalTarget ) {
  5328. return this.orthoPoint( point, optionalTarget ).sub( point ).negate();
  5329. },
  5330. orthoPoint: function ( point, optionalTarget ) {
  5331. var perpendicularMagnitude = this.distanceToPoint( point );
  5332. var result = optionalTarget || new Vector3();
  5333. return result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );
  5334. },
  5335. intersectLine: function () {
  5336. var v1 = new Vector3();
  5337. return function intersectLine( line, optionalTarget ) {
  5338. var result = optionalTarget || new Vector3();
  5339. var direction = line.delta( v1 );
  5340. var denominator = this.normal.dot( direction );
  5341. if ( denominator === 0 ) {
  5342. // line is coplanar, return origin
  5343. if ( this.distanceToPoint( line.start ) === 0 ) {
  5344. return result.copy( line.start );
  5345. }
  5346. // Unsure if this is the correct method to handle this case.
  5347. return undefined;
  5348. }
  5349. var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;
  5350. if ( t < 0 || t > 1 ) {
  5351. return undefined;
  5352. }
  5353. return result.copy( direction ).multiplyScalar( t ).add( line.start );
  5354. };
  5355. }(),
  5356. intersectsLine: function ( line ) {
  5357. // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
  5358. var startSign = this.distanceToPoint( line.start );
  5359. var endSign = this.distanceToPoint( line.end );
  5360. return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
  5361. },
  5362. intersectsBox: function ( box ) {
  5363. return box.intersectsPlane( this );
  5364. },
  5365. intersectsSphere: function ( sphere ) {
  5366. return sphere.intersectsPlane( this );
  5367. },
  5368. coplanarPoint: function ( optionalTarget ) {
  5369. var result = optionalTarget || new Vector3();
  5370. return result.copy( this.normal ).multiplyScalar( - this.constant );
  5371. },
  5372. applyMatrix4: function () {
  5373. var v1 = new Vector3();
  5374. var m1 = new Matrix3();
  5375. return function applyMatrix4( matrix, optionalNormalMatrix ) {
  5376. var referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );
  5377. // transform normal based on theory here:
  5378. // http://www.songho.ca/opengl/gl_normaltransform.html
  5379. var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );
  5380. var normal = this.normal.applyMatrix3( normalMatrix ).normalize();
  5381. // recalculate constant (like in setFromNormalAndCoplanarPoint)
  5382. this.constant = - referencePoint.dot( normal );
  5383. return this;
  5384. };
  5385. }(),
  5386. translate: function ( offset ) {
  5387. this.constant = this.constant - offset.dot( this.normal );
  5388. return this;
  5389. },
  5390. equals: function ( plane ) {
  5391. return plane.normal.equals( this.normal ) && ( plane.constant === this.constant );
  5392. }
  5393. };
  5394. /**
  5395. * @author mrdoob / http://mrdoob.com/
  5396. * @author alteredq / http://alteredqualia.com/
  5397. * @author bhouston / http://clara.io
  5398. */
  5399. function Frustum( p0, p1, p2, p3, p4, p5 ) {
  5400. this.planes = [
  5401. ( p0 !== undefined ) ? p0 : new Plane(),
  5402. ( p1 !== undefined ) ? p1 : new Plane(),
  5403. ( p2 !== undefined ) ? p2 : new Plane(),
  5404. ( p3 !== undefined ) ? p3 : new Plane(),
  5405. ( p4 !== undefined ) ? p4 : new Plane(),
  5406. ( p5 !== undefined ) ? p5 : new Plane()
  5407. ];
  5408. }
  5409. Frustum.prototype = {
  5410. constructor: Frustum,
  5411. set: function ( p0, p1, p2, p3, p4, p5 ) {
  5412. var planes = this.planes;
  5413. planes[ 0 ].copy( p0 );
  5414. planes[ 1 ].copy( p1 );
  5415. planes[ 2 ].copy( p2 );
  5416. planes[ 3 ].copy( p3 );
  5417. planes[ 4 ].copy( p4 );
  5418. planes[ 5 ].copy( p5 );
  5419. return this;
  5420. },
  5421. clone: function () {
  5422. return new this.constructor().copy( this );
  5423. },
  5424. copy: function ( frustum ) {
  5425. var planes = this.planes;
  5426. for ( var i = 0; i < 6; i ++ ) {
  5427. planes[ i ].copy( frustum.planes[ i ] );
  5428. }
  5429. return this;
  5430. },
  5431. setFromMatrix: function ( m ) {
  5432. var planes = this.planes;
  5433. var me = m.elements;
  5434. var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];
  5435. var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];
  5436. var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];
  5437. var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];
  5438. planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();
  5439. planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();
  5440. planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();
  5441. planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();
  5442. planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();
  5443. planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();
  5444. return this;
  5445. },
  5446. intersectsObject: function () {
  5447. var sphere = new Sphere();
  5448. return function intersectsObject( object ) {
  5449. var geometry = object.geometry;
  5450. if ( geometry.boundingSphere === null )
  5451. geometry.computeBoundingSphere();
  5452. sphere.copy( geometry.boundingSphere )
  5453. .applyMatrix4( object.matrixWorld );
  5454. return this.intersectsSphere( sphere );
  5455. };
  5456. }(),
  5457. intersectsSprite: function () {
  5458. var sphere = new Sphere();
  5459. return function intersectsSprite( sprite ) {
  5460. sphere.center.set( 0, 0, 0 );
  5461. sphere.radius = 0.7071067811865476;
  5462. sphere.applyMatrix4( sprite.matrixWorld );
  5463. return this.intersectsSphere( sphere );
  5464. };
  5465. }(),
  5466. intersectsSphere: function ( sphere ) {
  5467. var planes = this.planes;
  5468. var center = sphere.center;
  5469. var negRadius = - sphere.radius;
  5470. for ( var i = 0; i < 6; i ++ ) {
  5471. var distance = planes[ i ].distanceToPoint( center );
  5472. if ( distance < negRadius ) {
  5473. return false;
  5474. }
  5475. }
  5476. return true;
  5477. },
  5478. intersectsBox: function () {
  5479. var p1 = new Vector3(),
  5480. p2 = new Vector3();
  5481. return function intersectsBox( box ) {
  5482. var planes = this.planes;
  5483. for ( var i = 0; i < 6 ; i ++ ) {
  5484. var plane = planes[ i ];
  5485. p1.x = plane.normal.x > 0 ? box.min.x : box.max.x;
  5486. p2.x = plane.normal.x > 0 ? box.max.x : box.min.x;
  5487. p1.y = plane.normal.y > 0 ? box.min.y : box.max.y;
  5488. p2.y = plane.normal.y > 0 ? box.max.y : box.min.y;
  5489. p1.z = plane.normal.z > 0 ? box.min.z : box.max.z;
  5490. p2.z = plane.normal.z > 0 ? box.max.z : box.min.z;
  5491. var d1 = plane.distanceToPoint( p1 );
  5492. var d2 = plane.distanceToPoint( p2 );
  5493. // if both outside plane, no intersection
  5494. if ( d1 < 0 && d2 < 0 ) {
  5495. return false;
  5496. }
  5497. }
  5498. return true;
  5499. };
  5500. }(),
  5501. containsPoint: function ( point ) {
  5502. var planes = this.planes;
  5503. for ( var i = 0; i < 6; i ++ ) {
  5504. if ( planes[ i ].distanceToPoint( point ) < 0 ) {
  5505. return false;
  5506. }
  5507. }
  5508. return true;
  5509. }
  5510. };
  5511. /**
  5512. * @author alteredq / http://alteredqualia.com/
  5513. * @author mrdoob / http://mrdoob.com/
  5514. */
  5515. function WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {
  5516. var _gl = _renderer.context,
  5517. _state = _renderer.state,
  5518. _frustum = new Frustum(),
  5519. _projScreenMatrix = new Matrix4(),
  5520. _lightShadows = _lights.shadows,
  5521. _shadowMapSize = new Vector2(),
  5522. _maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),
  5523. _lookTarget = new Vector3(),
  5524. _lightPositionWorld = new Vector3(),
  5525. _renderList = [],
  5526. _MorphingFlag = 1,
  5527. _SkinningFlag = 2,
  5528. _NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,
  5529. _depthMaterials = new Array( _NumberOfMaterialVariants ),
  5530. _distanceMaterials = new Array( _NumberOfMaterialVariants ),
  5531. _materialCache = {};
  5532. var cubeDirections = [
  5533. new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),
  5534. new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )
  5535. ];
  5536. var cubeUps = [
  5537. new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),
  5538. new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 )
  5539. ];
  5540. var cube2DViewPorts = [
  5541. new Vector4(), new Vector4(), new Vector4(),
  5542. new Vector4(), new Vector4(), new Vector4()
  5543. ];
  5544. // init
  5545. var depthMaterialTemplate = new MeshDepthMaterial();
  5546. depthMaterialTemplate.depthPacking = RGBADepthPacking;
  5547. depthMaterialTemplate.clipping = true;
  5548. var distanceShader = ShaderLib[ "distanceRGBA" ];
  5549. var distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );
  5550. for ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {
  5551. var useMorphing = ( i & _MorphingFlag ) !== 0;
  5552. var useSkinning = ( i & _SkinningFlag ) !== 0;
  5553. var depthMaterial = depthMaterialTemplate.clone();
  5554. depthMaterial.morphTargets = useMorphing;
  5555. depthMaterial.skinning = useSkinning;
  5556. _depthMaterials[ i ] = depthMaterial;
  5557. var distanceMaterial = new ShaderMaterial( {
  5558. defines: {
  5559. 'USE_SHADOWMAP': ''
  5560. },
  5561. uniforms: distanceUniforms,
  5562. vertexShader: distanceShader.vertexShader,
  5563. fragmentShader: distanceShader.fragmentShader,
  5564. morphTargets: useMorphing,
  5565. skinning: useSkinning,
  5566. clipping: true
  5567. } );
  5568. _distanceMaterials[ i ] = distanceMaterial;
  5569. }
  5570. //
  5571. var scope = this;
  5572. this.enabled = false;
  5573. this.autoUpdate = true;
  5574. this.needsUpdate = false;
  5575. this.type = PCFShadowMap;
  5576. this.renderReverseSided = true;
  5577. this.renderSingleSided = true;
  5578. this.render = function ( scene, camera ) {
  5579. if ( scope.enabled === false ) return;
  5580. if ( scope.autoUpdate === false && scope.needsUpdate === false ) return;
  5581. if ( _lightShadows.length === 0 ) return;
  5582. // Set GL state for depth map.
  5583. _state.buffers.color.setClear( 1, 1, 1, 1 );
  5584. _state.disable( _gl.BLEND );
  5585. _state.setDepthTest( true );
  5586. _state.setScissorTest( false );
  5587. // render depth map
  5588. var faceCount, isPointLight;
  5589. for ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {
  5590. var light = _lightShadows[ i ];
  5591. var shadow = light.shadow;
  5592. if ( shadow === undefined ) {
  5593. console.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );
  5594. continue;
  5595. }
  5596. var shadowCamera = shadow.camera;
  5597. _shadowMapSize.copy( shadow.mapSize );
  5598. _shadowMapSize.min( _maxShadowMapSize );
  5599. if ( light && light.isPointLight ) {
  5600. faceCount = 6;
  5601. isPointLight = true;
  5602. var vpWidth = _shadowMapSize.x;
  5603. var vpHeight = _shadowMapSize.y;
  5604. // These viewports map a cube-map onto a 2D texture with the
  5605. // following orientation:
  5606. //
  5607. // xzXZ
  5608. // y Y
  5609. //
  5610. // X - Positive x direction
  5611. // x - Negative x direction
  5612. // Y - Positive y direction
  5613. // y - Negative y direction
  5614. // Z - Positive z direction
  5615. // z - Negative z direction
  5616. // positive X
  5617. cube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );
  5618. // negative X
  5619. cube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );
  5620. // positive Z
  5621. cube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );
  5622. // negative Z
  5623. cube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );
  5624. // positive Y
  5625. cube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );
  5626. // negative Y
  5627. cube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );
  5628. _shadowMapSize.x *= 4.0;
  5629. _shadowMapSize.y *= 2.0;
  5630. } else {
  5631. faceCount = 1;
  5632. isPointLight = false;
  5633. }
  5634. if ( shadow.map === null ) {
  5635. var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };
  5636. shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
  5637. shadowCamera.updateProjectionMatrix();
  5638. }
  5639. if ( shadow.isSpotLightShadow ) {
  5640. shadow.update( light );
  5641. }
  5642. // TODO (abelnation / sam-g-steel): is this needed?
  5643. if (shadow && shadow.isRectAreaLightShadow ) {
  5644. shadow.update( light );
  5645. }
  5646. var shadowMap = shadow.map;
  5647. var shadowMatrix = shadow.matrix;
  5648. _lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
  5649. shadowCamera.position.copy( _lightPositionWorld );
  5650. _renderer.setRenderTarget( shadowMap );
  5651. _renderer.clear();
  5652. // render shadow map for each cube face (if omni-directional) or
  5653. // run a single pass if not
  5654. for ( var face = 0; face < faceCount; face ++ ) {
  5655. if ( isPointLight ) {
  5656. _lookTarget.copy( shadowCamera.position );
  5657. _lookTarget.add( cubeDirections[ face ] );
  5658. shadowCamera.up.copy( cubeUps[ face ] );
  5659. shadowCamera.lookAt( _lookTarget );
  5660. var vpDimensions = cube2DViewPorts[ face ];
  5661. _state.viewport( vpDimensions );
  5662. } else {
  5663. _lookTarget.setFromMatrixPosition( light.target.matrixWorld );
  5664. shadowCamera.lookAt( _lookTarget );
  5665. }
  5666. shadowCamera.updateMatrixWorld();
  5667. shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
  5668. // compute shadow matrix
  5669. shadowMatrix.set(
  5670. 0.5, 0.0, 0.0, 0.5,
  5671. 0.0, 0.5, 0.0, 0.5,
  5672. 0.0, 0.0, 0.5, 0.5,
  5673. 0.0, 0.0, 0.0, 1.0
  5674. );
  5675. shadowMatrix.multiply( shadowCamera.projectionMatrix );
  5676. shadowMatrix.multiply( shadowCamera.matrixWorldInverse );
  5677. // update camera matrices and frustum
  5678. _projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
  5679. _frustum.setFromMatrix( _projScreenMatrix );
  5680. // set object matrices & frustum culling
  5681. _renderList.length = 0;
  5682. projectObject( scene, camera, shadowCamera );
  5683. // render shadow map
  5684. // render regular objects
  5685. for ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {
  5686. var object = _renderList[ j ];
  5687. var geometry = _objects.update( object );
  5688. var material = object.material;
  5689. if ( material && material.isMultiMaterial ) {
  5690. var groups = geometry.groups;
  5691. var materials = material.materials;
  5692. for ( var k = 0, kl = groups.length; k < kl; k ++ ) {
  5693. var group = groups[ k ];
  5694. var groupMaterial = materials[ group.materialIndex ];
  5695. if ( groupMaterial.visible === true ) {
  5696. var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );
  5697. _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );
  5698. }
  5699. }
  5700. } else {
  5701. var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );
  5702. _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );
  5703. }
  5704. }
  5705. }
  5706. }
  5707. // Restore GL state.
  5708. var clearColor = _renderer.getClearColor(),
  5709. clearAlpha = _renderer.getClearAlpha();
  5710. _renderer.setClearColor( clearColor, clearAlpha );
  5711. scope.needsUpdate = false;
  5712. };
  5713. function getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {
  5714. var geometry = object.geometry;
  5715. var result = null;
  5716. var materialVariants = _depthMaterials;
  5717. var customMaterial = object.customDepthMaterial;
  5718. if ( isPointLight ) {
  5719. materialVariants = _distanceMaterials;
  5720. customMaterial = object.customDistanceMaterial;
  5721. }
  5722. if ( ! customMaterial ) {
  5723. var useMorphing = false;
  5724. if ( material.morphTargets ) {
  5725. if ( geometry && geometry.isBufferGeometry ) {
  5726. useMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;
  5727. } else if ( geometry && geometry.isGeometry ) {
  5728. useMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;
  5729. }
  5730. }
  5731. var useSkinning = object.isSkinnedMesh && material.skinning;
  5732. var variantIndex = 0;
  5733. if ( useMorphing ) variantIndex |= _MorphingFlag;
  5734. if ( useSkinning ) variantIndex |= _SkinningFlag;
  5735. result = materialVariants[ variantIndex ];
  5736. } else {
  5737. result = customMaterial;
  5738. }
  5739. if ( _renderer.localClippingEnabled &&
  5740. material.clipShadows === true &&
  5741. material.clippingPlanes.length !== 0 ) {
  5742. // in this case we need a unique material instance reflecting the
  5743. // appropriate state
  5744. var keyA = result.uuid, keyB = material.uuid;
  5745. var materialsForVariant = _materialCache[ keyA ];
  5746. if ( materialsForVariant === undefined ) {
  5747. materialsForVariant = {};
  5748. _materialCache[ keyA ] = materialsForVariant;
  5749. }
  5750. var cachedMaterial = materialsForVariant[ keyB ];
  5751. if ( cachedMaterial === undefined ) {
  5752. cachedMaterial = result.clone();
  5753. materialsForVariant[ keyB ] = cachedMaterial;
  5754. }
  5755. result = cachedMaterial;
  5756. }
  5757. result.visible = material.visible;
  5758. result.wireframe = material.wireframe;
  5759. var side = material.side;
  5760. if ( scope.renderSingleSided && side == DoubleSide ) {
  5761. side = FrontSide;
  5762. }
  5763. if ( scope.renderReverseSided ) {
  5764. if ( side === FrontSide ) side = BackSide;
  5765. else if ( side === BackSide ) side = FrontSide;
  5766. }
  5767. result.side = side;
  5768. result.clipShadows = material.clipShadows;
  5769. result.clippingPlanes = material.clippingPlanes;
  5770. result.wireframeLinewidth = material.wireframeLinewidth;
  5771. result.linewidth = material.linewidth;
  5772. if ( isPointLight && result.uniforms.lightPos !== undefined ) {
  5773. result.uniforms.lightPos.value.copy( lightPositionWorld );
  5774. }
  5775. return result;
  5776. }
  5777. function projectObject( object, camera, shadowCamera ) {
  5778. if ( object.visible === false ) return;
  5779. var visible = ( object.layers.mask & camera.layers.mask ) !== 0;
  5780. if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {
  5781. if ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {
  5782. var material = object.material;
  5783. if ( material.visible === true ) {
  5784. object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );
  5785. _renderList.push( object );
  5786. }
  5787. }
  5788. }
  5789. var children = object.children;
  5790. for ( var i = 0, l = children.length; i < l; i ++ ) {
  5791. projectObject( children[ i ], camera, shadowCamera );
  5792. }
  5793. }
  5794. }
  5795. /**
  5796. * @author bhouston / http://clara.io
  5797. */
  5798. function Ray( origin, direction ) {
  5799. this.origin = ( origin !== undefined ) ? origin : new Vector3();
  5800. this.direction = ( direction !== undefined ) ? direction : new Vector3();
  5801. }
  5802. Ray.prototype = {
  5803. constructor: Ray,
  5804. set: function ( origin, direction ) {
  5805. this.origin.copy( origin );
  5806. this.direction.copy( direction );
  5807. return this;
  5808. },
  5809. clone: function () {
  5810. return new this.constructor().copy( this );
  5811. },
  5812. copy: function ( ray ) {
  5813. this.origin.copy( ray.origin );
  5814. this.direction.copy( ray.direction );
  5815. return this;
  5816. },
  5817. at: function ( t, optionalTarget ) {
  5818. var result = optionalTarget || new Vector3();
  5819. return result.copy( this.direction ).multiplyScalar( t ).add( this.origin );
  5820. },
  5821. lookAt: function ( v ) {
  5822. this.direction.copy( v ).sub( this.origin ).normalize();
  5823. return this;
  5824. },
  5825. recast: function () {
  5826. var v1 = new Vector3();
  5827. return function recast( t ) {
  5828. this.origin.copy( this.at( t, v1 ) );
  5829. return this;
  5830. };
  5831. }(),
  5832. closestPointToPoint: function ( point, optionalTarget ) {
  5833. var result = optionalTarget || new Vector3();
  5834. result.subVectors( point, this.origin );
  5835. var directionDistance = result.dot( this.direction );
  5836. if ( directionDistance < 0 ) {
  5837. return result.copy( this.origin );
  5838. }
  5839. return result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
  5840. },
  5841. distanceToPoint: function ( point ) {
  5842. return Math.sqrt( this.distanceSqToPoint( point ) );
  5843. },
  5844. distanceSqToPoint: function () {
  5845. var v1 = new Vector3();
  5846. return function distanceSqToPoint( point ) {
  5847. var directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );
  5848. // point behind the ray
  5849. if ( directionDistance < 0 ) {
  5850. return this.origin.distanceToSquared( point );
  5851. }
  5852. v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
  5853. return v1.distanceToSquared( point );
  5854. };
  5855. }(),
  5856. distanceSqToSegment: function () {
  5857. var segCenter = new Vector3();
  5858. var segDir = new Vector3();
  5859. var diff = new Vector3();
  5860. return function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {
  5861. // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h
  5862. // It returns the min distance between the ray and the segment
  5863. // defined by v0 and v1
  5864. // It can also set two optional targets :
  5865. // - The closest point on the ray
  5866. // - The closest point on the segment
  5867. segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );
  5868. segDir.copy( v1 ).sub( v0 ).normalize();
  5869. diff.copy( this.origin ).sub( segCenter );
  5870. var segExtent = v0.distanceTo( v1 ) * 0.5;
  5871. var a01 = - this.direction.dot( segDir );
  5872. var b0 = diff.dot( this.direction );
  5873. var b1 = - diff.dot( segDir );
  5874. var c = diff.lengthSq();
  5875. var det = Math.abs( 1 - a01 * a01 );
  5876. var s0, s1, sqrDist, extDet;
  5877. if ( det > 0 ) {
  5878. // The ray and segment are not parallel.
  5879. s0 = a01 * b1 - b0;
  5880. s1 = a01 * b0 - b1;
  5881. extDet = segExtent * det;
  5882. if ( s0 >= 0 ) {
  5883. if ( s1 >= - extDet ) {
  5884. if ( s1 <= extDet ) {
  5885. // region 0
  5886. // Minimum at interior points of ray and segment.
  5887. var invDet = 1 / det;
  5888. s0 *= invDet;
  5889. s1 *= invDet;
  5890. sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;
  5891. } else {
  5892. // region 1
  5893. s1 = segExtent;
  5894. s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
  5895. sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
  5896. }
  5897. } else {
  5898. // region 5
  5899. s1 = - segExtent;
  5900. s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
  5901. sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
  5902. }
  5903. } else {
  5904. if ( s1 <= - extDet ) {
  5905. // region 4
  5906. s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );
  5907. s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
  5908. sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
  5909. } else if ( s1 <= extDet ) {
  5910. // region 3
  5911. s0 = 0;
  5912. s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );
  5913. sqrDist = s1 * ( s1 + 2 * b1 ) + c;
  5914. } else {
  5915. // region 2
  5916. s0 = Math.max( 0, - ( a01 * segExtent + b0 ) );
  5917. s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
  5918. sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
  5919. }
  5920. }
  5921. } else {
  5922. // Ray and segment are parallel.
  5923. s1 = ( a01 > 0 ) ? - segExtent : segExtent;
  5924. s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
  5925. sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
  5926. }
  5927. if ( optionalPointOnRay ) {
  5928. optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );
  5929. }
  5930. if ( optionalPointOnSegment ) {
  5931. optionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );
  5932. }
  5933. return sqrDist;
  5934. };
  5935. }(),
  5936. intersectSphere: function () {
  5937. var v1 = new Vector3();
  5938. return function intersectSphere( sphere, optionalTarget ) {
  5939. v1.subVectors( sphere.center, this.origin );
  5940. var tca = v1.dot( this.direction );
  5941. var d2 = v1.dot( v1 ) - tca * tca;
  5942. var radius2 = sphere.radius * sphere.radius;
  5943. if ( d2 > radius2 ) return null;
  5944. var thc = Math.sqrt( radius2 - d2 );
  5945. // t0 = first intersect point - entrance on front of sphere
  5946. var t0 = tca - thc;
  5947. // t1 = second intersect point - exit point on back of sphere
  5948. var t1 = tca + thc;
  5949. // test to see if both t0 and t1 are behind the ray - if so, return null
  5950. if ( t0 < 0 && t1 < 0 ) return null;
  5951. // test to see if t0 is behind the ray:
  5952. // if it is, the ray is inside the sphere, so return the second exit point scaled by t1,
  5953. // in order to always return an intersect point that is in front of the ray.
  5954. if ( t0 < 0 ) return this.at( t1, optionalTarget );
  5955. // else t0 is in front of the ray, so return the first collision point scaled by t0
  5956. return this.at( t0, optionalTarget );
  5957. };
  5958. }(),
  5959. intersectsSphere: function ( sphere ) {
  5960. return this.distanceToPoint( sphere.center ) <= sphere.radius;
  5961. },
  5962. distanceToPlane: function ( plane ) {
  5963. var denominator = plane.normal.dot( this.direction );
  5964. if ( denominator === 0 ) {
  5965. // line is coplanar, return origin
  5966. if ( plane.distanceToPoint( this.origin ) === 0 ) {
  5967. return 0;
  5968. }
  5969. // Null is preferable to undefined since undefined means.... it is undefined
  5970. return null;
  5971. }
  5972. var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;
  5973. // Return if the ray never intersects the plane
  5974. return t >= 0 ? t : null;
  5975. },
  5976. intersectPlane: function ( plane, optionalTarget ) {
  5977. var t = this.distanceToPlane( plane );
  5978. if ( t === null ) {
  5979. return null;
  5980. }
  5981. return this.at( t, optionalTarget );
  5982. },
  5983. intersectsPlane: function ( plane ) {
  5984. // check if the ray lies on the plane first
  5985. var distToPoint = plane.distanceToPoint( this.origin );
  5986. if ( distToPoint === 0 ) {
  5987. return true;
  5988. }
  5989. var denominator = plane.normal.dot( this.direction );
  5990. if ( denominator * distToPoint < 0 ) {
  5991. return true;
  5992. }
  5993. // ray origin is behind the plane (and is pointing behind it)
  5994. return false;
  5995. },
  5996. intersectBox: function ( box, optionalTarget ) {
  5997. var tmin, tmax, tymin, tymax, tzmin, tzmax;
  5998. var invdirx = 1 / this.direction.x,
  5999. invdiry = 1 / this.direction.y,
  6000. invdirz = 1 / this.direction.z;
  6001. var origin = this.origin;
  6002. if ( invdirx >= 0 ) {
  6003. tmin = ( box.min.x - origin.x ) * invdirx;
  6004. tmax = ( box.max.x - origin.x ) * invdirx;
  6005. } else {
  6006. tmin = ( box.max.x - origin.x ) * invdirx;
  6007. tmax = ( box.min.x - origin.x ) * invdirx;
  6008. }
  6009. if ( invdiry >= 0 ) {
  6010. tymin = ( box.min.y - origin.y ) * invdiry;
  6011. tymax = ( box.max.y - origin.y ) * invdiry;
  6012. } else {
  6013. tymin = ( box.max.y - origin.y ) * invdiry;
  6014. tymax = ( box.min.y - origin.y ) * invdiry;
  6015. }
  6016. if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;
  6017. // These lines also handle the case where tmin or tmax is NaN
  6018. // (result of 0 * Infinity). x !== x returns true if x is NaN
  6019. if ( tymin > tmin || tmin !== tmin ) tmin = tymin;
  6020. if ( tymax < tmax || tmax !== tmax ) tmax = tymax;
  6021. if ( invdirz >= 0 ) {
  6022. tzmin = ( box.min.z - origin.z ) * invdirz;
  6023. tzmax = ( box.max.z - origin.z ) * invdirz;
  6024. } else {
  6025. tzmin = ( box.max.z - origin.z ) * invdirz;
  6026. tzmax = ( box.min.z - origin.z ) * invdirz;
  6027. }
  6028. if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;
  6029. if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;
  6030. if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;
  6031. //return point closest to the ray (positive side)
  6032. if ( tmax < 0 ) return null;
  6033. return this.at( tmin >= 0 ? tmin : tmax, optionalTarget );
  6034. },
  6035. intersectsBox: ( function () {
  6036. var v = new Vector3();
  6037. return function intersectsBox( box ) {
  6038. return this.intersectBox( box, v ) !== null;
  6039. };
  6040. } )(),
  6041. intersectTriangle: function () {
  6042. // Compute the offset origin, edges, and normal.
  6043. var diff = new Vector3();
  6044. var edge1 = new Vector3();
  6045. var edge2 = new Vector3();
  6046. var normal = new Vector3();
  6047. return function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {
  6048. // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h
  6049. edge1.subVectors( b, a );
  6050. edge2.subVectors( c, a );
  6051. normal.crossVectors( edge1, edge2 );
  6052. // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,
  6053. // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by
  6054. // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
  6055. // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
  6056. // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
  6057. var DdN = this.direction.dot( normal );
  6058. var sign;
  6059. if ( DdN > 0 ) {
  6060. if ( backfaceCulling ) return null;
  6061. sign = 1;
  6062. } else if ( DdN < 0 ) {
  6063. sign = - 1;
  6064. DdN = - DdN;
  6065. } else {
  6066. return null;
  6067. }
  6068. diff.subVectors( this.origin, a );
  6069. var DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );
  6070. // b1 < 0, no intersection
  6071. if ( DdQxE2 < 0 ) {
  6072. return null;
  6073. }
  6074. var DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );
  6075. // b2 < 0, no intersection
  6076. if ( DdE1xQ < 0 ) {
  6077. return null;
  6078. }
  6079. // b1+b2 > 1, no intersection
  6080. if ( DdQxE2 + DdE1xQ > DdN ) {
  6081. return null;
  6082. }
  6083. // Line intersects triangle, check if ray does.
  6084. var QdN = - sign * diff.dot( normal );
  6085. // t < 0, no intersection
  6086. if ( QdN < 0 ) {
  6087. return null;
  6088. }
  6089. // Ray intersects triangle.
  6090. return this.at( QdN / DdN, optionalTarget );
  6091. };
  6092. }(),
  6093. applyMatrix4: function ( matrix4 ) {
  6094. this.direction.add( this.origin ).applyMatrix4( matrix4 );
  6095. this.origin.applyMatrix4( matrix4 );
  6096. this.direction.sub( this.origin );
  6097. this.direction.normalize();
  6098. return this;
  6099. },
  6100. equals: function ( ray ) {
  6101. return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );
  6102. }
  6103. };
  6104. /**
  6105. * @author mrdoob / http://mrdoob.com/
  6106. * @author WestLangley / http://github.com/WestLangley
  6107. * @author bhouston / http://clara.io
  6108. */
  6109. function Euler( x, y, z, order ) {
  6110. this._x = x || 0;
  6111. this._y = y || 0;
  6112. this._z = z || 0;
  6113. this._order = order || Euler.DefaultOrder;
  6114. }
  6115. Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];
  6116. Euler.DefaultOrder = 'XYZ';
  6117. Euler.prototype = {
  6118. constructor: Euler,
  6119. isEuler: true,
  6120. get x () {
  6121. return this._x;
  6122. },
  6123. set x ( value ) {
  6124. this._x = value;
  6125. this.onChangeCallback();
  6126. },
  6127. get y () {
  6128. return this._y;
  6129. },
  6130. set y ( value ) {
  6131. this._y = value;
  6132. this.onChangeCallback();
  6133. },
  6134. get z () {
  6135. return this._z;
  6136. },
  6137. set z ( value ) {
  6138. this._z = value;
  6139. this.onChangeCallback();
  6140. },
  6141. get order () {
  6142. return this._order;
  6143. },
  6144. set order ( value ) {
  6145. this._order = value;
  6146. this.onChangeCallback();
  6147. },
  6148. set: function ( x, y, z, order ) {
  6149. this._x = x;
  6150. this._y = y;
  6151. this._z = z;
  6152. this._order = order || this._order;
  6153. this.onChangeCallback();
  6154. return this;
  6155. },
  6156. clone: function () {
  6157. return new this.constructor( this._x, this._y, this._z, this._order );
  6158. },
  6159. copy: function ( euler ) {
  6160. this._x = euler._x;
  6161. this._y = euler._y;
  6162. this._z = euler._z;
  6163. this._order = euler._order;
  6164. this.onChangeCallback();
  6165. return this;
  6166. },
  6167. setFromRotationMatrix: function ( m, order, update ) {
  6168. var clamp = _Math.clamp;
  6169. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  6170. var te = m.elements;
  6171. var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];
  6172. var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];
  6173. var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
  6174. order = order || this._order;
  6175. if ( order === 'XYZ' ) {
  6176. this._y = Math.asin( clamp( m13, - 1, 1 ) );
  6177. if ( Math.abs( m13 ) < 0.99999 ) {
  6178. this._x = Math.atan2( - m23, m33 );
  6179. this._z = Math.atan2( - m12, m11 );
  6180. } else {
  6181. this._x = Math.atan2( m32, m22 );
  6182. this._z = 0;
  6183. }
  6184. } else if ( order === 'YXZ' ) {
  6185. this._x = Math.asin( - clamp( m23, - 1, 1 ) );
  6186. if ( Math.abs( m23 ) < 0.99999 ) {
  6187. this._y = Math.atan2( m13, m33 );
  6188. this._z = Math.atan2( m21, m22 );
  6189. } else {
  6190. this._y = Math.atan2( - m31, m11 );
  6191. this._z = 0;
  6192. }
  6193. } else if ( order === 'ZXY' ) {
  6194. this._x = Math.asin( clamp( m32, - 1, 1 ) );
  6195. if ( Math.abs( m32 ) < 0.99999 ) {
  6196. this._y = Math.atan2( - m31, m33 );
  6197. this._z = Math.atan2( - m12, m22 );
  6198. } else {
  6199. this._y = 0;
  6200. this._z = Math.atan2( m21, m11 );
  6201. }
  6202. } else if ( order === 'ZYX' ) {
  6203. this._y = Math.asin( - clamp( m31, - 1, 1 ) );
  6204. if ( Math.abs( m31 ) < 0.99999 ) {
  6205. this._x = Math.atan2( m32, m33 );
  6206. this._z = Math.atan2( m21, m11 );
  6207. } else {
  6208. this._x = 0;
  6209. this._z = Math.atan2( - m12, m22 );
  6210. }
  6211. } else if ( order === 'YZX' ) {
  6212. this._z = Math.asin( clamp( m21, - 1, 1 ) );
  6213. if ( Math.abs( m21 ) < 0.99999 ) {
  6214. this._x = Math.atan2( - m23, m22 );
  6215. this._y = Math.atan2( - m31, m11 );
  6216. } else {
  6217. this._x = 0;
  6218. this._y = Math.atan2( m13, m33 );
  6219. }
  6220. } else if ( order === 'XZY' ) {
  6221. this._z = Math.asin( - clamp( m12, - 1, 1 ) );
  6222. if ( Math.abs( m12 ) < 0.99999 ) {
  6223. this._x = Math.atan2( m32, m22 );
  6224. this._y = Math.atan2( m13, m11 );
  6225. } else {
  6226. this._x = Math.atan2( - m23, m33 );
  6227. this._y = 0;
  6228. }
  6229. } else {
  6230. console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );
  6231. }
  6232. this._order = order;
  6233. if ( update !== false ) this.onChangeCallback();
  6234. return this;
  6235. },
  6236. setFromQuaternion: function () {
  6237. var matrix;
  6238. return function setFromQuaternion( q, order, update ) {
  6239. if ( matrix === undefined ) matrix = new Matrix4();
  6240. matrix.makeRotationFromQuaternion( q );
  6241. return this.setFromRotationMatrix( matrix, order, update );
  6242. };
  6243. }(),
  6244. setFromVector3: function ( v, order ) {
  6245. return this.set( v.x, v.y, v.z, order || this._order );
  6246. },
  6247. reorder: function () {
  6248. // WARNING: this discards revolution information -bhouston
  6249. var q = new Quaternion();
  6250. return function reorder( newOrder ) {
  6251. q.setFromEuler( this );
  6252. return this.setFromQuaternion( q, newOrder );
  6253. };
  6254. }(),
  6255. equals: function ( euler ) {
  6256. return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );
  6257. },
  6258. fromArray: function ( array ) {
  6259. this._x = array[ 0 ];
  6260. this._y = array[ 1 ];
  6261. this._z = array[ 2 ];
  6262. if ( array[ 3 ] !== undefined ) this._order = array[ 3 ];
  6263. this.onChangeCallback();
  6264. return this;
  6265. },
  6266. toArray: function ( array, offset ) {
  6267. if ( array === undefined ) array = [];
  6268. if ( offset === undefined ) offset = 0;
  6269. array[ offset ] = this._x;
  6270. array[ offset + 1 ] = this._y;
  6271. array[ offset + 2 ] = this._z;
  6272. array[ offset + 3 ] = this._order;
  6273. return array;
  6274. },
  6275. toVector3: function ( optionalResult ) {
  6276. if ( optionalResult ) {
  6277. return optionalResult.set( this._x, this._y, this._z );
  6278. } else {
  6279. return new Vector3( this._x, this._y, this._z );
  6280. }
  6281. },
  6282. onChange: function ( callback ) {
  6283. this.onChangeCallback = callback;
  6284. return this;
  6285. },
  6286. onChangeCallback: function () {}
  6287. };
  6288. /**
  6289. * @author mrdoob / http://mrdoob.com/
  6290. */
  6291. function Layers() {
  6292. this.mask = 1;
  6293. }
  6294. Layers.prototype = {
  6295. constructor: Layers,
  6296. set: function ( channel ) {
  6297. this.mask = 1 << channel;
  6298. },
  6299. enable: function ( channel ) {
  6300. this.mask |= 1 << channel;
  6301. },
  6302. toggle: function ( channel ) {
  6303. this.mask ^= 1 << channel;
  6304. },
  6305. disable: function ( channel ) {
  6306. this.mask &= ~ ( 1 << channel );
  6307. },
  6308. test: function ( layers ) {
  6309. return ( this.mask & layers.mask ) !== 0;
  6310. }
  6311. };
  6312. /**
  6313. * @author mrdoob / http://mrdoob.com/
  6314. * @author mikael emtinger / http://gomo.se/
  6315. * @author alteredq / http://alteredqualia.com/
  6316. * @author WestLangley / http://github.com/WestLangley
  6317. * @author elephantatwork / www.elephantatwork.ch
  6318. */
  6319. var object3DId = 0;
  6320. function Object3D() {
  6321. Object.defineProperty( this, 'id', { value: object3DId ++ } );
  6322. this.uuid = _Math.generateUUID();
  6323. this.name = '';
  6324. this.type = 'Object3D';
  6325. this.parent = null;
  6326. this.children = [];
  6327. this.up = Object3D.DefaultUp.clone();
  6328. var position = new Vector3();
  6329. var rotation = new Euler();
  6330. var quaternion = new Quaternion();
  6331. var scale = new Vector3( 1, 1, 1 );
  6332. function onRotationChange() {
  6333. quaternion.setFromEuler( rotation, false );
  6334. }
  6335. function onQuaternionChange() {
  6336. rotation.setFromQuaternion( quaternion, undefined, false );
  6337. }
  6338. rotation.onChange( onRotationChange );
  6339. quaternion.onChange( onQuaternionChange );
  6340. Object.defineProperties( this, {
  6341. position: {
  6342. enumerable: true,
  6343. value: position
  6344. },
  6345. rotation: {
  6346. enumerable: true,
  6347. value: rotation
  6348. },
  6349. quaternion: {
  6350. enumerable: true,
  6351. value: quaternion
  6352. },
  6353. scale: {
  6354. enumerable: true,
  6355. value: scale
  6356. },
  6357. modelViewMatrix: {
  6358. value: new Matrix4()
  6359. },
  6360. normalMatrix: {
  6361. value: new Matrix3()
  6362. }
  6363. } );
  6364. this.matrix = new Matrix4();
  6365. this.matrixWorld = new Matrix4();
  6366. this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;
  6367. this.matrixWorldNeedsUpdate = false;
  6368. this.layers = new Layers();
  6369. this.visible = true;
  6370. this.castShadow = false;
  6371. this.receiveShadow = false;
  6372. this.frustumCulled = true;
  6373. this.renderOrder = 0;
  6374. this.userData = {};
  6375. this.onBeforeRender = function () {};
  6376. this.onAfterRender = function () {};
  6377. }
  6378. Object3D.DefaultUp = new Vector3( 0, 1, 0 );
  6379. Object3D.DefaultMatrixAutoUpdate = true;
  6380. Object3D.prototype = {
  6381. constructor: Object3D,
  6382. isObject3D: true,
  6383. applyMatrix: function ( matrix ) {
  6384. this.matrix.multiplyMatrices( matrix, this.matrix );
  6385. this.matrix.decompose( this.position, this.quaternion, this.scale );
  6386. },
  6387. setRotationFromAxisAngle: function ( axis, angle ) {
  6388. // assumes axis is normalized
  6389. this.quaternion.setFromAxisAngle( axis, angle );
  6390. },
  6391. setRotationFromEuler: function ( euler ) {
  6392. this.quaternion.setFromEuler( euler, true );
  6393. },
  6394. setRotationFromMatrix: function ( m ) {
  6395. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  6396. this.quaternion.setFromRotationMatrix( m );
  6397. },
  6398. setRotationFromQuaternion: function ( q ) {
  6399. // assumes q is normalized
  6400. this.quaternion.copy( q );
  6401. },
  6402. rotateOnAxis: function () {
  6403. // rotate object on axis in object space
  6404. // axis is assumed to be normalized
  6405. var q1 = new Quaternion();
  6406. return function rotateOnAxis( axis, angle ) {
  6407. q1.setFromAxisAngle( axis, angle );
  6408. this.quaternion.multiply( q1 );
  6409. return this;
  6410. };
  6411. }(),
  6412. rotateX: function () {
  6413. var v1 = new Vector3( 1, 0, 0 );
  6414. return function rotateX( angle ) {
  6415. return this.rotateOnAxis( v1, angle );
  6416. };
  6417. }(),
  6418. rotateY: function () {
  6419. var v1 = new Vector3( 0, 1, 0 );
  6420. return function rotateY( angle ) {
  6421. return this.rotateOnAxis( v1, angle );
  6422. };
  6423. }(),
  6424. rotateZ: function () {
  6425. var v1 = new Vector3( 0, 0, 1 );
  6426. return function rotateZ( angle ) {
  6427. return this.rotateOnAxis( v1, angle );
  6428. };
  6429. }(),
  6430. translateOnAxis: function () {
  6431. // translate object by distance along axis in object space
  6432. // axis is assumed to be normalized
  6433. var v1 = new Vector3();
  6434. return function translateOnAxis( axis, distance ) {
  6435. v1.copy( axis ).applyQuaternion( this.quaternion );
  6436. this.position.add( v1.multiplyScalar( distance ) );
  6437. return this;
  6438. };
  6439. }(),
  6440. translateX: function () {
  6441. var v1 = new Vector3( 1, 0, 0 );
  6442. return function translateX( distance ) {
  6443. return this.translateOnAxis( v1, distance );
  6444. };
  6445. }(),
  6446. translateY: function () {
  6447. var v1 = new Vector3( 0, 1, 0 );
  6448. return function translateY( distance ) {
  6449. return this.translateOnAxis( v1, distance );
  6450. };
  6451. }(),
  6452. translateZ: function () {
  6453. var v1 = new Vector3( 0, 0, 1 );
  6454. return function translateZ( distance ) {
  6455. return this.translateOnAxis( v1, distance );
  6456. };
  6457. }(),
  6458. localToWorld: function ( vector ) {
  6459. return vector.applyMatrix4( this.matrixWorld );
  6460. },
  6461. worldToLocal: function () {
  6462. var m1 = new Matrix4();
  6463. return function worldToLocal( vector ) {
  6464. return vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );
  6465. };
  6466. }(),
  6467. lookAt: function () {
  6468. // This routine does not support objects with rotated and/or translated parent(s)
  6469. var m1 = new Matrix4();
  6470. return function lookAt( vector ) {
  6471. m1.lookAt( vector, this.position, this.up );
  6472. this.quaternion.setFromRotationMatrix( m1 );
  6473. };
  6474. }(),
  6475. add: function ( object ) {
  6476. if ( arguments.length > 1 ) {
  6477. for ( var i = 0; i < arguments.length; i ++ ) {
  6478. this.add( arguments[ i ] );
  6479. }
  6480. return this;
  6481. }
  6482. if ( object === this ) {
  6483. console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object );
  6484. return this;
  6485. }
  6486. if ( ( object && object.isObject3D ) ) {
  6487. if ( object.parent !== null ) {
  6488. object.parent.remove( object );
  6489. }
  6490. object.parent = this;
  6491. object.dispatchEvent( { type: 'added' } );
  6492. this.children.push( object );
  6493. } else {
  6494. console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object );
  6495. }
  6496. return this;
  6497. },
  6498. remove: function ( object ) {
  6499. if ( arguments.length > 1 ) {
  6500. for ( var i = 0; i < arguments.length; i ++ ) {
  6501. this.remove( arguments[ i ] );
  6502. }
  6503. }
  6504. var index = this.children.indexOf( object );
  6505. if ( index !== - 1 ) {
  6506. object.parent = null;
  6507. object.dispatchEvent( { type: 'removed' } );
  6508. this.children.splice( index, 1 );
  6509. }
  6510. },
  6511. getObjectById: function ( id ) {
  6512. return this.getObjectByProperty( 'id', id );
  6513. },
  6514. getObjectByName: function ( name ) {
  6515. return this.getObjectByProperty( 'name', name );
  6516. },
  6517. getObjectByProperty: function ( name, value ) {
  6518. if ( this[ name ] === value ) return this;
  6519. for ( var i = 0, l = this.children.length; i < l; i ++ ) {
  6520. var child = this.children[ i ];
  6521. var object = child.getObjectByProperty( name, value );
  6522. if ( object !== undefined ) {
  6523. return object;
  6524. }
  6525. }
  6526. return undefined;
  6527. },
  6528. getWorldPosition: function ( optionalTarget ) {
  6529. var result = optionalTarget || new Vector3();
  6530. this.updateMatrixWorld( true );
  6531. return result.setFromMatrixPosition( this.matrixWorld );
  6532. },
  6533. getWorldQuaternion: function () {
  6534. var position = new Vector3();
  6535. var scale = new Vector3();
  6536. return function getWorldQuaternion( optionalTarget ) {
  6537. var result = optionalTarget || new Quaternion();
  6538. this.updateMatrixWorld( true );
  6539. this.matrixWorld.decompose( position, result, scale );
  6540. return result;
  6541. };
  6542. }(),
  6543. getWorldRotation: function () {
  6544. var quaternion = new Quaternion();
  6545. return function getWorldRotation( optionalTarget ) {
  6546. var result = optionalTarget || new Euler();
  6547. this.getWorldQuaternion( quaternion );
  6548. return result.setFromQuaternion( quaternion, this.rotation.order, false );
  6549. };
  6550. }(),
  6551. getWorldScale: function () {
  6552. var position = new Vector3();
  6553. var quaternion = new Quaternion();
  6554. return function getWorldScale( optionalTarget ) {
  6555. var result = optionalTarget || new Vector3();
  6556. this.updateMatrixWorld( true );
  6557. this.matrixWorld.decompose( position, quaternion, result );
  6558. return result;
  6559. };
  6560. }(),
  6561. getWorldDirection: function () {
  6562. var quaternion = new Quaternion();
  6563. return function getWorldDirection( optionalTarget ) {
  6564. var result = optionalTarget || new Vector3();
  6565. this.getWorldQuaternion( quaternion );
  6566. return result.set( 0, 0, 1 ).applyQuaternion( quaternion );
  6567. };
  6568. }(),
  6569. raycast: function () {},
  6570. traverse: function ( callback ) {
  6571. callback( this );
  6572. var children = this.children;
  6573. for ( var i = 0, l = children.length; i < l; i ++ ) {
  6574. children[ i ].traverse( callback );
  6575. }
  6576. },
  6577. traverseVisible: function ( callback ) {
  6578. if ( this.visible === false ) return;
  6579. callback( this );
  6580. var children = this.children;
  6581. for ( var i = 0, l = children.length; i < l; i ++ ) {
  6582. children[ i ].traverseVisible( callback );
  6583. }
  6584. },
  6585. traverseAncestors: function ( callback ) {
  6586. var parent = this.parent;
  6587. if ( parent !== null ) {
  6588. callback( parent );
  6589. parent.traverseAncestors( callback );
  6590. }
  6591. },
  6592. updateMatrix: function () {
  6593. this.matrix.compose( this.position, this.quaternion, this.scale );
  6594. this.matrixWorldNeedsUpdate = true;
  6595. },
  6596. updateMatrixWorld: function ( force ) {
  6597. if ( this.matrixAutoUpdate === true ) this.updateMatrix();
  6598. if ( this.matrixWorldNeedsUpdate === true || force === true ) {
  6599. if ( this.parent === null ) {
  6600. this.matrixWorld.copy( this.matrix );
  6601. } else {
  6602. this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
  6603. }
  6604. this.matrixWorldNeedsUpdate = false;
  6605. force = true;
  6606. }
  6607. // update children
  6608. var children = this.children;
  6609. for ( var i = 0, l = children.length; i < l; i ++ ) {
  6610. children[ i ].updateMatrixWorld( force );
  6611. }
  6612. },
  6613. toJSON: function ( meta ) {
  6614. // meta is '' when called from JSON.stringify
  6615. var isRootObject = ( meta === undefined || meta === '' );
  6616. var output = {};
  6617. // meta is a hash used to collect geometries, materials.
  6618. // not providing it implies that this is the root object
  6619. // being serialized.
  6620. if ( isRootObject ) {
  6621. // initialize meta obj
  6622. meta = {
  6623. geometries: {},
  6624. materials: {},
  6625. textures: {},
  6626. images: {}
  6627. };
  6628. output.metadata = {
  6629. version: 4.4,
  6630. type: 'Object',
  6631. generator: 'Object3D.toJSON'
  6632. };
  6633. }
  6634. // standard Object3D serialization
  6635. var object = {};
  6636. object.uuid = this.uuid;
  6637. object.type = this.type;
  6638. if ( this.name !== '' ) object.name = this.name;
  6639. if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;
  6640. if ( this.castShadow === true ) object.castShadow = true;
  6641. if ( this.receiveShadow === true ) object.receiveShadow = true;
  6642. if ( this.visible === false ) object.visible = false;
  6643. object.matrix = this.matrix.toArray();
  6644. //
  6645. if ( this.geometry !== undefined ) {
  6646. if ( meta.geometries[ this.geometry.uuid ] === undefined ) {
  6647. meta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );
  6648. }
  6649. object.geometry = this.geometry.uuid;
  6650. }
  6651. if ( this.material !== undefined ) {
  6652. if ( meta.materials[ this.material.uuid ] === undefined ) {
  6653. meta.materials[ this.material.uuid ] = this.material.toJSON( meta );
  6654. }
  6655. object.material = this.material.uuid;
  6656. }
  6657. //
  6658. if ( this.children.length > 0 ) {
  6659. object.children = [];
  6660. for ( var i = 0; i < this.children.length; i ++ ) {
  6661. object.children.push( this.children[ i ].toJSON( meta ).object );
  6662. }
  6663. }
  6664. if ( isRootObject ) {
  6665. var geometries = extractFromCache( meta.geometries );
  6666. var materials = extractFromCache( meta.materials );
  6667. var textures = extractFromCache( meta.textures );
  6668. var images = extractFromCache( meta.images );
  6669. if ( geometries.length > 0 ) output.geometries = geometries;
  6670. if ( materials.length > 0 ) output.materials = materials;
  6671. if ( textures.length > 0 ) output.textures = textures;
  6672. if ( images.length > 0 ) output.images = images;
  6673. }
  6674. output.object = object;
  6675. return output;
  6676. // extract data from the cache hash
  6677. // remove metadata on each item
  6678. // and return as array
  6679. function extractFromCache( cache ) {
  6680. var values = [];
  6681. for ( var key in cache ) {
  6682. var data = cache[ key ];
  6683. delete data.metadata;
  6684. values.push( data );
  6685. }
  6686. return values;
  6687. }
  6688. },
  6689. clone: function ( recursive ) {
  6690. return new this.constructor().copy( this, recursive );
  6691. },
  6692. copy: function ( source, recursive ) {
  6693. if ( recursive === undefined ) recursive = true;
  6694. this.name = source.name;
  6695. this.up.copy( source.up );
  6696. this.position.copy( source.position );
  6697. this.quaternion.copy( source.quaternion );
  6698. this.scale.copy( source.scale );
  6699. this.matrix.copy( source.matrix );
  6700. this.matrixWorld.copy( source.matrixWorld );
  6701. this.matrixAutoUpdate = source.matrixAutoUpdate;
  6702. this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
  6703. this.layers.mask = source.layers.mask;
  6704. this.visible = source.visible;
  6705. this.castShadow = source.castShadow;
  6706. this.receiveShadow = source.receiveShadow;
  6707. this.frustumCulled = source.frustumCulled;
  6708. this.renderOrder = source.renderOrder;
  6709. this.userData = JSON.parse( JSON.stringify( source.userData ) );
  6710. if ( recursive === true ) {
  6711. for ( var i = 0; i < source.children.length; i ++ ) {
  6712. var child = source.children[ i ];
  6713. this.add( child.clone() );
  6714. }
  6715. }
  6716. return this;
  6717. }
  6718. };
  6719. Object.assign( Object3D.prototype, EventDispatcher.prototype );
  6720. /**
  6721. * @author bhouston / http://clara.io
  6722. */
  6723. function Line3( start, end ) {
  6724. this.start = ( start !== undefined ) ? start : new Vector3();
  6725. this.end = ( end !== undefined ) ? end : new Vector3();
  6726. }
  6727. Line3.prototype = {
  6728. constructor: Line3,
  6729. set: function ( start, end ) {
  6730. this.start.copy( start );
  6731. this.end.copy( end );
  6732. return this;
  6733. },
  6734. clone: function () {
  6735. return new this.constructor().copy( this );
  6736. },
  6737. copy: function ( line ) {
  6738. this.start.copy( line.start );
  6739. this.end.copy( line.end );
  6740. return this;
  6741. },
  6742. getCenter: function ( optionalTarget ) {
  6743. var result = optionalTarget || new Vector3();
  6744. return result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );
  6745. },
  6746. delta: function ( optionalTarget ) {
  6747. var result = optionalTarget || new Vector3();
  6748. return result.subVectors( this.end, this.start );
  6749. },
  6750. distanceSq: function () {
  6751. return this.start.distanceToSquared( this.end );
  6752. },
  6753. distance: function () {
  6754. return this.start.distanceTo( this.end );
  6755. },
  6756. at: function ( t, optionalTarget ) {
  6757. var result = optionalTarget || new Vector3();
  6758. return this.delta( result ).multiplyScalar( t ).add( this.start );
  6759. },
  6760. closestPointToPointParameter: function () {
  6761. var startP = new Vector3();
  6762. var startEnd = new Vector3();
  6763. return function closestPointToPointParameter( point, clampToLine ) {
  6764. startP.subVectors( point, this.start );
  6765. startEnd.subVectors( this.end, this.start );
  6766. var startEnd2 = startEnd.dot( startEnd );
  6767. var startEnd_startP = startEnd.dot( startP );
  6768. var t = startEnd_startP / startEnd2;
  6769. if ( clampToLine ) {
  6770. t = _Math.clamp( t, 0, 1 );
  6771. }
  6772. return t;
  6773. };
  6774. }(),
  6775. closestPointToPoint: function ( point, clampToLine, optionalTarget ) {
  6776. var t = this.closestPointToPointParameter( point, clampToLine );
  6777. var result = optionalTarget || new Vector3();
  6778. return this.delta( result ).multiplyScalar( t ).add( this.start );
  6779. },
  6780. applyMatrix4: function ( matrix ) {
  6781. this.start.applyMatrix4( matrix );
  6782. this.end.applyMatrix4( matrix );
  6783. return this;
  6784. },
  6785. equals: function ( line ) {
  6786. return line.start.equals( this.start ) && line.end.equals( this.end );
  6787. }
  6788. };
  6789. /**
  6790. * @author bhouston / http://clara.io
  6791. * @author mrdoob / http://mrdoob.com/
  6792. */
  6793. function Triangle( a, b, c ) {
  6794. this.a = ( a !== undefined ) ? a : new Vector3();
  6795. this.b = ( b !== undefined ) ? b : new Vector3();
  6796. this.c = ( c !== undefined ) ? c : new Vector3();
  6797. }
  6798. Triangle.normal = function () {
  6799. var v0 = new Vector3();
  6800. return function normal( a, b, c, optionalTarget ) {
  6801. var result = optionalTarget || new Vector3();
  6802. result.subVectors( c, b );
  6803. v0.subVectors( a, b );
  6804. result.cross( v0 );
  6805. var resultLengthSq = result.lengthSq();
  6806. if ( resultLengthSq > 0 ) {
  6807. return result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );
  6808. }
  6809. return result.set( 0, 0, 0 );
  6810. };
  6811. }();
  6812. // static/instance method to calculate barycentric coordinates
  6813. // based on: http://www.blackpawn.com/texts/pointinpoly/default.html
  6814. Triangle.barycoordFromPoint = function () {
  6815. var v0 = new Vector3();
  6816. var v1 = new Vector3();
  6817. var v2 = new Vector3();
  6818. return function barycoordFromPoint( point, a, b, c, optionalTarget ) {
  6819. v0.subVectors( c, a );
  6820. v1.subVectors( b, a );
  6821. v2.subVectors( point, a );
  6822. var dot00 = v0.dot( v0 );
  6823. var dot01 = v0.dot( v1 );
  6824. var dot02 = v0.dot( v2 );
  6825. var dot11 = v1.dot( v1 );
  6826. var dot12 = v1.dot( v2 );
  6827. var denom = ( dot00 * dot11 - dot01 * dot01 );
  6828. var result = optionalTarget || new Vector3();
  6829. // collinear or singular triangle
  6830. if ( denom === 0 ) {
  6831. // arbitrary location outside of triangle?
  6832. // not sure if this is the best idea, maybe should be returning undefined
  6833. return result.set( - 2, - 1, - 1 );
  6834. }
  6835. var invDenom = 1 / denom;
  6836. var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
  6837. var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
  6838. // barycentric coordinates must always sum to 1
  6839. return result.set( 1 - u - v, v, u );
  6840. };
  6841. }();
  6842. Triangle.containsPoint = function () {
  6843. var v1 = new Vector3();
  6844. return function containsPoint( point, a, b, c ) {
  6845. var result = Triangle.barycoordFromPoint( point, a, b, c, v1 );
  6846. return ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );
  6847. };
  6848. }();
  6849. Triangle.prototype = {
  6850. constructor: Triangle,
  6851. set: function ( a, b, c ) {
  6852. this.a.copy( a );
  6853. this.b.copy( b );
  6854. this.c.copy( c );
  6855. return this;
  6856. },
  6857. setFromPointsAndIndices: function ( points, i0, i1, i2 ) {
  6858. this.a.copy( points[ i0 ] );
  6859. this.b.copy( points[ i1 ] );
  6860. this.c.copy( points[ i2 ] );
  6861. return this;
  6862. },
  6863. clone: function () {
  6864. return new this.constructor().copy( this );
  6865. },
  6866. copy: function ( triangle ) {
  6867. this.a.copy( triangle.a );
  6868. this.b.copy( triangle.b );
  6869. this.c.copy( triangle.c );
  6870. return this;
  6871. },
  6872. area: function () {
  6873. var v0 = new Vector3();
  6874. var v1 = new Vector3();
  6875. return function area() {
  6876. v0.subVectors( this.c, this.b );
  6877. v1.subVectors( this.a, this.b );
  6878. return v0.cross( v1 ).length() * 0.5;
  6879. };
  6880. }(),
  6881. midpoint: function ( optionalTarget ) {
  6882. var result = optionalTarget || new Vector3();
  6883. return result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );
  6884. },
  6885. normal: function ( optionalTarget ) {
  6886. return Triangle.normal( this.a, this.b, this.c, optionalTarget );
  6887. },
  6888. plane: function ( optionalTarget ) {
  6889. var result = optionalTarget || new Plane();
  6890. return result.setFromCoplanarPoints( this.a, this.b, this.c );
  6891. },
  6892. barycoordFromPoint: function ( point, optionalTarget ) {
  6893. return Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );
  6894. },
  6895. containsPoint: function ( point ) {
  6896. return Triangle.containsPoint( point, this.a, this.b, this.c );
  6897. },
  6898. closestPointToPoint: function () {
  6899. var plane, edgeList, projectedPoint, closestPoint;
  6900. return function closestPointToPoint( point, optionalTarget ) {
  6901. if ( plane === undefined ) {
  6902. plane = new Plane();
  6903. edgeList = [ new Line3(), new Line3(), new Line3() ];
  6904. projectedPoint = new Vector3();
  6905. closestPoint = new Vector3();
  6906. }
  6907. var result = optionalTarget || new Vector3();
  6908. var minDistance = Infinity;
  6909. // project the point onto the plane of the triangle
  6910. plane.setFromCoplanarPoints( this.a, this.b, this.c );
  6911. plane.projectPoint( point, projectedPoint );
  6912. // check if the projection lies within the triangle
  6913. if( this.containsPoint( projectedPoint ) === true ) {
  6914. // if so, this is the closest point
  6915. result.copy( projectedPoint );
  6916. } else {
  6917. // if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices
  6918. edgeList[ 0 ].set( this.a, this.b );
  6919. edgeList[ 1 ].set( this.b, this.c );
  6920. edgeList[ 2 ].set( this.c, this.a );
  6921. for( var i = 0; i < edgeList.length; i ++ ) {
  6922. edgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );
  6923. var distance = projectedPoint.distanceToSquared( closestPoint );
  6924. if( distance < minDistance ) {
  6925. minDistance = distance;
  6926. result.copy( closestPoint );
  6927. }
  6928. }
  6929. }
  6930. return result;
  6931. };
  6932. }(),
  6933. equals: function ( triangle ) {
  6934. return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );
  6935. }
  6936. };
  6937. /**
  6938. * @author mrdoob / http://mrdoob.com/
  6939. * @author alteredq / http://alteredqualia.com/
  6940. */
  6941. function Face3( a, b, c, normal, color, materialIndex ) {
  6942. this.a = a;
  6943. this.b = b;
  6944. this.c = c;
  6945. this.normal = (normal && normal.isVector3) ? normal : new Vector3();
  6946. this.vertexNormals = Array.isArray( normal ) ? normal : [];
  6947. this.color = (color && color.isColor) ? color : new Color();
  6948. this.vertexColors = Array.isArray( color ) ? color : [];
  6949. this.materialIndex = materialIndex !== undefined ? materialIndex : 0;
  6950. }
  6951. Face3.prototype = {
  6952. constructor: Face3,
  6953. clone: function () {
  6954. return new this.constructor().copy( this );
  6955. },
  6956. copy: function ( source ) {
  6957. this.a = source.a;
  6958. this.b = source.b;
  6959. this.c = source.c;
  6960. this.normal.copy( source.normal );
  6961. this.color.copy( source.color );
  6962. this.materialIndex = source.materialIndex;
  6963. for ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {
  6964. this.vertexNormals[ i ] = source.vertexNormals[ i ].clone();
  6965. }
  6966. for ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {
  6967. this.vertexColors[ i ] = source.vertexColors[ i ].clone();
  6968. }
  6969. return this;
  6970. }
  6971. };
  6972. /**
  6973. * @author mrdoob / http://mrdoob.com/
  6974. * @author alteredq / http://alteredqualia.com/
  6975. *
  6976. * parameters = {
  6977. * color: <hex>,
  6978. * opacity: <float>,
  6979. * map: new THREE.Texture( <Image> ),
  6980. *
  6981. * lightMap: new THREE.Texture( <Image> ),
  6982. * lightMapIntensity: <float>
  6983. *
  6984. * aoMap: new THREE.Texture( <Image> ),
  6985. * aoMapIntensity: <float>
  6986. *
  6987. * specularMap: new THREE.Texture( <Image> ),
  6988. *
  6989. * alphaMap: new THREE.Texture( <Image> ),
  6990. *
  6991. * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
  6992. * combine: THREE.Multiply,
  6993. * reflectivity: <float>,
  6994. * refractionRatio: <float>,
  6995. *
  6996. * shading: THREE.SmoothShading,
  6997. * depthTest: <bool>,
  6998. * depthWrite: <bool>,
  6999. *
  7000. * wireframe: <boolean>,
  7001. * wireframeLinewidth: <float>,
  7002. *
  7003. * skinning: <bool>,
  7004. * morphTargets: <bool>
  7005. * }
  7006. */
  7007. function MeshBasicMaterial( parameters ) {
  7008. Material.call( this );
  7009. this.type = 'MeshBasicMaterial';
  7010. this.color = new Color( 0xffffff ); // emissive
  7011. this.map = null;
  7012. this.lightMap = null;
  7013. this.lightMapIntensity = 1.0;
  7014. this.aoMap = null;
  7015. this.aoMapIntensity = 1.0;
  7016. this.specularMap = null;
  7017. this.alphaMap = null;
  7018. this.envMap = null;
  7019. this.combine = MultiplyOperation;
  7020. this.reflectivity = 1;
  7021. this.refractionRatio = 0.98;
  7022. this.wireframe = false;
  7023. this.wireframeLinewidth = 1;
  7024. this.wireframeLinecap = 'round';
  7025. this.wireframeLinejoin = 'round';
  7026. this.skinning = false;
  7027. this.morphTargets = false;
  7028. this.lights = false;
  7029. this.setValues( parameters );
  7030. }
  7031. MeshBasicMaterial.prototype = Object.create( Material.prototype );
  7032. MeshBasicMaterial.prototype.constructor = MeshBasicMaterial;
  7033. MeshBasicMaterial.prototype.isMeshBasicMaterial = true;
  7034. MeshBasicMaterial.prototype.copy = function ( source ) {
  7035. Material.prototype.copy.call( this, source );
  7036. this.color.copy( source.color );
  7037. this.map = source.map;
  7038. this.lightMap = source.lightMap;
  7039. this.lightMapIntensity = source.lightMapIntensity;
  7040. this.aoMap = source.aoMap;
  7041. this.aoMapIntensity = source.aoMapIntensity;
  7042. this.specularMap = source.specularMap;
  7043. this.alphaMap = source.alphaMap;
  7044. this.envMap = source.envMap;
  7045. this.combine = source.combine;
  7046. this.reflectivity = source.reflectivity;
  7047. this.refractionRatio = source.refractionRatio;
  7048. this.wireframe = source.wireframe;
  7049. this.wireframeLinewidth = source.wireframeLinewidth;
  7050. this.wireframeLinecap = source.wireframeLinecap;
  7051. this.wireframeLinejoin = source.wireframeLinejoin;
  7052. this.skinning = source.skinning;
  7053. this.morphTargets = source.morphTargets;
  7054. return this;
  7055. };
  7056. /**
  7057. * @author mrdoob / http://mrdoob.com/
  7058. */
  7059. function BufferAttribute( array, itemSize, normalized ) {
  7060. if ( Array.isArray( array ) ) {
  7061. throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
  7062. }
  7063. this.uuid = _Math.generateUUID();
  7064. this.array = array;
  7065. this.itemSize = itemSize;
  7066. this.count = array !== undefined ? array.length / itemSize : 0;
  7067. this.normalized = normalized === true;
  7068. this.dynamic = false;
  7069. this.updateRange = { offset: 0, count: - 1 };
  7070. this.onUploadCallback = function () {};
  7071. this.version = 0;
  7072. }
  7073. BufferAttribute.prototype = {
  7074. constructor: BufferAttribute,
  7075. isBufferAttribute: true,
  7076. set needsUpdate( value ) {
  7077. if ( value === true ) this.version ++;
  7078. },
  7079. setArray: function ( array ) {
  7080. if ( Array.isArray( array ) ) {
  7081. throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
  7082. }
  7083. this.count = array !== undefined ? array.length / this.itemSize : 0;
  7084. this.array = array;
  7085. },
  7086. setDynamic: function ( value ) {
  7087. this.dynamic = value;
  7088. return this;
  7089. },
  7090. copy: function ( source ) {
  7091. this.array = new source.array.constructor( source.array );
  7092. this.itemSize = source.itemSize;
  7093. this.count = source.count;
  7094. this.normalized = source.normalized;
  7095. this.dynamic = source.dynamic;
  7096. return this;
  7097. },
  7098. copyAt: function ( index1, attribute, index2 ) {
  7099. index1 *= this.itemSize;
  7100. index2 *= attribute.itemSize;
  7101. for ( var i = 0, l = this.itemSize; i < l; i ++ ) {
  7102. this.array[ index1 + i ] = attribute.array[ index2 + i ];
  7103. }
  7104. return this;
  7105. },
  7106. copyArray: function ( array ) {
  7107. this.array.set( array );
  7108. return this;
  7109. },
  7110. copyColorsArray: function ( colors ) {
  7111. var array = this.array, offset = 0;
  7112. for ( var i = 0, l = colors.length; i < l; i ++ ) {
  7113. var color = colors[ i ];
  7114. if ( color === undefined ) {
  7115. console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );
  7116. color = new Color();
  7117. }
  7118. array[ offset ++ ] = color.r;
  7119. array[ offset ++ ] = color.g;
  7120. array[ offset ++ ] = color.b;
  7121. }
  7122. return this;
  7123. },
  7124. copyIndicesArray: function ( indices ) {
  7125. var array = this.array, offset = 0;
  7126. for ( var i = 0, l = indices.length; i < l; i ++ ) {
  7127. var index = indices[ i ];
  7128. array[ offset ++ ] = index.a;
  7129. array[ offset ++ ] = index.b;
  7130. array[ offset ++ ] = index.c;
  7131. }
  7132. return this;
  7133. },
  7134. copyVector2sArray: function ( vectors ) {
  7135. var array = this.array, offset = 0;
  7136. for ( var i = 0, l = vectors.length; i < l; i ++ ) {
  7137. var vector = vectors[ i ];
  7138. if ( vector === undefined ) {
  7139. console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );
  7140. vector = new Vector2();
  7141. }
  7142. array[ offset ++ ] = vector.x;
  7143. array[ offset ++ ] = vector.y;
  7144. }
  7145. return this;
  7146. },
  7147. copyVector3sArray: function ( vectors ) {
  7148. var array = this.array, offset = 0;
  7149. for ( var i = 0, l = vectors.length; i < l; i ++ ) {
  7150. var vector = vectors[ i ];
  7151. if ( vector === undefined ) {
  7152. console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );
  7153. vector = new Vector3();
  7154. }
  7155. array[ offset ++ ] = vector.x;
  7156. array[ offset ++ ] = vector.y;
  7157. array[ offset ++ ] = vector.z;
  7158. }
  7159. return this;
  7160. },
  7161. copyVector4sArray: function ( vectors ) {
  7162. var array = this.array, offset = 0;
  7163. for ( var i = 0, l = vectors.length; i < l; i ++ ) {
  7164. var vector = vectors[ i ];
  7165. if ( vector === undefined ) {
  7166. console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );
  7167. vector = new Vector4();
  7168. }
  7169. array[ offset ++ ] = vector.x;
  7170. array[ offset ++ ] = vector.y;
  7171. array[ offset ++ ] = vector.z;
  7172. array[ offset ++ ] = vector.w;
  7173. }
  7174. return this;
  7175. },
  7176. set: function ( value, offset ) {
  7177. if ( offset === undefined ) offset = 0;
  7178. this.array.set( value, offset );
  7179. return this;
  7180. },
  7181. getX: function ( index ) {
  7182. return this.array[ index * this.itemSize ];
  7183. },
  7184. setX: function ( index, x ) {
  7185. this.array[ index * this.itemSize ] = x;
  7186. return this;
  7187. },
  7188. getY: function ( index ) {
  7189. return this.array[ index * this.itemSize + 1 ];
  7190. },
  7191. setY: function ( index, y ) {
  7192. this.array[ index * this.itemSize + 1 ] = y;
  7193. return this;
  7194. },
  7195. getZ: function ( index ) {
  7196. return this.array[ index * this.itemSize + 2 ];
  7197. },
  7198. setZ: function ( index, z ) {
  7199. this.array[ index * this.itemSize + 2 ] = z;
  7200. return this;
  7201. },
  7202. getW: function ( index ) {
  7203. return this.array[ index * this.itemSize + 3 ];
  7204. },
  7205. setW: function ( index, w ) {
  7206. this.array[ index * this.itemSize + 3 ] = w;
  7207. return this;
  7208. },
  7209. setXY: function ( index, x, y ) {
  7210. index *= this.itemSize;
  7211. this.array[ index + 0 ] = x;
  7212. this.array[ index + 1 ] = y;
  7213. return this;
  7214. },
  7215. setXYZ: function ( index, x, y, z ) {
  7216. index *= this.itemSize;
  7217. this.array[ index + 0 ] = x;
  7218. this.array[ index + 1 ] = y;
  7219. this.array[ index + 2 ] = z;
  7220. return this;
  7221. },
  7222. setXYZW: function ( index, x, y, z, w ) {
  7223. index *= this.itemSize;
  7224. this.array[ index + 0 ] = x;
  7225. this.array[ index + 1 ] = y;
  7226. this.array[ index + 2 ] = z;
  7227. this.array[ index + 3 ] = w;
  7228. return this;
  7229. },
  7230. onUpload: function ( callback ) {
  7231. this.onUploadCallback = callback;
  7232. return this;
  7233. },
  7234. clone: function () {
  7235. return new this.constructor( this.array, this.itemSize ).copy( this );
  7236. }
  7237. };
  7238. function Uint16BufferAttribute( array, itemSize ) {
  7239. BufferAttribute.call( this, new Uint16Array( array ), itemSize );
  7240. }
  7241. Uint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
  7242. Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;
  7243. function Uint32BufferAttribute( array, itemSize ) {
  7244. BufferAttribute.call( this, new Uint32Array( array ), itemSize );
  7245. }
  7246. Uint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
  7247. Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;
  7248. function Float32BufferAttribute( array, itemSize ) {
  7249. BufferAttribute.call( this, new Float32Array( array ), itemSize );
  7250. }
  7251. Float32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
  7252. Float32BufferAttribute.prototype.constructor = Float32BufferAttribute;
  7253. /**
  7254. * @author mrdoob / http://mrdoob.com/
  7255. */
  7256. function DirectGeometry() {
  7257. this.indices = [];
  7258. this.vertices = [];
  7259. this.normals = [];
  7260. this.colors = [];
  7261. this.uvs = [];
  7262. this.uvs2 = [];
  7263. this.groups = [];
  7264. this.morphTargets = {};
  7265. this.skinWeights = [];
  7266. this.skinIndices = [];
  7267. // this.lineDistances = [];
  7268. this.boundingBox = null;
  7269. this.boundingSphere = null;
  7270. // update flags
  7271. this.verticesNeedUpdate = false;
  7272. this.normalsNeedUpdate = false;
  7273. this.colorsNeedUpdate = false;
  7274. this.uvsNeedUpdate = false;
  7275. this.groupsNeedUpdate = false;
  7276. }
  7277. Object.assign( DirectGeometry.prototype, {
  7278. computeGroups: function ( geometry ) {
  7279. var group;
  7280. var groups = [];
  7281. var materialIndex = undefined;
  7282. var faces = geometry.faces;
  7283. for ( var i = 0; i < faces.length; i ++ ) {
  7284. var face = faces[ i ];
  7285. // materials
  7286. if ( face.materialIndex !== materialIndex ) {
  7287. materialIndex = face.materialIndex;
  7288. if ( group !== undefined ) {
  7289. group.count = ( i * 3 ) - group.start;
  7290. groups.push( group );
  7291. }
  7292. group = {
  7293. start: i * 3,
  7294. materialIndex: materialIndex
  7295. };
  7296. }
  7297. }
  7298. if ( group !== undefined ) {
  7299. group.count = ( i * 3 ) - group.start;
  7300. groups.push( group );
  7301. }
  7302. this.groups = groups;
  7303. },
  7304. fromGeometry: function ( geometry ) {
  7305. var faces = geometry.faces;
  7306. var vertices = geometry.vertices;
  7307. var faceVertexUvs = geometry.faceVertexUvs;
  7308. var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;
  7309. var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;
  7310. // morphs
  7311. var morphTargets = geometry.morphTargets;
  7312. var morphTargetsLength = morphTargets.length;
  7313. var morphTargetsPosition;
  7314. if ( morphTargetsLength > 0 ) {
  7315. morphTargetsPosition = [];
  7316. for ( var i = 0; i < morphTargetsLength; i ++ ) {
  7317. morphTargetsPosition[ i ] = [];
  7318. }
  7319. this.morphTargets.position = morphTargetsPosition;
  7320. }
  7321. var morphNormals = geometry.morphNormals;
  7322. var morphNormalsLength = morphNormals.length;
  7323. var morphTargetsNormal;
  7324. if ( morphNormalsLength > 0 ) {
  7325. morphTargetsNormal = [];
  7326. for ( var i = 0; i < morphNormalsLength; i ++ ) {
  7327. morphTargetsNormal[ i ] = [];
  7328. }
  7329. this.morphTargets.normal = morphTargetsNormal;
  7330. }
  7331. // skins
  7332. var skinIndices = geometry.skinIndices;
  7333. var skinWeights = geometry.skinWeights;
  7334. var hasSkinIndices = skinIndices.length === vertices.length;
  7335. var hasSkinWeights = skinWeights.length === vertices.length;
  7336. //
  7337. for ( var i = 0; i < faces.length; i ++ ) {
  7338. var face = faces[ i ];
  7339. this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );
  7340. var vertexNormals = face.vertexNormals;
  7341. if ( vertexNormals.length === 3 ) {
  7342. this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );
  7343. } else {
  7344. var normal = face.normal;
  7345. this.normals.push( normal, normal, normal );
  7346. }
  7347. var vertexColors = face.vertexColors;
  7348. if ( vertexColors.length === 3 ) {
  7349. this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );
  7350. } else {
  7351. var color = face.color;
  7352. this.colors.push( color, color, color );
  7353. }
  7354. if ( hasFaceVertexUv === true ) {
  7355. var vertexUvs = faceVertexUvs[ 0 ][ i ];
  7356. if ( vertexUvs !== undefined ) {
  7357. this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
  7358. } else {
  7359. console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );
  7360. this.uvs.push( new Vector2(), new Vector2(), new Vector2() );
  7361. }
  7362. }
  7363. if ( hasFaceVertexUv2 === true ) {
  7364. var vertexUvs = faceVertexUvs[ 1 ][ i ];
  7365. if ( vertexUvs !== undefined ) {
  7366. this.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
  7367. } else {
  7368. console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );
  7369. this.uvs2.push( new Vector2(), new Vector2(), new Vector2() );
  7370. }
  7371. }
  7372. // morphs
  7373. for ( var j = 0; j < morphTargetsLength; j ++ ) {
  7374. var morphTarget = morphTargets[ j ].vertices;
  7375. morphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );
  7376. }
  7377. for ( var j = 0; j < morphNormalsLength; j ++ ) {
  7378. var morphNormal = morphNormals[ j ].vertexNormals[ i ];
  7379. morphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );
  7380. }
  7381. // skins
  7382. if ( hasSkinIndices ) {
  7383. this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );
  7384. }
  7385. if ( hasSkinWeights ) {
  7386. this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );
  7387. }
  7388. }
  7389. this.computeGroups( geometry );
  7390. this.verticesNeedUpdate = geometry.verticesNeedUpdate;
  7391. this.normalsNeedUpdate = geometry.normalsNeedUpdate;
  7392. this.colorsNeedUpdate = geometry.colorsNeedUpdate;
  7393. this.uvsNeedUpdate = geometry.uvsNeedUpdate;
  7394. this.groupsNeedUpdate = geometry.groupsNeedUpdate;
  7395. return this;
  7396. }
  7397. } );
  7398. // http://stackoverflow.com/questions/1669190/javascript-min-max-array-values/13440842#13440842
  7399. function arrayMax( array ) {
  7400. var length = array.length, max = - Infinity;
  7401. while ( length -- ) {
  7402. if ( array[ length ] > max ) {
  7403. max = array[ length ];
  7404. }
  7405. }
  7406. return max;
  7407. }
  7408. /**
  7409. * @author mrdoob / http://mrdoob.com/
  7410. * @author kile / http://kile.stravaganza.org/
  7411. * @author alteredq / http://alteredqualia.com/
  7412. * @author mikael emtinger / http://gomo.se/
  7413. * @author zz85 / http://www.lab4games.net/zz85/blog
  7414. * @author bhouston / http://clara.io
  7415. */
  7416. var count = 0;
  7417. function GeometryIdCount() { return count++; }
  7418. function Geometry() {
  7419. Object.defineProperty( this, 'id', { value: GeometryIdCount() } );
  7420. this.uuid = _Math.generateUUID();
  7421. this.name = '';
  7422. this.type = 'Geometry';
  7423. this.vertices = [];
  7424. this.colors = [];
  7425. this.faces = [];
  7426. this.faceVertexUvs = [[]];
  7427. this.morphTargets = [];
  7428. this.morphNormals = [];
  7429. this.skinWeights = [];
  7430. this.skinIndices = [];
  7431. this.lineDistances = [];
  7432. this.boundingBox = null;
  7433. this.boundingSphere = null;
  7434. // update flags
  7435. this.elementsNeedUpdate = false;
  7436. this.verticesNeedUpdate = false;
  7437. this.uvsNeedUpdate = false;
  7438. this.normalsNeedUpdate = false;
  7439. this.colorsNeedUpdate = false;
  7440. this.lineDistancesNeedUpdate = false;
  7441. this.groupsNeedUpdate = false;
  7442. }
  7443. Geometry.prototype = {
  7444. constructor: Geometry,
  7445. isGeometry: true,
  7446. applyMatrix: function ( matrix ) {
  7447. var normalMatrix = new Matrix3().getNormalMatrix( matrix );
  7448. for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
  7449. var vertex = this.vertices[ i ];
  7450. vertex.applyMatrix4( matrix );
  7451. }
  7452. for ( var i = 0, il = this.faces.length; i < il; i ++ ) {
  7453. var face = this.faces[ i ];
  7454. face.normal.applyMatrix3( normalMatrix ).normalize();
  7455. for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
  7456. face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();
  7457. }
  7458. }
  7459. if ( this.boundingBox !== null ) {
  7460. this.computeBoundingBox();
  7461. }
  7462. if ( this.boundingSphere !== null ) {
  7463. this.computeBoundingSphere();
  7464. }
  7465. this.verticesNeedUpdate = true;
  7466. this.normalsNeedUpdate = true;
  7467. return this;
  7468. },
  7469. rotateX: function () {
  7470. // rotate geometry around world x-axis
  7471. var m1;
  7472. return function rotateX( angle ) {
  7473. if ( m1 === undefined ) m1 = new Matrix4();
  7474. m1.makeRotationX( angle );
  7475. this.applyMatrix( m1 );
  7476. return this;
  7477. };
  7478. }(),
  7479. rotateY: function () {
  7480. // rotate geometry around world y-axis
  7481. var m1;
  7482. return function rotateY( angle ) {
  7483. if ( m1 === undefined ) m1 = new Matrix4();
  7484. m1.makeRotationY( angle );
  7485. this.applyMatrix( m1 );
  7486. return this;
  7487. };
  7488. }(),
  7489. rotateZ: function () {
  7490. // rotate geometry around world z-axis
  7491. var m1;
  7492. return function rotateZ( angle ) {
  7493. if ( m1 === undefined ) m1 = new Matrix4();
  7494. m1.makeRotationZ( angle );
  7495. this.applyMatrix( m1 );
  7496. return this;
  7497. };
  7498. }(),
  7499. translate: function () {
  7500. // translate geometry
  7501. var m1;
  7502. return function translate( x, y, z ) {
  7503. if ( m1 === undefined ) m1 = new Matrix4();
  7504. m1.makeTranslation( x, y, z );
  7505. this.applyMatrix( m1 );
  7506. return this;
  7507. };
  7508. }(),
  7509. scale: function () {
  7510. // scale geometry
  7511. var m1;
  7512. return function scale( x, y, z ) {
  7513. if ( m1 === undefined ) m1 = new Matrix4();
  7514. m1.makeScale( x, y, z );
  7515. this.applyMatrix( m1 );
  7516. return this;
  7517. };
  7518. }(),
  7519. lookAt: function () {
  7520. var obj;
  7521. return function lookAt( vector ) {
  7522. if ( obj === undefined ) obj = new Object3D();
  7523. obj.lookAt( vector );
  7524. obj.updateMatrix();
  7525. this.applyMatrix( obj.matrix );
  7526. };
  7527. }(),
  7528. fromBufferGeometry: function ( geometry ) {
  7529. var scope = this;
  7530. var indices = geometry.index !== null ? geometry.index.array : undefined;
  7531. var attributes = geometry.attributes;
  7532. var positions = attributes.position.array;
  7533. var normals = attributes.normal !== undefined ? attributes.normal.array : undefined;
  7534. var colors = attributes.color !== undefined ? attributes.color.array : undefined;
  7535. var uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;
  7536. var uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;
  7537. if ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];
  7538. var tempNormals = [];
  7539. var tempUVs = [];
  7540. var tempUVs2 = [];
  7541. for ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {
  7542. scope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );
  7543. if ( normals !== undefined ) {
  7544. tempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );
  7545. }
  7546. if ( colors !== undefined ) {
  7547. scope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );
  7548. }
  7549. if ( uvs !== undefined ) {
  7550. tempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );
  7551. }
  7552. if ( uvs2 !== undefined ) {
  7553. tempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );
  7554. }
  7555. }
  7556. function addFace( a, b, c, materialIndex ) {
  7557. var vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];
  7558. var vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];
  7559. var face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );
  7560. scope.faces.push( face );
  7561. if ( uvs !== undefined ) {
  7562. scope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );
  7563. }
  7564. if ( uvs2 !== undefined ) {
  7565. scope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );
  7566. }
  7567. }
  7568. if ( indices !== undefined ) {
  7569. var groups = geometry.groups;
  7570. if ( groups.length > 0 ) {
  7571. for ( var i = 0; i < groups.length; i ++ ) {
  7572. var group = groups[ i ];
  7573. var start = group.start;
  7574. var count = group.count;
  7575. for ( var j = start, jl = start + count; j < jl; j += 3 ) {
  7576. addFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );
  7577. }
  7578. }
  7579. } else {
  7580. for ( var i = 0; i < indices.length; i += 3 ) {
  7581. addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );
  7582. }
  7583. }
  7584. } else {
  7585. for ( var i = 0; i < positions.length / 3; i += 3 ) {
  7586. addFace( i, i + 1, i + 2 );
  7587. }
  7588. }
  7589. this.computeFaceNormals();
  7590. if ( geometry.boundingBox !== null ) {
  7591. this.boundingBox = geometry.boundingBox.clone();
  7592. }
  7593. if ( geometry.boundingSphere !== null ) {
  7594. this.boundingSphere = geometry.boundingSphere.clone();
  7595. }
  7596. return this;
  7597. },
  7598. center: function () {
  7599. this.computeBoundingBox();
  7600. var offset = this.boundingBox.getCenter().negate();
  7601. this.translate( offset.x, offset.y, offset.z );
  7602. return offset;
  7603. },
  7604. normalize: function () {
  7605. this.computeBoundingSphere();
  7606. var center = this.boundingSphere.center;
  7607. var radius = this.boundingSphere.radius;
  7608. var s = radius === 0 ? 1 : 1.0 / radius;
  7609. var matrix = new Matrix4();
  7610. matrix.set(
  7611. s, 0, 0, - s * center.x,
  7612. 0, s, 0, - s * center.y,
  7613. 0, 0, s, - s * center.z,
  7614. 0, 0, 0, 1
  7615. );
  7616. this.applyMatrix( matrix );
  7617. return this;
  7618. },
  7619. computeFaceNormals: function () {
  7620. var cb = new Vector3(), ab = new Vector3();
  7621. for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {
  7622. var face = this.faces[ f ];
  7623. var vA = this.vertices[ face.a ];
  7624. var vB = this.vertices[ face.b ];
  7625. var vC = this.vertices[ face.c ];
  7626. cb.subVectors( vC, vB );
  7627. ab.subVectors( vA, vB );
  7628. cb.cross( ab );
  7629. cb.normalize();
  7630. face.normal.copy( cb );
  7631. }
  7632. },
  7633. computeVertexNormals: function ( areaWeighted ) {
  7634. if ( areaWeighted === undefined ) areaWeighted = true;
  7635. var v, vl, f, fl, face, vertices;
  7636. vertices = new Array( this.vertices.length );
  7637. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  7638. vertices[ v ] = new Vector3();
  7639. }
  7640. if ( areaWeighted ) {
  7641. // vertex normals weighted by triangle areas
  7642. // http://www.iquilezles.org/www/articles/normals/normals.htm
  7643. var vA, vB, vC;
  7644. var cb = new Vector3(), ab = new Vector3();
  7645. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  7646. face = this.faces[ f ];
  7647. vA = this.vertices[ face.a ];
  7648. vB = this.vertices[ face.b ];
  7649. vC = this.vertices[ face.c ];
  7650. cb.subVectors( vC, vB );
  7651. ab.subVectors( vA, vB );
  7652. cb.cross( ab );
  7653. vertices[ face.a ].add( cb );
  7654. vertices[ face.b ].add( cb );
  7655. vertices[ face.c ].add( cb );
  7656. }
  7657. } else {
  7658. this.computeFaceNormals();
  7659. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  7660. face = this.faces[ f ];
  7661. vertices[ face.a ].add( face.normal );
  7662. vertices[ face.b ].add( face.normal );
  7663. vertices[ face.c ].add( face.normal );
  7664. }
  7665. }
  7666. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  7667. vertices[ v ].normalize();
  7668. }
  7669. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  7670. face = this.faces[ f ];
  7671. var vertexNormals = face.vertexNormals;
  7672. if ( vertexNormals.length === 3 ) {
  7673. vertexNormals[ 0 ].copy( vertices[ face.a ] );
  7674. vertexNormals[ 1 ].copy( vertices[ face.b ] );
  7675. vertexNormals[ 2 ].copy( vertices[ face.c ] );
  7676. } else {
  7677. vertexNormals[ 0 ] = vertices[ face.a ].clone();
  7678. vertexNormals[ 1 ] = vertices[ face.b ].clone();
  7679. vertexNormals[ 2 ] = vertices[ face.c ].clone();
  7680. }
  7681. }
  7682. if ( this.faces.length > 0 ) {
  7683. this.normalsNeedUpdate = true;
  7684. }
  7685. },
  7686. computeFlatVertexNormals: function () {
  7687. var f, fl, face;
  7688. this.computeFaceNormals();
  7689. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  7690. face = this.faces[ f ];
  7691. var vertexNormals = face.vertexNormals;
  7692. if ( vertexNormals.length === 3 ) {
  7693. vertexNormals[ 0 ].copy( face.normal );
  7694. vertexNormals[ 1 ].copy( face.normal );
  7695. vertexNormals[ 2 ].copy( face.normal );
  7696. } else {
  7697. vertexNormals[ 0 ] = face.normal.clone();
  7698. vertexNormals[ 1 ] = face.normal.clone();
  7699. vertexNormals[ 2 ] = face.normal.clone();
  7700. }
  7701. }
  7702. if ( this.faces.length > 0 ) {
  7703. this.normalsNeedUpdate = true;
  7704. }
  7705. },
  7706. computeMorphNormals: function () {
  7707. var i, il, f, fl, face;
  7708. // save original normals
  7709. // - create temp variables on first access
  7710. // otherwise just copy (for faster repeated calls)
  7711. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  7712. face = this.faces[ f ];
  7713. if ( ! face.__originalFaceNormal ) {
  7714. face.__originalFaceNormal = face.normal.clone();
  7715. } else {
  7716. face.__originalFaceNormal.copy( face.normal );
  7717. }
  7718. if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];
  7719. for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {
  7720. if ( ! face.__originalVertexNormals[ i ] ) {
  7721. face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();
  7722. } else {
  7723. face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );
  7724. }
  7725. }
  7726. }
  7727. // use temp geometry to compute face and vertex normals for each morph
  7728. var tmpGeo = new Geometry();
  7729. tmpGeo.faces = this.faces;
  7730. for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {
  7731. // create on first access
  7732. if ( ! this.morphNormals[ i ] ) {
  7733. this.morphNormals[ i ] = {};
  7734. this.morphNormals[ i ].faceNormals = [];
  7735. this.morphNormals[ i ].vertexNormals = [];
  7736. var dstNormalsFace = this.morphNormals[ i ].faceNormals;
  7737. var dstNormalsVertex = this.morphNormals[ i ].vertexNormals;
  7738. var faceNormal, vertexNormals;
  7739. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  7740. faceNormal = new Vector3();
  7741. vertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };
  7742. dstNormalsFace.push( faceNormal );
  7743. dstNormalsVertex.push( vertexNormals );
  7744. }
  7745. }
  7746. var morphNormals = this.morphNormals[ i ];
  7747. // set vertices to morph target
  7748. tmpGeo.vertices = this.morphTargets[ i ].vertices;
  7749. // compute morph normals
  7750. tmpGeo.computeFaceNormals();
  7751. tmpGeo.computeVertexNormals();
  7752. // store morph normals
  7753. var faceNormal, vertexNormals;
  7754. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  7755. face = this.faces[ f ];
  7756. faceNormal = morphNormals.faceNormals[ f ];
  7757. vertexNormals = morphNormals.vertexNormals[ f ];
  7758. faceNormal.copy( face.normal );
  7759. vertexNormals.a.copy( face.vertexNormals[ 0 ] );
  7760. vertexNormals.b.copy( face.vertexNormals[ 1 ] );
  7761. vertexNormals.c.copy( face.vertexNormals[ 2 ] );
  7762. }
  7763. }
  7764. // restore original normals
  7765. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  7766. face = this.faces[ f ];
  7767. face.normal = face.__originalFaceNormal;
  7768. face.vertexNormals = face.__originalVertexNormals;
  7769. }
  7770. },
  7771. computeLineDistances: function () {
  7772. var d = 0;
  7773. var vertices = this.vertices;
  7774. for ( var i = 0, il = vertices.length; i < il; i ++ ) {
  7775. if ( i > 0 ) {
  7776. d += vertices[ i ].distanceTo( vertices[ i - 1 ] );
  7777. }
  7778. this.lineDistances[ i ] = d;
  7779. }
  7780. },
  7781. computeBoundingBox: function () {
  7782. if ( this.boundingBox === null ) {
  7783. this.boundingBox = new Box3();
  7784. }
  7785. this.boundingBox.setFromPoints( this.vertices );
  7786. },
  7787. computeBoundingSphere: function () {
  7788. if ( this.boundingSphere === null ) {
  7789. this.boundingSphere = new Sphere();
  7790. }
  7791. this.boundingSphere.setFromPoints( this.vertices );
  7792. },
  7793. merge: function ( geometry, matrix, materialIndexOffset ) {
  7794. if ( ( geometry && geometry.isGeometry ) === false ) {
  7795. console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );
  7796. return;
  7797. }
  7798. var normalMatrix,
  7799. vertexOffset = this.vertices.length,
  7800. vertices1 = this.vertices,
  7801. vertices2 = geometry.vertices,
  7802. faces1 = this.faces,
  7803. faces2 = geometry.faces,
  7804. uvs1 = this.faceVertexUvs[ 0 ],
  7805. uvs2 = geometry.faceVertexUvs[ 0 ],
  7806. colors1 = this.colors,
  7807. colors2 = geometry.colors;
  7808. if ( materialIndexOffset === undefined ) materialIndexOffset = 0;
  7809. if ( matrix !== undefined ) {
  7810. normalMatrix = new Matrix3().getNormalMatrix( matrix );
  7811. }
  7812. // vertices
  7813. for ( var i = 0, il = vertices2.length; i < il; i ++ ) {
  7814. var vertex = vertices2[ i ];
  7815. var vertexCopy = vertex.clone();
  7816. if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );
  7817. vertices1.push( vertexCopy );
  7818. }
  7819. // colors
  7820. for ( var i = 0, il = colors2.length; i < il; i ++ ) {
  7821. colors1.push( colors2[ i ].clone() );
  7822. }
  7823. // faces
  7824. for ( i = 0, il = faces2.length; i < il; i ++ ) {
  7825. var face = faces2[ i ], faceCopy, normal, color,
  7826. faceVertexNormals = face.vertexNormals,
  7827. faceVertexColors = face.vertexColors;
  7828. faceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );
  7829. faceCopy.normal.copy( face.normal );
  7830. if ( normalMatrix !== undefined ) {
  7831. faceCopy.normal.applyMatrix3( normalMatrix ).normalize();
  7832. }
  7833. for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
  7834. normal = faceVertexNormals[ j ].clone();
  7835. if ( normalMatrix !== undefined ) {
  7836. normal.applyMatrix3( normalMatrix ).normalize();
  7837. }
  7838. faceCopy.vertexNormals.push( normal );
  7839. }
  7840. faceCopy.color.copy( face.color );
  7841. for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {
  7842. color = faceVertexColors[ j ];
  7843. faceCopy.vertexColors.push( color.clone() );
  7844. }
  7845. faceCopy.materialIndex = face.materialIndex + materialIndexOffset;
  7846. faces1.push( faceCopy );
  7847. }
  7848. // uvs
  7849. for ( i = 0, il = uvs2.length; i < il; i ++ ) {
  7850. var uv = uvs2[ i ], uvCopy = [];
  7851. if ( uv === undefined ) {
  7852. continue;
  7853. }
  7854. for ( var j = 0, jl = uv.length; j < jl; j ++ ) {
  7855. uvCopy.push( uv[ j ].clone() );
  7856. }
  7857. uvs1.push( uvCopy );
  7858. }
  7859. },
  7860. mergeMesh: function ( mesh ) {
  7861. if ( ( mesh && mesh.isMesh ) === false ) {
  7862. console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );
  7863. return;
  7864. }
  7865. mesh.matrixAutoUpdate && mesh.updateMatrix();
  7866. this.merge( mesh.geometry, mesh.matrix );
  7867. },
  7868. /*
  7869. * Checks for duplicate vertices with hashmap.
  7870. * Duplicated vertices are removed
  7871. * and faces' vertices are updated.
  7872. */
  7873. mergeVertices: function () {
  7874. var verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)
  7875. var unique = [], changes = [];
  7876. var v, key;
  7877. var precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001
  7878. var precision = Math.pow( 10, precisionPoints );
  7879. var i, il, face;
  7880. var indices, j, jl;
  7881. for ( i = 0, il = this.vertices.length; i < il; i ++ ) {
  7882. v = this.vertices[ i ];
  7883. key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );
  7884. if ( verticesMap[ key ] === undefined ) {
  7885. verticesMap[ key ] = i;
  7886. unique.push( this.vertices[ i ] );
  7887. changes[ i ] = unique.length - 1;
  7888. } else {
  7889. //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
  7890. changes[ i ] = changes[ verticesMap[ key ] ];
  7891. }
  7892. }
  7893. // if faces are completely degenerate after merging vertices, we
  7894. // have to remove them from the geometry.
  7895. var faceIndicesToRemove = [];
  7896. for ( i = 0, il = this.faces.length; i < il; i ++ ) {
  7897. face = this.faces[ i ];
  7898. face.a = changes[ face.a ];
  7899. face.b = changes[ face.b ];
  7900. face.c = changes[ face.c ];
  7901. indices = [ face.a, face.b, face.c ];
  7902. // if any duplicate vertices are found in a Face3
  7903. // we have to remove the face as nothing can be saved
  7904. for ( var n = 0; n < 3; n ++ ) {
  7905. if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {
  7906. faceIndicesToRemove.push( i );
  7907. break;
  7908. }
  7909. }
  7910. }
  7911. for ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {
  7912. var idx = faceIndicesToRemove[ i ];
  7913. this.faces.splice( idx, 1 );
  7914. for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
  7915. this.faceVertexUvs[ j ].splice( idx, 1 );
  7916. }
  7917. }
  7918. // Use unique set of vertices
  7919. var diff = this.vertices.length - unique.length;
  7920. this.vertices = unique;
  7921. return diff;
  7922. },
  7923. sortFacesByMaterialIndex: function () {
  7924. var faces = this.faces;
  7925. var length = faces.length;
  7926. // tag faces
  7927. for ( var i = 0; i < length; i ++ ) {
  7928. faces[ i ]._id = i;
  7929. }
  7930. // sort faces
  7931. function materialIndexSort( a, b ) {
  7932. return a.materialIndex - b.materialIndex;
  7933. }
  7934. faces.sort( materialIndexSort );
  7935. // sort uvs
  7936. var uvs1 = this.faceVertexUvs[ 0 ];
  7937. var uvs2 = this.faceVertexUvs[ 1 ];
  7938. var newUvs1, newUvs2;
  7939. if ( uvs1 && uvs1.length === length ) newUvs1 = [];
  7940. if ( uvs2 && uvs2.length === length ) newUvs2 = [];
  7941. for ( var i = 0; i < length; i ++ ) {
  7942. var id = faces[ i ]._id;
  7943. if ( newUvs1 ) newUvs1.push( uvs1[ id ] );
  7944. if ( newUvs2 ) newUvs2.push( uvs2[ id ] );
  7945. }
  7946. if ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;
  7947. if ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;
  7948. },
  7949. toJSON: function () {
  7950. var data = {
  7951. metadata: {
  7952. version: 4.4,
  7953. type: 'Geometry',
  7954. generator: 'Geometry.toJSON'
  7955. }
  7956. };
  7957. // standard Geometry serialization
  7958. data.uuid = this.uuid;
  7959. data.type = this.type;
  7960. if ( this.name !== '' ) data.name = this.name;
  7961. if ( this.parameters !== undefined ) {
  7962. var parameters = this.parameters;
  7963. for ( var key in parameters ) {
  7964. if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];
  7965. }
  7966. return data;
  7967. }
  7968. var vertices = [];
  7969. for ( var i = 0; i < this.vertices.length; i ++ ) {
  7970. var vertex = this.vertices[ i ];
  7971. vertices.push( vertex.x, vertex.y, vertex.z );
  7972. }
  7973. var faces = [];
  7974. var normals = [];
  7975. var normalsHash = {};
  7976. var colors = [];
  7977. var colorsHash = {};
  7978. var uvs = [];
  7979. var uvsHash = {};
  7980. for ( var i = 0; i < this.faces.length; i ++ ) {
  7981. var face = this.faces[ i ];
  7982. var hasMaterial = true;
  7983. var hasFaceUv = false; // deprecated
  7984. var hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;
  7985. var hasFaceNormal = face.normal.length() > 0;
  7986. var hasFaceVertexNormal = face.vertexNormals.length > 0;
  7987. var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;
  7988. var hasFaceVertexColor = face.vertexColors.length > 0;
  7989. var faceType = 0;
  7990. faceType = setBit( faceType, 0, 0 ); // isQuad
  7991. faceType = setBit( faceType, 1, hasMaterial );
  7992. faceType = setBit( faceType, 2, hasFaceUv );
  7993. faceType = setBit( faceType, 3, hasFaceVertexUv );
  7994. faceType = setBit( faceType, 4, hasFaceNormal );
  7995. faceType = setBit( faceType, 5, hasFaceVertexNormal );
  7996. faceType = setBit( faceType, 6, hasFaceColor );
  7997. faceType = setBit( faceType, 7, hasFaceVertexColor );
  7998. faces.push( faceType );
  7999. faces.push( face.a, face.b, face.c );
  8000. faces.push( face.materialIndex );
  8001. if ( hasFaceVertexUv ) {
  8002. var faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];
  8003. faces.push(
  8004. getUvIndex( faceVertexUvs[ 0 ] ),
  8005. getUvIndex( faceVertexUvs[ 1 ] ),
  8006. getUvIndex( faceVertexUvs[ 2 ] )
  8007. );
  8008. }
  8009. if ( hasFaceNormal ) {
  8010. faces.push( getNormalIndex( face.normal ) );
  8011. }
  8012. if ( hasFaceVertexNormal ) {
  8013. var vertexNormals = face.vertexNormals;
  8014. faces.push(
  8015. getNormalIndex( vertexNormals[ 0 ] ),
  8016. getNormalIndex( vertexNormals[ 1 ] ),
  8017. getNormalIndex( vertexNormals[ 2 ] )
  8018. );
  8019. }
  8020. if ( hasFaceColor ) {
  8021. faces.push( getColorIndex( face.color ) );
  8022. }
  8023. if ( hasFaceVertexColor ) {
  8024. var vertexColors = face.vertexColors;
  8025. faces.push(
  8026. getColorIndex( vertexColors[ 0 ] ),
  8027. getColorIndex( vertexColors[ 1 ] ),
  8028. getColorIndex( vertexColors[ 2 ] )
  8029. );
  8030. }
  8031. }
  8032. function setBit( value, position, enabled ) {
  8033. return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );
  8034. }
  8035. function getNormalIndex( normal ) {
  8036. var hash = normal.x.toString() + normal.y.toString() + normal.z.toString();
  8037. if ( normalsHash[ hash ] !== undefined ) {
  8038. return normalsHash[ hash ];
  8039. }
  8040. normalsHash[ hash ] = normals.length / 3;
  8041. normals.push( normal.x, normal.y, normal.z );
  8042. return normalsHash[ hash ];
  8043. }
  8044. function getColorIndex( color ) {
  8045. var hash = color.r.toString() + color.g.toString() + color.b.toString();
  8046. if ( colorsHash[ hash ] !== undefined ) {
  8047. return colorsHash[ hash ];
  8048. }
  8049. colorsHash[ hash ] = colors.length;
  8050. colors.push( color.getHex() );
  8051. return colorsHash[ hash ];
  8052. }
  8053. function getUvIndex( uv ) {
  8054. var hash = uv.x.toString() + uv.y.toString();
  8055. if ( uvsHash[ hash ] !== undefined ) {
  8056. return uvsHash[ hash ];
  8057. }
  8058. uvsHash[ hash ] = uvs.length / 2;
  8059. uvs.push( uv.x, uv.y );
  8060. return uvsHash[ hash ];
  8061. }
  8062. data.data = {};
  8063. data.data.vertices = vertices;
  8064. data.data.normals = normals;
  8065. if ( colors.length > 0 ) data.data.colors = colors;
  8066. if ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility
  8067. data.data.faces = faces;
  8068. return data;
  8069. },
  8070. clone: function () {
  8071. /*
  8072. // Handle primitives
  8073. var parameters = this.parameters;
  8074. if ( parameters !== undefined ) {
  8075. var values = [];
  8076. for ( var key in parameters ) {
  8077. values.push( parameters[ key ] );
  8078. }
  8079. var geometry = Object.create( this.constructor.prototype );
  8080. this.constructor.apply( geometry, values );
  8081. return geometry;
  8082. }
  8083. return new this.constructor().copy( this );
  8084. */
  8085. return new Geometry().copy( this );
  8086. },
  8087. copy: function ( source ) {
  8088. var i, il, j, jl, k, kl;
  8089. // reset
  8090. this.vertices = [];
  8091. this.colors = [];
  8092. this.faces = [];
  8093. this.faceVertexUvs = [[]];
  8094. this.morphTargets = [];
  8095. this.morphNormals = [];
  8096. this.skinWeights = [];
  8097. this.skinIndices = [];
  8098. this.lineDistances = [];
  8099. this.boundingBox = null;
  8100. this.boundingSphere = null;
  8101. // name
  8102. this.name = source.name;
  8103. // vertices
  8104. var vertices = source.vertices;
  8105. for ( i = 0, il = vertices.length; i < il; i ++ ) {
  8106. this.vertices.push( vertices[ i ].clone() );
  8107. }
  8108. // colors
  8109. var colors = source.colors;
  8110. for ( i = 0, il = colors.length; i < il; i ++ ) {
  8111. this.colors.push( colors[ i ].clone() );
  8112. }
  8113. // faces
  8114. var faces = source.faces;
  8115. for ( i = 0, il = faces.length; i < il; i ++ ) {
  8116. this.faces.push( faces[ i ].clone() );
  8117. }
  8118. // face vertex uvs
  8119. for ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {
  8120. var faceVertexUvs = source.faceVertexUvs[ i ];
  8121. if ( this.faceVertexUvs[ i ] === undefined ) {
  8122. this.faceVertexUvs[ i ] = [];
  8123. }
  8124. for ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {
  8125. var uvs = faceVertexUvs[ j ], uvsCopy = [];
  8126. for ( k = 0, kl = uvs.length; k < kl; k ++ ) {
  8127. var uv = uvs[ k ];
  8128. uvsCopy.push( uv.clone() );
  8129. }
  8130. this.faceVertexUvs[ i ].push( uvsCopy );
  8131. }
  8132. }
  8133. // morph targets
  8134. var morphTargets = source.morphTargets;
  8135. for ( i = 0, il = morphTargets.length; i < il; i ++ ) {
  8136. var morphTarget = {};
  8137. morphTarget.name = morphTargets[ i ].name;
  8138. // vertices
  8139. if ( morphTargets[ i ].vertices !== undefined ) {
  8140. morphTarget.vertices = [];
  8141. for ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {
  8142. morphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );
  8143. }
  8144. }
  8145. // normals
  8146. if ( morphTargets[ i ].normals !== undefined ) {
  8147. morphTarget.normals = [];
  8148. for ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {
  8149. morphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );
  8150. }
  8151. }
  8152. this.morphTargets.push( morphTarget );
  8153. }
  8154. // morph normals
  8155. var morphNormals = source.morphNormals;
  8156. for ( i = 0, il = morphNormals.length; i < il; i ++ ) {
  8157. var morphNormal = {};
  8158. // vertex normals
  8159. if ( morphNormals[ i ].vertexNormals !== undefined ) {
  8160. morphNormal.vertexNormals = [];
  8161. for ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {
  8162. var srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];
  8163. var destVertexNormal = {};
  8164. destVertexNormal.a = srcVertexNormal.a.clone();
  8165. destVertexNormal.b = srcVertexNormal.b.clone();
  8166. destVertexNormal.c = srcVertexNormal.c.clone();
  8167. morphNormal.vertexNormals.push( destVertexNormal );
  8168. }
  8169. }
  8170. // face normals
  8171. if ( morphNormals[ i ].faceNormals !== undefined ) {
  8172. morphNormal.faceNormals = [];
  8173. for ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {
  8174. morphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );
  8175. }
  8176. }
  8177. this.morphNormals.push( morphNormal );
  8178. }
  8179. // skin weights
  8180. var skinWeights = source.skinWeights;
  8181. for ( i = 0, il = skinWeights.length; i < il; i ++ ) {
  8182. this.skinWeights.push( skinWeights[ i ].clone() );
  8183. }
  8184. // skin indices
  8185. var skinIndices = source.skinIndices;
  8186. for ( i = 0, il = skinIndices.length; i < il; i ++ ) {
  8187. this.skinIndices.push( skinIndices[ i ].clone() );
  8188. }
  8189. // line distances
  8190. var lineDistances = source.lineDistances;
  8191. for ( i = 0, il = lineDistances.length; i < il; i ++ ) {
  8192. this.lineDistances.push( lineDistances[ i ] );
  8193. }
  8194. // bounding box
  8195. var boundingBox = source.boundingBox;
  8196. if ( boundingBox !== null ) {
  8197. this.boundingBox = boundingBox.clone();
  8198. }
  8199. // bounding sphere
  8200. var boundingSphere = source.boundingSphere;
  8201. if ( boundingSphere !== null ) {
  8202. this.boundingSphere = boundingSphere.clone();
  8203. }
  8204. // update flags
  8205. this.elementsNeedUpdate = source.elementsNeedUpdate;
  8206. this.verticesNeedUpdate = source.verticesNeedUpdate;
  8207. this.uvsNeedUpdate = source.uvsNeedUpdate;
  8208. this.normalsNeedUpdate = source.normalsNeedUpdate;
  8209. this.colorsNeedUpdate = source.colorsNeedUpdate;
  8210. this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;
  8211. this.groupsNeedUpdate = source.groupsNeedUpdate;
  8212. return this;
  8213. },
  8214. dispose: function () {
  8215. this.dispatchEvent( { type: 'dispose' } );
  8216. }
  8217. };
  8218. Object.assign( Geometry.prototype, EventDispatcher.prototype );
  8219. /**
  8220. * @author alteredq / http://alteredqualia.com/
  8221. * @author mrdoob / http://mrdoob.com/
  8222. */
  8223. function BufferGeometry() {
  8224. Object.defineProperty( this, 'id', { value: GeometryIdCount() } );
  8225. this.uuid = _Math.generateUUID();
  8226. this.name = '';
  8227. this.type = 'BufferGeometry';
  8228. this.index = null;
  8229. this.attributes = {};
  8230. this.morphAttributes = {};
  8231. this.groups = [];
  8232. this.boundingBox = null;
  8233. this.boundingSphere = null;
  8234. this.drawRange = { start: 0, count: Infinity };
  8235. }
  8236. BufferGeometry.prototype = {
  8237. constructor: BufferGeometry,
  8238. isBufferGeometry: true,
  8239. getIndex: function () {
  8240. return this.index;
  8241. },
  8242. setIndex: function ( index ) {
  8243. if ( Array.isArray( index ) ) {
  8244. this.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );
  8245. } else {
  8246. this.index = index;
  8247. }
  8248. },
  8249. addAttribute: function ( name, attribute ) {
  8250. if ( ( attribute && attribute.isBufferAttribute ) === false && ( attribute && attribute.isInterleavedBufferAttribute ) === false ) {
  8251. console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );
  8252. this.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );
  8253. return;
  8254. }
  8255. if ( name === 'index' ) {
  8256. console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );
  8257. this.setIndex( attribute );
  8258. return;
  8259. }
  8260. this.attributes[ name ] = attribute;
  8261. return this;
  8262. },
  8263. getAttribute: function ( name ) {
  8264. return this.attributes[ name ];
  8265. },
  8266. removeAttribute: function ( name ) {
  8267. delete this.attributes[ name ];
  8268. return this;
  8269. },
  8270. addGroup: function ( start, count, materialIndex ) {
  8271. this.groups.push( {
  8272. start: start,
  8273. count: count,
  8274. materialIndex: materialIndex !== undefined ? materialIndex : 0
  8275. } );
  8276. },
  8277. clearGroups: function () {
  8278. this.groups = [];
  8279. },
  8280. setDrawRange: function ( start, count ) {
  8281. this.drawRange.start = start;
  8282. this.drawRange.count = count;
  8283. },
  8284. applyMatrix: function ( matrix ) {
  8285. var position = this.attributes.position;
  8286. if ( position !== undefined ) {
  8287. matrix.applyToBufferAttribute( position );
  8288. position.needsUpdate = true;
  8289. }
  8290. var normal = this.attributes.normal;
  8291. if ( normal !== undefined ) {
  8292. var normalMatrix = new Matrix3().getNormalMatrix( matrix );
  8293. normalMatrix.applyToBufferAttribute( normal );
  8294. normal.needsUpdate = true;
  8295. }
  8296. if ( this.boundingBox !== null ) {
  8297. this.computeBoundingBox();
  8298. }
  8299. if ( this.boundingSphere !== null ) {
  8300. this.computeBoundingSphere();
  8301. }
  8302. return this;
  8303. },
  8304. rotateX: function () {
  8305. // rotate geometry around world x-axis
  8306. var m1;
  8307. return function rotateX( angle ) {
  8308. if ( m1 === undefined ) m1 = new Matrix4();
  8309. m1.makeRotationX( angle );
  8310. this.applyMatrix( m1 );
  8311. return this;
  8312. };
  8313. }(),
  8314. rotateY: function () {
  8315. // rotate geometry around world y-axis
  8316. var m1;
  8317. return function rotateY( angle ) {
  8318. if ( m1 === undefined ) m1 = new Matrix4();
  8319. m1.makeRotationY( angle );
  8320. this.applyMatrix( m1 );
  8321. return this;
  8322. };
  8323. }(),
  8324. rotateZ: function () {
  8325. // rotate geometry around world z-axis
  8326. var m1;
  8327. return function rotateZ( angle ) {
  8328. if ( m1 === undefined ) m1 = new Matrix4();
  8329. m1.makeRotationZ( angle );
  8330. this.applyMatrix( m1 );
  8331. return this;
  8332. };
  8333. }(),
  8334. translate: function () {
  8335. // translate geometry
  8336. var m1;
  8337. return function translate( x, y, z ) {
  8338. if ( m1 === undefined ) m1 = new Matrix4();
  8339. m1.makeTranslation( x, y, z );
  8340. this.applyMatrix( m1 );
  8341. return this;
  8342. };
  8343. }(),
  8344. scale: function () {
  8345. // scale geometry
  8346. var m1;
  8347. return function scale( x, y, z ) {
  8348. if ( m1 === undefined ) m1 = new Matrix4();
  8349. m1.makeScale( x, y, z );
  8350. this.applyMatrix( m1 );
  8351. return this;
  8352. };
  8353. }(),
  8354. lookAt: function () {
  8355. var obj;
  8356. return function lookAt( vector ) {
  8357. if ( obj === undefined ) obj = new Object3D();
  8358. obj.lookAt( vector );
  8359. obj.updateMatrix();
  8360. this.applyMatrix( obj.matrix );
  8361. };
  8362. }(),
  8363. center: function () {
  8364. this.computeBoundingBox();
  8365. var offset = this.boundingBox.getCenter().negate();
  8366. this.translate( offset.x, offset.y, offset.z );
  8367. return offset;
  8368. },
  8369. setFromObject: function ( object ) {
  8370. // console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );
  8371. var geometry = object.geometry;
  8372. if ( object.isPoints || object.isLine ) {
  8373. var positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );
  8374. var colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );
  8375. this.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );
  8376. this.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );
  8377. if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {
  8378. var lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );
  8379. this.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );
  8380. }
  8381. if ( geometry.boundingSphere !== null ) {
  8382. this.boundingSphere = geometry.boundingSphere.clone();
  8383. }
  8384. if ( geometry.boundingBox !== null ) {
  8385. this.boundingBox = geometry.boundingBox.clone();
  8386. }
  8387. } else if ( object.isMesh ) {
  8388. if ( geometry && geometry.isGeometry ) {
  8389. this.fromGeometry( geometry );
  8390. }
  8391. }
  8392. return this;
  8393. },
  8394. updateFromObject: function ( object ) {
  8395. var geometry = object.geometry;
  8396. if ( object.isMesh ) {
  8397. var direct = geometry.__directGeometry;
  8398. if ( geometry.elementsNeedUpdate === true ) {
  8399. direct = undefined;
  8400. geometry.elementsNeedUpdate = false;
  8401. }
  8402. if ( direct === undefined ) {
  8403. return this.fromGeometry( geometry );
  8404. }
  8405. direct.verticesNeedUpdate = geometry.verticesNeedUpdate;
  8406. direct.normalsNeedUpdate = geometry.normalsNeedUpdate;
  8407. direct.colorsNeedUpdate = geometry.colorsNeedUpdate;
  8408. direct.uvsNeedUpdate = geometry.uvsNeedUpdate;
  8409. direct.groupsNeedUpdate = geometry.groupsNeedUpdate;
  8410. geometry.verticesNeedUpdate = false;
  8411. geometry.normalsNeedUpdate = false;
  8412. geometry.colorsNeedUpdate = false;
  8413. geometry.uvsNeedUpdate = false;
  8414. geometry.groupsNeedUpdate = false;
  8415. geometry = direct;
  8416. }
  8417. var attribute;
  8418. if ( geometry.verticesNeedUpdate === true ) {
  8419. attribute = this.attributes.position;
  8420. if ( attribute !== undefined ) {
  8421. attribute.copyVector3sArray( geometry.vertices );
  8422. attribute.needsUpdate = true;
  8423. }
  8424. geometry.verticesNeedUpdate = false;
  8425. }
  8426. if ( geometry.normalsNeedUpdate === true ) {
  8427. attribute = this.attributes.normal;
  8428. if ( attribute !== undefined ) {
  8429. attribute.copyVector3sArray( geometry.normals );
  8430. attribute.needsUpdate = true;
  8431. }
  8432. geometry.normalsNeedUpdate = false;
  8433. }
  8434. if ( geometry.colorsNeedUpdate === true ) {
  8435. attribute = this.attributes.color;
  8436. if ( attribute !== undefined ) {
  8437. attribute.copyColorsArray( geometry.colors );
  8438. attribute.needsUpdate = true;
  8439. }
  8440. geometry.colorsNeedUpdate = false;
  8441. }
  8442. if ( geometry.uvsNeedUpdate ) {
  8443. attribute = this.attributes.uv;
  8444. if ( attribute !== undefined ) {
  8445. attribute.copyVector2sArray( geometry.uvs );
  8446. attribute.needsUpdate = true;
  8447. }
  8448. geometry.uvsNeedUpdate = false;
  8449. }
  8450. if ( geometry.lineDistancesNeedUpdate ) {
  8451. attribute = this.attributes.lineDistance;
  8452. if ( attribute !== undefined ) {
  8453. attribute.copyArray( geometry.lineDistances );
  8454. attribute.needsUpdate = true;
  8455. }
  8456. geometry.lineDistancesNeedUpdate = false;
  8457. }
  8458. if ( geometry.groupsNeedUpdate ) {
  8459. geometry.computeGroups( object.geometry );
  8460. this.groups = geometry.groups;
  8461. geometry.groupsNeedUpdate = false;
  8462. }
  8463. return this;
  8464. },
  8465. fromGeometry: function ( geometry ) {
  8466. geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );
  8467. return this.fromDirectGeometry( geometry.__directGeometry );
  8468. },
  8469. fromDirectGeometry: function ( geometry ) {
  8470. var positions = new Float32Array( geometry.vertices.length * 3 );
  8471. this.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );
  8472. if ( geometry.normals.length > 0 ) {
  8473. var normals = new Float32Array( geometry.normals.length * 3 );
  8474. this.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );
  8475. }
  8476. if ( geometry.colors.length > 0 ) {
  8477. var colors = new Float32Array( geometry.colors.length * 3 );
  8478. this.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );
  8479. }
  8480. if ( geometry.uvs.length > 0 ) {
  8481. var uvs = new Float32Array( geometry.uvs.length * 2 );
  8482. this.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );
  8483. }
  8484. if ( geometry.uvs2.length > 0 ) {
  8485. var uvs2 = new Float32Array( geometry.uvs2.length * 2 );
  8486. this.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );
  8487. }
  8488. if ( geometry.indices.length > 0 ) {
  8489. var TypeArray = arrayMax( geometry.indices ) > 65535 ? Uint32Array : Uint16Array;
  8490. var indices = new TypeArray( geometry.indices.length * 3 );
  8491. this.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );
  8492. }
  8493. // groups
  8494. this.groups = geometry.groups;
  8495. // morphs
  8496. for ( var name in geometry.morphTargets ) {
  8497. var array = [];
  8498. var morphTargets = geometry.morphTargets[ name ];
  8499. for ( var i = 0, l = morphTargets.length; i < l; i ++ ) {
  8500. var morphTarget = morphTargets[ i ];
  8501. var attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 );
  8502. array.push( attribute.copyVector3sArray( morphTarget ) );
  8503. }
  8504. this.morphAttributes[ name ] = array;
  8505. }
  8506. // skinning
  8507. if ( geometry.skinIndices.length > 0 ) {
  8508. var skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );
  8509. this.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );
  8510. }
  8511. if ( geometry.skinWeights.length > 0 ) {
  8512. var skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );
  8513. this.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );
  8514. }
  8515. //
  8516. if ( geometry.boundingSphere !== null ) {
  8517. this.boundingSphere = geometry.boundingSphere.clone();
  8518. }
  8519. if ( geometry.boundingBox !== null ) {
  8520. this.boundingBox = geometry.boundingBox.clone();
  8521. }
  8522. return this;
  8523. },
  8524. computeBoundingBox: function () {
  8525. if ( this.boundingBox === null ) {
  8526. this.boundingBox = new Box3();
  8527. }
  8528. var position = this.attributes.position;
  8529. if ( position !== undefined ) {
  8530. this.boundingBox.setFromBufferAttribute( position );
  8531. } else {
  8532. this.boundingBox.makeEmpty();
  8533. }
  8534. if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
  8535. console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this );
  8536. }
  8537. },
  8538. computeBoundingSphere: function () {
  8539. var box = new Box3();
  8540. var vector = new Vector3();
  8541. return function computeBoundingSphere() {
  8542. if ( this.boundingSphere === null ) {
  8543. this.boundingSphere = new Sphere();
  8544. }
  8545. var position = this.attributes.position;
  8546. if ( position ) {
  8547. var center = this.boundingSphere.center;
  8548. box.setFromBufferAttribute( position );
  8549. box.getCenter( center );
  8550. // hoping to find a boundingSphere with a radius smaller than the
  8551. // boundingSphere of the boundingBox: sqrt(3) smaller in the best case
  8552. var maxRadiusSq = 0;
  8553. for ( var i = 0, il = position.count; i < il; i ++ ) {
  8554. vector.x = position.getX( i );
  8555. vector.y = position.getY( i );
  8556. vector.z = position.getZ( i );
  8557. maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
  8558. }
  8559. this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
  8560. if ( isNaN( this.boundingSphere.radius ) ) {
  8561. console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this );
  8562. }
  8563. }
  8564. };
  8565. }(),
  8566. computeFaceNormals: function () {
  8567. // backwards compatibility
  8568. },
  8569. computeVertexNormals: function () {
  8570. var index = this.index;
  8571. var attributes = this.attributes;
  8572. var groups = this.groups;
  8573. if ( attributes.position ) {
  8574. var positions = attributes.position.array;
  8575. if ( attributes.normal === undefined ) {
  8576. this.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );
  8577. } else {
  8578. // reset existing normals to zero
  8579. var array = attributes.normal.array;
  8580. for ( var i = 0, il = array.length; i < il; i ++ ) {
  8581. array[ i ] = 0;
  8582. }
  8583. }
  8584. var normals = attributes.normal.array;
  8585. var vA, vB, vC;
  8586. var pA = new Vector3(), pB = new Vector3(), pC = new Vector3();
  8587. var cb = new Vector3(), ab = new Vector3();
  8588. // indexed elements
  8589. if ( index ) {
  8590. var indices = index.array;
  8591. if ( groups.length === 0 ) {
  8592. this.addGroup( 0, indices.length );
  8593. }
  8594. for ( var j = 0, jl = groups.length; j < jl; ++ j ) {
  8595. var group = groups[ j ];
  8596. var start = group.start;
  8597. var count = group.count;
  8598. for ( var i = start, il = start + count; i < il; i += 3 ) {
  8599. vA = indices[ i + 0 ] * 3;
  8600. vB = indices[ i + 1 ] * 3;
  8601. vC = indices[ i + 2 ] * 3;
  8602. pA.fromArray( positions, vA );
  8603. pB.fromArray( positions, vB );
  8604. pC.fromArray( positions, vC );
  8605. cb.subVectors( pC, pB );
  8606. ab.subVectors( pA, pB );
  8607. cb.cross( ab );
  8608. normals[ vA ] += cb.x;
  8609. normals[ vA + 1 ] += cb.y;
  8610. normals[ vA + 2 ] += cb.z;
  8611. normals[ vB ] += cb.x;
  8612. normals[ vB + 1 ] += cb.y;
  8613. normals[ vB + 2 ] += cb.z;
  8614. normals[ vC ] += cb.x;
  8615. normals[ vC + 1 ] += cb.y;
  8616. normals[ vC + 2 ] += cb.z;
  8617. }
  8618. }
  8619. } else {
  8620. // non-indexed elements (unconnected triangle soup)
  8621. for ( var i = 0, il = positions.length; i < il; i += 9 ) {
  8622. pA.fromArray( positions, i );
  8623. pB.fromArray( positions, i + 3 );
  8624. pC.fromArray( positions, i + 6 );
  8625. cb.subVectors( pC, pB );
  8626. ab.subVectors( pA, pB );
  8627. cb.cross( ab );
  8628. normals[ i ] = cb.x;
  8629. normals[ i + 1 ] = cb.y;
  8630. normals[ i + 2 ] = cb.z;
  8631. normals[ i + 3 ] = cb.x;
  8632. normals[ i + 4 ] = cb.y;
  8633. normals[ i + 5 ] = cb.z;
  8634. normals[ i + 6 ] = cb.x;
  8635. normals[ i + 7 ] = cb.y;
  8636. normals[ i + 8 ] = cb.z;
  8637. }
  8638. }
  8639. this.normalizeNormals();
  8640. attributes.normal.needsUpdate = true;
  8641. }
  8642. },
  8643. merge: function ( geometry, offset ) {
  8644. if ( ( geometry && geometry.isBufferGeometry ) === false ) {
  8645. console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );
  8646. return;
  8647. }
  8648. if ( offset === undefined ) offset = 0;
  8649. var attributes = this.attributes;
  8650. for ( var key in attributes ) {
  8651. if ( geometry.attributes[ key ] === undefined ) continue;
  8652. var attribute1 = attributes[ key ];
  8653. var attributeArray1 = attribute1.array;
  8654. var attribute2 = geometry.attributes[ key ];
  8655. var attributeArray2 = attribute2.array;
  8656. var attributeSize = attribute2.itemSize;
  8657. for ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {
  8658. attributeArray1[ j ] = attributeArray2[ i ];
  8659. }
  8660. }
  8661. return this;
  8662. },
  8663. normalizeNormals: function () {
  8664. var normals = this.attributes.normal.array;
  8665. var x, y, z, n;
  8666. for ( var i = 0, il = normals.length; i < il; i += 3 ) {
  8667. x = normals[ i ];
  8668. y = normals[ i + 1 ];
  8669. z = normals[ i + 2 ];
  8670. n = 1.0 / Math.sqrt( x * x + y * y + z * z );
  8671. normals[ i ] *= n;
  8672. normals[ i + 1 ] *= n;
  8673. normals[ i + 2 ] *= n;
  8674. }
  8675. },
  8676. toNonIndexed: function () {
  8677. if ( this.index === null ) {
  8678. console.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );
  8679. return this;
  8680. }
  8681. var geometry2 = new BufferGeometry();
  8682. var indices = this.index.array;
  8683. var attributes = this.attributes;
  8684. for ( var name in attributes ) {
  8685. var attribute = attributes[ name ];
  8686. var array = attribute.array;
  8687. var itemSize = attribute.itemSize;
  8688. var array2 = new array.constructor( indices.length * itemSize );
  8689. var index = 0, index2 = 0;
  8690. for ( var i = 0, l = indices.length; i < l; i ++ ) {
  8691. index = indices[ i ] * itemSize;
  8692. for ( var j = 0; j < itemSize; j ++ ) {
  8693. array2[ index2 ++ ] = array[ index ++ ];
  8694. }
  8695. }
  8696. geometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );
  8697. }
  8698. return geometry2;
  8699. },
  8700. toJSON: function () {
  8701. var data = {
  8702. metadata: {
  8703. version: 4.4,
  8704. type: 'BufferGeometry',
  8705. generator: 'BufferGeometry.toJSON'
  8706. }
  8707. };
  8708. // standard BufferGeometry serialization
  8709. data.uuid = this.uuid;
  8710. data.type = this.type;
  8711. if ( this.name !== '' ) data.name = this.name;
  8712. if ( this.parameters !== undefined ) {
  8713. var parameters = this.parameters;
  8714. for ( var key in parameters ) {
  8715. if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];
  8716. }
  8717. return data;
  8718. }
  8719. data.data = { attributes: {} };
  8720. var index = this.index;
  8721. if ( index !== null ) {
  8722. var array = Array.prototype.slice.call( index.array );
  8723. data.data.index = {
  8724. type: index.array.constructor.name,
  8725. array: array
  8726. };
  8727. }
  8728. var attributes = this.attributes;
  8729. for ( var key in attributes ) {
  8730. var attribute = attributes[ key ];
  8731. var array = Array.prototype.slice.call( attribute.array );
  8732. data.data.attributes[ key ] = {
  8733. itemSize: attribute.itemSize,
  8734. type: attribute.array.constructor.name,
  8735. array: array,
  8736. normalized: attribute.normalized
  8737. };
  8738. }
  8739. var groups = this.groups;
  8740. if ( groups.length > 0 ) {
  8741. data.data.groups = JSON.parse( JSON.stringify( groups ) );
  8742. }
  8743. var boundingSphere = this.boundingSphere;
  8744. if ( boundingSphere !== null ) {
  8745. data.data.boundingSphere = {
  8746. center: boundingSphere.center.toArray(),
  8747. radius: boundingSphere.radius
  8748. };
  8749. }
  8750. return data;
  8751. },
  8752. clone: function () {
  8753. /*
  8754. // Handle primitives
  8755. var parameters = this.parameters;
  8756. if ( parameters !== undefined ) {
  8757. var values = [];
  8758. for ( var key in parameters ) {
  8759. values.push( parameters[ key ] );
  8760. }
  8761. var geometry = Object.create( this.constructor.prototype );
  8762. this.constructor.apply( geometry, values );
  8763. return geometry;
  8764. }
  8765. return new this.constructor().copy( this );
  8766. */
  8767. return new BufferGeometry().copy( this );
  8768. },
  8769. copy: function ( source ) {
  8770. var name, i, l;
  8771. // reset
  8772. this.index = null;
  8773. this.attributes = {};
  8774. this.morphAttributes = {};
  8775. this.groups = [];
  8776. this.boundingBox = null;
  8777. this.boundingSphere = null;
  8778. // name
  8779. this.name = source.name;
  8780. // index
  8781. var index = source.index;
  8782. if ( index !== null ) {
  8783. this.setIndex( index.clone() );
  8784. }
  8785. // attributes
  8786. var attributes = source.attributes;
  8787. for ( name in attributes ) {
  8788. var attribute = attributes[ name ];
  8789. this.addAttribute( name, attribute.clone() );
  8790. }
  8791. // morph attributes
  8792. var morphAttributes = source.morphAttributes;
  8793. for ( name in morphAttributes ) {
  8794. var array = [];
  8795. var morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes
  8796. for ( i = 0, l = morphAttribute.length; i < l; i ++ ) {
  8797. array.push( morphAttribute[ i ].clone() );
  8798. }
  8799. this.morphAttributes[ name ] = array;
  8800. }
  8801. // groups
  8802. var groups = source.groups;
  8803. for ( i = 0, l = groups.length; i < l; i ++ ) {
  8804. var group = groups[ i ];
  8805. this.addGroup( group.start, group.count, group.materialIndex );
  8806. }
  8807. // bounding box
  8808. var boundingBox = source.boundingBox;
  8809. if ( boundingBox !== null ) {
  8810. this.boundingBox = boundingBox.clone();
  8811. }
  8812. // bounding sphere
  8813. var boundingSphere = source.boundingSphere;
  8814. if ( boundingSphere !== null ) {
  8815. this.boundingSphere = boundingSphere.clone();
  8816. }
  8817. // draw range
  8818. this.drawRange.start = source.drawRange.start;
  8819. this.drawRange.count = source.drawRange.count;
  8820. return this;
  8821. },
  8822. dispose: function () {
  8823. this.dispatchEvent( { type: 'dispose' } );
  8824. }
  8825. };
  8826. BufferGeometry.MaxIndex = 65535;
  8827. Object.assign( BufferGeometry.prototype, EventDispatcher.prototype );
  8828. /**
  8829. * @author mrdoob / http://mrdoob.com/
  8830. * @author alteredq / http://alteredqualia.com/
  8831. * @author mikael emtinger / http://gomo.se/
  8832. * @author jonobr1 / http://jonobr1.com/
  8833. */
  8834. function Mesh( geometry, material ) {
  8835. Object3D.call( this );
  8836. this.type = 'Mesh';
  8837. this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
  8838. this.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );
  8839. this.drawMode = TrianglesDrawMode;
  8840. this.updateMorphTargets();
  8841. }
  8842. Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
  8843. constructor: Mesh,
  8844. isMesh: true,
  8845. setDrawMode: function ( value ) {
  8846. this.drawMode = value;
  8847. },
  8848. copy: function ( source ) {
  8849. Object3D.prototype.copy.call( this, source );
  8850. this.drawMode = source.drawMode;
  8851. return this;
  8852. },
  8853. updateMorphTargets: function () {
  8854. var morphTargets = this.geometry.morphTargets;
  8855. if ( morphTargets !== undefined && morphTargets.length > 0 ) {
  8856. this.morphTargetInfluences = [];
  8857. this.morphTargetDictionary = {};
  8858. for ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {
  8859. this.morphTargetInfluences.push( 0 );
  8860. this.morphTargetDictionary[ morphTargets[ m ].name ] = m;
  8861. }
  8862. }
  8863. },
  8864. raycast: ( function () {
  8865. var inverseMatrix = new Matrix4();
  8866. var ray = new Ray();
  8867. var sphere = new Sphere();
  8868. var vA = new Vector3();
  8869. var vB = new Vector3();
  8870. var vC = new Vector3();
  8871. var tempA = new Vector3();
  8872. var tempB = new Vector3();
  8873. var tempC = new Vector3();
  8874. var uvA = new Vector2();
  8875. var uvB = new Vector2();
  8876. var uvC = new Vector2();
  8877. var barycoord = new Vector3();
  8878. var intersectionPoint = new Vector3();
  8879. var intersectionPointWorld = new Vector3();
  8880. function uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {
  8881. Triangle.barycoordFromPoint( point, p1, p2, p3, barycoord );
  8882. uv1.multiplyScalar( barycoord.x );
  8883. uv2.multiplyScalar( barycoord.y );
  8884. uv3.multiplyScalar( barycoord.z );
  8885. uv1.add( uv2 ).add( uv3 );
  8886. return uv1.clone();
  8887. }
  8888. function checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {
  8889. var intersect;
  8890. var material = object.material;
  8891. if ( material.side === BackSide ) {
  8892. intersect = ray.intersectTriangle( pC, pB, pA, true, point );
  8893. } else {
  8894. intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );
  8895. }
  8896. if ( intersect === null ) return null;
  8897. intersectionPointWorld.copy( point );
  8898. intersectionPointWorld.applyMatrix4( object.matrixWorld );
  8899. var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );
  8900. if ( distance < raycaster.near || distance > raycaster.far ) return null;
  8901. return {
  8902. distance: distance,
  8903. point: intersectionPointWorld.clone(),
  8904. object: object
  8905. };
  8906. }
  8907. function checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) {
  8908. vA.fromBufferAttribute( position, a );
  8909. vB.fromBufferAttribute( position, b );
  8910. vC.fromBufferAttribute( position, c );
  8911. var intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );
  8912. if ( intersection ) {
  8913. if ( uv ) {
  8914. uvA.fromBufferAttribute( uv, a );
  8915. uvB.fromBufferAttribute( uv, b );
  8916. uvC.fromBufferAttribute( uv, c );
  8917. intersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );
  8918. }
  8919. intersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );
  8920. intersection.faceIndex = a;
  8921. }
  8922. return intersection;
  8923. }
  8924. return function raycast( raycaster, intersects ) {
  8925. var geometry = this.geometry;
  8926. var material = this.material;
  8927. var matrixWorld = this.matrixWorld;
  8928. if ( material === undefined ) return;
  8929. // Checking boundingSphere distance to ray
  8930. if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
  8931. sphere.copy( geometry.boundingSphere );
  8932. sphere.applyMatrix4( matrixWorld );
  8933. if ( raycaster.ray.intersectsSphere( sphere ) === false ) return;
  8934. //
  8935. inverseMatrix.getInverse( matrixWorld );
  8936. ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
  8937. // Check boundingBox before continuing
  8938. if ( geometry.boundingBox !== null ) {
  8939. if ( ray.intersectsBox( geometry.boundingBox ) === false ) return;
  8940. }
  8941. var intersection;
  8942. if ( geometry.isBufferGeometry ) {
  8943. var a, b, c;
  8944. var index = geometry.index;
  8945. var position = geometry.attributes.position;
  8946. var uv = geometry.attributes.uv;
  8947. var i, l;
  8948. if ( index !== null ) {
  8949. // indexed buffer geometry
  8950. for ( i = 0, l = index.count; i < l; i += 3 ) {
  8951. a = index.getX( i );
  8952. b = index.getX( i + 1 );
  8953. c = index.getX( i + 2 );
  8954. intersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );
  8955. if ( intersection ) {
  8956. intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics
  8957. intersects.push( intersection );
  8958. }
  8959. }
  8960. } else {
  8961. // non-indexed buffer geometry
  8962. for ( i = 0, l = position.count; i < l; i += 3 ) {
  8963. a = i;
  8964. b = i + 1;
  8965. c = i + 2;
  8966. intersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );
  8967. if ( intersection ) {
  8968. intersection.index = a; // triangle number in positions buffer semantics
  8969. intersects.push( intersection );
  8970. }
  8971. }
  8972. }
  8973. } else if ( geometry.isGeometry ) {
  8974. var fvA, fvB, fvC;
  8975. var isFaceMaterial = ( material && material.isMultiMaterial );
  8976. var materials = isFaceMaterial === true ? material.materials : null;
  8977. var vertices = geometry.vertices;
  8978. var faces = geometry.faces;
  8979. var uvs;
  8980. var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
  8981. if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;
  8982. for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
  8983. var face = faces[ f ];
  8984. var faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;
  8985. if ( faceMaterial === undefined ) continue;
  8986. fvA = vertices[ face.a ];
  8987. fvB = vertices[ face.b ];
  8988. fvC = vertices[ face.c ];
  8989. if ( faceMaterial.morphTargets === true ) {
  8990. var morphTargets = geometry.morphTargets;
  8991. var morphInfluences = this.morphTargetInfluences;
  8992. vA.set( 0, 0, 0 );
  8993. vB.set( 0, 0, 0 );
  8994. vC.set( 0, 0, 0 );
  8995. for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {
  8996. var influence = morphInfluences[ t ];
  8997. if ( influence === 0 ) continue;
  8998. var targets = morphTargets[ t ].vertices;
  8999. vA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );
  9000. vB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );
  9001. vC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );
  9002. }
  9003. vA.add( fvA );
  9004. vB.add( fvB );
  9005. vC.add( fvC );
  9006. fvA = vA;
  9007. fvB = vB;
  9008. fvC = vC;
  9009. }
  9010. intersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );
  9011. if ( intersection ) {
  9012. if ( uvs ) {
  9013. var uvs_f = uvs[ f ];
  9014. uvA.copy( uvs_f[ 0 ] );
  9015. uvB.copy( uvs_f[ 1 ] );
  9016. uvC.copy( uvs_f[ 2 ] );
  9017. intersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );
  9018. }
  9019. intersection.face = face;
  9020. intersection.faceIndex = f;
  9021. intersects.push( intersection );
  9022. }
  9023. }
  9024. }
  9025. };
  9026. }() ),
  9027. clone: function () {
  9028. return new this.constructor( this.geometry, this.material ).copy( this );
  9029. }
  9030. } );
  9031. /**
  9032. * @author mrdoob / http://mrdoob.com/
  9033. * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as
  9034. */
  9035. /**
  9036. * @author Mugen87 / https://github.com/Mugen87
  9037. */
  9038. function BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {
  9039. BufferGeometry.call( this );
  9040. this.type = 'BoxBufferGeometry';
  9041. this.parameters = {
  9042. width: width,
  9043. height: height,
  9044. depth: depth,
  9045. widthSegments: widthSegments,
  9046. heightSegments: heightSegments,
  9047. depthSegments: depthSegments
  9048. };
  9049. var scope = this;
  9050. // segments
  9051. widthSegments = Math.floor( widthSegments ) || 1;
  9052. heightSegments = Math.floor( heightSegments ) || 1;
  9053. depthSegments = Math.floor( depthSegments ) || 1;
  9054. // buffers
  9055. var indices = [];
  9056. var vertices = [];
  9057. var normals = [];
  9058. var uvs = [];
  9059. // helper variables
  9060. var numberOfVertices = 0;
  9061. var groupStart = 0;
  9062. // build each side of the box geometry
  9063. buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px
  9064. buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx
  9065. buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py
  9066. buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny
  9067. buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz
  9068. buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz
  9069. // build geometry
  9070. this.setIndex( indices );
  9071. this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
  9072. this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
  9073. this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
  9074. function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {
  9075. var segmentWidth = width / gridX;
  9076. var segmentHeight = height / gridY;
  9077. var widthHalf = width / 2;
  9078. var heightHalf = height / 2;
  9079. var depthHalf = depth / 2;
  9080. var gridX1 = gridX + 1;
  9081. var gridY1 = gridY + 1;
  9082. var vertexCounter = 0;
  9083. var groupCount = 0;
  9084. var ix, iy;
  9085. var vector = new Vector3();
  9086. // generate vertices, normals and uvs
  9087. for ( iy = 0; iy < gridY1; iy ++ ) {
  9088. var y = iy * segmentHeight - heightHalf;
  9089. for ( ix = 0; ix < gridX1; ix ++ ) {
  9090. var x = ix * segmentWidth - widthHalf;
  9091. // set values to correct vector component
  9092. vector[ u ] = x * udir;
  9093. vector[ v ] = y * vdir;
  9094. vector[ w ] = depthHalf;
  9095. // now apply vector to vertex buffer
  9096. vertices.push( vector.x, vector.y, vector.z );
  9097. // set values to correct vector component
  9098. vector[ u ] = 0;
  9099. vector[ v ] = 0;
  9100. vector[ w ] = depth > 0 ? 1 : - 1;
  9101. // now apply vector to normal buffer
  9102. normals.push( vector.x, vector.y, vector.z );
  9103. // uvs
  9104. uvs.push( ix / gridX );
  9105. uvs.push( 1 - ( iy / gridY ) );
  9106. // counters
  9107. vertexCounter += 1;
  9108. }
  9109. }
  9110. // indices
  9111. // 1. you need three indices to draw a single face
  9112. // 2. a single segment consists of two faces
  9113. // 3. so we need to generate six (2*3) indices per segment
  9114. for ( iy = 0; iy < gridY; iy ++ ) {
  9115. for ( ix = 0; ix < gridX; ix ++ ) {
  9116. var a = numberOfVertices + ix + gridX1 * iy;
  9117. var b = numberOfVertices + ix + gridX1 * ( iy + 1 );
  9118. var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );
  9119. var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;
  9120. // faces
  9121. indices.push( a, b, d );
  9122. indices.push( b, c, d );
  9123. // increase counter
  9124. groupCount += 6;
  9125. }
  9126. }
  9127. // add a group to the geometry. this will ensure multi material support
  9128. scope.addGroup( groupStart, groupCount, materialIndex );
  9129. // calculate new start value for groups
  9130. groupStart += groupCount;
  9131. // update total number of vertices
  9132. numberOfVertices += vertexCounter;
  9133. }
  9134. }
  9135. BoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
  9136. BoxBufferGeometry.prototype.constructor = BoxBufferGeometry;
  9137. /**
  9138. * @author mrdoob / http://mrdoob.com/
  9139. * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as
  9140. */
  9141. /**
  9142. * @author mrdoob / http://mrdoob.com/
  9143. * @author Mugen87 / https://github.com/Mugen87
  9144. *
  9145. * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as
  9146. */
  9147. function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {
  9148. BufferGeometry.call( this );
  9149. this.type = 'PlaneBufferGeometry';
  9150. this.parameters = {
  9151. width: width,
  9152. height: height,
  9153. widthSegments: widthSegments,
  9154. heightSegments: heightSegments
  9155. };
  9156. var width_half = width / 2;
  9157. var height_half = height / 2;
  9158. var gridX = Math.floor( widthSegments ) || 1;
  9159. var gridY = Math.floor( heightSegments ) || 1;
  9160. var gridX1 = gridX + 1;
  9161. var gridY1 = gridY + 1;
  9162. var segment_width = width / gridX;
  9163. var segment_height = height / gridY;
  9164. var ix, iy;
  9165. // buffers
  9166. var indices = [];
  9167. var vertices = [];
  9168. var normals = [];
  9169. var uvs = [];
  9170. // generate vertices, normals and uvs
  9171. for ( iy = 0; iy < gridY1; iy ++ ) {
  9172. var y = iy * segment_height - height_half;
  9173. for ( ix = 0; ix < gridX1; ix ++ ) {
  9174. var x = ix * segment_width - width_half;
  9175. vertices.push( x, - y, 0 );
  9176. normals.push( 0, 0, 1 );
  9177. uvs.push( ix / gridX );
  9178. uvs.push( 1 - ( iy / gridY ) );
  9179. }
  9180. }
  9181. // indices
  9182. for ( iy = 0; iy < gridY; iy ++ ) {
  9183. for ( ix = 0; ix < gridX; ix ++ ) {
  9184. var a = ix + gridX1 * iy;
  9185. var b = ix + gridX1 * ( iy + 1 );
  9186. var c = ( ix + 1 ) + gridX1 * ( iy + 1 );
  9187. var d = ( ix + 1 ) + gridX1 * iy;
  9188. // faces
  9189. indices.push( a, b, d );
  9190. indices.push( b, c, d );
  9191. }
  9192. }
  9193. // build geometry
  9194. this.setIndex( indices );
  9195. this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
  9196. this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
  9197. this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
  9198. }
  9199. PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
  9200. PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;
  9201. /**
  9202. * @author mrdoob / http://mrdoob.com/
  9203. * @author mikael emtinger / http://gomo.se/
  9204. * @author WestLangley / http://github.com/WestLangley
  9205. */
  9206. function Camera() {
  9207. Object3D.call( this );
  9208. this.type = 'Camera';
  9209. this.matrixWorldInverse = new Matrix4();
  9210. this.projectionMatrix = new Matrix4();
  9211. }
  9212. Camera.prototype = Object.create( Object3D.prototype );
  9213. Camera.prototype.constructor = Camera;
  9214. Camera.prototype.isCamera = true;
  9215. Camera.prototype.getWorldDirection = function () {
  9216. var quaternion = new Quaternion();
  9217. return function getWorldDirection( optionalTarget ) {
  9218. var result = optionalTarget || new Vector3();
  9219. this.getWorldQuaternion( quaternion );
  9220. return result.set( 0, 0, - 1 ).applyQuaternion( quaternion );
  9221. };
  9222. }();
  9223. Camera.prototype.lookAt = function () {
  9224. // This routine does not support cameras with rotated and/or translated parent(s)
  9225. var m1 = new Matrix4();
  9226. return function lookAt( vector ) {
  9227. m1.lookAt( this.position, vector, this.up );
  9228. this.quaternion.setFromRotationMatrix( m1 );
  9229. };
  9230. }();
  9231. Camera.prototype.clone = function () {
  9232. return new this.constructor().copy( this );
  9233. };
  9234. Camera.prototype.copy = function ( source ) {
  9235. Object3D.prototype.copy.call( this, source );
  9236. this.matrixWorldInverse.copy( source.matrixWorldInverse );
  9237. this.projectionMatrix.copy( source.projectionMatrix );
  9238. return this;
  9239. };
  9240. /**
  9241. * @author mrdoob / http://mrdoob.com/
  9242. * @author greggman / http://games.greggman.com/
  9243. * @author zz85 / http://www.lab4games.net/zz85/blog
  9244. * @author tschw
  9245. */
  9246. function PerspectiveCamera( fov, aspect, near, far ) {
  9247. Camera.call( this );
  9248. this.type = 'PerspectiveCamera';
  9249. this.fov = fov !== undefined ? fov : 50;
  9250. this.zoom = 1;
  9251. this.near = near !== undefined ? near : 0.1;
  9252. this.far = far !== undefined ? far : 2000;
  9253. this.focus = 10;
  9254. this.aspect = aspect !== undefined ? aspect : 1;
  9255. this.view = null;
  9256. this.filmGauge = 35; // width of the film (default in millimeters)
  9257. this.filmOffset = 0; // horizontal film offset (same unit as gauge)
  9258. this.updateProjectionMatrix();
  9259. }
  9260. PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {
  9261. constructor: PerspectiveCamera,
  9262. isPerspectiveCamera: true,
  9263. copy: function ( source ) {
  9264. Camera.prototype.copy.call( this, source );
  9265. this.fov = source.fov;
  9266. this.zoom = source.zoom;
  9267. this.near = source.near;
  9268. this.far = source.far;
  9269. this.focus = source.focus;
  9270. this.aspect = source.aspect;
  9271. this.view = source.view === null ? null : Object.assign( {}, source.view );
  9272. this.filmGauge = source.filmGauge;
  9273. this.filmOffset = source.filmOffset;
  9274. return this;
  9275. },
  9276. /**
  9277. * Sets the FOV by focal length in respect to the current .filmGauge.
  9278. *
  9279. * The default film gauge is 35, so that the focal length can be specified for
  9280. * a 35mm (full frame) camera.
  9281. *
  9282. * Values for focal length and film gauge must have the same unit.
  9283. */
  9284. setFocalLength: function ( focalLength ) {
  9285. // see http://www.bobatkins.com/photography/technical/field_of_view.html
  9286. var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;
  9287. this.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );
  9288. this.updateProjectionMatrix();
  9289. },
  9290. /**
  9291. * Calculates the focal length from the current .fov and .filmGauge.
  9292. */
  9293. getFocalLength: function () {
  9294. var vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );
  9295. return 0.5 * this.getFilmHeight() / vExtentSlope;
  9296. },
  9297. getEffectiveFOV: function () {
  9298. return _Math.RAD2DEG * 2 * Math.atan(
  9299. Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );
  9300. },
  9301. getFilmWidth: function () {
  9302. // film not completely covered in portrait format (aspect < 1)
  9303. return this.filmGauge * Math.min( this.aspect, 1 );
  9304. },
  9305. getFilmHeight: function () {
  9306. // film not completely covered in landscape format (aspect > 1)
  9307. return this.filmGauge / Math.max( this.aspect, 1 );
  9308. },
  9309. /**
  9310. * Sets an offset in a larger frustum. This is useful for multi-window or
  9311. * multi-monitor/multi-machine setups.
  9312. *
  9313. * For example, if you have 3x2 monitors and each monitor is 1920x1080 and
  9314. * the monitors are in grid like this
  9315. *
  9316. * +---+---+---+
  9317. * | A | B | C |
  9318. * +---+---+---+
  9319. * | D | E | F |
  9320. * +---+---+---+
  9321. *
  9322. * then for each monitor you would call it like this
  9323. *
  9324. * var w = 1920;
  9325. * var h = 1080;
  9326. * var fullWidth = w * 3;
  9327. * var fullHeight = h * 2;
  9328. *
  9329. * --A--
  9330. * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
  9331. * --B--
  9332. * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
  9333. * --C--
  9334. * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
  9335. * --D--
  9336. * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
  9337. * --E--
  9338. * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
  9339. * --F--
  9340. * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
  9341. *
  9342. * Note there is no reason monitors have to be the same size or in a grid.
  9343. */
  9344. setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {
  9345. this.aspect = fullWidth / fullHeight;
  9346. this.view = {
  9347. fullWidth: fullWidth,
  9348. fullHeight: fullHeight,
  9349. offsetX: x,
  9350. offsetY: y,
  9351. width: width,
  9352. height: height
  9353. };
  9354. this.updateProjectionMatrix();
  9355. },
  9356. clearViewOffset: function() {
  9357. this.view = null;
  9358. this.updateProjectionMatrix();
  9359. },
  9360. updateProjectionMatrix: function () {
  9361. var near = this.near,
  9362. top = near * Math.tan(
  9363. _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,
  9364. height = 2 * top,
  9365. width = this.aspect * height,
  9366. left = - 0.5 * width,
  9367. view = this.view;
  9368. if ( view !== null ) {
  9369. var fullWidth = view.fullWidth,
  9370. fullHeight = view.fullHeight;
  9371. left += view.offsetX * width / fullWidth;
  9372. top -= view.offsetY * height / fullHeight;
  9373. width *= view.width / fullWidth;
  9374. height *= view.height / fullHeight;
  9375. }
  9376. var skew = this.filmOffset;
  9377. if ( skew !== 0 ) left += near * skew / this.getFilmWidth();
  9378. this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );
  9379. },
  9380. toJSON: function ( meta ) {
  9381. var data = Object3D.prototype.toJSON.call( this, meta );
  9382. data.object.fov = this.fov;
  9383. data.object.zoom = this.zoom;
  9384. data.object.near = this.near;
  9385. data.object.far = this.far;
  9386. data.object.focus = this.focus;
  9387. data.object.aspect = this.aspect;
  9388. if ( this.view !== null ) data.object.view = Object.assign( {}, this.view );
  9389. data.object.filmGauge = this.filmGauge;
  9390. data.object.filmOffset = this.filmOffset;
  9391. return data;
  9392. }
  9393. } );
  9394. /**
  9395. * @author alteredq / http://alteredqualia.com/
  9396. * @author arose / http://github.com/arose
  9397. */
  9398. function OrthographicCamera( left, right, top, bottom, near, far ) {
  9399. Camera.call( this );
  9400. this.type = 'OrthographicCamera';
  9401. this.zoom = 1;
  9402. this.view = null;
  9403. this.left = left;
  9404. this.right = right;
  9405. this.top = top;
  9406. this.bottom = bottom;
  9407. this.near = ( near !== undefined ) ? near : 0.1;
  9408. this.far = ( far !== undefined ) ? far : 2000;
  9409. this.updateProjectionMatrix();
  9410. }
  9411. OrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {
  9412. constructor: OrthographicCamera,
  9413. isOrthographicCamera: true,
  9414. copy: function ( source ) {
  9415. Camera.prototype.copy.call( this, source );
  9416. this.left = source.left;
  9417. this.right = source.right;
  9418. this.top = source.top;
  9419. this.bottom = source.bottom;
  9420. this.near = source.near;
  9421. this.far = source.far;
  9422. this.zoom = source.zoom;
  9423. this.view = source.view === null ? null : Object.assign( {}, source.view );
  9424. return this;
  9425. },
  9426. setViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {
  9427. this.view = {
  9428. fullWidth: fullWidth,
  9429. fullHeight: fullHeight,
  9430. offsetX: x,
  9431. offsetY: y,
  9432. width: width,
  9433. height: height
  9434. };
  9435. this.updateProjectionMatrix();
  9436. },
  9437. clearViewOffset: function() {
  9438. this.view = null;
  9439. this.updateProjectionMatrix();
  9440. },
  9441. updateProjectionMatrix: function () {
  9442. var dx = ( this.right - this.left ) / ( 2 * this.zoom );
  9443. var dy = ( this.top - this.bottom ) / ( 2 * this.zoom );
  9444. var cx = ( this.right + this.left ) / 2;
  9445. var cy = ( this.top + this.bottom ) / 2;
  9446. var left = cx - dx;
  9447. var right = cx + dx;
  9448. var top = cy + dy;
  9449. var bottom = cy - dy;
  9450. if ( this.view !== null ) {
  9451. var zoomW = this.zoom / ( this.view.width / this.view.fullWidth );
  9452. var zoomH = this.zoom / ( this.view.height / this.view.fullHeight );
  9453. var scaleW = ( this.right - this.left ) / this.view.width;
  9454. var scaleH = ( this.top - this.bottom ) / this.view.height;
  9455. left += scaleW * ( this.view.offsetX / zoomW );
  9456. right = left + scaleW * ( this.view.width / zoomW );
  9457. top -= scaleH * ( this.view.offsetY / zoomH );
  9458. bottom = top - scaleH * ( this.view.height / zoomH );
  9459. }
  9460. this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );
  9461. },
  9462. toJSON: function ( meta ) {
  9463. var data = Object3D.prototype.toJSON.call( this, meta );
  9464. data.object.zoom = this.zoom;
  9465. data.object.left = this.left;
  9466. data.object.right = this.right;
  9467. data.object.top = this.top;
  9468. data.object.bottom = this.bottom;
  9469. data.object.near = this.near;
  9470. data.object.far = this.far;
  9471. if ( this.view !== null ) data.object.view = Object.assign( {}, this.view );
  9472. return data;
  9473. }
  9474. } );
  9475. /**
  9476. * @author mrdoob / http://mrdoob.com/
  9477. */
  9478. function WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {
  9479. var mode;
  9480. function setMode( value ) {
  9481. mode = value;
  9482. }
  9483. var type, size;
  9484. function setIndex( index ) {
  9485. if ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {
  9486. type = gl.UNSIGNED_INT;
  9487. size = 4;
  9488. } else if ( index.array instanceof Uint16Array ) {
  9489. type = gl.UNSIGNED_SHORT;
  9490. size = 2;
  9491. } else {
  9492. type = gl.UNSIGNED_BYTE;
  9493. size = 1;
  9494. }
  9495. }
  9496. function render( start, count ) {
  9497. gl.drawElements( mode, count, type, start * size );
  9498. infoRender.calls ++;
  9499. infoRender.vertices += count;
  9500. if ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;
  9501. }
  9502. function renderInstances( geometry, start, count ) {
  9503. var extension = extensions.get( 'ANGLE_instanced_arrays' );
  9504. if ( extension === null ) {
  9505. console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
  9506. return;
  9507. }
  9508. extension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );
  9509. infoRender.calls ++;
  9510. infoRender.vertices += count * geometry.maxInstancedCount;
  9511. if ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;
  9512. }
  9513. return {
  9514. setMode: setMode,
  9515. setIndex: setIndex,
  9516. render: render,
  9517. renderInstances: renderInstances
  9518. };
  9519. }
  9520. /**
  9521. * @author mrdoob / http://mrdoob.com/
  9522. */
  9523. function WebGLBufferRenderer( gl, extensions, infoRender ) {
  9524. var mode;
  9525. function setMode( value ) {
  9526. mode = value;
  9527. }
  9528. function render( start, count ) {
  9529. gl.drawArrays( mode, start, count );
  9530. infoRender.calls ++;
  9531. infoRender.vertices += count;
  9532. if ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;
  9533. }
  9534. function renderInstances( geometry ) {
  9535. var extension = extensions.get( 'ANGLE_instanced_arrays' );
  9536. if ( extension === null ) {
  9537. console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
  9538. return;
  9539. }
  9540. var position = geometry.attributes.position;
  9541. var count = 0;
  9542. if ( position.isInterleavedBufferAttribute ) {
  9543. count = position.data.count;
  9544. extension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );
  9545. } else {
  9546. count = position.count;
  9547. extension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );
  9548. }
  9549. infoRender.calls ++;
  9550. infoRender.vertices += count * geometry.maxInstancedCount;
  9551. if ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;
  9552. }
  9553. return {
  9554. setMode: setMode,
  9555. render: render,
  9556. renderInstances: renderInstances
  9557. };
  9558. }
  9559. /**
  9560. * @author mrdoob / http://mrdoob.com/
  9561. */
  9562. function WebGLLights() {
  9563. var lights = {};
  9564. return {
  9565. get: function ( light ) {
  9566. if ( lights[ light.id ] !== undefined ) {
  9567. return lights[ light.id ];
  9568. }
  9569. var uniforms;
  9570. switch ( light.type ) {
  9571. case 'DirectionalLight':
  9572. uniforms = {
  9573. direction: new Vector3(),
  9574. color: new Color(),
  9575. shadow: false,
  9576. shadowBias: 0,
  9577. shadowRadius: 1,
  9578. shadowMapSize: new Vector2()
  9579. };
  9580. break;
  9581. case 'SpotLight':
  9582. uniforms = {
  9583. position: new Vector3(),
  9584. direction: new Vector3(),
  9585. color: new Color(),
  9586. distance: 0,
  9587. coneCos: 0,
  9588. penumbraCos: 0,
  9589. decay: 0,
  9590. shadow: false,
  9591. shadowBias: 0,
  9592. shadowRadius: 1,
  9593. shadowMapSize: new Vector2()
  9594. };
  9595. break;
  9596. case 'PointLight':
  9597. uniforms = {
  9598. position: new Vector3(),
  9599. color: new Color(),
  9600. distance: 0,
  9601. decay: 0,
  9602. shadow: false,
  9603. shadowBias: 0,
  9604. shadowRadius: 1,
  9605. shadowMapSize: new Vector2()
  9606. };
  9607. break;
  9608. case 'HemisphereLight':
  9609. uniforms = {
  9610. direction: new Vector3(),
  9611. skyColor: new Color(),
  9612. groundColor: new Color()
  9613. };
  9614. break;
  9615. case 'RectAreaLight':
  9616. uniforms = {
  9617. color: new Color(),
  9618. position: new Vector3(),
  9619. halfWidth: new Vector3(),
  9620. halfHeight: new Vector3()
  9621. // TODO (abelnation): set RectAreaLight shadow uniforms
  9622. };
  9623. break;
  9624. }
  9625. lights[ light.id ] = uniforms;
  9626. return uniforms;
  9627. }
  9628. };
  9629. }
  9630. /**
  9631. * @author mrdoob / http://mrdoob.com/
  9632. */
  9633. function addLineNumbers( string ) {
  9634. var lines = string.split( '\n' );
  9635. for ( var i = 0; i < lines.length; i ++ ) {
  9636. lines[ i ] = ( i + 1 ) + ': ' + lines[ i ];
  9637. }
  9638. return lines.join( '\n' );
  9639. }
  9640. function WebGLShader( gl, type, string ) {
  9641. var shader = gl.createShader( type );
  9642. gl.shaderSource( shader, string );
  9643. gl.compileShader( shader );
  9644. if ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {
  9645. console.error( 'THREE.WebGLShader: Shader couldn\'t compile.' );
  9646. }
  9647. if ( gl.getShaderInfoLog( shader ) !== '' ) {
  9648. console.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );
  9649. }
  9650. // --enable-privileged-webgl-extension
  9651. // console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );
  9652. return shader;
  9653. }
  9654. /**
  9655. * @author mrdoob / http://mrdoob.com/
  9656. */
  9657. var programIdCount = 0;
  9658. function getEncodingComponents( encoding ) {
  9659. switch ( encoding ) {
  9660. case LinearEncoding:
  9661. return [ 'Linear','( value )' ];
  9662. case sRGBEncoding:
  9663. return [ 'sRGB','( value )' ];
  9664. case RGBEEncoding:
  9665. return [ 'RGBE','( value )' ];
  9666. case RGBM7Encoding:
  9667. return [ 'RGBM','( value, 7.0 )' ];
  9668. case RGBM16Encoding:
  9669. return [ 'RGBM','( value, 16.0 )' ];
  9670. case RGBDEncoding:
  9671. return [ 'RGBD','( value, 256.0 )' ];
  9672. case GammaEncoding:
  9673. return [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];
  9674. default:
  9675. throw new Error( 'unsupported encoding: ' + encoding );
  9676. }
  9677. }
  9678. function getTexelDecodingFunction( functionName, encoding ) {
  9679. var components = getEncodingComponents( encoding );
  9680. return "vec4 " + functionName + "( vec4 value ) { return " + components[ 0 ] + "ToLinear" + components[ 1 ] + "; }";
  9681. }
  9682. function getTexelEncodingFunction( functionName, encoding ) {
  9683. var components = getEncodingComponents( encoding );
  9684. return "vec4 " + functionName + "( vec4 value ) { return LinearTo" + components[ 0 ] + components[ 1 ] + "; }";
  9685. }
  9686. function getToneMappingFunction( functionName, toneMapping ) {
  9687. var toneMappingName;
  9688. switch ( toneMapping ) {
  9689. case LinearToneMapping:
  9690. toneMappingName = "Linear";
  9691. break;
  9692. case ReinhardToneMapping:
  9693. toneMappingName = "Reinhard";
  9694. break;
  9695. case Uncharted2ToneMapping:
  9696. toneMappingName = "Uncharted2";
  9697. break;
  9698. case CineonToneMapping:
  9699. toneMappingName = "OptimizedCineon";
  9700. break;
  9701. default:
  9702. throw new Error( 'unsupported toneMapping: ' + toneMapping );
  9703. }
  9704. return "vec3 " + functionName + "( vec3 color ) { return " + toneMappingName + "ToneMapping( color ); }";
  9705. }
  9706. function generateExtensions( extensions, parameters, rendererExtensions ) {
  9707. extensions = extensions || {};
  9708. var chunks = [
  9709. ( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',
  9710. ( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',
  9711. ( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',
  9712. ( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''
  9713. ];
  9714. return chunks.filter( filterEmptyLine ).join( '\n' );
  9715. }
  9716. function generateDefines( defines ) {
  9717. var chunks = [];
  9718. for ( var name in defines ) {
  9719. var value = defines[ name ];
  9720. if ( value === false ) continue;
  9721. chunks.push( '#define ' + name + ' ' + value );
  9722. }
  9723. return chunks.join( '\n' );
  9724. }
  9725. function fetchAttributeLocations( gl, program, identifiers ) {
  9726. var attributes = {};
  9727. var n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );
  9728. for ( var i = 0; i < n; i ++ ) {
  9729. var info = gl.getActiveAttrib( program, i );
  9730. var name = info.name;
  9731. // console.log("THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:", name, i );
  9732. attributes[ name ] = gl.getAttribLocation( program, name );
  9733. }
  9734. return attributes;
  9735. }
  9736. function filterEmptyLine( string ) {
  9737. return string !== '';
  9738. }
  9739. function replaceLightNums( string, parameters ) {
  9740. return string
  9741. .replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )
  9742. .replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )
  9743. .replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )
  9744. .replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )
  9745. .replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );
  9746. }
  9747. function parseIncludes( string ) {
  9748. var pattern = /#include +<([\w\d.]+)>/g;
  9749. function replace( match, include ) {
  9750. var replace = ShaderChunk[ include ];
  9751. if ( replace === undefined ) {
  9752. throw new Error( 'Can not resolve #include <' + include + '>' );
  9753. }
  9754. return parseIncludes( replace );
  9755. }
  9756. return string.replace( pattern, replace );
  9757. }
  9758. function unrollLoops( string ) {
  9759. var pattern = /for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g;
  9760. function replace( match, start, end, snippet ) {
  9761. var unroll = '';
  9762. for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {
  9763. unroll += snippet.replace( /\[ i \]/g, '[ ' + i + ' ]' );
  9764. }
  9765. return unroll;
  9766. }
  9767. return string.replace( pattern, replace );
  9768. }
  9769. function WebGLProgram( renderer, code, material, parameters ) {
  9770. var gl = renderer.context;
  9771. var extensions = material.extensions;
  9772. var defines = material.defines;
  9773. var vertexShader = material.__webglShader.vertexShader;
  9774. var fragmentShader = material.__webglShader.fragmentShader;
  9775. var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
  9776. if ( parameters.shadowMapType === PCFShadowMap ) {
  9777. shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
  9778. } else if ( parameters.shadowMapType === PCFSoftShadowMap ) {
  9779. shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
  9780. }
  9781. var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
  9782. var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
  9783. var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
  9784. if ( parameters.envMap ) {
  9785. switch ( material.envMap.mapping ) {
  9786. case CubeReflectionMapping:
  9787. case CubeRefractionMapping:
  9788. envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
  9789. break;
  9790. case CubeUVReflectionMapping:
  9791. case CubeUVRefractionMapping:
  9792. envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
  9793. break;
  9794. case EquirectangularReflectionMapping:
  9795. case EquirectangularRefractionMapping:
  9796. envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
  9797. break;
  9798. case SphericalReflectionMapping:
  9799. envMapTypeDefine = 'ENVMAP_TYPE_SPHERE';
  9800. break;
  9801. }
  9802. switch ( material.envMap.mapping ) {
  9803. case CubeRefractionMapping:
  9804. case EquirectangularRefractionMapping:
  9805. envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
  9806. break;
  9807. }
  9808. switch ( material.combine ) {
  9809. case MultiplyOperation:
  9810. envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
  9811. break;
  9812. case MixOperation:
  9813. envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
  9814. break;
  9815. case AddOperation:
  9816. envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
  9817. break;
  9818. }
  9819. }
  9820. var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;
  9821. // console.log( 'building new program ' );
  9822. //
  9823. var customExtensions = generateExtensions( extensions, parameters, renderer.extensions );
  9824. var customDefines = generateDefines( defines );
  9825. //
  9826. var program = gl.createProgram();
  9827. var prefixVertex, prefixFragment;
  9828. if ( material.isRawShaderMaterial ) {
  9829. prefixVertex = [
  9830. customDefines,
  9831. '\n'
  9832. ].filter( filterEmptyLine ).join( '\n' );
  9833. prefixFragment = [
  9834. customExtensions,
  9835. customDefines,
  9836. '\n'
  9837. ].filter( filterEmptyLine ).join( '\n' );
  9838. } else {
  9839. prefixVertex = [
  9840. 'precision ' + parameters.precision + ' float;',
  9841. 'precision ' + parameters.precision + ' int;',
  9842. '#define SHADER_NAME ' + material.__webglShader.name,
  9843. customDefines,
  9844. parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
  9845. '#define GAMMA_FACTOR ' + gammaFactorDefine,
  9846. '#define MAX_BONES ' + parameters.maxBones,
  9847. ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
  9848. ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',
  9849. parameters.map ? '#define USE_MAP' : '',
  9850. parameters.envMap ? '#define USE_ENVMAP' : '',
  9851. parameters.envMap ? '#define ' + envMapModeDefine : '',
  9852. parameters.lightMap ? '#define USE_LIGHTMAP' : '',
  9853. parameters.aoMap ? '#define USE_AOMAP' : '',
  9854. parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
  9855. parameters.bumpMap ? '#define USE_BUMPMAP' : '',
  9856. parameters.normalMap ? '#define USE_NORMALMAP' : '',
  9857. parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',
  9858. parameters.specularMap ? '#define USE_SPECULARMAP' : '',
  9859. parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
  9860. parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
  9861. parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
  9862. parameters.vertexColors ? '#define USE_COLOR' : '',
  9863. parameters.flatShading ? '#define FLAT_SHADED' : '',
  9864. parameters.skinning ? '#define USE_SKINNING' : '',
  9865. parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
  9866. parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
  9867. parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',
  9868. parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
  9869. parameters.flipSided ? '#define FLIP_SIDED' : '',
  9870. '#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,
  9871. parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
  9872. parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
  9873. parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
  9874. parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
  9875. parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
  9876. 'uniform mat4 modelMatrix;',
  9877. 'uniform mat4 modelViewMatrix;',
  9878. 'uniform mat4 projectionMatrix;',
  9879. 'uniform mat4 viewMatrix;',
  9880. 'uniform mat3 normalMatrix;',
  9881. 'uniform vec3 cameraPosition;',
  9882. 'attribute vec3 position;',
  9883. 'attribute vec3 normal;',
  9884. 'attribute vec2 uv;',
  9885. '#ifdef USE_COLOR',
  9886. ' attribute vec3 color;',
  9887. '#endif',
  9888. '#ifdef USE_MORPHTARGETS',
  9889. ' attribute vec3 morphTarget0;',
  9890. ' attribute vec3 morphTarget1;',
  9891. ' attribute vec3 morphTarget2;',
  9892. ' attribute vec3 morphTarget3;',
  9893. ' #ifdef USE_MORPHNORMALS',
  9894. ' attribute vec3 morphNormal0;',
  9895. ' attribute vec3 morphNormal1;',
  9896. ' attribute vec3 morphNormal2;',
  9897. ' attribute vec3 morphNormal3;',
  9898. ' #else',
  9899. ' attribute vec3 morphTarget4;',
  9900. ' attribute vec3 morphTarget5;',
  9901. ' attribute vec3 morphTarget6;',
  9902. ' attribute vec3 morphTarget7;',
  9903. ' #endif',
  9904. '#endif',
  9905. '#ifdef USE_SKINNING',
  9906. ' attribute vec4 skinIndex;',
  9907. ' attribute vec4 skinWeight;',
  9908. '#endif',
  9909. '\n'
  9910. ].filter( filterEmptyLine ).join( '\n' );
  9911. prefixFragment = [
  9912. customExtensions,
  9913. 'precision ' + parameters.precision + ' float;',
  9914. 'precision ' + parameters.precision + ' int;',
  9915. '#define SHADER_NAME ' + material.__webglShader.name,
  9916. customDefines,
  9917. parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',
  9918. '#define GAMMA_FACTOR ' + gammaFactorDefine,
  9919. ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
  9920. ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',
  9921. parameters.map ? '#define USE_MAP' : '',
  9922. parameters.envMap ? '#define USE_ENVMAP' : '',
  9923. parameters.envMap ? '#define ' + envMapTypeDefine : '',
  9924. parameters.envMap ? '#define ' + envMapModeDefine : '',
  9925. parameters.envMap ? '#define ' + envMapBlendingDefine : '',
  9926. parameters.lightMap ? '#define USE_LIGHTMAP' : '',
  9927. parameters.aoMap ? '#define USE_AOMAP' : '',
  9928. parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
  9929. parameters.bumpMap ? '#define USE_BUMPMAP' : '',
  9930. parameters.normalMap ? '#define USE_NORMALMAP' : '',
  9931. parameters.specularMap ? '#define USE_SPECULARMAP' : '',
  9932. parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
  9933. parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
  9934. parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
  9935. parameters.vertexColors ? '#define USE_COLOR' : '',
  9936. parameters.gradientMap ? '#define USE_GRADIENTMAP' : '',
  9937. parameters.flatShading ? '#define FLAT_SHADED' : '',
  9938. parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
  9939. parameters.flipSided ? '#define FLIP_SIDED' : '',
  9940. '#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,
  9941. '#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),
  9942. parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
  9943. parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
  9944. parameters.premultipliedAlpha ? "#define PREMULTIPLIED_ALPHA" : '',
  9945. parameters.physicallyCorrectLights ? "#define PHYSICALLY_CORRECT_LIGHTS" : '',
  9946. parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
  9947. parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
  9948. parameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',
  9949. 'uniform mat4 viewMatrix;',
  9950. 'uniform vec3 cameraPosition;',
  9951. ( parameters.toneMapping !== NoToneMapping ) ? "#define TONE_MAPPING" : '',
  9952. ( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below
  9953. ( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( "toneMapping", parameters.toneMapping ) : '',
  9954. ( 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
  9955. parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
  9956. parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
  9957. parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
  9958. parameters.outputEncoding ? getTexelEncodingFunction( "linearToOutputTexel", parameters.outputEncoding ) : '',
  9959. parameters.depthPacking ? "#define DEPTH_PACKING " + material.depthPacking : '',
  9960. '\n'
  9961. ].filter( filterEmptyLine ).join( '\n' );
  9962. }
  9963. vertexShader = parseIncludes( vertexShader, parameters );
  9964. vertexShader = replaceLightNums( vertexShader, parameters );
  9965. fragmentShader = parseIncludes( fragmentShader, parameters );
  9966. fragmentShader = replaceLightNums( fragmentShader, parameters );
  9967. if ( ! material.isShaderMaterial ) {
  9968. vertexShader = unrollLoops( vertexShader );
  9969. fragmentShader = unrollLoops( fragmentShader );
  9970. }
  9971. var vertexGlsl = prefixVertex + vertexShader;
  9972. var fragmentGlsl = prefixFragment + fragmentShader;
  9973. // console.log( '*VERTEX*', vertexGlsl );
  9974. // console.log( '*FRAGMENT*', fragmentGlsl );
  9975. var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );
  9976. var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );
  9977. gl.attachShader( program, glVertexShader );
  9978. gl.attachShader( program, glFragmentShader );
  9979. // Force a particular attribute to index 0.
  9980. if ( material.index0AttributeName !== undefined ) {
  9981. gl.bindAttribLocation( program, 0, material.index0AttributeName );
  9982. } else if ( parameters.morphTargets === true ) {
  9983. // programs with morphTargets displace position out of attribute 0
  9984. gl.bindAttribLocation( program, 0, 'position' );
  9985. }
  9986. gl.linkProgram( program );
  9987. var programLog = gl.getProgramInfoLog( program );
  9988. var vertexLog = gl.getShaderInfoLog( glVertexShader );
  9989. var fragmentLog = gl.getShaderInfoLog( glFragmentShader );
  9990. var runnable = true;
  9991. var haveDiagnostics = true;
  9992. // console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );
  9993. // console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );
  9994. if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
  9995. runnable = false;
  9996. console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );
  9997. } else if ( programLog !== '' ) {
  9998. console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
  9999. } else if ( vertexLog === '' || fragmentLog === '' ) {
  10000. haveDiagnostics = false;
  10001. }
  10002. if ( haveDiagnostics ) {
  10003. this.diagnostics = {
  10004. runnable: runnable,
  10005. material: material,
  10006. programLog: programLog,
  10007. vertexShader: {
  10008. log: vertexLog,
  10009. prefix: prefixVertex
  10010. },
  10011. fragmentShader: {
  10012. log: fragmentLog,
  10013. prefix: prefixFragment
  10014. }
  10015. };
  10016. }
  10017. // clean up
  10018. gl.deleteShader( glVertexShader );
  10019. gl.deleteShader( glFragmentShader );
  10020. // set up caching for uniform locations
  10021. var cachedUniforms;
  10022. this.getUniforms = function() {
  10023. if ( cachedUniforms === undefined ) {
  10024. cachedUniforms =
  10025. new WebGLUniforms( gl, program, renderer );
  10026. }
  10027. return cachedUniforms;
  10028. };
  10029. // set up caching for attribute locations
  10030. var cachedAttributes;
  10031. this.getAttributes = function() {
  10032. if ( cachedAttributes === undefined ) {
  10033. cachedAttributes = fetchAttributeLocations( gl, program );
  10034. }
  10035. return cachedAttributes;
  10036. };
  10037. // free resource
  10038. this.destroy = function() {
  10039. gl.deleteProgram( program );
  10040. this.program = undefined;
  10041. };
  10042. // DEPRECATED
  10043. Object.defineProperties( this, {
  10044. uniforms: {
  10045. get: function() {
  10046. console.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );
  10047. return this.getUniforms();
  10048. }
  10049. },
  10050. attributes: {
  10051. get: function() {
  10052. console.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );
  10053. return this.getAttributes();
  10054. }
  10055. }
  10056. } );
  10057. //
  10058. this.id = programIdCount ++;
  10059. this.code = code;
  10060. this.usedTimes = 1;
  10061. this.program = program;
  10062. this.vertexShader = glVertexShader;
  10063. this.fragmentShader = glFragmentShader;
  10064. return this;
  10065. }
  10066. /**
  10067. * @author mrdoob / http://mrdoob.com/
  10068. */
  10069. function WebGLPrograms( renderer, capabilities ) {
  10070. var programs = [];
  10071. var shaderIDs = {
  10072. MeshDepthMaterial: 'depth',
  10073. MeshNormalMaterial: 'normal',
  10074. MeshBasicMaterial: 'basic',
  10075. MeshLambertMaterial: 'lambert',
  10076. MeshPhongMaterial: 'phong',
  10077. MeshToonMaterial: 'phong',
  10078. MeshStandardMaterial: 'physical',
  10079. MeshPhysicalMaterial: 'physical',
  10080. LineBasicMaterial: 'basic',
  10081. LineDashedMaterial: 'dashed',
  10082. PointsMaterial: 'points'
  10083. };
  10084. var parameterNames = [
  10085. "precision", "supportsVertexTextures", "map", "mapEncoding", "envMap", "envMapMode", "envMapEncoding",
  10086. "lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "displacementMap", "specularMap",
  10087. "roughnessMap", "metalnessMap", "gradientMap",
  10088. "alphaMap", "combine", "vertexColors", "fog", "useFog", "fogExp",
  10089. "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
  10090. "maxBones", "useVertexTexture", "morphTargets", "morphNormals",
  10091. "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha",
  10092. "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights",
  10093. "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights',
  10094. "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking"
  10095. ];
  10096. function allocateBones( object ) {
  10097. if ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {
  10098. return 1024;
  10099. } else {
  10100. // default for when object is not specified
  10101. // ( for example when prebuilding shader to be used with multiple objects )
  10102. //
  10103. // - leave some extra space for other uniforms
  10104. // - limit here is ANGLE's 254 max uniform vectors
  10105. // (up to 54 should be safe)
  10106. var nVertexUniforms = capabilities.maxVertexUniforms;
  10107. var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
  10108. var maxBones = nVertexMatrices;
  10109. if ( object !== undefined && (object && object.isSkinnedMesh) ) {
  10110. maxBones = Math.min( object.skeleton.bones.length, maxBones );
  10111. if ( maxBones < object.skeleton.bones.length ) {
  10112. console.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );
  10113. }
  10114. }
  10115. return maxBones;
  10116. }
  10117. }
  10118. function getTextureEncodingFromMap( map, gammaOverrideLinear ) {
  10119. var encoding;
  10120. if ( ! map ) {
  10121. encoding = LinearEncoding;
  10122. } else if ( map.isTexture ) {
  10123. encoding = map.encoding;
  10124. } else if ( map.isWebGLRenderTarget ) {
  10125. console.warn( "THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead." );
  10126. encoding = map.texture.encoding;
  10127. }
  10128. // add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.
  10129. if ( encoding === LinearEncoding && gammaOverrideLinear ) {
  10130. encoding = GammaEncoding;
  10131. }
  10132. return encoding;
  10133. }
  10134. this.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {
  10135. var shaderID = shaderIDs[ material.type ];
  10136. // heuristics to create shader parameters according to lights in the scene
  10137. // (not to blow over maxLights budget)
  10138. var maxBones = allocateBones( object );
  10139. var precision = renderer.getPrecision();
  10140. if ( material.precision !== null ) {
  10141. precision = capabilities.getMaxPrecision( material.precision );
  10142. if ( precision !== material.precision ) {
  10143. console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );
  10144. }
  10145. }
  10146. var currentRenderTarget = renderer.getCurrentRenderTarget();
  10147. var parameters = {
  10148. shaderID: shaderID,
  10149. precision: precision,
  10150. supportsVertexTextures: capabilities.vertexTextures,
  10151. outputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),
  10152. map: !! material.map,
  10153. mapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),
  10154. envMap: !! material.envMap,
  10155. envMapMode: material.envMap && material.envMap.mapping,
  10156. envMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),
  10157. envMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),
  10158. lightMap: !! material.lightMap,
  10159. aoMap: !! material.aoMap,
  10160. emissiveMap: !! material.emissiveMap,
  10161. emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),
  10162. bumpMap: !! material.bumpMap,
  10163. normalMap: !! material.normalMap,
  10164. displacementMap: !! material.displacementMap,
  10165. roughnessMap: !! material.roughnessMap,
  10166. metalnessMap: !! material.metalnessMap,
  10167. specularMap: !! material.specularMap,
  10168. alphaMap: !! material.alphaMap,
  10169. gradientMap: !! material.gradientMap,
  10170. combine: material.combine,
  10171. vertexColors: material.vertexColors,
  10172. fog: !! fog,
  10173. useFog: material.fog,
  10174. fogExp: (fog && fog.isFogExp2),
  10175. flatShading: material.shading === FlatShading,
  10176. sizeAttenuation: material.sizeAttenuation,
  10177. logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,
  10178. skinning: material.skinning,
  10179. maxBones: maxBones,
  10180. useVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,
  10181. morphTargets: material.morphTargets,
  10182. morphNormals: material.morphNormals,
  10183. maxMorphTargets: renderer.maxMorphTargets,
  10184. maxMorphNormals: renderer.maxMorphNormals,
  10185. numDirLights: lights.directional.length,
  10186. numPointLights: lights.point.length,
  10187. numSpotLights: lights.spot.length,
  10188. numRectAreaLights: lights.rectArea.length,
  10189. numHemiLights: lights.hemi.length,
  10190. numClippingPlanes: nClipPlanes,
  10191. numClipIntersection: nClipIntersection,
  10192. shadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,
  10193. shadowMapType: renderer.shadowMap.type,
  10194. toneMapping: renderer.toneMapping,
  10195. physicallyCorrectLights: renderer.physicallyCorrectLights,
  10196. premultipliedAlpha: material.premultipliedAlpha,
  10197. alphaTest: material.alphaTest,
  10198. doubleSided: material.side === DoubleSide,
  10199. flipSided: material.side === BackSide,
  10200. depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false
  10201. };
  10202. return parameters;
  10203. };
  10204. this.getProgramCode = function ( material, parameters ) {
  10205. var array = [];
  10206. if ( parameters.shaderID ) {
  10207. array.push( parameters.shaderID );
  10208. } else {
  10209. array.push( material.fragmentShader );
  10210. array.push( material.vertexShader );
  10211. }
  10212. if ( material.defines !== undefined ) {
  10213. for ( var name in material.defines ) {
  10214. array.push( name );
  10215. array.push( material.defines[ name ] );
  10216. }
  10217. }
  10218. for ( var i = 0; i < parameterNames.length; i ++ ) {
  10219. array.push( parameters[ parameterNames[ i ] ] );
  10220. }
  10221. return array.join();
  10222. };
  10223. this.acquireProgram = function ( material, parameters, code ) {
  10224. var program;
  10225. // Check if code has been already compiled
  10226. for ( var p = 0, pl = programs.length; p < pl; p ++ ) {
  10227. var programInfo = programs[ p ];
  10228. if ( programInfo.code === code ) {
  10229. program = programInfo;
  10230. ++ program.usedTimes;
  10231. break;
  10232. }
  10233. }
  10234. if ( program === undefined ) {
  10235. program = new WebGLProgram( renderer, code, material, parameters );
  10236. programs.push( program );
  10237. }
  10238. return program;
  10239. };
  10240. this.releaseProgram = function( program ) {
  10241. if ( -- program.usedTimes === 0 ) {
  10242. // Remove from unordered set
  10243. var i = programs.indexOf( program );
  10244. programs[ i ] = programs[ programs.length - 1 ];
  10245. programs.pop();
  10246. // Free WebGL resources
  10247. program.destroy();
  10248. }
  10249. };
  10250. // Exposed for resource monitoring & error feedback via renderer.info:
  10251. this.programs = programs;
  10252. }
  10253. /**
  10254. * @author mrdoob / http://mrdoob.com/
  10255. */
  10256. function WebGLGeometries( gl, properties, info ) {
  10257. var geometries = {};
  10258. function onGeometryDispose( event ) {
  10259. var geometry = event.target;
  10260. var buffergeometry = geometries[ geometry.id ];
  10261. if ( buffergeometry.index !== null ) {
  10262. deleteAttribute( buffergeometry.index );
  10263. }
  10264. deleteAttributes( buffergeometry.attributes );
  10265. geometry.removeEventListener( 'dispose', onGeometryDispose );
  10266. delete geometries[ geometry.id ];
  10267. // TODO
  10268. var property = properties.get( geometry );
  10269. if ( property.wireframe ) {
  10270. deleteAttribute( property.wireframe );
  10271. }
  10272. properties.delete( geometry );
  10273. var bufferproperty = properties.get( buffergeometry );
  10274. if ( bufferproperty.wireframe ) {
  10275. deleteAttribute( bufferproperty.wireframe );
  10276. }
  10277. properties.delete( buffergeometry );
  10278. //
  10279. info.memory.geometries --;
  10280. }
  10281. function getAttributeBuffer( attribute ) {
  10282. if ( attribute.isInterleavedBufferAttribute ) {
  10283. return properties.get( attribute.data ).__webglBuffer;
  10284. }
  10285. return properties.get( attribute ).__webglBuffer;
  10286. }
  10287. function deleteAttribute( attribute ) {
  10288. var buffer = getAttributeBuffer( attribute );
  10289. if ( buffer !== undefined ) {
  10290. gl.deleteBuffer( buffer );
  10291. removeAttributeBuffer( attribute );
  10292. }
  10293. }
  10294. function deleteAttributes( attributes ) {
  10295. for ( var name in attributes ) {
  10296. deleteAttribute( attributes[ name ] );
  10297. }
  10298. }
  10299. function removeAttributeBuffer( attribute ) {
  10300. if ( attribute.isInterleavedBufferAttribute ) {
  10301. properties.delete( attribute.data );
  10302. } else {
  10303. properties.delete( attribute );
  10304. }
  10305. }
  10306. return {
  10307. get: function ( object ) {
  10308. var geometry = object.geometry;
  10309. if ( geometries[ geometry.id ] !== undefined ) {
  10310. return geometries[ geometry.id ];
  10311. }
  10312. geometry.addEventListener( 'dispose', onGeometryDispose );
  10313. var buffergeometry;
  10314. if ( geometry.isBufferGeometry ) {
  10315. buffergeometry = geometry;
  10316. } else if ( geometry.isGeometry ) {
  10317. if ( geometry._bufferGeometry === undefined ) {
  10318. geometry._bufferGeometry = new BufferGeometry().setFromObject( object );
  10319. }
  10320. buffergeometry = geometry._bufferGeometry;
  10321. }
  10322. geometries[ geometry.id ] = buffergeometry;
  10323. info.memory.geometries ++;
  10324. return buffergeometry;
  10325. }
  10326. };
  10327. }
  10328. /**
  10329. * @author mrdoob / http://mrdoob.com/
  10330. */
  10331. function WebGLObjects( gl, properties, info ) {
  10332. var geometries = new WebGLGeometries( gl, properties, info );
  10333. //
  10334. function update( object ) {
  10335. // TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.
  10336. var geometry = geometries.get( object );
  10337. if ( object.geometry.isGeometry ) {
  10338. geometry.updateFromObject( object );
  10339. }
  10340. var index = geometry.index;
  10341. var attributes = geometry.attributes;
  10342. if ( index !== null ) {
  10343. updateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );
  10344. }
  10345. for ( var name in attributes ) {
  10346. updateAttribute( attributes[ name ], gl.ARRAY_BUFFER );
  10347. }
  10348. // morph targets
  10349. var morphAttributes = geometry.morphAttributes;
  10350. for ( var name in morphAttributes ) {
  10351. var array = morphAttributes[ name ];
  10352. for ( var i = 0, l = array.length; i < l; i ++ ) {
  10353. updateAttribute( array[ i ], gl.ARRAY_BUFFER );
  10354. }
  10355. }
  10356. return geometry;
  10357. }
  10358. function updateAttribute( attribute, bufferType ) {
  10359. var data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;
  10360. var attributeProperties = properties.get( data );
  10361. if ( attributeProperties.__webglBuffer === undefined ) {
  10362. createBuffer( attributeProperties, data, bufferType );
  10363. } else if ( attributeProperties.version !== data.version ) {
  10364. updateBuffer( attributeProperties, data, bufferType );
  10365. }
  10366. }
  10367. function createBuffer( attributeProperties, data, bufferType ) {
  10368. attributeProperties.__webglBuffer = gl.createBuffer();
  10369. gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
  10370. var usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;
  10371. gl.bufferData( bufferType, data.array, usage );
  10372. var type = gl.FLOAT;
  10373. var array = data.array;
  10374. if ( array instanceof Float32Array ) {
  10375. type = gl.FLOAT;
  10376. } else if ( array instanceof Float64Array ) {
  10377. console.warn( "Unsupported data buffer format: Float64Array" );
  10378. } else if ( array instanceof Uint16Array ) {
  10379. type = gl.UNSIGNED_SHORT;
  10380. } else if ( array instanceof Int16Array ) {
  10381. type = gl.SHORT;
  10382. } else if ( array instanceof Uint32Array ) {
  10383. type = gl.UNSIGNED_INT;
  10384. } else if ( array instanceof Int32Array ) {
  10385. type = gl.INT;
  10386. } else if ( array instanceof Int8Array ) {
  10387. type = gl.BYTE;
  10388. } else if ( array instanceof Uint8Array ) {
  10389. type = gl.UNSIGNED_BYTE;
  10390. }
  10391. attributeProperties.bytesPerElement = array.BYTES_PER_ELEMENT;
  10392. attributeProperties.type = type;
  10393. attributeProperties.version = data.version;
  10394. data.onUploadCallback();
  10395. }
  10396. function updateBuffer( attributeProperties, data, bufferType ) {
  10397. gl.bindBuffer( bufferType, attributeProperties.__webglBuffer );
  10398. if ( data.dynamic === false ) {
  10399. gl.bufferData( bufferType, data.array, gl.STATIC_DRAW );
  10400. } else if ( data.updateRange.count === - 1 ) {
  10401. // Not using update ranges
  10402. gl.bufferSubData( bufferType, 0, data.array );
  10403. } else if ( data.updateRange.count === 0 ) {
  10404. 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.' );
  10405. } else {
  10406. gl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,
  10407. data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );
  10408. data.updateRange.count = 0; // reset range
  10409. }
  10410. attributeProperties.version = data.version;
  10411. }
  10412. function getAttributeBuffer( attribute ) {
  10413. if ( attribute.isInterleavedBufferAttribute ) {
  10414. return properties.get( attribute.data ).__webglBuffer;
  10415. }
  10416. return properties.get( attribute ).__webglBuffer;
  10417. }
  10418. function getAttributeProperties( attribute ) {
  10419. if ( attribute.isInterleavedBufferAttribute ) {
  10420. return properties.get( attribute.data );
  10421. }
  10422. return properties.get( attribute );
  10423. }
  10424. function getWireframeAttribute( geometry ) {
  10425. var property = properties.get( geometry );
  10426. if ( property.wireframe !== undefined ) {
  10427. return property.wireframe;
  10428. }
  10429. var indices = [];
  10430. var index = geometry.index;
  10431. var attributes = geometry.attributes;
  10432. // console.time( 'wireframe' );
  10433. if ( index !== null ) {
  10434. var array = index.array;
  10435. for ( var i = 0, l = array.length; i < l; i += 3 ) {
  10436. var a = array[ i + 0 ];
  10437. var b = array[ i + 1 ];
  10438. var c = array[ i + 2 ];
  10439. indices.push( a, b, b, c, c, a );
  10440. }
  10441. } else {
  10442. var array = attributes.position.array;
  10443. for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {
  10444. var a = i + 0;
  10445. var b = i + 1;
  10446. var c = i + 2;
  10447. indices.push( a, b, b, c, c, a );
  10448. }
  10449. }
  10450. // console.timeEnd( 'wireframe' );
  10451. var attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );
  10452. updateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );
  10453. property.wireframe = attribute;
  10454. return attribute;
  10455. }
  10456. return {
  10457. getAttributeBuffer: getAttributeBuffer,
  10458. getAttributeProperties: getAttributeProperties,
  10459. getWireframeAttribute: getWireframeAttribute,
  10460. update: update
  10461. };
  10462. }
  10463. /**
  10464. * @author mrdoob / http://mrdoob.com/
  10465. */
  10466. function WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {
  10467. var _infoMemory = info.memory;
  10468. var _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );
  10469. //
  10470. function clampToMaxSize( image, maxSize ) {
  10471. if ( image.width > maxSize || image.height > maxSize ) {
  10472. // Warning: Scaling through the canvas will only work with images that use
  10473. // premultiplied alpha.
  10474. var scale = maxSize / Math.max( image.width, image.height );
  10475. var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
  10476. canvas.width = Math.floor( image.width * scale );
  10477. canvas.height = Math.floor( image.height * scale );
  10478. var context = canvas.getContext( '2d' );
  10479. context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );
  10480. console.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
  10481. return canvas;
  10482. }
  10483. return image;
  10484. }
  10485. function isPowerOfTwo( image ) {
  10486. return _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );
  10487. }
  10488. function makePowerOfTwo( image ) {
  10489. if ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {
  10490. var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
  10491. canvas.width = _Math.nearestPowerOfTwo( image.width );
  10492. canvas.height = _Math.nearestPowerOfTwo( image.height );
  10493. var context = canvas.getContext( '2d' );
  10494. context.drawImage( image, 0, 0, canvas.width, canvas.height );
  10495. console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
  10496. return canvas;
  10497. }
  10498. return image;
  10499. }
  10500. function textureNeedsPowerOfTwo( texture ) {
  10501. return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||
  10502. ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );
  10503. }
  10504. // Fallback filters for non-power-of-2 textures
  10505. function filterFallback( f ) {
  10506. if ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {
  10507. return _gl.NEAREST;
  10508. }
  10509. return _gl.LINEAR;
  10510. }
  10511. //
  10512. function onTextureDispose( event ) {
  10513. var texture = event.target;
  10514. texture.removeEventListener( 'dispose', onTextureDispose );
  10515. deallocateTexture( texture );
  10516. _infoMemory.textures --;
  10517. }
  10518. function onRenderTargetDispose( event ) {
  10519. var renderTarget = event.target;
  10520. renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );
  10521. deallocateRenderTarget( renderTarget );
  10522. _infoMemory.textures --;
  10523. }
  10524. //
  10525. function deallocateTexture( texture ) {
  10526. var textureProperties = properties.get( texture );
  10527. if ( texture.image && textureProperties.__image__webglTextureCube ) {
  10528. // cube texture
  10529. _gl.deleteTexture( textureProperties.__image__webglTextureCube );
  10530. } else {
  10531. // 2D texture
  10532. if ( textureProperties.__webglInit === undefined ) return;
  10533. _gl.deleteTexture( textureProperties.__webglTexture );
  10534. }
  10535. // remove all webgl properties
  10536. properties.delete( texture );
  10537. }
  10538. function deallocateRenderTarget( renderTarget ) {
  10539. var renderTargetProperties = properties.get( renderTarget );
  10540. var textureProperties = properties.get( renderTarget.texture );
  10541. if ( ! renderTarget ) return;
  10542. if ( textureProperties.__webglTexture !== undefined ) {
  10543. _gl.deleteTexture( textureProperties.__webglTexture );
  10544. }
  10545. if ( renderTarget.depthTexture ) {
  10546. renderTarget.depthTexture.dispose();
  10547. }
  10548. if ( renderTarget.isWebGLRenderTargetCube ) {
  10549. for ( var i = 0; i < 6; i ++ ) {
  10550. _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
  10551. if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );
  10552. }
  10553. } else {
  10554. _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
  10555. if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );
  10556. }
  10557. properties.delete( renderTarget.texture );
  10558. properties.delete( renderTarget );
  10559. }
  10560. //
  10561. function setTexture2D( texture, slot ) {
  10562. var textureProperties = properties.get( texture );
  10563. if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
  10564. var image = texture.image;
  10565. if ( image === undefined ) {
  10566. console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
  10567. } else if ( image.complete === false ) {
  10568. console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
  10569. } else {
  10570. uploadTexture( textureProperties, texture, slot );
  10571. return;
  10572. }
  10573. }
  10574. state.activeTexture( _gl.TEXTURE0 + slot );
  10575. state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
  10576. }
  10577. function setTextureCube( texture, slot ) {
  10578. var textureProperties = properties.get( texture );
  10579. if ( texture.image.length === 6 ) {
  10580. if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
  10581. if ( ! textureProperties.__image__webglTextureCube ) {
  10582. texture.addEventListener( 'dispose', onTextureDispose );
  10583. textureProperties.__image__webglTextureCube = _gl.createTexture();
  10584. _infoMemory.textures ++;
  10585. }
  10586. state.activeTexture( _gl.TEXTURE0 + slot );
  10587. state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
  10588. _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
  10589. var isCompressed = ( texture && texture.isCompressedTexture );
  10590. var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );
  10591. var cubeImage = [];
  10592. for ( var i = 0; i < 6; i ++ ) {
  10593. if ( ! isCompressed && ! isDataTexture ) {
  10594. cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
  10595. } else {
  10596. cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
  10597. }
  10598. }
  10599. var image = cubeImage[ 0 ],
  10600. isPowerOfTwoImage = isPowerOfTwo( image ),
  10601. glFormat = paramThreeToGL( texture.format ),
  10602. glType = paramThreeToGL( texture.type );
  10603. setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );
  10604. for ( var i = 0; i < 6; i ++ ) {
  10605. if ( ! isCompressed ) {
  10606. if ( isDataTexture ) {
  10607. state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );
  10608. } else {
  10609. state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
  10610. }
  10611. } else {
  10612. var mipmap, mipmaps = cubeImage[ i ].mipmaps;
  10613. for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
  10614. mipmap = mipmaps[ j ];
  10615. if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {
  10616. if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
  10617. state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
  10618. } else {
  10619. console.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()" );
  10620. }
  10621. } else {
  10622. state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
  10623. }
  10624. }
  10625. }
  10626. }
  10627. if ( texture.generateMipmaps && isPowerOfTwoImage ) {
  10628. _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
  10629. }
  10630. textureProperties.__version = texture.version;
  10631. if ( texture.onUpdate ) texture.onUpdate( texture );
  10632. } else {
  10633. state.activeTexture( _gl.TEXTURE0 + slot );
  10634. state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
  10635. }
  10636. }
  10637. }
  10638. function setTextureCubeDynamic( texture, slot ) {
  10639. state.activeTexture( _gl.TEXTURE0 + slot );
  10640. state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );
  10641. }
  10642. function setTextureParameters( textureType, texture, isPowerOfTwoImage ) {
  10643. var extension;
  10644. if ( isPowerOfTwoImage ) {
  10645. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
  10646. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
  10647. _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
  10648. _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
  10649. } else {
  10650. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
  10651. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
  10652. if ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {
  10653. console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );
  10654. }
  10655. _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
  10656. _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
  10657. if ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {
  10658. console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );
  10659. }
  10660. }
  10661. extension = extensions.get( 'EXT_texture_filter_anisotropic' );
  10662. if ( extension ) {
  10663. if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;
  10664. if ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;
  10665. if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {
  10666. _gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );
  10667. properties.get( texture ).__currentAnisotropy = texture.anisotropy;
  10668. }
  10669. }
  10670. }
  10671. function uploadTexture( textureProperties, texture, slot ) {
  10672. if ( textureProperties.__webglInit === undefined ) {
  10673. textureProperties.__webglInit = true;
  10674. texture.addEventListener( 'dispose', onTextureDispose );
  10675. textureProperties.__webglTexture = _gl.createTexture();
  10676. _infoMemory.textures ++;
  10677. }
  10678. state.activeTexture( _gl.TEXTURE0 + slot );
  10679. state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
  10680. _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
  10681. _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
  10682. _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
  10683. var image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
  10684. if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {
  10685. image = makePowerOfTwo( image );
  10686. }
  10687. var isPowerOfTwoImage = isPowerOfTwo( image ),
  10688. glFormat = paramThreeToGL( texture.format ),
  10689. glType = paramThreeToGL( texture.type );
  10690. setTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );
  10691. var mipmap, mipmaps = texture.mipmaps;
  10692. if ( texture.isDepthTexture ) {
  10693. // populate depth texture with dummy data
  10694. var internalFormat = _gl.DEPTH_COMPONENT;
  10695. if ( texture.type === FloatType ) {
  10696. if ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');
  10697. internalFormat = _gl.DEPTH_COMPONENT32F;
  10698. } else if ( _isWebGL2 ) {
  10699. // WebGL 2.0 requires signed internalformat for glTexImage2D
  10700. internalFormat = _gl.DEPTH_COMPONENT16;
  10701. }
  10702. if ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) {
  10703. // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
  10704. // DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT
  10705. // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
  10706. if ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {
  10707. console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );
  10708. texture.type = UnsignedShortType;
  10709. glType = paramThreeToGL( texture.type );
  10710. }
  10711. }
  10712. // Depth stencil textures need the DEPTH_STENCIL internal format
  10713. // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
  10714. if ( texture.format === DepthStencilFormat ) {
  10715. internalFormat = _gl.DEPTH_STENCIL;
  10716. // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
  10717. // DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.
  10718. // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
  10719. if ( texture.type !== UnsignedInt248Type ) {
  10720. console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );
  10721. texture.type = UnsignedInt248Type;
  10722. glType = paramThreeToGL( texture.type );
  10723. }
  10724. }
  10725. state.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );
  10726. } else if ( texture.isDataTexture ) {
  10727. // use manually created mipmaps if available
  10728. // if there are no manual mipmaps
  10729. // set 0 level mipmap and then use GL to generate other mipmap levels
  10730. if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
  10731. for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
  10732. mipmap = mipmaps[ i ];
  10733. state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
  10734. }
  10735. texture.generateMipmaps = false;
  10736. } else {
  10737. state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
  10738. }
  10739. } else if ( texture.isCompressedTexture ) {
  10740. for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
  10741. mipmap = mipmaps[ i ];
  10742. if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {
  10743. if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
  10744. state.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
  10745. } else {
  10746. console.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()" );
  10747. }
  10748. } else {
  10749. state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
  10750. }
  10751. }
  10752. } else {
  10753. // regular Texture (image, video, canvas)
  10754. // use manually created mipmaps if available
  10755. // if there are no manual mipmaps
  10756. // set 0 level mipmap and then use GL to generate other mipmap levels
  10757. if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
  10758. for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
  10759. mipmap = mipmaps[ i ];
  10760. state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
  10761. }
  10762. texture.generateMipmaps = false;
  10763. } else {
  10764. state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );
  10765. }
  10766. }
  10767. if ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );
  10768. textureProperties.__version = texture.version;
  10769. if ( texture.onUpdate ) texture.onUpdate( texture );
  10770. }
  10771. // Render targets
  10772. // Setup storage for target texture and bind it to correct framebuffer
  10773. function setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {
  10774. var glFormat = paramThreeToGL( renderTarget.texture.format );
  10775. var glType = paramThreeToGL( renderTarget.texture.type );
  10776. state.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
  10777. _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
  10778. _gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
  10779. _gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
  10780. }
  10781. // Setup storage for internal depth/stencil buffers and bind to correct framebuffer
  10782. function setupRenderBufferStorage( renderbuffer, renderTarget ) {
  10783. _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
  10784. if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
  10785. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
  10786. _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
  10787. } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
  10788. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
  10789. _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
  10790. } else {
  10791. // FIXME: We don't support !depth !stencil
  10792. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
  10793. }
  10794. _gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
  10795. }
  10796. // Setup resources for a Depth Texture for a FBO (needs an extension)
  10797. function setupDepthTexture( framebuffer, renderTarget ) {
  10798. var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );
  10799. if ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');
  10800. _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
  10801. if ( !( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {
  10802. throw new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');
  10803. }
  10804. // upload an empty depth texture with framebuffer size
  10805. if ( !properties.get( renderTarget.depthTexture ).__webglTexture ||
  10806. renderTarget.depthTexture.image.width !== renderTarget.width ||
  10807. renderTarget.depthTexture.image.height !== renderTarget.height ) {
  10808. renderTarget.depthTexture.image.width = renderTarget.width;
  10809. renderTarget.depthTexture.image.height = renderTarget.height;
  10810. renderTarget.depthTexture.needsUpdate = true;
  10811. }
  10812. setTexture2D( renderTarget.depthTexture, 0 );
  10813. var webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;
  10814. if ( renderTarget.depthTexture.format === DepthFormat ) {
  10815. _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
  10816. } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
  10817. _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
  10818. } else {
  10819. throw new Error('Unknown depthTexture format')
  10820. }
  10821. }
  10822. // Setup GL resources for a non-texture depth buffer
  10823. function setupDepthRenderbuffer( renderTarget ) {
  10824. var renderTargetProperties = properties.get( renderTarget );
  10825. var isCube = ( renderTarget.isWebGLRenderTargetCube === true );
  10826. if ( renderTarget.depthTexture ) {
  10827. if ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');
  10828. setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );
  10829. } else {
  10830. if ( isCube ) {
  10831. renderTargetProperties.__webglDepthbuffer = [];
  10832. for ( var i = 0; i < 6; i ++ ) {
  10833. _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );
  10834. renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
  10835. setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );
  10836. }
  10837. } else {
  10838. _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
  10839. renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
  10840. setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );
  10841. }
  10842. }
  10843. _gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
  10844. }
  10845. // Set up GL resources for the render target
  10846. function setupRenderTarget( renderTarget ) {
  10847. var renderTargetProperties = properties.get( renderTarget );
  10848. var textureProperties = properties.get( renderTarget.texture );
  10849. renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
  10850. textureProperties.__webglTexture = _gl.createTexture();
  10851. _infoMemory.textures ++;
  10852. var isCube = ( renderTarget.isWebGLRenderTargetCube === true );
  10853. var isTargetPowerOfTwo = isPowerOfTwo( renderTarget );
  10854. // Setup framebuffer
  10855. if ( isCube ) {
  10856. renderTargetProperties.__webglFramebuffer = [];
  10857. for ( var i = 0; i < 6; i ++ ) {
  10858. renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
  10859. }
  10860. } else {
  10861. renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
  10862. }
  10863. // Setup color buffer
  10864. if ( isCube ) {
  10865. state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
  10866. setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
  10867. for ( var i = 0; i < 6; i ++ ) {
  10868. setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
  10869. }
  10870. if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
  10871. state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
  10872. } else {
  10873. state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
  10874. setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );
  10875. setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );
  10876. if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
  10877. state.bindTexture( _gl.TEXTURE_2D, null );
  10878. }
  10879. // Setup depth and stencil buffers
  10880. if ( renderTarget.depthBuffer ) {
  10881. setupDepthRenderbuffer( renderTarget );
  10882. }
  10883. }
  10884. function updateRenderTargetMipmap( renderTarget ) {
  10885. var texture = renderTarget.texture;
  10886. if ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&
  10887. texture.minFilter !== NearestFilter &&
  10888. texture.minFilter !== LinearFilter ) {
  10889. var target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;
  10890. var webglTexture = properties.get( texture ).__webglTexture;
  10891. state.bindTexture( target, webglTexture );
  10892. _gl.generateMipmap( target );
  10893. state.bindTexture( target, null );
  10894. }
  10895. }
  10896. this.setTexture2D = setTexture2D;
  10897. this.setTextureCube = setTextureCube;
  10898. this.setTextureCubeDynamic = setTextureCubeDynamic;
  10899. this.setupRenderTarget = setupRenderTarget;
  10900. this.updateRenderTargetMipmap = updateRenderTargetMipmap;
  10901. }
  10902. /**
  10903. * @author fordacious / fordacious.github.io
  10904. */
  10905. function WebGLProperties() {
  10906. var properties = {};
  10907. return {
  10908. get: function ( object ) {
  10909. var uuid = object.uuid;
  10910. var map = properties[ uuid ];
  10911. if ( map === undefined ) {
  10912. map = {};
  10913. properties[ uuid ] = map;
  10914. }
  10915. return map;
  10916. },
  10917. delete: function ( object ) {
  10918. delete properties[ object.uuid ];
  10919. },
  10920. clear: function () {
  10921. properties = {};
  10922. }
  10923. };
  10924. }
  10925. /**
  10926. * @author mrdoob / http://mrdoob.com/
  10927. */
  10928. function WebGLState( gl, extensions, paramThreeToGL ) {
  10929. function ColorBuffer() {
  10930. var locked = false;
  10931. var color = new Vector4();
  10932. var currentColorMask = null;
  10933. var currentColorClear = new Vector4();
  10934. return {
  10935. setMask: function ( colorMask ) {
  10936. if ( currentColorMask !== colorMask && ! locked ) {
  10937. gl.colorMask( colorMask, colorMask, colorMask, colorMask );
  10938. currentColorMask = colorMask;
  10939. }
  10940. },
  10941. setLocked: function ( lock ) {
  10942. locked = lock;
  10943. },
  10944. setClear: function ( r, g, b, a, premultipliedAlpha ) {
  10945. if ( premultipliedAlpha === true ) {
  10946. r *= a; g *= a; b *= a;
  10947. }
  10948. color.set( r, g, b, a );
  10949. if ( currentColorClear.equals( color ) === false ) {
  10950. gl.clearColor( r, g, b, a );
  10951. currentColorClear.copy( color );
  10952. }
  10953. },
  10954. reset: function () {
  10955. locked = false;
  10956. currentColorMask = null;
  10957. currentColorClear.set( 0, 0, 0, 1 );
  10958. }
  10959. };
  10960. }
  10961. function DepthBuffer() {
  10962. var locked = false;
  10963. var currentDepthMask = null;
  10964. var currentDepthFunc = null;
  10965. var currentDepthClear = null;
  10966. return {
  10967. setTest: function ( depthTest ) {
  10968. if ( depthTest ) {
  10969. enable( gl.DEPTH_TEST );
  10970. } else {
  10971. disable( gl.DEPTH_TEST );
  10972. }
  10973. },
  10974. setMask: function ( depthMask ) {
  10975. if ( currentDepthMask !== depthMask && ! locked ) {
  10976. gl.depthMask( depthMask );
  10977. currentDepthMask = depthMask;
  10978. }
  10979. },
  10980. setFunc: function ( depthFunc ) {
  10981. if ( currentDepthFunc !== depthFunc ) {
  10982. if ( depthFunc ) {
  10983. switch ( depthFunc ) {
  10984. case NeverDepth:
  10985. gl.depthFunc( gl.NEVER );
  10986. break;
  10987. case AlwaysDepth:
  10988. gl.depthFunc( gl.ALWAYS );
  10989. break;
  10990. case LessDepth:
  10991. gl.depthFunc( gl.LESS );
  10992. break;
  10993. case LessEqualDepth:
  10994. gl.depthFunc( gl.LEQUAL );
  10995. break;
  10996. case EqualDepth:
  10997. gl.depthFunc( gl.EQUAL );
  10998. break;
  10999. case GreaterEqualDepth:
  11000. gl.depthFunc( gl.GEQUAL );
  11001. break;
  11002. case GreaterDepth:
  11003. gl.depthFunc( gl.GREATER );
  11004. break;
  11005. case NotEqualDepth:
  11006. gl.depthFunc( gl.NOTEQUAL );
  11007. break;
  11008. default:
  11009. gl.depthFunc( gl.LEQUAL );
  11010. }
  11011. } else {
  11012. gl.depthFunc( gl.LEQUAL );
  11013. }
  11014. currentDepthFunc = depthFunc;
  11015. }
  11016. },
  11017. setLocked: function ( lock ) {
  11018. locked = lock;
  11019. },
  11020. setClear: function ( depth ) {
  11021. if ( currentDepthClear !== depth ) {
  11022. gl.clearDepth( depth );
  11023. currentDepthClear = depth;
  11024. }
  11025. },
  11026. reset: function () {
  11027. locked = false;
  11028. currentDepthMask = null;
  11029. currentDepthFunc = null;
  11030. currentDepthClear = null;
  11031. }
  11032. };
  11033. }
  11034. function StencilBuffer() {
  11035. var locked = false;
  11036. var currentStencilMask = null;
  11037. var currentStencilFunc = null;
  11038. var currentStencilRef = null;
  11039. var currentStencilFuncMask = null;
  11040. var currentStencilFail = null;
  11041. var currentStencilZFail = null;
  11042. var currentStencilZPass = null;
  11043. var currentStencilClear = null;
  11044. return {
  11045. setTest: function ( stencilTest ) {
  11046. if ( stencilTest ) {
  11047. enable( gl.STENCIL_TEST );
  11048. } else {
  11049. disable( gl.STENCIL_TEST );
  11050. }
  11051. },
  11052. setMask: function ( stencilMask ) {
  11053. if ( currentStencilMask !== stencilMask && ! locked ) {
  11054. gl.stencilMask( stencilMask );
  11055. currentStencilMask = stencilMask;
  11056. }
  11057. },
  11058. setFunc: function ( stencilFunc, stencilRef, stencilMask ) {
  11059. if ( currentStencilFunc !== stencilFunc ||
  11060. currentStencilRef !== stencilRef ||
  11061. currentStencilFuncMask !== stencilMask ) {
  11062. gl.stencilFunc( stencilFunc, stencilRef, stencilMask );
  11063. currentStencilFunc = stencilFunc;
  11064. currentStencilRef = stencilRef;
  11065. currentStencilFuncMask = stencilMask;
  11066. }
  11067. },
  11068. setOp: function ( stencilFail, stencilZFail, stencilZPass ) {
  11069. if ( currentStencilFail !== stencilFail ||
  11070. currentStencilZFail !== stencilZFail ||
  11071. currentStencilZPass !== stencilZPass ) {
  11072. gl.stencilOp( stencilFail, stencilZFail, stencilZPass );
  11073. currentStencilFail = stencilFail;
  11074. currentStencilZFail = stencilZFail;
  11075. currentStencilZPass = stencilZPass;
  11076. }
  11077. },
  11078. setLocked: function ( lock ) {
  11079. locked = lock;
  11080. },
  11081. setClear: function ( stencil ) {
  11082. if ( currentStencilClear !== stencil ) {
  11083. gl.clearStencil( stencil );
  11084. currentStencilClear = stencil;
  11085. }
  11086. },
  11087. reset: function () {
  11088. locked = false;
  11089. currentStencilMask = null;
  11090. currentStencilFunc = null;
  11091. currentStencilRef = null;
  11092. currentStencilFuncMask = null;
  11093. currentStencilFail = null;
  11094. currentStencilZFail = null;
  11095. currentStencilZPass = null;
  11096. currentStencilClear = null;
  11097. }
  11098. };
  11099. }
  11100. //
  11101. var colorBuffer = new ColorBuffer();
  11102. var depthBuffer = new DepthBuffer();
  11103. var stencilBuffer = new StencilBuffer();
  11104. var maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );
  11105. var newAttributes = new Uint8Array( maxVertexAttributes );
  11106. var enabledAttributes = new Uint8Array( maxVertexAttributes );
  11107. var attributeDivisors = new Uint8Array( maxVertexAttributes );
  11108. var capabilities = {};
  11109. var compressedTextureFormats = null;
  11110. var currentBlending = null;
  11111. var currentBlendEquation = null;
  11112. var currentBlendSrc = null;
  11113. var currentBlendDst = null;
  11114. var currentBlendEquationAlpha = null;
  11115. var currentBlendSrcAlpha = null;
  11116. var currentBlendDstAlpha = null;
  11117. var currentPremultipledAlpha = false;
  11118. var currentFlipSided = null;
  11119. var currentCullFace = null;
  11120. var currentLineWidth = null;
  11121. var currentPolygonOffsetFactor = null;
  11122. var currentPolygonOffsetUnits = null;
  11123. var currentScissorTest = null;
  11124. var maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );
  11125. var version = parseFloat( /^WebGL\ ([0-9])/.exec( gl.getParameter( gl.VERSION ) )[ 1 ] );
  11126. var lineWidthAvailable = parseFloat( version ) >= 1.0;
  11127. var currentTextureSlot = null;
  11128. var currentBoundTextures = {};
  11129. var currentScissor = new Vector4();
  11130. var currentViewport = new Vector4();
  11131. function createTexture( type, target, count ) {
  11132. var data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.
  11133. var texture = gl.createTexture();
  11134. gl.bindTexture( type, texture );
  11135. gl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
  11136. gl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
  11137. for ( var i = 0; i < count; i ++ ) {
  11138. gl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );
  11139. }
  11140. return texture;
  11141. }
  11142. var emptyTextures = {};
  11143. emptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );
  11144. emptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );
  11145. //
  11146. function init() {
  11147. colorBuffer.setClear( 0, 0, 0, 1 );
  11148. depthBuffer.setClear( 1 );
  11149. stencilBuffer.setClear( 0 );
  11150. enable( gl.DEPTH_TEST );
  11151. setDepthFunc( LessEqualDepth );
  11152. setFlipSided( false );
  11153. setCullFace( CullFaceBack );
  11154. enable( gl.CULL_FACE );
  11155. enable( gl.BLEND );
  11156. setBlending( NormalBlending );
  11157. }
  11158. function initAttributes() {
  11159. for ( var i = 0, l = newAttributes.length; i < l; i ++ ) {
  11160. newAttributes[ i ] = 0;
  11161. }
  11162. }
  11163. function enableAttribute( attribute ) {
  11164. newAttributes[ attribute ] = 1;
  11165. if ( enabledAttributes[ attribute ] === 0 ) {
  11166. gl.enableVertexAttribArray( attribute );
  11167. enabledAttributes[ attribute ] = 1;
  11168. }
  11169. if ( attributeDivisors[ attribute ] !== 0 ) {
  11170. var extension = extensions.get( 'ANGLE_instanced_arrays' );
  11171. extension.vertexAttribDivisorANGLE( attribute, 0 );
  11172. attributeDivisors[ attribute ] = 0;
  11173. }
  11174. }
  11175. function enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {
  11176. newAttributes[ attribute ] = 1;
  11177. if ( enabledAttributes[ attribute ] === 0 ) {
  11178. gl.enableVertexAttribArray( attribute );
  11179. enabledAttributes[ attribute ] = 1;
  11180. }
  11181. if ( attributeDivisors[ attribute ] !== meshPerAttribute ) {
  11182. extension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );
  11183. attributeDivisors[ attribute ] = meshPerAttribute;
  11184. }
  11185. }
  11186. function disableUnusedAttributes() {
  11187. for ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {
  11188. if ( enabledAttributes[ i ] !== newAttributes[ i ] ) {
  11189. gl.disableVertexAttribArray( i );
  11190. enabledAttributes[ i ] = 0;
  11191. }
  11192. }
  11193. }
  11194. function enable( id ) {
  11195. if ( capabilities[ id ] !== true ) {
  11196. gl.enable( id );
  11197. capabilities[ id ] = true;
  11198. }
  11199. }
  11200. function disable( id ) {
  11201. if ( capabilities[ id ] !== false ) {
  11202. gl.disable( id );
  11203. capabilities[ id ] = false;
  11204. }
  11205. }
  11206. function getCompressedTextureFormats() {
  11207. if ( compressedTextureFormats === null ) {
  11208. compressedTextureFormats = [];
  11209. if ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||
  11210. extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||
  11211. extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {
  11212. var formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );
  11213. for ( var i = 0; i < formats.length; i ++ ) {
  11214. compressedTextureFormats.push( formats[ i ] );
  11215. }
  11216. }
  11217. }
  11218. return compressedTextureFormats;
  11219. }
  11220. function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {
  11221. if ( blending !== NoBlending ) {
  11222. enable( gl.BLEND );
  11223. } else {
  11224. disable( gl.BLEND );
  11225. }
  11226. if ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {
  11227. if ( blending === AdditiveBlending ) {
  11228. if ( premultipliedAlpha ) {
  11229. gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );
  11230. gl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );
  11231. } else {
  11232. gl.blendEquation( gl.FUNC_ADD );
  11233. gl.blendFunc( gl.SRC_ALPHA, gl.ONE );
  11234. }
  11235. } else if ( blending === SubtractiveBlending ) {
  11236. if ( premultipliedAlpha ) {
  11237. gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );
  11238. gl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );
  11239. } else {
  11240. gl.blendEquation( gl.FUNC_ADD );
  11241. gl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );
  11242. }
  11243. } else if ( blending === MultiplyBlending ) {
  11244. if ( premultipliedAlpha ) {
  11245. gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );
  11246. gl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );
  11247. } else {
  11248. gl.blendEquation( gl.FUNC_ADD );
  11249. gl.blendFunc( gl.ZERO, gl.SRC_COLOR );
  11250. }
  11251. } else {
  11252. if ( premultipliedAlpha ) {
  11253. gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );
  11254. gl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );
  11255. } else {
  11256. gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );
  11257. gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );
  11258. }
  11259. }
  11260. currentBlending = blending;
  11261. currentPremultipledAlpha = premultipliedAlpha;
  11262. }
  11263. if ( blending === CustomBlending ) {
  11264. blendEquationAlpha = blendEquationAlpha || blendEquation;
  11265. blendSrcAlpha = blendSrcAlpha || blendSrc;
  11266. blendDstAlpha = blendDstAlpha || blendDst;
  11267. if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {
  11268. gl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );
  11269. currentBlendEquation = blendEquation;
  11270. currentBlendEquationAlpha = blendEquationAlpha;
  11271. }
  11272. if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {
  11273. gl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );
  11274. currentBlendSrc = blendSrc;
  11275. currentBlendDst = blendDst;
  11276. currentBlendSrcAlpha = blendSrcAlpha;
  11277. currentBlendDstAlpha = blendDstAlpha;
  11278. }
  11279. } else {
  11280. currentBlendEquation = null;
  11281. currentBlendSrc = null;
  11282. currentBlendDst = null;
  11283. currentBlendEquationAlpha = null;
  11284. currentBlendSrcAlpha = null;
  11285. currentBlendDstAlpha = null;
  11286. }
  11287. }
  11288. // TODO Deprecate
  11289. function setColorWrite( colorWrite ) {
  11290. colorBuffer.setMask( colorWrite );
  11291. }
  11292. function setDepthTest( depthTest ) {
  11293. depthBuffer.setTest( depthTest );
  11294. }
  11295. function setDepthWrite( depthWrite ) {
  11296. depthBuffer.setMask( depthWrite );
  11297. }
  11298. function setDepthFunc( depthFunc ) {
  11299. depthBuffer.setFunc( depthFunc );
  11300. }
  11301. function setStencilTest( stencilTest ) {
  11302. stencilBuffer.setTest( stencilTest );
  11303. }
  11304. function setStencilWrite( stencilWrite ) {
  11305. stencilBuffer.setMask( stencilWrite );
  11306. }
  11307. function setStencilFunc( stencilFunc, stencilRef, stencilMask ) {
  11308. stencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );
  11309. }
  11310. function setStencilOp( stencilFail, stencilZFail, stencilZPass ) {
  11311. stencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );
  11312. }
  11313. //
  11314. function setFlipSided( flipSided ) {
  11315. if ( currentFlipSided !== flipSided ) {
  11316. if ( flipSided ) {
  11317. gl.frontFace( gl.CW );
  11318. } else {
  11319. gl.frontFace( gl.CCW );
  11320. }
  11321. currentFlipSided = flipSided;
  11322. }
  11323. }
  11324. function setCullFace( cullFace ) {
  11325. if ( cullFace !== CullFaceNone ) {
  11326. enable( gl.CULL_FACE );
  11327. if ( cullFace !== currentCullFace ) {
  11328. if ( cullFace === CullFaceBack ) {
  11329. gl.cullFace( gl.BACK );
  11330. } else if ( cullFace === CullFaceFront ) {
  11331. gl.cullFace( gl.FRONT );
  11332. } else {
  11333. gl.cullFace( gl.FRONT_AND_BACK );
  11334. }
  11335. }
  11336. } else {
  11337. disable( gl.CULL_FACE );
  11338. }
  11339. currentCullFace = cullFace;
  11340. }
  11341. function setLineWidth( width ) {
  11342. if ( width !== currentLineWidth ) {
  11343. if ( lineWidthAvailable ) gl.lineWidth( width );
  11344. currentLineWidth = width;
  11345. }
  11346. }
  11347. function setPolygonOffset( polygonOffset, factor, units ) {
  11348. if ( polygonOffset ) {
  11349. enable( gl.POLYGON_OFFSET_FILL );
  11350. if ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {
  11351. gl.polygonOffset( factor, units );
  11352. currentPolygonOffsetFactor = factor;
  11353. currentPolygonOffsetUnits = units;
  11354. }
  11355. } else {
  11356. disable( gl.POLYGON_OFFSET_FILL );
  11357. }
  11358. }
  11359. function getScissorTest() {
  11360. return currentScissorTest;
  11361. }
  11362. function setScissorTest( scissorTest ) {
  11363. currentScissorTest = scissorTest;
  11364. if ( scissorTest ) {
  11365. enable( gl.SCISSOR_TEST );
  11366. } else {
  11367. disable( gl.SCISSOR_TEST );
  11368. }
  11369. }
  11370. // texture
  11371. function activeTexture( webglSlot ) {
  11372. if ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;
  11373. if ( currentTextureSlot !== webglSlot ) {
  11374. gl.activeTexture( webglSlot );
  11375. currentTextureSlot = webglSlot;
  11376. }
  11377. }
  11378. function bindTexture( webglType, webglTexture ) {
  11379. if ( currentTextureSlot === null ) {
  11380. activeTexture();
  11381. }
  11382. var boundTexture = currentBoundTextures[ currentTextureSlot ];
  11383. if ( boundTexture === undefined ) {
  11384. boundTexture = { type: undefined, texture: undefined };
  11385. currentBoundTextures[ currentTextureSlot ] = boundTexture;
  11386. }
  11387. if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {
  11388. gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );
  11389. boundTexture.type = webglType;
  11390. boundTexture.texture = webglTexture;
  11391. }
  11392. }
  11393. function compressedTexImage2D() {
  11394. try {
  11395. gl.compressedTexImage2D.apply( gl, arguments );
  11396. } catch ( error ) {
  11397. console.error( error );
  11398. }
  11399. }
  11400. function texImage2D() {
  11401. try {
  11402. gl.texImage2D.apply( gl, arguments );
  11403. } catch ( error ) {
  11404. console.error( error );
  11405. }
  11406. }
  11407. //
  11408. function scissor( scissor ) {
  11409. if ( currentScissor.equals( scissor ) === false ) {
  11410. gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );
  11411. currentScissor.copy( scissor );
  11412. }
  11413. }
  11414. function viewport( viewport ) {
  11415. if ( currentViewport.equals( viewport ) === false ) {
  11416. gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );
  11417. currentViewport.copy( viewport );
  11418. }
  11419. }
  11420. //
  11421. function reset() {
  11422. for ( var i = 0; i < enabledAttributes.length; i ++ ) {
  11423. if ( enabledAttributes[ i ] === 1 ) {
  11424. gl.disableVertexAttribArray( i );
  11425. enabledAttributes[ i ] = 0;
  11426. }
  11427. }
  11428. capabilities = {};
  11429. compressedTextureFormats = null;
  11430. currentTextureSlot = null;
  11431. currentBoundTextures = {};
  11432. currentBlending = null;
  11433. currentFlipSided = null;
  11434. currentCullFace = null;
  11435. colorBuffer.reset();
  11436. depthBuffer.reset();
  11437. stencilBuffer.reset();
  11438. }
  11439. return {
  11440. buffers: {
  11441. color: colorBuffer,
  11442. depth: depthBuffer,
  11443. stencil: stencilBuffer
  11444. },
  11445. init: init,
  11446. initAttributes: initAttributes,
  11447. enableAttribute: enableAttribute,
  11448. enableAttributeAndDivisor: enableAttributeAndDivisor,
  11449. disableUnusedAttributes: disableUnusedAttributes,
  11450. enable: enable,
  11451. disable: disable,
  11452. getCompressedTextureFormats: getCompressedTextureFormats,
  11453. setBlending: setBlending,
  11454. setColorWrite: setColorWrite,
  11455. setDepthTest: setDepthTest,
  11456. setDepthWrite: setDepthWrite,
  11457. setDepthFunc: setDepthFunc,
  11458. setStencilTest: setStencilTest,
  11459. setStencilWrite: setStencilWrite,
  11460. setStencilFunc: setStencilFunc,
  11461. setStencilOp: setStencilOp,
  11462. setFlipSided: setFlipSided,
  11463. setCullFace: setCullFace,
  11464. setLineWidth: setLineWidth,
  11465. setPolygonOffset: setPolygonOffset,
  11466. getScissorTest: getScissorTest,
  11467. setScissorTest: setScissorTest,
  11468. activeTexture: activeTexture,
  11469. bindTexture: bindTexture,
  11470. compressedTexImage2D: compressedTexImage2D,
  11471. texImage2D: texImage2D,
  11472. scissor: scissor,
  11473. viewport: viewport,
  11474. reset: reset
  11475. };
  11476. }
  11477. /**
  11478. * @author mrdoob / http://mrdoob.com/
  11479. */
  11480. function WebGLCapabilities( gl, extensions, parameters ) {
  11481. var maxAnisotropy;
  11482. function getMaxAnisotropy() {
  11483. if ( maxAnisotropy !== undefined ) return maxAnisotropy;
  11484. var extension = extensions.get( 'EXT_texture_filter_anisotropic' );
  11485. if ( extension !== null ) {
  11486. maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );
  11487. } else {
  11488. maxAnisotropy = 0;
  11489. }
  11490. return maxAnisotropy;
  11491. }
  11492. function getMaxPrecision( precision ) {
  11493. if ( precision === 'highp' ) {
  11494. if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&
  11495. gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {
  11496. return 'highp';
  11497. }
  11498. precision = 'mediump';
  11499. }
  11500. if ( precision === 'mediump' ) {
  11501. if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&
  11502. gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {
  11503. return 'mediump';
  11504. }
  11505. }
  11506. return 'lowp';
  11507. }
  11508. var precision = parameters.precision !== undefined ? parameters.precision : 'highp';
  11509. var maxPrecision = getMaxPrecision( precision );
  11510. if ( maxPrecision !== precision ) {
  11511. console.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );
  11512. precision = maxPrecision;
  11513. }
  11514. var logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );
  11515. var maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );
  11516. var maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
  11517. var maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );
  11518. var maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );
  11519. var maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );
  11520. var maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );
  11521. var maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );
  11522. var maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );
  11523. var vertexTextures = maxVertexTextures > 0;
  11524. var floatFragmentTextures = !! extensions.get( 'OES_texture_float' );
  11525. var floatVertexTextures = vertexTextures && floatFragmentTextures;
  11526. return {
  11527. getMaxAnisotropy: getMaxAnisotropy,
  11528. getMaxPrecision: getMaxPrecision,
  11529. precision: precision,
  11530. logarithmicDepthBuffer: logarithmicDepthBuffer,
  11531. maxTextures: maxTextures,
  11532. maxVertexTextures: maxVertexTextures,
  11533. maxTextureSize: maxTextureSize,
  11534. maxCubemapSize: maxCubemapSize,
  11535. maxAttributes: maxAttributes,
  11536. maxVertexUniforms: maxVertexUniforms,
  11537. maxVaryings: maxVaryings,
  11538. maxFragmentUniforms: maxFragmentUniforms,
  11539. vertexTextures: vertexTextures,
  11540. floatFragmentTextures: floatFragmentTextures,
  11541. floatVertexTextures: floatVertexTextures
  11542. };
  11543. }
  11544. /**
  11545. * @author mrdoob / http://mrdoob.com/
  11546. */
  11547. function WebGLExtensions( gl ) {
  11548. var extensions = {};
  11549. return {
  11550. get: function ( name ) {
  11551. if ( extensions[ name ] !== undefined ) {
  11552. return extensions[ name ];
  11553. }
  11554. var extension;
  11555. switch ( name ) {
  11556. case 'WEBGL_depth_texture':
  11557. extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );
  11558. break;
  11559. case 'EXT_texture_filter_anisotropic':
  11560. extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );
  11561. break;
  11562. case 'WEBGL_compressed_texture_s3tc':
  11563. extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );
  11564. break;
  11565. case 'WEBGL_compressed_texture_pvrtc':
  11566. extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );
  11567. break;
  11568. case 'WEBGL_compressed_texture_etc1':
  11569. extension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );
  11570. break;
  11571. default:
  11572. extension = gl.getExtension( name );
  11573. }
  11574. if ( extension === null ) {
  11575. console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );
  11576. }
  11577. extensions[ name ] = extension;
  11578. return extension;
  11579. }
  11580. };
  11581. }
  11582. /**
  11583. * @author tschw
  11584. */
  11585. function WebGLClipping() {
  11586. var scope = this,
  11587. globalState = null,
  11588. numGlobalPlanes = 0,
  11589. localClippingEnabled = false,
  11590. renderingShadows = false,
  11591. plane = new Plane(),
  11592. viewNormalMatrix = new Matrix3(),
  11593. uniform = { value: null, needsUpdate: false };
  11594. this.uniform = uniform;
  11595. this.numPlanes = 0;
  11596. this.numIntersection = 0;
  11597. this.init = function( planes, enableLocalClipping, camera ) {
  11598. var enabled =
  11599. planes.length !== 0 ||
  11600. enableLocalClipping ||
  11601. // enable state of previous frame - the clipping code has to
  11602. // run another frame in order to reset the state:
  11603. numGlobalPlanes !== 0 ||
  11604. localClippingEnabled;
  11605. localClippingEnabled = enableLocalClipping;
  11606. globalState = projectPlanes( planes, camera, 0 );
  11607. numGlobalPlanes = planes.length;
  11608. return enabled;
  11609. };
  11610. this.beginShadows = function() {
  11611. renderingShadows = true;
  11612. projectPlanes( null );
  11613. };
  11614. this.endShadows = function() {
  11615. renderingShadows = false;
  11616. resetGlobalState();
  11617. };
  11618. this.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {
  11619. if ( ! localClippingEnabled ||
  11620. planes === null || planes.length === 0 ||
  11621. renderingShadows && ! clipShadows ) {
  11622. // there's no local clipping
  11623. if ( renderingShadows ) {
  11624. // there's no global clipping
  11625. projectPlanes( null );
  11626. } else {
  11627. resetGlobalState();
  11628. }
  11629. } else {
  11630. var nGlobal = renderingShadows ? 0 : numGlobalPlanes,
  11631. lGlobal = nGlobal * 4,
  11632. dstArray = cache.clippingState || null;
  11633. uniform.value = dstArray; // ensure unique state
  11634. dstArray = projectPlanes( planes, camera, lGlobal, fromCache );
  11635. for ( var i = 0; i !== lGlobal; ++ i ) {
  11636. dstArray[ i ] = globalState[ i ];
  11637. }
  11638. cache.clippingState = dstArray;
  11639. this.numIntersection = clipIntersection ? this.numPlanes : 0;
  11640. this.numPlanes += nGlobal;
  11641. }
  11642. };
  11643. function resetGlobalState() {
  11644. if ( uniform.value !== globalState ) {
  11645. uniform.value = globalState;
  11646. uniform.needsUpdate = numGlobalPlanes > 0;
  11647. }
  11648. scope.numPlanes = numGlobalPlanes;
  11649. scope.numIntersection = 0;
  11650. }
  11651. function projectPlanes( planes, camera, dstOffset, skipTransform ) {
  11652. var nPlanes = planes !== null ? planes.length : 0,
  11653. dstArray = null;
  11654. if ( nPlanes !== 0 ) {
  11655. dstArray = uniform.value;
  11656. if ( skipTransform !== true || dstArray === null ) {
  11657. var flatSize = dstOffset + nPlanes * 4,
  11658. viewMatrix = camera.matrixWorldInverse;
  11659. viewNormalMatrix.getNormalMatrix( viewMatrix );
  11660. if ( dstArray === null || dstArray.length < flatSize ) {
  11661. dstArray = new Float32Array( flatSize );
  11662. }
  11663. for ( var i = 0, i4 = dstOffset;
  11664. i !== nPlanes; ++ i, i4 += 4 ) {
  11665. plane.copy( planes[ i ] ).
  11666. applyMatrix4( viewMatrix, viewNormalMatrix );
  11667. plane.normal.toArray( dstArray, i4 );
  11668. dstArray[ i4 + 3 ] = plane.constant;
  11669. }
  11670. }
  11671. uniform.value = dstArray;
  11672. uniform.needsUpdate = true;
  11673. }
  11674. scope.numPlanes = nPlanes;
  11675. return dstArray;
  11676. }
  11677. }
  11678. /**
  11679. * @author supereggbert / http://www.paulbrunt.co.uk/
  11680. * @author mrdoob / http://mrdoob.com/
  11681. * @author alteredq / http://alteredqualia.com/
  11682. * @author szimek / https://github.com/szimek/
  11683. * @author tschw
  11684. */
  11685. function WebGLRenderer( parameters ) {
  11686. console.log( 'THREE.WebGLRenderer', REVISION );
  11687. parameters = parameters || {};
  11688. var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),
  11689. _context = parameters.context !== undefined ? parameters.context : null,
  11690. _alpha = parameters.alpha !== undefined ? parameters.alpha : false,
  11691. _depth = parameters.depth !== undefined ? parameters.depth : true,
  11692. _stencil = parameters.stencil !== undefined ? parameters.stencil : true,
  11693. _antialias = parameters.antialias !== undefined ? parameters.antialias : false,
  11694. _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
  11695. _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;
  11696. var lights = [];
  11697. var opaqueObjects = [];
  11698. var opaqueObjectsLastIndex = - 1;
  11699. var transparentObjects = [];
  11700. var transparentObjectsLastIndex = - 1;
  11701. var morphInfluences = new Float32Array( 8 );
  11702. var sprites = [];
  11703. var lensFlares = [];
  11704. // public properties
  11705. this.domElement = _canvas;
  11706. this.context = null;
  11707. // clearing
  11708. this.autoClear = true;
  11709. this.autoClearColor = true;
  11710. this.autoClearDepth = true;
  11711. this.autoClearStencil = true;
  11712. // scene graph
  11713. this.sortObjects = true;
  11714. // user-defined clipping
  11715. this.clippingPlanes = [];
  11716. this.localClippingEnabled = false;
  11717. // physically based shading
  11718. this.gammaFactor = 2.0; // for backwards compatibility
  11719. this.gammaInput = false;
  11720. this.gammaOutput = false;
  11721. // physical lights
  11722. this.physicallyCorrectLights = false;
  11723. // tone mapping
  11724. this.toneMapping = LinearToneMapping;
  11725. this.toneMappingExposure = 1.0;
  11726. this.toneMappingWhitePoint = 1.0;
  11727. // morphs
  11728. this.maxMorphTargets = 8;
  11729. this.maxMorphNormals = 4;
  11730. // internal properties
  11731. var _this = this,
  11732. // internal state cache
  11733. _currentProgram = null,
  11734. _currentRenderTarget = null,
  11735. _currentFramebuffer = null,
  11736. _currentMaterialId = - 1,
  11737. _currentGeometryProgram = '',
  11738. _currentCamera = null,
  11739. _currentScissor = new Vector4(),
  11740. _currentScissorTest = null,
  11741. _currentViewport = new Vector4(),
  11742. //
  11743. _usedTextureUnits = 0,
  11744. //
  11745. _clearColor = new Color( 0x000000 ),
  11746. _clearAlpha = 0,
  11747. _width = _canvas.width,
  11748. _height = _canvas.height,
  11749. _pixelRatio = 1,
  11750. _scissor = new Vector4( 0, 0, _width, _height ),
  11751. _scissorTest = false,
  11752. _viewport = new Vector4( 0, 0, _width, _height ),
  11753. // frustum
  11754. _frustum = new Frustum(),
  11755. // clipping
  11756. _clipping = new WebGLClipping(),
  11757. _clippingEnabled = false,
  11758. _localClippingEnabled = false,
  11759. _sphere = new Sphere(),
  11760. // camera matrices cache
  11761. _projScreenMatrix = new Matrix4(),
  11762. _vector3 = new Vector3(),
  11763. _matrix4 = new Matrix4(),
  11764. _matrix42 = new Matrix4(),
  11765. // light arrays cache
  11766. _lights = {
  11767. hash: '',
  11768. ambient: [ 0, 0, 0 ],
  11769. directional: [],
  11770. directionalShadowMap: [],
  11771. directionalShadowMatrix: [],
  11772. spot: [],
  11773. spotShadowMap: [],
  11774. spotShadowMatrix: [],
  11775. rectArea: [],
  11776. point: [],
  11777. pointShadowMap: [],
  11778. pointShadowMatrix: [],
  11779. hemi: [],
  11780. shadows: []
  11781. },
  11782. // info
  11783. _infoRender = {
  11784. calls: 0,
  11785. vertices: 0,
  11786. faces: 0,
  11787. points: 0
  11788. };
  11789. this.info = {
  11790. render: _infoRender,
  11791. memory: {
  11792. geometries: 0,
  11793. textures: 0
  11794. },
  11795. programs: null
  11796. };
  11797. // initialize
  11798. var _gl;
  11799. try {
  11800. var attributes = {
  11801. alpha: _alpha,
  11802. depth: _depth,
  11803. stencil: _stencil,
  11804. antialias: _antialias,
  11805. premultipliedAlpha: _premultipliedAlpha,
  11806. preserveDrawingBuffer: _preserveDrawingBuffer
  11807. };
  11808. _gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );
  11809. if ( _gl === null ) {
  11810. if ( _canvas.getContext( 'webgl' ) !== null ) {
  11811. throw 'Error creating WebGL context with your selected attributes.';
  11812. } else {
  11813. throw 'Error creating WebGL context.';
  11814. }
  11815. }
  11816. // Some experimental-webgl implementations do not have getShaderPrecisionFormat
  11817. if ( _gl.getShaderPrecisionFormat === undefined ) {
  11818. _gl.getShaderPrecisionFormat = function () {
  11819. return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };
  11820. };
  11821. }
  11822. _canvas.addEventListener( 'webglcontextlost', onContextLost, false );
  11823. } catch ( error ) {
  11824. console.error( 'THREE.WebGLRenderer: ' + error );
  11825. }
  11826. var extensions = new WebGLExtensions( _gl );
  11827. extensions.get( 'WEBGL_depth_texture' );
  11828. extensions.get( 'OES_texture_float' );
  11829. extensions.get( 'OES_texture_float_linear' );
  11830. extensions.get( 'OES_texture_half_float' );
  11831. extensions.get( 'OES_texture_half_float_linear' );
  11832. extensions.get( 'OES_standard_derivatives' );
  11833. extensions.get( 'ANGLE_instanced_arrays' );
  11834. if ( extensions.get( 'OES_element_index_uint' ) ) {
  11835. BufferGeometry.MaxIndex = 4294967296;
  11836. }
  11837. var capabilities = new WebGLCapabilities( _gl, extensions, parameters );
  11838. var state = new WebGLState( _gl, extensions, paramThreeToGL );
  11839. var properties = new WebGLProperties();
  11840. var textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );
  11841. var objects = new WebGLObjects( _gl, properties, this.info );
  11842. var programCache = new WebGLPrograms( this, capabilities );
  11843. var lightCache = new WebGLLights();
  11844. this.info.programs = programCache.programs;
  11845. var bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );
  11846. var indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
  11847. //
  11848. var backgroundPlaneCamera, backgroundPlaneMesh;
  11849. var backgroundBoxCamera, backgroundBoxMesh;
  11850. //
  11851. function getTargetPixelRatio() {
  11852. return _currentRenderTarget === null ? _pixelRatio : 1;
  11853. }
  11854. function setDefaultGLState() {
  11855. state.init();
  11856. state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
  11857. state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
  11858. state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
  11859. }
  11860. function resetGLState() {
  11861. _currentProgram = null;
  11862. _currentCamera = null;
  11863. _currentGeometryProgram = '';
  11864. _currentMaterialId = - 1;
  11865. state.reset();
  11866. }
  11867. setDefaultGLState();
  11868. this.context = _gl;
  11869. this.capabilities = capabilities;
  11870. this.extensions = extensions;
  11871. this.properties = properties;
  11872. this.state = state;
  11873. // shadow map
  11874. var shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );
  11875. this.shadowMap = shadowMap;
  11876. // Plugins
  11877. var spritePlugin = new SpritePlugin( this, sprites );
  11878. var lensFlarePlugin = new LensFlarePlugin( this, lensFlares );
  11879. // API
  11880. this.getContext = function () {
  11881. return _gl;
  11882. };
  11883. this.getContextAttributes = function () {
  11884. return _gl.getContextAttributes();
  11885. };
  11886. this.forceContextLoss = function () {
  11887. extensions.get( 'WEBGL_lose_context' ).loseContext();
  11888. };
  11889. this.getMaxAnisotropy = function () {
  11890. return capabilities.getMaxAnisotropy();
  11891. };
  11892. this.getPrecision = function () {
  11893. return capabilities.precision;
  11894. };
  11895. this.getPixelRatio = function () {
  11896. return _pixelRatio;
  11897. };
  11898. this.setPixelRatio = function ( value ) {
  11899. if ( value === undefined ) return;
  11900. _pixelRatio = value;
  11901. this.setSize( _viewport.z, _viewport.w, false );
  11902. };
  11903. this.getSize = function () {
  11904. return {
  11905. width: _width,
  11906. height: _height
  11907. };
  11908. };
  11909. this.setSize = function ( width, height, updateStyle ) {
  11910. _width = width;
  11911. _height = height;
  11912. _canvas.width = width * _pixelRatio;
  11913. _canvas.height = height * _pixelRatio;
  11914. if ( updateStyle !== false ) {
  11915. _canvas.style.width = width + 'px';
  11916. _canvas.style.height = height + 'px';
  11917. }
  11918. this.setViewport( 0, 0, width, height );
  11919. };
  11920. this.setViewport = function ( x, y, width, height ) {
  11921. state.viewport( _viewport.set( x, y, width, height ) );
  11922. };
  11923. this.setScissor = function ( x, y, width, height ) {
  11924. state.scissor( _scissor.set( x, y, width, height ) );
  11925. };
  11926. this.setScissorTest = function ( boolean ) {
  11927. state.setScissorTest( _scissorTest = boolean );
  11928. };
  11929. // Clearing
  11930. this.getClearColor = function () {
  11931. return _clearColor;
  11932. };
  11933. this.setClearColor = function ( color, alpha ) {
  11934. _clearColor.set( color );
  11935. _clearAlpha = alpha !== undefined ? alpha : 1;
  11936. state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
  11937. };
  11938. this.getClearAlpha = function () {
  11939. return _clearAlpha;
  11940. };
  11941. this.setClearAlpha = function ( alpha ) {
  11942. _clearAlpha = alpha;
  11943. state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
  11944. };
  11945. this.clear = function ( color, depth, stencil ) {
  11946. var bits = 0;
  11947. if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;
  11948. if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;
  11949. if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;
  11950. _gl.clear( bits );
  11951. };
  11952. this.clearColor = function () {
  11953. this.clear( true, false, false );
  11954. };
  11955. this.clearDepth = function () {
  11956. this.clear( false, true, false );
  11957. };
  11958. this.clearStencil = function () {
  11959. this.clear( false, false, true );
  11960. };
  11961. this.clearTarget = function ( renderTarget, color, depth, stencil ) {
  11962. this.setRenderTarget( renderTarget );
  11963. this.clear( color, depth, stencil );
  11964. };
  11965. // Reset
  11966. this.resetGLState = resetGLState;
  11967. this.dispose = function() {
  11968. transparentObjects = [];
  11969. transparentObjectsLastIndex = -1;
  11970. opaqueObjects = [];
  11971. opaqueObjectsLastIndex = -1;
  11972. _canvas.removeEventListener( 'webglcontextlost', onContextLost, false );
  11973. };
  11974. // Events
  11975. function onContextLost( event ) {
  11976. event.preventDefault();
  11977. resetGLState();
  11978. setDefaultGLState();
  11979. properties.clear();
  11980. }
  11981. function onMaterialDispose( event ) {
  11982. var material = event.target;
  11983. material.removeEventListener( 'dispose', onMaterialDispose );
  11984. deallocateMaterial( material );
  11985. }
  11986. // Buffer deallocation
  11987. function deallocateMaterial( material ) {
  11988. releaseMaterialProgramReference( material );
  11989. properties.delete( material );
  11990. }
  11991. function releaseMaterialProgramReference( material ) {
  11992. var programInfo = properties.get( material ).program;
  11993. material.program = undefined;
  11994. if ( programInfo !== undefined ) {
  11995. programCache.releaseProgram( programInfo );
  11996. }
  11997. }
  11998. // Buffer rendering
  11999. this.renderBufferImmediate = function ( object, program, material ) {
  12000. state.initAttributes();
  12001. var buffers = properties.get( object );
  12002. if ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();
  12003. if ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();
  12004. if ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();
  12005. if ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();
  12006. var attributes = program.getAttributes();
  12007. if ( object.hasPositions ) {
  12008. _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
  12009. _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
  12010. state.enableAttribute( attributes.position );
  12011. _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
  12012. }
  12013. if ( object.hasNormals ) {
  12014. _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );
  12015. if ( ! material.isMeshPhongMaterial &&
  12016. ! material.isMeshStandardMaterial &&
  12017. ! material.isMeshNormalMaterial &&
  12018. material.shading === FlatShading ) {
  12019. for ( var i = 0, l = object.count * 3; i < l; i += 9 ) {
  12020. var array = object.normalArray;
  12021. var nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;
  12022. var ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;
  12023. var nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;
  12024. array[ i + 0 ] = nx;
  12025. array[ i + 1 ] = ny;
  12026. array[ i + 2 ] = nz;
  12027. array[ i + 3 ] = nx;
  12028. array[ i + 4 ] = ny;
  12029. array[ i + 5 ] = nz;
  12030. array[ i + 6 ] = nx;
  12031. array[ i + 7 ] = ny;
  12032. array[ i + 8 ] = nz;
  12033. }
  12034. }
  12035. _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
  12036. state.enableAttribute( attributes.normal );
  12037. _gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
  12038. }
  12039. if ( object.hasUvs && material.map ) {
  12040. _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
  12041. _gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
  12042. state.enableAttribute( attributes.uv );
  12043. _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
  12044. }
  12045. if ( object.hasColors && material.vertexColors !== NoColors ) {
  12046. _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
  12047. _gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
  12048. state.enableAttribute( attributes.color );
  12049. _gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
  12050. }
  12051. state.disableUnusedAttributes();
  12052. _gl.drawArrays( _gl.TRIANGLES, 0, object.count );
  12053. object.count = 0;
  12054. };
  12055. this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
  12056. setMaterial( material );
  12057. var program = setProgram( camera, fog, material, object );
  12058. var updateBuffers = false;
  12059. var geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;
  12060. if ( geometryProgram !== _currentGeometryProgram ) {
  12061. _currentGeometryProgram = geometryProgram;
  12062. updateBuffers = true;
  12063. }
  12064. // morph targets
  12065. var morphTargetInfluences = object.morphTargetInfluences;
  12066. if ( morphTargetInfluences !== undefined ) {
  12067. var activeInfluences = [];
  12068. for ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {
  12069. var influence = morphTargetInfluences[ i ];
  12070. activeInfluences.push( [ influence, i ] );
  12071. }
  12072. activeInfluences.sort( absNumericalSort );
  12073. if ( activeInfluences.length > 8 ) {
  12074. activeInfluences.length = 8;
  12075. }
  12076. var morphAttributes = geometry.morphAttributes;
  12077. for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {
  12078. var influence = activeInfluences[ i ];
  12079. morphInfluences[ i ] = influence[ 0 ];
  12080. if ( influence[ 0 ] !== 0 ) {
  12081. var index = influence[ 1 ];
  12082. if ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );
  12083. if ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );
  12084. } else {
  12085. if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
  12086. if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
  12087. }
  12088. }
  12089. for ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {
  12090. morphInfluences[ i ] = 0.0;
  12091. }
  12092. program.getUniforms().setValue(
  12093. _gl, 'morphTargetInfluences', morphInfluences );
  12094. updateBuffers = true;
  12095. }
  12096. //
  12097. var index = geometry.index;
  12098. var position = geometry.attributes.position;
  12099. var rangeFactor = 1;
  12100. if ( material.wireframe === true ) {
  12101. index = objects.getWireframeAttribute( geometry );
  12102. rangeFactor = 2;
  12103. }
  12104. var renderer;
  12105. if ( index !== null ) {
  12106. renderer = indexedBufferRenderer;
  12107. renderer.setIndex( index );
  12108. } else {
  12109. renderer = bufferRenderer;
  12110. }
  12111. if ( updateBuffers ) {
  12112. setupVertexAttributes( material, program, geometry );
  12113. if ( index !== null ) {
  12114. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
  12115. }
  12116. }
  12117. //
  12118. var dataCount = 0;
  12119. if ( index !== null ) {
  12120. dataCount = index.count;
  12121. } else if ( position !== undefined ) {
  12122. dataCount = position.count;
  12123. }
  12124. var rangeStart = geometry.drawRange.start * rangeFactor;
  12125. var rangeCount = geometry.drawRange.count * rangeFactor;
  12126. var groupStart = group !== null ? group.start * rangeFactor : 0;
  12127. var groupCount = group !== null ? group.count * rangeFactor : Infinity;
  12128. var drawStart = Math.max( rangeStart, groupStart );
  12129. var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
  12130. var drawCount = Math.max( 0, drawEnd - drawStart + 1 );
  12131. if ( drawCount === 0 ) return;
  12132. //
  12133. if ( object.isMesh ) {
  12134. if ( material.wireframe === true ) {
  12135. state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
  12136. renderer.setMode( _gl.LINES );
  12137. } else {
  12138. switch ( object.drawMode ) {
  12139. case TrianglesDrawMode:
  12140. renderer.setMode( _gl.TRIANGLES );
  12141. break;
  12142. case TriangleStripDrawMode:
  12143. renderer.setMode( _gl.TRIANGLE_STRIP );
  12144. break;
  12145. case TriangleFanDrawMode:
  12146. renderer.setMode( _gl.TRIANGLE_FAN );
  12147. break;
  12148. }
  12149. }
  12150. } else if ( object.isLine ) {
  12151. var lineWidth = material.linewidth;
  12152. if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
  12153. state.setLineWidth( lineWidth * getTargetPixelRatio() );
  12154. if ( object.isLineSegments ) {
  12155. renderer.setMode( _gl.LINES );
  12156. } else {
  12157. renderer.setMode( _gl.LINE_STRIP );
  12158. }
  12159. } else if ( object.isPoints ) {
  12160. renderer.setMode( _gl.POINTS );
  12161. }
  12162. if ( geometry && geometry.isInstancedBufferGeometry ) {
  12163. if ( geometry.maxInstancedCount > 0 ) {
  12164. renderer.renderInstances( geometry, drawStart, drawCount );
  12165. }
  12166. } else {
  12167. renderer.render( drawStart, drawCount );
  12168. }
  12169. };
  12170. function setupVertexAttributes( material, program, geometry, startIndex ) {
  12171. var extension;
  12172. if ( geometry && geometry.isInstancedBufferGeometry ) {
  12173. extension = extensions.get( 'ANGLE_instanced_arrays' );
  12174. if ( extension === null ) {
  12175. console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
  12176. return;
  12177. }
  12178. }
  12179. if ( startIndex === undefined ) startIndex = 0;
  12180. state.initAttributes();
  12181. var geometryAttributes = geometry.attributes;
  12182. var programAttributes = program.getAttributes();
  12183. var materialDefaultAttributeValues = material.defaultAttributeValues;
  12184. for ( var name in programAttributes ) {
  12185. var programAttribute = programAttributes[ name ];
  12186. if ( programAttribute >= 0 ) {
  12187. var geometryAttribute = geometryAttributes[ name ];
  12188. if ( geometryAttribute !== undefined ) {
  12189. var normalized = geometryAttribute.normalized;
  12190. var size = geometryAttribute.itemSize;
  12191. var attributeProperties = objects.getAttributeProperties( geometryAttribute );
  12192. var buffer = attributeProperties.__webglBuffer;
  12193. var type = attributeProperties.type;
  12194. var bytesPerElement = attributeProperties.bytesPerElement;
  12195. if ( geometryAttribute.isInterleavedBufferAttribute ) {
  12196. var data = geometryAttribute.data;
  12197. var stride = data.stride;
  12198. var offset = geometryAttribute.offset;
  12199. if ( data && data.isInstancedInterleavedBuffer ) {
  12200. state.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );
  12201. if ( geometry.maxInstancedCount === undefined ) {
  12202. geometry.maxInstancedCount = data.meshPerAttribute * data.count;
  12203. }
  12204. } else {
  12205. state.enableAttribute( programAttribute );
  12206. }
  12207. _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
  12208. _gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );
  12209. } else {
  12210. if ( geometryAttribute.isInstancedBufferAttribute ) {
  12211. state.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );
  12212. if ( geometry.maxInstancedCount === undefined ) {
  12213. geometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
  12214. }
  12215. } else {
  12216. state.enableAttribute( programAttribute );
  12217. }
  12218. _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
  12219. _gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );
  12220. }
  12221. } else if ( materialDefaultAttributeValues !== undefined ) {
  12222. var value = materialDefaultAttributeValues[ name ];
  12223. if ( value !== undefined ) {
  12224. switch ( value.length ) {
  12225. case 2:
  12226. _gl.vertexAttrib2fv( programAttribute, value );
  12227. break;
  12228. case 3:
  12229. _gl.vertexAttrib3fv( programAttribute, value );
  12230. break;
  12231. case 4:
  12232. _gl.vertexAttrib4fv( programAttribute, value );
  12233. break;
  12234. default:
  12235. _gl.vertexAttrib1fv( programAttribute, value );
  12236. }
  12237. }
  12238. }
  12239. }
  12240. }
  12241. state.disableUnusedAttributes();
  12242. }
  12243. // Sorting
  12244. function absNumericalSort( a, b ) {
  12245. return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
  12246. }
  12247. function painterSortStable( a, b ) {
  12248. if ( a.object.renderOrder !== b.object.renderOrder ) {
  12249. return a.object.renderOrder - b.object.renderOrder;
  12250. } else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {
  12251. return a.material.program.id - b.material.program.id;
  12252. } else if ( a.material.id !== b.material.id ) {
  12253. return a.material.id - b.material.id;
  12254. } else if ( a.z !== b.z ) {
  12255. return a.z - b.z;
  12256. } else {
  12257. return a.id - b.id;
  12258. }
  12259. }
  12260. function reversePainterSortStable( a, b ) {
  12261. if ( a.object.renderOrder !== b.object.renderOrder ) {
  12262. return a.object.renderOrder - b.object.renderOrder;
  12263. } if ( a.z !== b.z ) {
  12264. return b.z - a.z;
  12265. } else {
  12266. return a.id - b.id;
  12267. }
  12268. }
  12269. // Rendering
  12270. this.render = function ( scene, camera, renderTarget, forceClear ) {
  12271. if ( camera !== undefined && camera.isCamera !== true ) {
  12272. console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
  12273. return;
  12274. }
  12275. // reset caching for this frame
  12276. _currentGeometryProgram = '';
  12277. _currentMaterialId = - 1;
  12278. _currentCamera = null;
  12279. // update scene graph
  12280. if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
  12281. // update camera matrices and frustum
  12282. if ( camera.parent === null ) camera.updateMatrixWorld();
  12283. camera.matrixWorldInverse.getInverse( camera.matrixWorld );
  12284. _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
  12285. _frustum.setFromMatrix( _projScreenMatrix );
  12286. lights.length = 0;
  12287. opaqueObjectsLastIndex = - 1;
  12288. transparentObjectsLastIndex = - 1;
  12289. sprites.length = 0;
  12290. lensFlares.length = 0;
  12291. _localClippingEnabled = this.localClippingEnabled;
  12292. _clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
  12293. projectObject( scene, camera );
  12294. opaqueObjects.length = opaqueObjectsLastIndex + 1;
  12295. transparentObjects.length = transparentObjectsLastIndex + 1;
  12296. if ( _this.sortObjects === true ) {
  12297. opaqueObjects.sort( painterSortStable );
  12298. transparentObjects.sort( reversePainterSortStable );
  12299. }
  12300. //
  12301. if ( _clippingEnabled ) _clipping.beginShadows();
  12302. setupShadows( lights );
  12303. shadowMap.render( scene, camera );
  12304. setupLights( lights, camera );
  12305. if ( _clippingEnabled ) _clipping.endShadows();
  12306. //
  12307. _infoRender.calls = 0;
  12308. _infoRender.vertices = 0;
  12309. _infoRender.faces = 0;
  12310. _infoRender.points = 0;
  12311. if ( renderTarget === undefined ) {
  12312. renderTarget = null;
  12313. }
  12314. this.setRenderTarget( renderTarget );
  12315. //
  12316. var background = scene.background;
  12317. if ( background === null ) {
  12318. state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
  12319. } else if ( background && background.isColor ) {
  12320. state.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );
  12321. forceClear = true;
  12322. }
  12323. if ( this.autoClear || forceClear ) {
  12324. this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
  12325. }
  12326. if ( background && background.isCubeTexture ) {
  12327. if ( backgroundBoxCamera === undefined ) {
  12328. backgroundBoxCamera = new PerspectiveCamera();
  12329. backgroundBoxMesh = new Mesh(
  12330. new BoxBufferGeometry( 5, 5, 5 ),
  12331. new ShaderMaterial( {
  12332. uniforms: ShaderLib.cube.uniforms,
  12333. vertexShader: ShaderLib.cube.vertexShader,
  12334. fragmentShader: ShaderLib.cube.fragmentShader,
  12335. side: BackSide,
  12336. depthTest: false,
  12337. depthWrite: false,
  12338. fog: false
  12339. } )
  12340. );
  12341. }
  12342. backgroundBoxCamera.projectionMatrix.copy( camera.projectionMatrix );
  12343. backgroundBoxCamera.matrixWorld.extractRotation( camera.matrixWorld );
  12344. backgroundBoxCamera.matrixWorldInverse.getInverse( backgroundBoxCamera.matrixWorld );
  12345. backgroundBoxMesh.material.uniforms[ "tCube" ].value = background;
  12346. backgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundBoxCamera.matrixWorldInverse, backgroundBoxMesh.matrixWorld );
  12347. objects.update( backgroundBoxMesh );
  12348. _this.renderBufferDirect( backgroundBoxCamera, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );
  12349. } else if ( background && background.isTexture ) {
  12350. if ( backgroundPlaneCamera === undefined ) {
  12351. backgroundPlaneCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
  12352. backgroundPlaneMesh = new Mesh(
  12353. new PlaneBufferGeometry( 2, 2 ),
  12354. new MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )
  12355. );
  12356. }
  12357. backgroundPlaneMesh.material.map = background;
  12358. objects.update( backgroundPlaneMesh );
  12359. _this.renderBufferDirect( backgroundPlaneCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );
  12360. }
  12361. //
  12362. if ( scene.overrideMaterial ) {
  12363. var overrideMaterial = scene.overrideMaterial;
  12364. renderObjects( opaqueObjects, scene, camera, overrideMaterial );
  12365. renderObjects( transparentObjects, scene, camera, overrideMaterial );
  12366. } else {
  12367. // opaque pass (front-to-back order)
  12368. state.setBlending( NoBlending );
  12369. renderObjects( opaqueObjects, scene, camera );
  12370. // transparent pass (back-to-front order)
  12371. renderObjects( transparentObjects, scene, camera );
  12372. }
  12373. // custom render plugins (post pass)
  12374. spritePlugin.render( scene, camera );
  12375. lensFlarePlugin.render( scene, camera, _currentViewport );
  12376. // Generate mipmap if we're using any kind of mipmap filtering
  12377. if ( renderTarget ) {
  12378. textures.updateRenderTargetMipmap( renderTarget );
  12379. }
  12380. // Ensure depth buffer writing is enabled so it can be cleared on next render
  12381. state.setDepthTest( true );
  12382. state.setDepthWrite( true );
  12383. state.setColorWrite( true );
  12384. // _gl.finish();
  12385. };
  12386. function pushRenderItem( object, geometry, material, z, group ) {
  12387. var array, index;
  12388. // allocate the next position in the appropriate array
  12389. if ( material.transparent ) {
  12390. array = transparentObjects;
  12391. index = ++ transparentObjectsLastIndex;
  12392. } else {
  12393. array = opaqueObjects;
  12394. index = ++ opaqueObjectsLastIndex;
  12395. }
  12396. // recycle existing render item or grow the array
  12397. var renderItem = array[ index ];
  12398. if ( renderItem !== undefined ) {
  12399. renderItem.id = object.id;
  12400. renderItem.object = object;
  12401. renderItem.geometry = geometry;
  12402. renderItem.material = material;
  12403. renderItem.z = _vector3.z;
  12404. renderItem.group = group;
  12405. } else {
  12406. renderItem = {
  12407. id: object.id,
  12408. object: object,
  12409. geometry: geometry,
  12410. material: material,
  12411. z: _vector3.z,
  12412. group: group
  12413. };
  12414. // assert( index === array.length );
  12415. array.push( renderItem );
  12416. }
  12417. }
  12418. // TODO Duplicated code (Frustum)
  12419. function isObjectViewable( object ) {
  12420. var geometry = object.geometry;
  12421. if ( geometry.boundingSphere === null )
  12422. geometry.computeBoundingSphere();
  12423. _sphere.copy( geometry.boundingSphere ).
  12424. applyMatrix4( object.matrixWorld );
  12425. return isSphereViewable( _sphere );
  12426. }
  12427. function isSpriteViewable( sprite ) {
  12428. _sphere.center.set( 0, 0, 0 );
  12429. _sphere.radius = 0.7071067811865476;
  12430. _sphere.applyMatrix4( sprite.matrixWorld );
  12431. return isSphereViewable( _sphere );
  12432. }
  12433. function isSphereViewable( sphere ) {
  12434. if ( ! _frustum.intersectsSphere( sphere ) ) return false;
  12435. var numPlanes = _clipping.numPlanes;
  12436. if ( numPlanes === 0 ) return true;
  12437. var planes = _this.clippingPlanes,
  12438. center = sphere.center,
  12439. negRad = - sphere.radius,
  12440. i = 0;
  12441. do {
  12442. // out when deeper than radius in the negative halfspace
  12443. if ( planes[ i ].distanceToPoint( center ) < negRad ) return false;
  12444. } while ( ++ i !== numPlanes );
  12445. return true;
  12446. }
  12447. function projectObject( object, camera ) {
  12448. if ( object.visible === false ) return;
  12449. var visible = ( object.layers.mask & camera.layers.mask ) !== 0;
  12450. if ( visible ) {
  12451. if ( object.isLight ) {
  12452. lights.push( object );
  12453. } else if ( object.isSprite ) {
  12454. if ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {
  12455. sprites.push( object );
  12456. }
  12457. } else if ( object.isLensFlare ) {
  12458. lensFlares.push( object );
  12459. } else if ( object.isImmediateRenderObject ) {
  12460. if ( _this.sortObjects === true ) {
  12461. _vector3.setFromMatrixPosition( object.matrixWorld );
  12462. _vector3.applyMatrix4( _projScreenMatrix );
  12463. }
  12464. pushRenderItem( object, null, object.material, _vector3.z, null );
  12465. } else if ( object.isMesh || object.isLine || object.isPoints ) {
  12466. if ( object.isSkinnedMesh ) {
  12467. object.skeleton.update();
  12468. }
  12469. if ( object.frustumCulled === false || isObjectViewable( object ) === true ) {
  12470. var material = object.material;
  12471. if ( material.visible === true ) {
  12472. if ( _this.sortObjects === true ) {
  12473. _vector3.setFromMatrixPosition( object.matrixWorld );
  12474. _vector3.applyMatrix4( _projScreenMatrix );
  12475. }
  12476. var geometry = objects.update( object );
  12477. if ( material.isMultiMaterial ) {
  12478. var groups = geometry.groups;
  12479. var materials = material.materials;
  12480. for ( var i = 0, l = groups.length; i < l; i ++ ) {
  12481. var group = groups[ i ];
  12482. var groupMaterial = materials[ group.materialIndex ];
  12483. if ( groupMaterial.visible === true ) {
  12484. pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );
  12485. }
  12486. }
  12487. } else {
  12488. pushRenderItem( object, geometry, material, _vector3.z, null );
  12489. }
  12490. }
  12491. }
  12492. }
  12493. }
  12494. var children = object.children;
  12495. for ( var i = 0, l = children.length; i < l; i ++ ) {
  12496. projectObject( children[ i ], camera );
  12497. }
  12498. }
  12499. function renderObjects( renderList, scene, camera, overrideMaterial ) {
  12500. for ( var i = 0, l = renderList.length; i < l; i ++ ) {
  12501. var renderItem = renderList[ i ];
  12502. var object = renderItem.object;
  12503. var geometry = renderItem.geometry;
  12504. var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
  12505. var group = renderItem.group;
  12506. object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
  12507. object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
  12508. object.onBeforeRender( _this, scene, camera, geometry, material, group );
  12509. if ( object.isImmediateRenderObject ) {
  12510. setMaterial( material );
  12511. var program = setProgram( camera, scene.fog, material, object );
  12512. _currentGeometryProgram = '';
  12513. object.render( function ( object ) {
  12514. _this.renderBufferImmediate( object, program, material );
  12515. } );
  12516. } else {
  12517. _this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );
  12518. }
  12519. object.onAfterRender( _this, scene, camera, geometry, material, group );
  12520. }
  12521. }
  12522. function initMaterial( material, fog, object ) {
  12523. var materialProperties = properties.get( material );
  12524. var parameters = programCache.getParameters(
  12525. material, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );
  12526. var code = programCache.getProgramCode( material, parameters );
  12527. var program = materialProperties.program;
  12528. var programChange = true;
  12529. if ( program === undefined ) {
  12530. // new material
  12531. material.addEventListener( 'dispose', onMaterialDispose );
  12532. } else if ( program.code !== code ) {
  12533. // changed glsl or parameters
  12534. releaseMaterialProgramReference( material );
  12535. } else if ( parameters.shaderID !== undefined ) {
  12536. // same glsl and uniform list
  12537. return;
  12538. } else {
  12539. // only rebuild uniform list
  12540. programChange = false;
  12541. }
  12542. if ( programChange ) {
  12543. if ( parameters.shaderID ) {
  12544. var shader = ShaderLib[ parameters.shaderID ];
  12545. materialProperties.__webglShader = {
  12546. name: material.type,
  12547. uniforms: UniformsUtils.clone( shader.uniforms ),
  12548. vertexShader: shader.vertexShader,
  12549. fragmentShader: shader.fragmentShader
  12550. };
  12551. } else {
  12552. materialProperties.__webglShader = {
  12553. name: material.type,
  12554. uniforms: material.uniforms,
  12555. vertexShader: material.vertexShader,
  12556. fragmentShader: material.fragmentShader
  12557. };
  12558. }
  12559. material.__webglShader = materialProperties.__webglShader;
  12560. program = programCache.acquireProgram( material, parameters, code );
  12561. materialProperties.program = program;
  12562. material.program = program;
  12563. }
  12564. var attributes = program.getAttributes();
  12565. if ( material.morphTargets ) {
  12566. material.numSupportedMorphTargets = 0;
  12567. for ( var i = 0; i < _this.maxMorphTargets; i ++ ) {
  12568. if ( attributes[ 'morphTarget' + i ] >= 0 ) {
  12569. material.numSupportedMorphTargets ++;
  12570. }
  12571. }
  12572. }
  12573. if ( material.morphNormals ) {
  12574. material.numSupportedMorphNormals = 0;
  12575. for ( var i = 0; i < _this.maxMorphNormals; i ++ ) {
  12576. if ( attributes[ 'morphNormal' + i ] >= 0 ) {
  12577. material.numSupportedMorphNormals ++;
  12578. }
  12579. }
  12580. }
  12581. var uniforms = materialProperties.__webglShader.uniforms;
  12582. if ( ! material.isShaderMaterial &&
  12583. ! material.isRawShaderMaterial ||
  12584. material.clipping === true ) {
  12585. materialProperties.numClippingPlanes = _clipping.numPlanes;
  12586. materialProperties.numIntersection = _clipping.numIntersection;
  12587. uniforms.clippingPlanes = _clipping.uniform;
  12588. }
  12589. materialProperties.fog = fog;
  12590. // store the light setup it was created for
  12591. materialProperties.lightsHash = _lights.hash;
  12592. if ( material.lights ) {
  12593. // wire up the material to this renderer's lighting state
  12594. uniforms.ambientLightColor.value = _lights.ambient;
  12595. uniforms.directionalLights.value = _lights.directional;
  12596. uniforms.spotLights.value = _lights.spot;
  12597. uniforms.rectAreaLights.value = _lights.rectArea;
  12598. uniforms.pointLights.value = _lights.point;
  12599. uniforms.hemisphereLights.value = _lights.hemi;
  12600. uniforms.directionalShadowMap.value = _lights.directionalShadowMap;
  12601. uniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;
  12602. uniforms.spotShadowMap.value = _lights.spotShadowMap;
  12603. uniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;
  12604. uniforms.pointShadowMap.value = _lights.pointShadowMap;
  12605. uniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;
  12606. // TODO (abelnation): add area lights shadow info to uniforms
  12607. }
  12608. var progUniforms = materialProperties.program.getUniforms(),
  12609. uniformsList =
  12610. WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
  12611. materialProperties.uniformsList = uniformsList;
  12612. }
  12613. function setMaterial( material ) {
  12614. material.side === DoubleSide
  12615. ? state.disable( _gl.CULL_FACE )
  12616. : state.enable( _gl.CULL_FACE );
  12617. state.setFlipSided( material.side === BackSide );
  12618. material.transparent === true
  12619. ? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )
  12620. : state.setBlending( NoBlending );
  12621. state.setDepthFunc( material.depthFunc );
  12622. state.setDepthTest( material.depthTest );
  12623. state.setDepthWrite( material.depthWrite );
  12624. state.setColorWrite( material.colorWrite );
  12625. state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
  12626. }
  12627. function setProgram( camera, fog, material, object ) {
  12628. _usedTextureUnits = 0;
  12629. var materialProperties = properties.get( material );
  12630. if ( _clippingEnabled ) {
  12631. if ( _localClippingEnabled || camera !== _currentCamera ) {
  12632. var useCache =
  12633. camera === _currentCamera &&
  12634. material.id === _currentMaterialId;
  12635. // we might want to call this function with some ClippingGroup
  12636. // object instead of the material, once it becomes feasible
  12637. // (#8465, #8379)
  12638. _clipping.setState(
  12639. material.clippingPlanes, material.clipIntersection, material.clipShadows,
  12640. camera, materialProperties, useCache );
  12641. }
  12642. }
  12643. if ( material.needsUpdate === false ) {
  12644. if ( materialProperties.program === undefined ) {
  12645. material.needsUpdate = true;
  12646. } else if ( material.fog && materialProperties.fog !== fog ) {
  12647. material.needsUpdate = true;
  12648. } else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {
  12649. material.needsUpdate = true;
  12650. } else if ( materialProperties.numClippingPlanes !== undefined &&
  12651. ( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
  12652. materialProperties.numIntersection !== _clipping.numIntersection ) ) {
  12653. material.needsUpdate = true;
  12654. }
  12655. }
  12656. if ( material.needsUpdate ) {
  12657. initMaterial( material, fog, object );
  12658. material.needsUpdate = false;
  12659. }
  12660. var refreshProgram = false;
  12661. var refreshMaterial = false;
  12662. var refreshLights = false;
  12663. var program = materialProperties.program,
  12664. p_uniforms = program.getUniforms(),
  12665. m_uniforms = materialProperties.__webglShader.uniforms;
  12666. if ( program.id !== _currentProgram ) {
  12667. _gl.useProgram( program.program );
  12668. _currentProgram = program.id;
  12669. refreshProgram = true;
  12670. refreshMaterial = true;
  12671. refreshLights = true;
  12672. }
  12673. if ( material.id !== _currentMaterialId ) {
  12674. _currentMaterialId = material.id;
  12675. refreshMaterial = true;
  12676. }
  12677. if ( refreshProgram || camera !== _currentCamera ) {
  12678. p_uniforms.set( _gl, camera, 'projectionMatrix' );
  12679. if ( capabilities.logarithmicDepthBuffer ) {
  12680. p_uniforms.setValue( _gl, 'logDepthBufFC',
  12681. 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
  12682. }
  12683. if ( camera !== _currentCamera ) {
  12684. _currentCamera = camera;
  12685. // lighting uniforms depend on the camera so enforce an update
  12686. // now, in case this material supports lights - or later, when
  12687. // the next material that does gets activated:
  12688. refreshMaterial = true; // set to true on material change
  12689. refreshLights = true; // remains set until update done
  12690. }
  12691. // load material specific uniforms
  12692. // (shader material also gets them for the sake of genericity)
  12693. if ( material.isShaderMaterial ||
  12694. material.isMeshPhongMaterial ||
  12695. material.isMeshStandardMaterial ||
  12696. material.envMap ) {
  12697. var uCamPos = p_uniforms.map.cameraPosition;
  12698. if ( uCamPos !== undefined ) {
  12699. uCamPos.setValue( _gl,
  12700. _vector3.setFromMatrixPosition( camera.matrixWorld ) );
  12701. }
  12702. }
  12703. if ( material.isMeshPhongMaterial ||
  12704. material.isMeshLambertMaterial ||
  12705. material.isMeshBasicMaterial ||
  12706. material.isMeshStandardMaterial ||
  12707. material.isShaderMaterial ||
  12708. material.skinning ) {
  12709. p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
  12710. }
  12711. p_uniforms.set( _gl, _this, 'toneMappingExposure' );
  12712. p_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );
  12713. }
  12714. // skinning uniforms must be set even if material didn't change
  12715. // auto-setting of texture unit for bone texture must go before other textures
  12716. // not sure why, but otherwise weird things happen
  12717. if ( material.skinning ) {
  12718. p_uniforms.setOptional( _gl, object, 'bindMatrix' );
  12719. p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
  12720. var skeleton = object.skeleton;
  12721. if ( skeleton ) {
  12722. if ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {
  12723. p_uniforms.set( _gl, skeleton, 'boneTexture' );
  12724. p_uniforms.set( _gl, skeleton, 'boneTextureWidth' );
  12725. p_uniforms.set( _gl, skeleton, 'boneTextureHeight' );
  12726. } else {
  12727. p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
  12728. }
  12729. }
  12730. }
  12731. if ( refreshMaterial ) {
  12732. if ( material.lights ) {
  12733. // the current material requires lighting info
  12734. // note: all lighting uniforms are always set correctly
  12735. // they simply reference the renderer's state for their
  12736. // values
  12737. //
  12738. // use the current material's .needsUpdate flags to set
  12739. // the GL state when required
  12740. markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
  12741. }
  12742. // refresh uniforms common to several materials
  12743. if ( fog && material.fog ) {
  12744. refreshUniformsFog( m_uniforms, fog );
  12745. }
  12746. if ( material.isMeshBasicMaterial ||
  12747. material.isMeshLambertMaterial ||
  12748. material.isMeshPhongMaterial ||
  12749. material.isMeshStandardMaterial ||
  12750. material.isMeshNormalMaterial ||
  12751. material.isMeshDepthMaterial ) {
  12752. refreshUniformsCommon( m_uniforms, material );
  12753. }
  12754. // refresh single material specific uniforms
  12755. if ( material.isLineBasicMaterial ) {
  12756. refreshUniformsLine( m_uniforms, material );
  12757. } else if ( material.isLineDashedMaterial ) {
  12758. refreshUniformsLine( m_uniforms, material );
  12759. refreshUniformsDash( m_uniforms, material );
  12760. } else if ( material.isPointsMaterial ) {
  12761. refreshUniformsPoints( m_uniforms, material );
  12762. } else if ( material.isMeshLambertMaterial ) {
  12763. refreshUniformsLambert( m_uniforms, material );
  12764. } else if ( material.isMeshToonMaterial ) {
  12765. refreshUniformsToon( m_uniforms, material );
  12766. } else if ( material.isMeshPhongMaterial ) {
  12767. refreshUniformsPhong( m_uniforms, material );
  12768. } else if ( material.isMeshPhysicalMaterial ) {
  12769. refreshUniformsPhysical( m_uniforms, material );
  12770. } else if ( material.isMeshStandardMaterial ) {
  12771. refreshUniformsStandard( m_uniforms, material );
  12772. } else if ( material.isMeshDepthMaterial ) {
  12773. if ( material.displacementMap ) {
  12774. m_uniforms.displacementMap.value = material.displacementMap;
  12775. m_uniforms.displacementScale.value = material.displacementScale;
  12776. m_uniforms.displacementBias.value = material.displacementBias;
  12777. }
  12778. } else if ( material.isMeshNormalMaterial ) {
  12779. refreshUniformsNormal( m_uniforms, material );
  12780. }
  12781. // RectAreaLight Texture
  12782. // TODO (mrdoob): Find a nicer implementation
  12783. if ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = THREE.UniformsLib.LTC_MAT_TEXTURE;
  12784. if ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = THREE.UniformsLib.LTC_MAG_TEXTURE;
  12785. WebGLUniforms.upload(
  12786. _gl, materialProperties.uniformsList, m_uniforms, _this );
  12787. }
  12788. // common matrices
  12789. p_uniforms.set( _gl, object, 'modelViewMatrix' );
  12790. p_uniforms.set( _gl, object, 'normalMatrix' );
  12791. p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
  12792. return program;
  12793. }
  12794. // Uniforms (refresh uniforms objects)
  12795. function refreshUniformsCommon( uniforms, material ) {
  12796. uniforms.opacity.value = material.opacity;
  12797. uniforms.diffuse.value = material.color;
  12798. if ( material.emissive ) {
  12799. uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
  12800. }
  12801. uniforms.map.value = material.map;
  12802. uniforms.specularMap.value = material.specularMap;
  12803. uniforms.alphaMap.value = material.alphaMap;
  12804. if ( material.lightMap ) {
  12805. uniforms.lightMap.value = material.lightMap;
  12806. uniforms.lightMapIntensity.value = material.lightMapIntensity;
  12807. }
  12808. if ( material.aoMap ) {
  12809. uniforms.aoMap.value = material.aoMap;
  12810. uniforms.aoMapIntensity.value = material.aoMapIntensity;
  12811. }
  12812. // uv repeat and offset setting priorities
  12813. // 1. color map
  12814. // 2. specular map
  12815. // 3. normal map
  12816. // 4. bump map
  12817. // 5. alpha map
  12818. // 6. emissive map
  12819. var uvScaleMap;
  12820. if ( material.map ) {
  12821. uvScaleMap = material.map;
  12822. } else if ( material.specularMap ) {
  12823. uvScaleMap = material.specularMap;
  12824. } else if ( material.displacementMap ) {
  12825. uvScaleMap = material.displacementMap;
  12826. } else if ( material.normalMap ) {
  12827. uvScaleMap = material.normalMap;
  12828. } else if ( material.bumpMap ) {
  12829. uvScaleMap = material.bumpMap;
  12830. } else if ( material.roughnessMap ) {
  12831. uvScaleMap = material.roughnessMap;
  12832. } else if ( material.metalnessMap ) {
  12833. uvScaleMap = material.metalnessMap;
  12834. } else if ( material.alphaMap ) {
  12835. uvScaleMap = material.alphaMap;
  12836. } else if ( material.emissiveMap ) {
  12837. uvScaleMap = material.emissiveMap;
  12838. }
  12839. if ( uvScaleMap !== undefined ) {
  12840. // backwards compatibility
  12841. if ( uvScaleMap.isWebGLRenderTarget ) {
  12842. uvScaleMap = uvScaleMap.texture;
  12843. }
  12844. var offset = uvScaleMap.offset;
  12845. var repeat = uvScaleMap.repeat;
  12846. uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
  12847. }
  12848. uniforms.envMap.value = material.envMap;
  12849. // don't flip CubeTexture envMaps, flip everything else:
  12850. // WebGLRenderTargetCube will be flipped for backwards compatibility
  12851. // WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
  12852. // this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
  12853. uniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;
  12854. uniforms.reflectivity.value = material.reflectivity;
  12855. uniforms.refractionRatio.value = material.refractionRatio;
  12856. }
  12857. function refreshUniformsLine( uniforms, material ) {
  12858. uniforms.diffuse.value = material.color;
  12859. uniforms.opacity.value = material.opacity;
  12860. }
  12861. function refreshUniformsDash( uniforms, material ) {
  12862. uniforms.dashSize.value = material.dashSize;
  12863. uniforms.totalSize.value = material.dashSize + material.gapSize;
  12864. uniforms.scale.value = material.scale;
  12865. }
  12866. function refreshUniformsPoints( uniforms, material ) {
  12867. uniforms.diffuse.value = material.color;
  12868. uniforms.opacity.value = material.opacity;
  12869. uniforms.size.value = material.size * _pixelRatio;
  12870. uniforms.scale.value = _height * 0.5;
  12871. uniforms.map.value = material.map;
  12872. if ( material.map !== null ) {
  12873. var offset = material.map.offset;
  12874. var repeat = material.map.repeat;
  12875. uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
  12876. }
  12877. }
  12878. function refreshUniformsFog( uniforms, fog ) {
  12879. uniforms.fogColor.value = fog.color;
  12880. if ( fog.isFog ) {
  12881. uniforms.fogNear.value = fog.near;
  12882. uniforms.fogFar.value = fog.far;
  12883. } else if ( fog.isFogExp2 ) {
  12884. uniforms.fogDensity.value = fog.density;
  12885. }
  12886. }
  12887. function refreshUniformsLambert( uniforms, material ) {
  12888. if ( material.emissiveMap ) {
  12889. uniforms.emissiveMap.value = material.emissiveMap;
  12890. }
  12891. }
  12892. function refreshUniformsPhong( uniforms, material ) {
  12893. uniforms.specular.value = material.specular;
  12894. uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
  12895. if ( material.emissiveMap ) {
  12896. uniforms.emissiveMap.value = material.emissiveMap;
  12897. }
  12898. if ( material.bumpMap ) {
  12899. uniforms.bumpMap.value = material.bumpMap;
  12900. uniforms.bumpScale.value = material.bumpScale;
  12901. }
  12902. if ( material.normalMap ) {
  12903. uniforms.normalMap.value = material.normalMap;
  12904. uniforms.normalScale.value.copy( material.normalScale );
  12905. }
  12906. if ( material.displacementMap ) {
  12907. uniforms.displacementMap.value = material.displacementMap;
  12908. uniforms.displacementScale.value = material.displacementScale;
  12909. uniforms.displacementBias.value = material.displacementBias;
  12910. }
  12911. }
  12912. function refreshUniformsToon( uniforms, material ) {
  12913. refreshUniformsPhong( uniforms, material );
  12914. if ( material.gradientMap ) {
  12915. uniforms.gradientMap.value = material.gradientMap;
  12916. }
  12917. }
  12918. function refreshUniformsStandard( uniforms, material ) {
  12919. uniforms.roughness.value = material.roughness;
  12920. uniforms.metalness.value = material.metalness;
  12921. if ( material.roughnessMap ) {
  12922. uniforms.roughnessMap.value = material.roughnessMap;
  12923. }
  12924. if ( material.metalnessMap ) {
  12925. uniforms.metalnessMap.value = material.metalnessMap;
  12926. }
  12927. if ( material.emissiveMap ) {
  12928. uniforms.emissiveMap.value = material.emissiveMap;
  12929. }
  12930. if ( material.bumpMap ) {
  12931. uniforms.bumpMap.value = material.bumpMap;
  12932. uniforms.bumpScale.value = material.bumpScale;
  12933. }
  12934. if ( material.normalMap ) {
  12935. uniforms.normalMap.value = material.normalMap;
  12936. uniforms.normalScale.value.copy( material.normalScale );
  12937. }
  12938. if ( material.displacementMap ) {
  12939. uniforms.displacementMap.value = material.displacementMap;
  12940. uniforms.displacementScale.value = material.displacementScale;
  12941. uniforms.displacementBias.value = material.displacementBias;
  12942. }
  12943. if ( material.envMap ) {
  12944. //uniforms.envMap.value = material.envMap; // part of uniforms common
  12945. uniforms.envMapIntensity.value = material.envMapIntensity;
  12946. }
  12947. }
  12948. function refreshUniformsPhysical( uniforms, material ) {
  12949. uniforms.clearCoat.value = material.clearCoat;
  12950. uniforms.clearCoatRoughness.value = material.clearCoatRoughness;
  12951. refreshUniformsStandard( uniforms, material );
  12952. }
  12953. function refreshUniformsNormal( uniforms, material ) {
  12954. if ( material.bumpMap ) {
  12955. uniforms.bumpMap.value = material.bumpMap;
  12956. uniforms.bumpScale.value = material.bumpScale;
  12957. }
  12958. if ( material.normalMap ) {
  12959. uniforms.normalMap.value = material.normalMap;
  12960. uniforms.normalScale.value.copy( material.normalScale );
  12961. }
  12962. if ( material.displacementMap ) {
  12963. uniforms.displacementMap.value = material.displacementMap;
  12964. uniforms.displacementScale.value = material.displacementScale;
  12965. uniforms.displacementBias.value = material.displacementBias;
  12966. }
  12967. }
  12968. // If uniforms are marked as clean, they don't need to be loaded to the GPU.
  12969. function markUniformsLightsNeedsUpdate( uniforms, value ) {
  12970. uniforms.ambientLightColor.needsUpdate = value;
  12971. uniforms.directionalLights.needsUpdate = value;
  12972. uniforms.pointLights.needsUpdate = value;
  12973. uniforms.spotLights.needsUpdate = value;
  12974. uniforms.rectAreaLights.needsUpdate = value;
  12975. uniforms.hemisphereLights.needsUpdate = value;
  12976. }
  12977. // Lighting
  12978. function setupShadows( lights ) {
  12979. var lightShadowsLength = 0;
  12980. for ( var i = 0, l = lights.length; i < l; i ++ ) {
  12981. var light = lights[ i ];
  12982. if ( light.castShadow ) {
  12983. _lights.shadows[ lightShadowsLength ++ ] = light;
  12984. }
  12985. }
  12986. _lights.shadows.length = lightShadowsLength;
  12987. }
  12988. function setupLights( lights, camera ) {
  12989. var l, ll, light,
  12990. r = 0, g = 0, b = 0,
  12991. color,
  12992. intensity,
  12993. distance,
  12994. shadowMap,
  12995. viewMatrix = camera.matrixWorldInverse,
  12996. directionalLength = 0,
  12997. pointLength = 0,
  12998. spotLength = 0,
  12999. rectAreaLength = 0,
  13000. hemiLength = 0;
  13001. for ( l = 0, ll = lights.length; l < ll; l ++ ) {
  13002. light = lights[ l ];
  13003. color = light.color;
  13004. intensity = light.intensity;
  13005. distance = light.distance;
  13006. shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
  13007. if ( light.isAmbientLight ) {
  13008. r += color.r * intensity;
  13009. g += color.g * intensity;
  13010. b += color.b * intensity;
  13011. } else if ( light.isDirectionalLight ) {
  13012. var uniforms = lightCache.get( light );
  13013. uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
  13014. uniforms.direction.setFromMatrixPosition( light.matrixWorld );
  13015. _vector3.setFromMatrixPosition( light.target.matrixWorld );
  13016. uniforms.direction.sub( _vector3 );
  13017. uniforms.direction.transformDirection( viewMatrix );
  13018. uniforms.shadow = light.castShadow;
  13019. if ( light.castShadow ) {
  13020. uniforms.shadowBias = light.shadow.bias;
  13021. uniforms.shadowRadius = light.shadow.radius;
  13022. uniforms.shadowMapSize = light.shadow.mapSize;
  13023. }
  13024. _lights.directionalShadowMap[ directionalLength ] = shadowMap;
  13025. _lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
  13026. _lights.directional[ directionalLength ++ ] = uniforms;
  13027. } else if ( light.isSpotLight ) {
  13028. var uniforms = lightCache.get( light );
  13029. uniforms.position.setFromMatrixPosition( light.matrixWorld );
  13030. uniforms.position.applyMatrix4( viewMatrix );
  13031. uniforms.color.copy( color ).multiplyScalar( intensity );
  13032. uniforms.distance = distance;
  13033. uniforms.direction.setFromMatrixPosition( light.matrixWorld );
  13034. _vector3.setFromMatrixPosition( light.target.matrixWorld );
  13035. uniforms.direction.sub( _vector3 );
  13036. uniforms.direction.transformDirection( viewMatrix );
  13037. uniforms.coneCos = Math.cos( light.angle );
  13038. uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
  13039. uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
  13040. uniforms.shadow = light.castShadow;
  13041. if ( light.castShadow ) {
  13042. uniforms.shadowBias = light.shadow.bias;
  13043. uniforms.shadowRadius = light.shadow.radius;
  13044. uniforms.shadowMapSize = light.shadow.mapSize;
  13045. }
  13046. _lights.spotShadowMap[ spotLength ] = shadowMap;
  13047. _lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
  13048. _lights.spot[ spotLength ++ ] = uniforms;
  13049. } else if ( light.isRectAreaLight ) {
  13050. var uniforms = lightCache.get( light );
  13051. // (a) intensity controls irradiance of entire light
  13052. uniforms.color
  13053. .copy( color )
  13054. .multiplyScalar( intensity / ( light.width * light.height ) );
  13055. // (b) intensity controls the radiance per light area
  13056. // uniforms.color.copy( color ).multiplyScalar( intensity );
  13057. uniforms.position.setFromMatrixPosition( light.matrixWorld );
  13058. uniforms.position.applyMatrix4( viewMatrix );
  13059. // extract local rotation of light to derive width/height half vectors
  13060. _matrix42.identity();
  13061. _matrix4.copy( light.matrixWorld );
  13062. _matrix4.premultiply( viewMatrix );
  13063. _matrix42.extractRotation( _matrix4 );
  13064. uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );
  13065. uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );
  13066. uniforms.halfWidth.applyMatrix4( _matrix42 );
  13067. uniforms.halfHeight.applyMatrix4( _matrix42 );
  13068. // TODO (abelnation): RectAreaLight distance?
  13069. // uniforms.distance = distance;
  13070. _lights.rectArea[ rectAreaLength ++ ] = uniforms;
  13071. } else if ( light.isPointLight ) {
  13072. var uniforms = lightCache.get( light );
  13073. uniforms.position.setFromMatrixPosition( light.matrixWorld );
  13074. uniforms.position.applyMatrix4( viewMatrix );
  13075. uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
  13076. uniforms.distance = light.distance;
  13077. uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
  13078. uniforms.shadow = light.castShadow;
  13079. if ( light.castShadow ) {
  13080. uniforms.shadowBias = light.shadow.bias;
  13081. uniforms.shadowRadius = light.shadow.radius;
  13082. uniforms.shadowMapSize = light.shadow.mapSize;
  13083. }
  13084. _lights.pointShadowMap[ pointLength ] = shadowMap;
  13085. if ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {
  13086. _lights.pointShadowMatrix[ pointLength ] = new Matrix4();
  13087. }
  13088. // for point lights we set the shadow matrix to be a translation-only matrix
  13089. // equal to inverse of the light's position
  13090. _vector3.setFromMatrixPosition( light.matrixWorld ).negate();
  13091. _lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );
  13092. _lights.point[ pointLength ++ ] = uniforms;
  13093. } else if ( light.isHemisphereLight ) {
  13094. var uniforms = lightCache.get( light );
  13095. uniforms.direction.setFromMatrixPosition( light.matrixWorld );
  13096. uniforms.direction.transformDirection( viewMatrix );
  13097. uniforms.direction.normalize();
  13098. uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
  13099. uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
  13100. _lights.hemi[ hemiLength ++ ] = uniforms;
  13101. }
  13102. }
  13103. _lights.ambient[ 0 ] = r;
  13104. _lights.ambient[ 1 ] = g;
  13105. _lights.ambient[ 2 ] = b;
  13106. _lights.directional.length = directionalLength;
  13107. _lights.spot.length = spotLength;
  13108. _lights.rectArea.length = rectAreaLength;
  13109. _lights.point.length = pointLength;
  13110. _lights.hemi.length = hemiLength;
  13111. // TODO (sam-g-steel) why aren't we using join
  13112. _lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;
  13113. }
  13114. // GL state setting
  13115. this.setFaceCulling = function ( cullFace, frontFaceDirection ) {
  13116. state.setCullFace( cullFace );
  13117. state.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );
  13118. };
  13119. // Textures
  13120. function allocTextureUnit() {
  13121. var textureUnit = _usedTextureUnits;
  13122. if ( textureUnit >= capabilities.maxTextures ) {
  13123. console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
  13124. }
  13125. _usedTextureUnits += 1;
  13126. return textureUnit;
  13127. }
  13128. this.allocTextureUnit = allocTextureUnit;
  13129. // this.setTexture2D = setTexture2D;
  13130. this.setTexture2D = ( function() {
  13131. var warned = false;
  13132. // backwards compatibility: peel texture.texture
  13133. return function setTexture2D( texture, slot ) {
  13134. if ( texture && texture.isWebGLRenderTarget ) {
  13135. if ( ! warned ) {
  13136. console.warn( "THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead." );
  13137. warned = true;
  13138. }
  13139. texture = texture.texture;
  13140. }
  13141. textures.setTexture2D( texture, slot );
  13142. };
  13143. }() );
  13144. this.setTexture = ( function() {
  13145. var warned = false;
  13146. return function setTexture( texture, slot ) {
  13147. if ( ! warned ) {
  13148. console.warn( "THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead." );
  13149. warned = true;
  13150. }
  13151. textures.setTexture2D( texture, slot );
  13152. };
  13153. }() );
  13154. this.setTextureCube = ( function() {
  13155. var warned = false;
  13156. return function setTextureCube( texture, slot ) {
  13157. // backwards compatibility: peel texture.texture
  13158. if ( texture && texture.isWebGLRenderTargetCube ) {
  13159. if ( ! warned ) {
  13160. console.warn( "THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead." );
  13161. warned = true;
  13162. }
  13163. texture = texture.texture;
  13164. }
  13165. // currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture
  13166. // TODO: unify these code paths
  13167. if ( ( texture && texture.isCubeTexture ) ||
  13168. ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
  13169. // CompressedTexture can have Array in image :/
  13170. // this function alone should take care of cube textures
  13171. textures.setTextureCube( texture, slot );
  13172. } else {
  13173. // assumed: texture property of THREE.WebGLRenderTargetCube
  13174. textures.setTextureCubeDynamic( texture, slot );
  13175. }
  13176. };
  13177. }() );
  13178. this.getCurrentRenderTarget = function() {
  13179. return _currentRenderTarget;
  13180. };
  13181. this.setRenderTarget = function ( renderTarget ) {
  13182. _currentRenderTarget = renderTarget;
  13183. if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
  13184. textures.setupRenderTarget( renderTarget );
  13185. }
  13186. var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );
  13187. var framebuffer;
  13188. if ( renderTarget ) {
  13189. var renderTargetProperties = properties.get( renderTarget );
  13190. if ( isCube ) {
  13191. framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
  13192. } else {
  13193. framebuffer = renderTargetProperties.__webglFramebuffer;
  13194. }
  13195. _currentScissor.copy( renderTarget.scissor );
  13196. _currentScissorTest = renderTarget.scissorTest;
  13197. _currentViewport.copy( renderTarget.viewport );
  13198. } else {
  13199. framebuffer = null;
  13200. _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
  13201. _currentScissorTest = _scissorTest;
  13202. _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
  13203. }
  13204. if ( _currentFramebuffer !== framebuffer ) {
  13205. _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
  13206. _currentFramebuffer = framebuffer;
  13207. }
  13208. state.scissor( _currentScissor );
  13209. state.setScissorTest( _currentScissorTest );
  13210. state.viewport( _currentViewport );
  13211. if ( isCube ) {
  13212. var textureProperties = properties.get( renderTarget.texture );
  13213. _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
  13214. }
  13215. };
  13216. this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {
  13217. if ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {
  13218. console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
  13219. return;
  13220. }
  13221. var framebuffer = properties.get( renderTarget ).__webglFramebuffer;
  13222. if ( framebuffer ) {
  13223. var restore = false;
  13224. if ( framebuffer !== _currentFramebuffer ) {
  13225. _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
  13226. restore = true;
  13227. }
  13228. try {
  13229. var texture = renderTarget.texture;
  13230. var textureFormat = texture.format;
  13231. var textureType = texture.type;
  13232. if ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
  13233. console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );
  13234. return;
  13235. }
  13236. if ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)
  13237. ! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
  13238. ! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {
  13239. console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
  13240. return;
  13241. }
  13242. if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {
  13243. // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)
  13244. if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {
  13245. _gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );
  13246. }
  13247. } else {
  13248. console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );
  13249. }
  13250. } finally {
  13251. if ( restore ) {
  13252. _gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );
  13253. }
  13254. }
  13255. }
  13256. };
  13257. // Map three.js constants to WebGL constants
  13258. function paramThreeToGL( p ) {
  13259. var extension;
  13260. if ( p === RepeatWrapping ) return _gl.REPEAT;
  13261. if ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
  13262. if ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;
  13263. if ( p === NearestFilter ) return _gl.NEAREST;
  13264. if ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;
  13265. if ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;
  13266. if ( p === LinearFilter ) return _gl.LINEAR;
  13267. if ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;
  13268. if ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;
  13269. if ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;
  13270. if ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;
  13271. if ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;
  13272. if ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;
  13273. if ( p === ByteType ) return _gl.BYTE;
  13274. if ( p === ShortType ) return _gl.SHORT;
  13275. if ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;
  13276. if ( p === IntType ) return _gl.INT;
  13277. if ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;
  13278. if ( p === FloatType ) return _gl.FLOAT;
  13279. if ( p === HalfFloatType ) {
  13280. extension = extensions.get( 'OES_texture_half_float' );
  13281. if ( extension !== null ) return extension.HALF_FLOAT_OES;
  13282. }
  13283. if ( p === AlphaFormat ) return _gl.ALPHA;
  13284. if ( p === RGBFormat ) return _gl.RGB;
  13285. if ( p === RGBAFormat ) return _gl.RGBA;
  13286. if ( p === LuminanceFormat ) return _gl.LUMINANCE;
  13287. if ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;
  13288. if ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;
  13289. if ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;
  13290. if ( p === AddEquation ) return _gl.FUNC_ADD;
  13291. if ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;
  13292. if ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;
  13293. if ( p === ZeroFactor ) return _gl.ZERO;
  13294. if ( p === OneFactor ) return _gl.ONE;
  13295. if ( p === SrcColorFactor ) return _gl.SRC_COLOR;
  13296. if ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;
  13297. if ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;
  13298. if ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;
  13299. if ( p === DstAlphaFactor ) return _gl.DST_ALPHA;
  13300. if ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;
  13301. if ( p === DstColorFactor ) return _gl.DST_COLOR;
  13302. if ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;
  13303. if ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;
  13304. if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||
  13305. p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {
  13306. extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
  13307. if ( extension !== null ) {
  13308. if ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;
  13309. if ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;
  13310. if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;
  13311. if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;
  13312. }
  13313. }
  13314. if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||
  13315. p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {
  13316. extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );
  13317. if ( extension !== null ) {
  13318. if ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  13319. if ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  13320. if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  13321. if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  13322. }
  13323. }
  13324. if ( p === RGB_ETC1_Format ) {
  13325. extension = extensions.get( 'WEBGL_compressed_texture_etc1' );
  13326. if ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;
  13327. }
  13328. if ( p === MinEquation || p === MaxEquation ) {
  13329. extension = extensions.get( 'EXT_blend_minmax' );
  13330. if ( extension !== null ) {
  13331. if ( p === MinEquation ) return extension.MIN_EXT;
  13332. if ( p === MaxEquation ) return extension.MAX_EXT;
  13333. }
  13334. }
  13335. if ( p === UnsignedInt248Type ) {
  13336. extension = extensions.get( 'WEBGL_depth_texture' );
  13337. if ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;
  13338. }
  13339. return 0;
  13340. }
  13341. }
  13342. /**
  13343. * @author mrdoob / http://mrdoob.com/
  13344. */
  13345. function Scene () {
  13346. Object3D.call( this );
  13347. this.type = 'Scene';
  13348. this.background = null;
  13349. this.fog = null;
  13350. this.overrideMaterial = null;
  13351. this.autoUpdate = true; // checked by the renderer
  13352. }
  13353. Scene.prototype = Object.create( Object3D.prototype );
  13354. Scene.prototype.constructor = Scene;
  13355. Scene.prototype.copy = function ( source, recursive ) {
  13356. Object3D.prototype.copy.call( this, source, recursive );
  13357. if ( source.background !== null ) this.background = source.background.clone();
  13358. if ( source.fog !== null ) this.fog = source.fog.clone();
  13359. if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
  13360. this.autoUpdate = source.autoUpdate;
  13361. this.matrixAutoUpdate = source.matrixAutoUpdate;
  13362. return this;
  13363. };
  13364. Scene.prototype.toJSON = function ( meta ) {
  13365. var data = Object3D.prototype.toJSON.call( this, meta );
  13366. if ( this.background !== null ) data.object.background = this.background.toJSON( meta );
  13367. if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
  13368. return data;
  13369. };
  13370. /**
  13371. * @author mrdoob / http://mrdoob.com/
  13372. */
  13373. function VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
  13374. Texture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
  13375. this.generateMipmaps = false;
  13376. var scope = this;
  13377. function update() {
  13378. requestAnimationFrame( update );
  13379. if ( video.readyState >= video.HAVE_CURRENT_DATA ) {
  13380. scope.needsUpdate = true;
  13381. }
  13382. }
  13383. update();
  13384. }
  13385. VideoTexture.prototype = Object.create( Texture.prototype );
  13386. VideoTexture.prototype.constructor = VideoTexture;
  13387. /**
  13388. * @author mrdoob / http://mrdoob.com/
  13389. */
  13390. var Cache = {
  13391. enabled: false,
  13392. files: {},
  13393. add: function ( key, file ) {
  13394. if ( this.enabled === false ) return;
  13395. // console.log( 'THREE.Cache', 'Adding key:', key );
  13396. this.files[ key ] = file;
  13397. },
  13398. get: function ( key ) {
  13399. if ( this.enabled === false ) return;
  13400. // console.log( 'THREE.Cache', 'Checking key:', key );
  13401. return this.files[ key ];
  13402. },
  13403. remove: function ( key ) {
  13404. delete this.files[ key ];
  13405. },
  13406. clear: function () {
  13407. this.files = {};
  13408. }
  13409. };
  13410. /**
  13411. * @author mrdoob / http://mrdoob.com/
  13412. */
  13413. function LoadingManager( onLoad, onProgress, onError ) {
  13414. var scope = this;
  13415. var isLoading = false, itemsLoaded = 0, itemsTotal = 0;
  13416. this.onStart = undefined;
  13417. this.onLoad = onLoad;
  13418. this.onProgress = onProgress;
  13419. this.onError = onError;
  13420. this.itemStart = function ( url ) {
  13421. itemsTotal ++;
  13422. if ( isLoading === false ) {
  13423. if ( scope.onStart !== undefined ) {
  13424. scope.onStart( url, itemsLoaded, itemsTotal );
  13425. }
  13426. }
  13427. isLoading = true;
  13428. };
  13429. this.itemEnd = function ( url ) {
  13430. itemsLoaded ++;
  13431. if ( scope.onProgress !== undefined ) {
  13432. scope.onProgress( url, itemsLoaded, itemsTotal );
  13433. }
  13434. if ( itemsLoaded === itemsTotal ) {
  13435. isLoading = false;
  13436. if ( scope.onLoad !== undefined ) {
  13437. scope.onLoad();
  13438. }
  13439. }
  13440. };
  13441. this.itemError = function ( url ) {
  13442. if ( scope.onError !== undefined ) {
  13443. scope.onError( url );
  13444. }
  13445. };
  13446. }
  13447. var DefaultLoadingManager = new LoadingManager();
  13448. /**
  13449. * @author mrdoob / http://mrdoob.com/
  13450. */
  13451. function ImageLoader( manager ) {
  13452. this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
  13453. }
  13454. Object.assign( ImageLoader.prototype, {
  13455. load: function ( url, onLoad, onProgress, onError ) {
  13456. if ( url === undefined ) url = '';
  13457. if ( this.path !== undefined ) url = this.path + url;
  13458. var scope = this;
  13459. var cached = Cache.get( url );
  13460. if ( cached !== undefined ) {
  13461. scope.manager.itemStart( url );
  13462. setTimeout( function () {
  13463. if ( onLoad ) onLoad( cached );
  13464. scope.manager.itemEnd( url );
  13465. }, 0 );
  13466. return cached;
  13467. }
  13468. var image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );
  13469. image.addEventListener( 'load', function () {
  13470. Cache.add( url, this );
  13471. if ( onLoad ) onLoad( this );
  13472. scope.manager.itemEnd( url );
  13473. }, false );
  13474. /*
  13475. image.addEventListener( 'progress', function ( event ) {
  13476. if ( onProgress ) onProgress( event );
  13477. }, false );
  13478. */
  13479. image.addEventListener( 'error', function ( event ) {
  13480. if ( onError ) onError( event );
  13481. scope.manager.itemError( url );
  13482. }, false );
  13483. if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;
  13484. scope.manager.itemStart( url );
  13485. image.src = url;
  13486. return image;
  13487. },
  13488. setCrossOrigin: function ( value ) {
  13489. this.crossOrigin = value;
  13490. return this;
  13491. },
  13492. setPath: function ( value ) {
  13493. this.path = value;
  13494. return this;
  13495. }
  13496. } );
  13497. /**
  13498. * @author mrdoob / http://mrdoob.com/
  13499. */
  13500. function TextureLoader( manager ) {
  13501. this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
  13502. }
  13503. Object.assign( TextureLoader.prototype, {
  13504. load: function ( url, onLoad, onProgress, onError ) {
  13505. var texture = new Texture();
  13506. var loader = new ImageLoader( this.manager );
  13507. loader.setCrossOrigin( this.crossOrigin );
  13508. loader.setPath( this.path );
  13509. loader.load( url, function ( image ) {
  13510. // JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.
  13511. var isJPEG = url.search( /\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\:image\/jpeg/ ) === 0;
  13512. texture.format = isJPEG ? RGBFormat : RGBAFormat;
  13513. texture.image = image;
  13514. texture.needsUpdate = true;
  13515. if ( onLoad !== undefined ) {
  13516. onLoad( texture );
  13517. }
  13518. }, onProgress, onError );
  13519. return texture;
  13520. },
  13521. setCrossOrigin: function ( value ) {
  13522. this.crossOrigin = value;
  13523. return this;
  13524. },
  13525. setPath: function ( value ) {
  13526. this.path = value;
  13527. return this;
  13528. }
  13529. } );
  13530. /**
  13531. * @author mrdoob / http://mrdoob.com/
  13532. * @author bhouston / http://clara.io/
  13533. * @author stephomi / http://stephaneginier.com/
  13534. */
  13535. function Raycaster( origin, direction, near, far ) {
  13536. this.ray = new Ray( origin, direction );
  13537. // direction is assumed to be normalized (for accurate distance calculations)
  13538. this.near = near || 0;
  13539. this.far = far || Infinity;
  13540. this.params = {
  13541. Mesh: {},
  13542. Line: {},
  13543. LOD: {},
  13544. Points: { threshold: 1 },
  13545. Sprite: {}
  13546. };
  13547. Object.defineProperties( this.params, {
  13548. PointCloud: {
  13549. get: function () {
  13550. console.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );
  13551. return this.Points;
  13552. }
  13553. }
  13554. } );
  13555. }
  13556. function ascSort( a, b ) {
  13557. return a.distance - b.distance;
  13558. }
  13559. function intersectObject( object, raycaster, intersects, recursive ) {
  13560. if ( object.visible === false ) return;
  13561. object.raycast( raycaster, intersects );
  13562. if ( recursive === true ) {
  13563. var children = object.children;
  13564. for ( var i = 0, l = children.length; i < l; i ++ ) {
  13565. intersectObject( children[ i ], raycaster, intersects, true );
  13566. }
  13567. }
  13568. }
  13569. //
  13570. Raycaster.prototype = {
  13571. constructor: Raycaster,
  13572. linePrecision: 1,
  13573. set: function ( origin, direction ) {
  13574. // direction is assumed to be normalized (for accurate distance calculations)
  13575. this.ray.set( origin, direction );
  13576. },
  13577. setFromCamera: function ( coords, camera ) {
  13578. if ( (camera && camera.isPerspectiveCamera) ) {
  13579. this.ray.origin.setFromMatrixPosition( camera.matrixWorld );
  13580. this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();
  13581. } else if ( (camera && camera.isOrthographicCamera) ) {
  13582. this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera
  13583. this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
  13584. } else {
  13585. console.error( 'THREE.Raycaster: Unsupported camera type.' );
  13586. }
  13587. },
  13588. intersectObject: function ( object, recursive ) {
  13589. var intersects = [];
  13590. intersectObject( object, this, intersects, recursive );
  13591. intersects.sort( ascSort );
  13592. return intersects;
  13593. },
  13594. intersectObjects: function ( objects, recursive ) {
  13595. var intersects = [];
  13596. if ( Array.isArray( objects ) === false ) {
  13597. console.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );
  13598. return intersects;
  13599. }
  13600. for ( var i = 0, l = objects.length; i < l; i ++ ) {
  13601. intersectObject( objects[ i ], this, intersects, recursive );
  13602. }
  13603. intersects.sort( ascSort );
  13604. return intersects;
  13605. }
  13606. };
  13607. /**
  13608. * @author oosmoxiecode
  13609. * @author mrdoob / http://mrdoob.com/
  13610. * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888
  13611. */
  13612. function TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {
  13613. Geometry.call( this );
  13614. this.type = 'TorusGeometry';
  13615. this.parameters = {
  13616. radius: radius,
  13617. tube: tube,
  13618. radialSegments: radialSegments,
  13619. tubularSegments: tubularSegments,
  13620. arc: arc
  13621. };
  13622. this.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );
  13623. }
  13624. TorusGeometry.prototype = Object.create( Geometry.prototype );
  13625. TorusGeometry.prototype.constructor = TorusGeometry;
  13626. /**
  13627. * @author Mugen87 / https://github.com/Mugen87
  13628. */
  13629. function TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {
  13630. BufferGeometry.call( this );
  13631. this.type = 'TorusBufferGeometry';
  13632. this.parameters = {
  13633. radius: radius,
  13634. tube: tube,
  13635. radialSegments: radialSegments,
  13636. tubularSegments: tubularSegments,
  13637. arc: arc
  13638. };
  13639. radius = radius || 100;
  13640. tube = tube || 40;
  13641. radialSegments = Math.floor( radialSegments ) || 8;
  13642. tubularSegments = Math.floor( tubularSegments ) || 6;
  13643. arc = arc || Math.PI * 2;
  13644. // buffers
  13645. var indices = [];
  13646. var vertices = [];
  13647. var normals = [];
  13648. var uvs = [];
  13649. // helper variables
  13650. var center = new Vector3();
  13651. var vertex = new Vector3();
  13652. var normal = new Vector3();
  13653. var j, i;
  13654. // generate vertices, normals and uvs
  13655. for ( j = 0; j <= radialSegments; j ++ ) {
  13656. for ( i = 0; i <= tubularSegments; i ++ ) {
  13657. var u = i / tubularSegments * arc;
  13658. var v = j / radialSegments * Math.PI * 2;
  13659. // vertex
  13660. vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );
  13661. vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );
  13662. vertex.z = tube * Math.sin( v );
  13663. vertices.push( vertex.x, vertex.y, vertex.z );
  13664. // normal
  13665. center.x = radius * Math.cos( u );
  13666. center.y = radius * Math.sin( u );
  13667. normal.subVectors( vertex, center ).normalize();
  13668. normals.push( normal.x, normal.y, normal.z );
  13669. // uv
  13670. uvs.push( i / tubularSegments );
  13671. uvs.push( j / radialSegments );
  13672. }
  13673. }
  13674. // generate indices
  13675. for ( j = 1; j <= radialSegments; j ++ ) {
  13676. for ( i = 1; i <= tubularSegments; i ++ ) {
  13677. // indices
  13678. var a = ( tubularSegments + 1 ) * j + i - 1;
  13679. var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;
  13680. var c = ( tubularSegments + 1 ) * ( j - 1 ) + i;
  13681. var d = ( tubularSegments + 1 ) * j + i;
  13682. // faces
  13683. indices.push( a, b, d );
  13684. indices.push( b, c, d );
  13685. }
  13686. }
  13687. // build geometry
  13688. this.setIndex( indices );
  13689. this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
  13690. this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
  13691. this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
  13692. }
  13693. TorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
  13694. TorusBufferGeometry.prototype.constructor = TorusBufferGeometry;
  13695. /**
  13696. * @author mrdoob / http://mrdoob.com/
  13697. */
  13698. function SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
  13699. Geometry.call( this );
  13700. this.type = 'SphereGeometry';
  13701. this.parameters = {
  13702. radius: radius,
  13703. widthSegments: widthSegments,
  13704. heightSegments: heightSegments,
  13705. phiStart: phiStart,
  13706. phiLength: phiLength,
  13707. thetaStart: thetaStart,
  13708. thetaLength: thetaLength
  13709. };
  13710. this.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );
  13711. }
  13712. SphereGeometry.prototype = Object.create( Geometry.prototype );
  13713. SphereGeometry.prototype.constructor = SphereGeometry;
  13714. /**
  13715. * @author benaadams / https://twitter.com/ben_a_adams
  13716. * @author Mugen87 / https://github.com/Mugen87
  13717. */
  13718. function SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
  13719. BufferGeometry.call( this );
  13720. this.type = 'SphereBufferGeometry';
  13721. this.parameters = {
  13722. radius: radius,
  13723. widthSegments: widthSegments,
  13724. heightSegments: heightSegments,
  13725. phiStart: phiStart,
  13726. phiLength: phiLength,
  13727. thetaStart: thetaStart,
  13728. thetaLength: thetaLength
  13729. };
  13730. radius = radius || 50;
  13731. widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );
  13732. heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );
  13733. phiStart = phiStart !== undefined ? phiStart : 0;
  13734. phiLength = phiLength !== undefined ? phiLength : Math.PI * 2;
  13735. thetaStart = thetaStart !== undefined ? thetaStart : 0;
  13736. thetaLength = thetaLength !== undefined ? thetaLength : Math.PI;
  13737. var thetaEnd = thetaStart + thetaLength;
  13738. var ix, iy;
  13739. var index = 0;
  13740. var grid = [];
  13741. var vertex = new Vector3();
  13742. var normal = new Vector3();
  13743. // buffers
  13744. var indices = [];
  13745. var vertices = [];
  13746. var normals = [];
  13747. var uvs = [];
  13748. // generate vertices, normals and uvs
  13749. for ( iy = 0; iy <= heightSegments; iy ++ ) {
  13750. var verticesRow = [];
  13751. var v = iy / heightSegments;
  13752. for ( ix = 0; ix <= widthSegments; ix ++ ) {
  13753. var u = ix / widthSegments;
  13754. // vertex
  13755. vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
  13756. vertex.y = radius * Math.cos( thetaStart + v * thetaLength );
  13757. vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
  13758. vertices.push( vertex.x, vertex.y, vertex.z );
  13759. // normal
  13760. normal.set( vertex.x, vertex.y, vertex.z ).normalize();
  13761. normals.push( normal.x, normal.y, normal.z );
  13762. // uv
  13763. uvs.push( u, 1 - v );
  13764. verticesRow.push( index ++ );
  13765. }
  13766. grid.push( verticesRow );
  13767. }
  13768. // indices
  13769. for ( iy = 0; iy < heightSegments; iy ++ ) {
  13770. for ( ix = 0; ix < widthSegments; ix ++ ) {
  13771. var a = grid[ iy ][ ix + 1 ];
  13772. var b = grid[ iy ][ ix ];
  13773. var c = grid[ iy + 1 ][ ix ];
  13774. var d = grid[ iy + 1 ][ ix + 1 ];
  13775. if ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );
  13776. if ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );
  13777. }
  13778. }
  13779. // build geometry
  13780. this.setIndex( indices );
  13781. this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
  13782. this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
  13783. this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
  13784. }
  13785. SphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
  13786. SphereBufferGeometry.prototype.constructor = SphereBufferGeometry;
  13787. /**
  13788. * @author hughes
  13789. */
  13790. function CircleGeometry( radius, segments, thetaStart, thetaLength ) {
  13791. Geometry.call( this );
  13792. this.type = 'CircleGeometry';
  13793. this.parameters = {
  13794. radius: radius,
  13795. segments: segments,
  13796. thetaStart: thetaStart,
  13797. thetaLength: thetaLength
  13798. };
  13799. this.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );
  13800. }
  13801. CircleGeometry.prototype = Object.create( Geometry.prototype );
  13802. CircleGeometry.prototype.constructor = CircleGeometry;
  13803. /**
  13804. * @author benaadams / https://twitter.com/ben_a_adams
  13805. * @author Mugen87 / https://github.com/Mugen87
  13806. */
  13807. function CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {
  13808. BufferGeometry.call( this );
  13809. this.type = 'CircleBufferGeometry';
  13810. this.parameters = {
  13811. radius: radius,
  13812. segments: segments,
  13813. thetaStart: thetaStart,
  13814. thetaLength: thetaLength
  13815. };
  13816. radius = radius || 50;
  13817. segments = segments !== undefined ? Math.max( 3, segments ) : 8;
  13818. thetaStart = thetaStart !== undefined ? thetaStart : 0;
  13819. thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
  13820. // buffers
  13821. var indices = [];
  13822. var vertices = [];
  13823. var normals = [];
  13824. var uvs = [];
  13825. // helper variables
  13826. var i, s;
  13827. var vertex = new Vector3();
  13828. var uv = new Vector2();
  13829. // center point
  13830. vertices.push( 0, 0, 0 );
  13831. normals.push( 0, 0, 1 );
  13832. uvs.push( 0.5, 0.5 );
  13833. for ( s = 0, i = 3; s <= segments; s ++, i += 3 ) {
  13834. var segment = thetaStart + s / segments * thetaLength;
  13835. // vertex
  13836. vertex.x = radius * Math.cos( segment );
  13837. vertex.y = radius * Math.sin( segment );
  13838. vertices.push( vertex.x, vertex.y, vertex.z );
  13839. // normal
  13840. normals.push( 0, 0, 1 );
  13841. // uvs
  13842. uv.x = ( vertices[ i ] / radius + 1 ) / 2;
  13843. uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;
  13844. uvs.push( uv.x, uv.y );
  13845. }
  13846. // indices
  13847. for ( i = 1; i <= segments; i ++ ) {
  13848. indices.push( i, i + 1, 0 );
  13849. }
  13850. // build geometry
  13851. this.setIndex( indices );
  13852. this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
  13853. this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
  13854. this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
  13855. }
  13856. CircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
  13857. CircleBufferGeometry.prototype.constructor = CircleBufferGeometry;
  13858. /**
  13859. * @author Kaleb Murphy
  13860. */
  13861. function RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
  13862. Geometry.call( this );
  13863. this.type = 'RingGeometry';
  13864. this.parameters = {
  13865. innerRadius: innerRadius,
  13866. outerRadius: outerRadius,
  13867. thetaSegments: thetaSegments,
  13868. phiSegments: phiSegments,
  13869. thetaStart: thetaStart,
  13870. thetaLength: thetaLength
  13871. };
  13872. this.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );
  13873. }
  13874. RingGeometry.prototype = Object.create( Geometry.prototype );
  13875. RingGeometry.prototype.constructor = RingGeometry;
  13876. /**
  13877. * @author Mugen87 / https://github.com/Mugen87
  13878. */
  13879. function RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
  13880. BufferGeometry.call( this );
  13881. this.type = 'RingBufferGeometry';
  13882. this.parameters = {
  13883. innerRadius: innerRadius,
  13884. outerRadius: outerRadius,
  13885. thetaSegments: thetaSegments,
  13886. phiSegments: phiSegments,
  13887. thetaStart: thetaStart,
  13888. thetaLength: thetaLength
  13889. };
  13890. innerRadius = innerRadius || 20;
  13891. outerRadius = outerRadius || 50;
  13892. thetaStart = thetaStart !== undefined ? thetaStart : 0;
  13893. thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
  13894. thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;
  13895. phiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;
  13896. // buffers
  13897. var indices = [];
  13898. var vertices = [];
  13899. var normals = [];
  13900. var uvs = [];
  13901. // some helper variables
  13902. var segment;
  13903. var radius = innerRadius;
  13904. var radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );
  13905. var vertex = new Vector3();
  13906. var uv = new Vector2();
  13907. var j, i;
  13908. // generate vertices, normals and uvs
  13909. for ( j = 0; j <= phiSegments; j ++ ) {
  13910. for ( i = 0; i <= thetaSegments; i ++ ) {
  13911. // values are generate from the inside of the ring to the outside
  13912. segment = thetaStart + i / thetaSegments * thetaLength;
  13913. // vertex
  13914. vertex.x = radius * Math.cos( segment );
  13915. vertex.y = radius * Math.sin( segment );
  13916. vertices.push( vertex.x, vertex.y, vertex.z );
  13917. // normal
  13918. normals.push( 0, 0, 1 );
  13919. // uv
  13920. uv.x = ( vertex.x / outerRadius + 1 ) / 2;
  13921. uv.y = ( vertex.y / outerRadius + 1 ) / 2;
  13922. uvs.push( uv.x, uv.y );
  13923. }
  13924. // increase the radius for next row of vertices
  13925. radius += radiusStep;
  13926. }
  13927. // indices
  13928. for ( j = 0; j < phiSegments; j ++ ) {
  13929. var thetaSegmentLevel = j * ( thetaSegments + 1 );
  13930. for ( i = 0; i < thetaSegments; i ++ ) {
  13931. segment = i + thetaSegmentLevel;
  13932. var a = segment;
  13933. var b = segment + thetaSegments + 1;
  13934. var c = segment + thetaSegments + 2;
  13935. var d = segment + 1;
  13936. // faces
  13937. indices.push( a, b, d );
  13938. indices.push( b, c, d );
  13939. }
  13940. }
  13941. // build geometry
  13942. this.setIndex( indices );
  13943. this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
  13944. this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
  13945. this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
  13946. }
  13947. RingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
  13948. RingBufferGeometry.prototype.constructor = RingBufferGeometry;
  13949. /**
  13950. * @author dmarcos / https://github.com/dmarcos
  13951. * @author mrdoob / http://mrdoob.com
  13952. */
  13953. THREE.VRControls = function ( object, onError ) {
  13954. var scope = this;
  13955. var vrDisplay, vrDisplays;
  13956. var standingMatrix = new THREE.Matrix4();
  13957. var frameData = null;
  13958. if ( 'VRFrameData' in window ) {
  13959. frameData = new VRFrameData();
  13960. }
  13961. function gotVRDisplays( displays ) {
  13962. vrDisplays = displays;
  13963. if ( displays.length > 0 ) {
  13964. vrDisplay = displays[ 0 ];
  13965. } else {
  13966. if ( onError ) onError( 'VR input not available.' );
  13967. }
  13968. }
  13969. if ( navigator.getVRDisplays ) {
  13970. navigator.getVRDisplays().then( gotVRDisplays ).catch ( function () {
  13971. console.warn( 'THREE.VRControls: Unable to get VR Displays' );
  13972. } );
  13973. }
  13974. // the Rift SDK returns the position in meters
  13975. // this scale factor allows the user to define how meters
  13976. // are converted to scene units.
  13977. this.scale = 1;
  13978. // If true will use "standing space" coordinate system where y=0 is the
  13979. // floor and x=0, z=0 is the center of the room.
  13980. this.standing = false;
  13981. // Distance from the users eyes to the floor in meters. Used when
  13982. // standing=true but the VRDisplay doesn't provide stageParameters.
  13983. this.userHeight = 1.6;
  13984. this.getVRDisplay = function () {
  13985. return vrDisplay;
  13986. };
  13987. this.setVRDisplay = function ( value ) {
  13988. vrDisplay = value;
  13989. };
  13990. this.getVRDisplays = function () {
  13991. console.warn( 'THREE.VRControls: getVRDisplays() is being deprecated.' );
  13992. return vrDisplays;
  13993. };
  13994. this.getStandingMatrix = function () {
  13995. return standingMatrix;
  13996. };
  13997. this.update = function () {
  13998. if ( vrDisplay ) {
  13999. var pose;
  14000. if ( vrDisplay.getFrameData ) {
  14001. vrDisplay.getFrameData( frameData );
  14002. pose = frameData.pose;
  14003. } else if ( vrDisplay.getPose ) {
  14004. pose = vrDisplay.getPose();
  14005. }
  14006. if ( pose.orientation !== null ) {
  14007. object.quaternion.fromArray( pose.orientation );
  14008. }
  14009. if ( pose.position !== null ) {
  14010. object.position.fromArray( pose.position );
  14011. } else {
  14012. object.position.set( 0, 0, 0 );
  14013. }
  14014. if ( this.standing ) {
  14015. if ( vrDisplay.stageParameters ) {
  14016. object.updateMatrix();
  14017. standingMatrix.fromArray( vrDisplay.stageParameters.sittingToStandingTransform );
  14018. object.applyMatrix( standingMatrix );
  14019. } else {
  14020. object.position.setY( object.position.y + this.userHeight );
  14021. }
  14022. }
  14023. object.position.multiplyScalar( scope.scale );
  14024. }
  14025. };
  14026. this.resetPose = function () {
  14027. if ( vrDisplay ) {
  14028. vrDisplay.resetPose();
  14029. }
  14030. };
  14031. this.resetSensor = function () {
  14032. console.warn( 'THREE.VRControls: .resetSensor() is now .resetPose().' );
  14033. this.resetPose();
  14034. };
  14035. this.zeroSensor = function () {
  14036. console.warn( 'THREE.VRControls: .zeroSensor() is now .resetPose().' );
  14037. this.resetPose();
  14038. };
  14039. this.dispose = function () {
  14040. vrDisplay = null;
  14041. };
  14042. };
  14043. /**
  14044. * @author dmarcos / https://github.com/dmarcos
  14045. * @author mrdoob / http://mrdoob.com
  14046. *
  14047. * WebVR Spec: http://mozvr.github.io/webvr-spec/webvr.html
  14048. *
  14049. * Firefox: http://mozvr.com/downloads/
  14050. * Chromium: https://webvr.info/get-chrome
  14051. *
  14052. */
  14053. THREE.VREffect = function( renderer, onError ) {
  14054. var vrDisplay, vrDisplays;
  14055. var eyeTranslationL = new THREE.Vector3();
  14056. var eyeTranslationR = new THREE.Vector3();
  14057. var renderRectL, renderRectR;
  14058. var frameData = null;
  14059. if ( 'VRFrameData' in window ) {
  14060. frameData = new window.VRFrameData();
  14061. }
  14062. function gotVRDisplays( displays ) {
  14063. vrDisplays = displays;
  14064. if ( displays.length > 0 ) {
  14065. vrDisplay = displays[ 0 ];
  14066. } else {
  14067. if ( onError ) onError( 'HMD not available' );
  14068. }
  14069. }
  14070. if ( navigator.getVRDisplays ) {
  14071. navigator.getVRDisplays().then( gotVRDisplays ).catch( function() {
  14072. console.warn( 'THREE.VREffect: Unable to get VR Displays' );
  14073. } );
  14074. }
  14075. //
  14076. this.isPresenting = false;
  14077. this.scale = 1;
  14078. var scope = this;
  14079. var rendererSize = renderer.getSize();
  14080. var rendererUpdateStyle = false;
  14081. var rendererPixelRatio = renderer.getPixelRatio();
  14082. this.getVRDisplay = function() {
  14083. return vrDisplay;
  14084. };
  14085. this.setVRDisplay = function( value ) {
  14086. vrDisplay = value;
  14087. };
  14088. this.getVRDisplays = function() {
  14089. console.warn( 'THREE.VREffect: getVRDisplays() is being deprecated.' );
  14090. return vrDisplays;
  14091. };
  14092. this.setSize = function( width, height, updateStyle ) {
  14093. rendererSize = { width: width, height: height };
  14094. rendererUpdateStyle = updateStyle;
  14095. if ( scope.isPresenting ) {
  14096. var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
  14097. renderer.setPixelRatio( 1 );
  14098. renderer.setSize( eyeParamsL.renderWidth * 2, eyeParamsL.renderHeight, false );
  14099. } else {
  14100. renderer.setPixelRatio( rendererPixelRatio );
  14101. renderer.setSize( width, height, updateStyle );
  14102. }
  14103. };
  14104. // VR presentation
  14105. var canvas = renderer.domElement;
  14106. var defaultLeftBounds = [ 0.0, 0.0, 0.5, 1.0 ];
  14107. var defaultRightBounds = [ 0.5, 0.0, 0.5, 1.0 ];
  14108. function onVRDisplayPresentChange() {
  14109. var wasPresenting = scope.isPresenting;
  14110. scope.isPresenting = vrDisplay !== undefined && vrDisplay.isPresenting;
  14111. if ( scope.isPresenting ) {
  14112. var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
  14113. var eyeWidth = eyeParamsL.renderWidth;
  14114. var eyeHeight = eyeParamsL.renderHeight;
  14115. if ( ! wasPresenting ) {
  14116. rendererPixelRatio = renderer.getPixelRatio();
  14117. rendererSize = renderer.getSize();
  14118. renderer.setPixelRatio( 1 );
  14119. renderer.setSize( eyeWidth * 2, eyeHeight, false );
  14120. }
  14121. } else if ( wasPresenting ) {
  14122. renderer.setPixelRatio( rendererPixelRatio );
  14123. renderer.setSize( rendererSize.width, rendererSize.height, rendererUpdateStyle );
  14124. }
  14125. }
  14126. window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
  14127. this.setFullScreen = function( boolean ) {
  14128. return new Promise( function( resolve, reject ) {
  14129. if ( vrDisplay === undefined ) {
  14130. reject( new Error( 'No VR hardware found.' ) );
  14131. return;
  14132. }
  14133. if ( scope.isPresenting === boolean ) {
  14134. resolve();
  14135. return;
  14136. }
  14137. if ( boolean ) {
  14138. resolve( vrDisplay.requestPresent( [ { source: canvas } ] ) );
  14139. } else {
  14140. resolve( vrDisplay.exitPresent() );
  14141. }
  14142. } );
  14143. };
  14144. this.requestPresent = function() {
  14145. return this.setFullScreen( true );
  14146. };
  14147. this.exitPresent = function() {
  14148. return this.setFullScreen( false );
  14149. };
  14150. this.requestAnimationFrame = function( f ) {
  14151. if ( vrDisplay !== undefined ) {
  14152. return vrDisplay.requestAnimationFrame( f );
  14153. } else {
  14154. return window.requestAnimationFrame( f );
  14155. }
  14156. };
  14157. this.cancelAnimationFrame = function( h ) {
  14158. if ( vrDisplay !== undefined ) {
  14159. vrDisplay.cancelAnimationFrame( h );
  14160. } else {
  14161. window.cancelAnimationFrame( h );
  14162. }
  14163. };
  14164. this.submitFrame = function() {
  14165. if ( vrDisplay !== undefined && scope.isPresenting ) {
  14166. vrDisplay.submitFrame();
  14167. }
  14168. };
  14169. this.autoSubmitFrame = true;
  14170. // render
  14171. var cameraL = new THREE.PerspectiveCamera();
  14172. cameraL.layers.enable( 1 );
  14173. var cameraR = new THREE.PerspectiveCamera();
  14174. cameraR.layers.enable( 2 );
  14175. this.render = function( scene, camera, renderTarget, forceClear ) {
  14176. if ( vrDisplay && scope.isPresenting ) {
  14177. var autoUpdate = scene.autoUpdate;
  14178. if ( autoUpdate ) {
  14179. scene.updateMatrixWorld();
  14180. scene.autoUpdate = false;
  14181. }
  14182. var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
  14183. var eyeParamsR = vrDisplay.getEyeParameters( 'right' );
  14184. eyeTranslationL.fromArray( eyeParamsL.offset );
  14185. eyeTranslationR.fromArray( eyeParamsR.offset );
  14186. if ( Array.isArray( scene ) ) {
  14187. console.warn( 'THREE.VREffect.render() no longer supports arrays. Use object.layers instead.' );
  14188. scene = scene[ 0 ];
  14189. }
  14190. // When rendering we don't care what the recommended size is, only what the actual size
  14191. // of the backbuffer is.
  14192. var size = renderer.getSize();
  14193. var layers = vrDisplay.getLayers();
  14194. var leftBounds;
  14195. var rightBounds;
  14196. if ( layers.length ) {
  14197. var layer = layers[ 0 ];
  14198. leftBounds = layer.leftBounds !== null && layer.leftBounds.length === 4 ? layer.leftBounds : defaultLeftBounds;
  14199. rightBounds = layer.rightBounds !== null && layer.rightBounds.length === 4 ? layer.rightBounds : defaultRightBounds;
  14200. } else {
  14201. leftBounds = defaultLeftBounds;
  14202. rightBounds = defaultRightBounds;
  14203. }
  14204. renderRectL = {
  14205. x: Math.round( size.width * leftBounds[ 0 ] ),
  14206. y: Math.round( size.height * leftBounds[ 1 ] ),
  14207. width: Math.round( size.width * leftBounds[ 2 ] ),
  14208. height: Math.round( size.height * leftBounds[ 3 ] )
  14209. };
  14210. renderRectR = {
  14211. x: Math.round( size.width * rightBounds[ 0 ] ),
  14212. y: Math.round( size.height * rightBounds[ 1 ] ),
  14213. width: Math.round( size.width * rightBounds[ 2 ] ),
  14214. height: Math.round( size.height * rightBounds[ 3 ] )
  14215. };
  14216. if ( renderTarget ) {
  14217. renderer.setRenderTarget( renderTarget );
  14218. renderTarget.scissorTest = true;
  14219. } else {
  14220. renderer.setRenderTarget( null );
  14221. renderer.setScissorTest( true );
  14222. }
  14223. if ( renderer.autoClear || forceClear ) renderer.clear();
  14224. if ( camera.parent === null ) camera.updateMatrixWorld();
  14225. camera.matrixWorld.decompose( cameraL.position, cameraL.quaternion, cameraL.scale );
  14226. camera.matrixWorld.decompose( cameraR.position, cameraR.quaternion, cameraR.scale );
  14227. var scale = this.scale;
  14228. cameraL.translateOnAxis( eyeTranslationL, scale );
  14229. cameraR.translateOnAxis( eyeTranslationR, scale );
  14230. if ( vrDisplay.getFrameData ) {
  14231. vrDisplay.depthNear = camera.near;
  14232. vrDisplay.depthFar = camera.far;
  14233. vrDisplay.getFrameData( frameData );
  14234. cameraL.projectionMatrix.elements = frameData.leftProjectionMatrix;
  14235. cameraR.projectionMatrix.elements = frameData.rightProjectionMatrix;
  14236. } else {
  14237. cameraL.projectionMatrix = fovToProjection( eyeParamsL.fieldOfView, true, camera.near, camera.far );
  14238. cameraR.projectionMatrix = fovToProjection( eyeParamsR.fieldOfView, true, camera.near, camera.far );
  14239. }
  14240. // render left eye
  14241. if ( renderTarget ) {
  14242. renderTarget.viewport.set( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
  14243. renderTarget.scissor.set( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
  14244. } else {
  14245. renderer.setViewport( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
  14246. renderer.setScissor( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
  14247. }
  14248. renderer.render( scene, cameraL, renderTarget, forceClear );
  14249. // render right eye
  14250. if ( renderTarget ) {
  14251. renderTarget.viewport.set( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
  14252. renderTarget.scissor.set( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
  14253. } else {
  14254. renderer.setViewport( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
  14255. renderer.setScissor( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
  14256. }
  14257. renderer.render( scene, cameraR, renderTarget, forceClear );
  14258. if ( renderTarget ) {
  14259. renderTarget.viewport.set( 0, 0, size.width, size.height );
  14260. renderTarget.scissor.set( 0, 0, size.width, size.height );
  14261. renderTarget.scissorTest = false;
  14262. renderer.setRenderTarget( null );
  14263. } else {
  14264. renderer.setViewport( 0, 0, size.width, size.height );
  14265. renderer.setScissorTest( false );
  14266. }
  14267. if ( autoUpdate ) {
  14268. scene.autoUpdate = true;
  14269. }
  14270. if ( scope.autoSubmitFrame ) {
  14271. scope.submitFrame();
  14272. }
  14273. return;
  14274. }
  14275. // Regular render mode if not HMD
  14276. renderer.render( scene, camera, renderTarget, forceClear );
  14277. };
  14278. this.dispose = function() {
  14279. window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
  14280. };
  14281. //
  14282. function fovToNDCScaleOffset( fov ) {
  14283. var pxscale = 2.0 / ( fov.leftTan + fov.rightTan );
  14284. var pxoffset = ( fov.leftTan - fov.rightTan ) * pxscale * 0.5;
  14285. var pyscale = 2.0 / ( fov.upTan + fov.downTan );
  14286. var pyoffset = ( fov.upTan - fov.downTan ) * pyscale * 0.5;
  14287. return { scale: [ pxscale, pyscale ], offset: [ pxoffset, pyoffset ] };
  14288. }
  14289. function fovPortToProjection( fov, rightHanded, zNear, zFar ) {
  14290. rightHanded = rightHanded === undefined ? true : rightHanded;
  14291. zNear = zNear === undefined ? 0.01 : zNear;
  14292. zFar = zFar === undefined ? 10000.0 : zFar;
  14293. var handednessScale = rightHanded ? - 1.0 : 1.0;
  14294. // start with an identity matrix
  14295. var mobj = new THREE.Matrix4();
  14296. var m = mobj.elements;
  14297. // and with scale/offset info for normalized device coords
  14298. var scaleAndOffset = fovToNDCScaleOffset( fov );
  14299. // X result, map clip edges to [-w,+w]
  14300. m[ 0 * 4 + 0 ] = scaleAndOffset.scale[ 0 ];
  14301. m[ 0 * 4 + 1 ] = 0.0;
  14302. m[ 0 * 4 + 2 ] = scaleAndOffset.offset[ 0 ] * handednessScale;
  14303. m[ 0 * 4 + 3 ] = 0.0;
  14304. // Y result, map clip edges to [-w,+w]
  14305. // Y offset is negated because this proj matrix transforms from world coords with Y=up,
  14306. // but the NDC scaling has Y=down (thanks D3D?)
  14307. m[ 1 * 4 + 0 ] = 0.0;
  14308. m[ 1 * 4 + 1 ] = scaleAndOffset.scale[ 1 ];
  14309. m[ 1 * 4 + 2 ] = - scaleAndOffset.offset[ 1 ] * handednessScale;
  14310. m[ 1 * 4 + 3 ] = 0.0;
  14311. // Z result (up to the app)
  14312. m[ 2 * 4 + 0 ] = 0.0;
  14313. m[ 2 * 4 + 1 ] = 0.0;
  14314. m[ 2 * 4 + 2 ] = zFar / ( zNear - zFar ) * - handednessScale;
  14315. m[ 2 * 4 + 3 ] = ( zFar * zNear ) / ( zNear - zFar );
  14316. // W result (= Z in)
  14317. m[ 3 * 4 + 0 ] = 0.0;
  14318. m[ 3 * 4 + 1 ] = 0.0;
  14319. m[ 3 * 4 + 2 ] = handednessScale;
  14320. m[ 3 * 4 + 3 ] = 0.0;
  14321. mobj.transpose();
  14322. return mobj;
  14323. }
  14324. function fovToProjection( fov, rightHanded, zNear, zFar ) {
  14325. var DEG2RAD = Math.PI / 180.0;
  14326. var fovPort = {
  14327. upTan: Math.tan( fov.upDegrees * DEG2RAD ),
  14328. downTan: Math.tan( fov.downDegrees * DEG2RAD ),
  14329. leftTan: Math.tan( fov.leftDegrees * DEG2RAD ),
  14330. rightTan: Math.tan( fov.rightDegrees * DEG2RAD )
  14331. };
  14332. return fovPortToProjection( fovPort, rightHanded, zNear, zFar );
  14333. }
  14334. };
  14335. exports.WebGLRenderer = WebGLRenderer;
  14336. exports.Scene = Scene;
  14337. exports.Mesh = Mesh;
  14338. exports.VideoTexture = VideoTexture;
  14339. exports.MeshBasicMaterial = MeshBasicMaterial;
  14340. exports.ShaderMaterial = ShaderMaterial;
  14341. exports.TextureLoader = TextureLoader;
  14342. exports.PerspectiveCamera = PerspectiveCamera;
  14343. exports.Object3D = Object3D;
  14344. exports.Raycaster = Raycaster;
  14345. exports.Math = _Math;
  14346. exports.Quaternion = Quaternion;
  14347. exports.Euler = Euler;
  14348. exports.Matrix4 = Matrix4;
  14349. exports.Matrix3 = Matrix3;
  14350. exports.Vector4 = Vector4;
  14351. exports.Vector3 = Vector3;
  14352. exports.Vector2 = Vector2;
  14353. exports.Color = Color;
  14354. exports.TorusGeometry = TorusGeometry;
  14355. exports.SphereGeometry = SphereGeometry;
  14356. exports.CircleGeometry = CircleGeometry;
  14357. exports.RingGeometry = RingGeometry;
  14358. exports.REVISION = REVISION;
  14359. exports.MOUSE = MOUSE;
  14360. exports.CullFaceNone = CullFaceNone;
  14361. exports.CullFaceBack = CullFaceBack;
  14362. exports.CullFaceFront = CullFaceFront;
  14363. exports.CullFaceFrontBack = CullFaceFrontBack;
  14364. exports.FrontFaceDirectionCW = FrontFaceDirectionCW;
  14365. exports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;
  14366. exports.BasicShadowMap = BasicShadowMap;
  14367. exports.PCFShadowMap = PCFShadowMap;
  14368. exports.PCFSoftShadowMap = PCFSoftShadowMap;
  14369. exports.FrontSide = FrontSide;
  14370. exports.BackSide = BackSide;
  14371. exports.DoubleSide = DoubleSide;
  14372. exports.FlatShading = FlatShading;
  14373. exports.SmoothShading = SmoothShading;
  14374. exports.NoColors = NoColors;
  14375. exports.FaceColors = FaceColors;
  14376. exports.VertexColors = VertexColors;
  14377. exports.NoBlending = NoBlending;
  14378. exports.NormalBlending = NormalBlending;
  14379. exports.AdditiveBlending = AdditiveBlending;
  14380. exports.SubtractiveBlending = SubtractiveBlending;
  14381. exports.MultiplyBlending = MultiplyBlending;
  14382. exports.CustomBlending = CustomBlending;
  14383. exports.AddEquation = AddEquation;
  14384. exports.SubtractEquation = SubtractEquation;
  14385. exports.ReverseSubtractEquation = ReverseSubtractEquation;
  14386. exports.MinEquation = MinEquation;
  14387. exports.MaxEquation = MaxEquation;
  14388. exports.ZeroFactor = ZeroFactor;
  14389. exports.OneFactor = OneFactor;
  14390. exports.SrcColorFactor = SrcColorFactor;
  14391. exports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;
  14392. exports.SrcAlphaFactor = SrcAlphaFactor;
  14393. exports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;
  14394. exports.DstAlphaFactor = DstAlphaFactor;
  14395. exports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;
  14396. exports.DstColorFactor = DstColorFactor;
  14397. exports.OneMinusDstColorFactor = OneMinusDstColorFactor;
  14398. exports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;
  14399. exports.NeverDepth = NeverDepth;
  14400. exports.AlwaysDepth = AlwaysDepth;
  14401. exports.LessDepth = LessDepth;
  14402. exports.LessEqualDepth = LessEqualDepth;
  14403. exports.EqualDepth = EqualDepth;
  14404. exports.GreaterEqualDepth = GreaterEqualDepth;
  14405. exports.GreaterDepth = GreaterDepth;
  14406. exports.NotEqualDepth = NotEqualDepth;
  14407. exports.MultiplyOperation = MultiplyOperation;
  14408. exports.MixOperation = MixOperation;
  14409. exports.AddOperation = AddOperation;
  14410. exports.NoToneMapping = NoToneMapping;
  14411. exports.LinearToneMapping = LinearToneMapping;
  14412. exports.ReinhardToneMapping = ReinhardToneMapping;
  14413. exports.Uncharted2ToneMapping = Uncharted2ToneMapping;
  14414. exports.CineonToneMapping = CineonToneMapping;
  14415. exports.UVMapping = UVMapping;
  14416. exports.CubeReflectionMapping = CubeReflectionMapping;
  14417. exports.CubeRefractionMapping = CubeRefractionMapping;
  14418. exports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;
  14419. exports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;
  14420. exports.SphericalReflectionMapping = SphericalReflectionMapping;
  14421. exports.CubeUVReflectionMapping = CubeUVReflectionMapping;
  14422. exports.CubeUVRefractionMapping = CubeUVRefractionMapping;
  14423. exports.RepeatWrapping = RepeatWrapping;
  14424. exports.ClampToEdgeWrapping = ClampToEdgeWrapping;
  14425. exports.MirroredRepeatWrapping = MirroredRepeatWrapping;
  14426. exports.NearestFilter = NearestFilter;
  14427. exports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;
  14428. exports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;
  14429. exports.LinearFilter = LinearFilter;
  14430. exports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;
  14431. exports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;
  14432. exports.UnsignedByteType = UnsignedByteType;
  14433. exports.ByteType = ByteType;
  14434. exports.ShortType = ShortType;
  14435. exports.UnsignedShortType = UnsignedShortType;
  14436. exports.IntType = IntType;
  14437. exports.UnsignedIntType = UnsignedIntType;
  14438. exports.FloatType = FloatType;
  14439. exports.HalfFloatType = HalfFloatType;
  14440. exports.UnsignedShort4444Type = UnsignedShort4444Type;
  14441. exports.UnsignedShort5551Type = UnsignedShort5551Type;
  14442. exports.UnsignedShort565Type = UnsignedShort565Type;
  14443. exports.UnsignedInt248Type = UnsignedInt248Type;
  14444. exports.AlphaFormat = AlphaFormat;
  14445. exports.RGBFormat = RGBFormat;
  14446. exports.RGBAFormat = RGBAFormat;
  14447. exports.LuminanceFormat = LuminanceFormat;
  14448. exports.LuminanceAlphaFormat = LuminanceAlphaFormat;
  14449. exports.RGBEFormat = RGBEFormat;
  14450. exports.DepthFormat = DepthFormat;
  14451. exports.DepthStencilFormat = DepthStencilFormat;
  14452. exports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;
  14453. exports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;
  14454. exports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;
  14455. exports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;
  14456. exports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;
  14457. exports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;
  14458. exports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;
  14459. exports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;
  14460. exports.RGB_ETC1_Format = RGB_ETC1_Format;
  14461. exports.LoopOnce = LoopOnce;
  14462. exports.LoopRepeat = LoopRepeat;
  14463. exports.LoopPingPong = LoopPingPong;
  14464. exports.InterpolateDiscrete = InterpolateDiscrete;
  14465. exports.InterpolateLinear = InterpolateLinear;
  14466. exports.InterpolateSmooth = InterpolateSmooth;
  14467. exports.ZeroCurvatureEnding = ZeroCurvatureEnding;
  14468. exports.ZeroSlopeEnding = ZeroSlopeEnding;
  14469. exports.WrapAroundEnding = WrapAroundEnding;
  14470. exports.TrianglesDrawMode = TrianglesDrawMode;
  14471. exports.TriangleStripDrawMode = TriangleStripDrawMode;
  14472. exports.TriangleFanDrawMode = TriangleFanDrawMode;
  14473. exports.LinearEncoding = LinearEncoding;
  14474. exports.sRGBEncoding = sRGBEncoding;
  14475. exports.GammaEncoding = GammaEncoding;
  14476. exports.RGBEEncoding = RGBEEncoding;
  14477. exports.LogLuvEncoding = LogLuvEncoding;
  14478. exports.RGBM7Encoding = RGBM7Encoding;
  14479. exports.RGBM16Encoding = RGBM16Encoding;
  14480. exports.RGBDEncoding = RGBDEncoding;
  14481. exports.BasicDepthPacking = BasicDepthPacking;
  14482. exports.RGBADepthPacking = RGBADepthPacking;
  14483. Object.defineProperty(exports, '__esModule', { value: true });
  14484. Object.defineProperty( exports, 'AudioContext', {
  14485. get: function () {
  14486. return exports.getAudioContext();
  14487. }
  14488. });
  14489. })));