ThreeWebGL.js 366 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059
  1. /**
  2. * @author mr.doob / http://mrdoob.com/
  3. */
  4. var THREE = THREE || { REVISION: '49dev' };
  5. if ( ! self.Int32Array ) {
  6. self.Int32Array = Array;
  7. self.Float32Array = Array;
  8. }
  9. // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
  10. // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
  11. // requestAnimationFrame polyfill by Erik Möller
  12. // fixes from Paul Irish and Tino Zijdel
  13. (function() {
  14. var lastTime = 0;
  15. var vendors = ['ms', 'moz', 'webkit', 'o'];
  16. for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
  17. window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
  18. window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
  19. || window[vendors[x]+'CancelRequestAnimationFrame'];
  20. }
  21. if (!window.requestAnimationFrame)
  22. window.requestAnimationFrame = function(callback, element) {
  23. var currTime = new Date().getTime();
  24. var timeToCall = Math.max(0, 16 - (currTime - lastTime));
  25. var id = window.setTimeout(function() { callback(currTime + timeToCall); },
  26. timeToCall);
  27. lastTime = currTime + timeToCall;
  28. return id;
  29. };
  30. if (!window.cancelAnimationFrame)
  31. window.cancelAnimationFrame = function(id) {
  32. clearTimeout(id);
  33. };
  34. }());
  35. /**
  36. * @author mr.doob / http://mrdoob.com/
  37. */
  38. THREE.Color = function ( hex ) {
  39. if ( hex !== undefined ) this.setHex( hex );
  40. return this;
  41. };
  42. THREE.Color.prototype = {
  43. constructor: THREE.Color,
  44. r: 1, g: 1, b: 1,
  45. copy: function ( color ) {
  46. this.r = color.r;
  47. this.g = color.g;
  48. this.b = color.b;
  49. return this;
  50. },
  51. copyGammaToLinear: function ( color ) {
  52. this.r = color.r * color.r;
  53. this.g = color.g * color.g;
  54. this.b = color.b * color.b;
  55. return this;
  56. },
  57. copyLinearToGamma: function ( color ) {
  58. this.r = Math.sqrt( color.r );
  59. this.g = Math.sqrt( color.g );
  60. this.b = Math.sqrt( color.b );
  61. return this;
  62. },
  63. convertGammaToLinear: function () {
  64. var r = this.r, g = this.g, b = this.b;
  65. this.r = r * r;
  66. this.g = g * g;
  67. this.b = b * b;
  68. return this;
  69. },
  70. convertLinearToGamma: function () {
  71. this.r = Math.sqrt( this.r );
  72. this.g = Math.sqrt( this.g );
  73. this.b = Math.sqrt( this.b );
  74. return this;
  75. },
  76. setRGB: function ( r, g, b ) {
  77. this.r = r;
  78. this.g = g;
  79. this.b = b;
  80. return this;
  81. },
  82. setHSV: function ( h, s, v ) {
  83. // based on MochiKit implementation by Bob Ippolito
  84. // h,s,v ranges are < 0.0 - 1.0 >
  85. var i, f, p, q, t;
  86. if ( v === 0 ) {
  87. this.r = this.g = this.b = 0;
  88. } else {
  89. i = Math.floor( h * 6 );
  90. f = ( h * 6 ) - i;
  91. p = v * ( 1 - s );
  92. q = v * ( 1 - ( s * f ) );
  93. t = v * ( 1 - ( s * ( 1 - f ) ) );
  94. switch ( i ) {
  95. case 1: this.r = q; this.g = v; this.b = p; break;
  96. case 2: this.r = p; this.g = v; this.b = t; break;
  97. case 3: this.r = p; this.g = q; this.b = v; break;
  98. case 4: this.r = t; this.g = p; this.b = v; break;
  99. case 5: this.r = v; this.g = p; this.b = q; break;
  100. case 6: // fall through
  101. case 0: this.r = v; this.g = t; this.b = p; break;
  102. }
  103. }
  104. return this;
  105. },
  106. setHex: function ( hex ) {
  107. hex = Math.floor( hex );
  108. this.r = ( hex >> 16 & 255 ) / 255;
  109. this.g = ( hex >> 8 & 255 ) / 255;
  110. this.b = ( hex & 255 ) / 255;
  111. return this;
  112. },
  113. lerpSelf: function ( color, alpha ) {
  114. this.r += ( color.r - this.r ) * alpha;
  115. this.g += ( color.g - this.g ) * alpha;
  116. this.b += ( color.b - this.b ) * alpha;
  117. return this;
  118. },
  119. getHex: function () {
  120. return Math.floor( this.r * 255 ) << 16 ^ Math.floor( this.g * 255 ) << 8 ^ Math.floor( this.b * 255 );
  121. },
  122. getContextStyle: function () {
  123. return 'rgb(' + Math.floor( this.r * 255 ) + ',' + Math.floor( this.g * 255 ) + ',' + Math.floor( this.b * 255 ) + ')';
  124. },
  125. clone: function () {
  126. return new THREE.Color().setRGB( this.r, this.g, this.b );
  127. }
  128. };
  129. /**
  130. * @author mr.doob / http://mrdoob.com/
  131. * @author philogb / http://blog.thejit.org/
  132. * @author egraether / http://egraether.com/
  133. * @author zz85 / http://www.lab4games.net/zz85/blog
  134. */
  135. THREE.Vector2 = function ( x, y ) {
  136. this.x = x || 0;
  137. this.y = y || 0;
  138. };
  139. THREE.Vector2.prototype = {
  140. constructor: THREE.Vector2,
  141. set: function ( x, y ) {
  142. this.x = x;
  143. this.y = y;
  144. return this;
  145. },
  146. copy: function ( v ) {
  147. this.x = v.x;
  148. this.y = v.y;
  149. return this;
  150. },
  151. add: function ( a, b ) {
  152. this.x = a.x + b.x;
  153. this.y = a.y + b.y;
  154. return this;
  155. },
  156. addSelf: function ( v ) {
  157. this.x += v.x;
  158. this.y += v.y;
  159. return this;
  160. },
  161. sub: function ( a, b ) {
  162. this.x = a.x - b.x;
  163. this.y = a.y - b.y;
  164. return this;
  165. },
  166. subSelf: function ( v ) {
  167. this.x -= v.x;
  168. this.y -= v.y;
  169. return this;
  170. },
  171. multiplyScalar: function ( s ) {
  172. this.x *= s;
  173. this.y *= s;
  174. return this;
  175. },
  176. divideScalar: function ( s ) {
  177. if ( s ) {
  178. this.x /= s;
  179. this.y /= s;
  180. } else {
  181. this.set( 0, 0 );
  182. }
  183. return this;
  184. },
  185. negate: function() {
  186. return this.multiplyScalar( - 1 );
  187. },
  188. dot: function ( v ) {
  189. return this.x * v.x + this.y * v.y;
  190. },
  191. lengthSq: function () {
  192. return this.x * this.x + this.y * this.y;
  193. },
  194. length: function () {
  195. return Math.sqrt( this.lengthSq() );
  196. },
  197. normalize: function () {
  198. return this.divideScalar( this.length() );
  199. },
  200. distanceTo: function ( v ) {
  201. return Math.sqrt( this.distanceToSquared( v ) );
  202. },
  203. distanceToSquared: function ( v ) {
  204. var dx = this.x - v.x, dy = this.y - v.y;
  205. return dx * dx + dy * dy;
  206. },
  207. setLength: function ( l ) {
  208. return this.normalize().multiplyScalar( l );
  209. },
  210. lerpSelf: function ( v, alpha ) {
  211. this.x += ( v.x - this.x ) * alpha;
  212. this.y += ( v.y - this.y ) * alpha;
  213. return this;
  214. },
  215. equals: function( v ) {
  216. return ( ( v.x === this.x ) && ( v.y === this.y ) );
  217. },
  218. isZero: function () {
  219. return ( this.lengthSq() < 0.0001 /* almostZero */ );
  220. },
  221. clone: function () {
  222. return new THREE.Vector2( this.x, this.y );
  223. }
  224. };
  225. /**
  226. * @author mr.doob / http://mrdoob.com/
  227. * @author kile / http://kile.stravaganza.org/
  228. * @author philogb / http://blog.thejit.org/
  229. * @author mikael emtinger / http://gomo.se/
  230. * @author egraether / http://egraether.com/
  231. */
  232. THREE.Vector3 = function ( x, y, z ) {
  233. this.x = x || 0;
  234. this.y = y || 0;
  235. this.z = z || 0;
  236. };
  237. THREE.Vector3.prototype = {
  238. constructor: THREE.Vector3,
  239. set: function ( x, y, z ) {
  240. this.x = x;
  241. this.y = y;
  242. this.z = z;
  243. return this;
  244. },
  245. setX: function ( x ) {
  246. this.x = x;
  247. return this;
  248. },
  249. setY: function ( y ) {
  250. this.y = y;
  251. return this;
  252. },
  253. setZ: function ( z ) {
  254. this.z = z;
  255. return this;
  256. },
  257. copy: function ( v ) {
  258. this.x = v.x;
  259. this.y = v.y;
  260. this.z = v.z;
  261. return this;
  262. },
  263. add: function ( a, b ) {
  264. this.x = a.x + b.x;
  265. this.y = a.y + b.y;
  266. this.z = a.z + b.z;
  267. return this;
  268. },
  269. addSelf: function ( v ) {
  270. this.x += v.x;
  271. this.y += v.y;
  272. this.z += v.z;
  273. return this;
  274. },
  275. addScalar: function ( s ) {
  276. this.x += s;
  277. this.y += s;
  278. this.z += s;
  279. return this;
  280. },
  281. sub: function ( a, b ) {
  282. this.x = a.x - b.x;
  283. this.y = a.y - b.y;
  284. this.z = a.z - b.z;
  285. return this;
  286. },
  287. subSelf: function ( v ) {
  288. this.x -= v.x;
  289. this.y -= v.y;
  290. this.z -= v.z;
  291. return this;
  292. },
  293. multiply: function ( a, b ) {
  294. this.x = a.x * b.x;
  295. this.y = a.y * b.y;
  296. this.z = a.z * b.z;
  297. return this;
  298. },
  299. multiplySelf: function ( v ) {
  300. this.x *= v.x;
  301. this.y *= v.y;
  302. this.z *= v.z;
  303. return this;
  304. },
  305. multiplyScalar: function ( s ) {
  306. this.x *= s;
  307. this.y *= s;
  308. this.z *= s;
  309. return this;
  310. },
  311. divideSelf: function ( v ) {
  312. this.x /= v.x;
  313. this.y /= v.y;
  314. this.z /= v.z;
  315. return this;
  316. },
  317. divideScalar: function ( s ) {
  318. if ( s ) {
  319. this.x /= s;
  320. this.y /= s;
  321. this.z /= s;
  322. } else {
  323. this.x = 0;
  324. this.y = 0;
  325. this.z = 0;
  326. }
  327. return this;
  328. },
  329. negate: function() {
  330. return this.multiplyScalar( - 1 );
  331. },
  332. dot: function ( v ) {
  333. return this.x * v.x + this.y * v.y + this.z * v.z;
  334. },
  335. lengthSq: function () {
  336. return this.x * this.x + this.y * this.y + this.z * this.z;
  337. },
  338. length: function () {
  339. return Math.sqrt( this.lengthSq() );
  340. },
  341. lengthManhattan: function () {
  342. return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
  343. },
  344. normalize: function () {
  345. return this.divideScalar( this.length() );
  346. },
  347. setLength: function ( l ) {
  348. return this.normalize().multiplyScalar( l );
  349. },
  350. lerpSelf: function ( v, alpha ) {
  351. this.x += ( v.x - this.x ) * alpha;
  352. this.y += ( v.y - this.y ) * alpha;
  353. this.z += ( v.z - this.z ) * alpha;
  354. return this;
  355. },
  356. cross: function ( a, b ) {
  357. this.x = a.y * b.z - a.z * b.y;
  358. this.y = a.z * b.x - a.x * b.z;
  359. this.z = a.x * b.y - a.y * b.x;
  360. return this;
  361. },
  362. crossSelf: function ( v ) {
  363. var x = this.x, y = this.y, z = this.z;
  364. this.x = y * v.z - z * v.y;
  365. this.y = z * v.x - x * v.z;
  366. this.z = x * v.y - y * v.x;
  367. return this;
  368. },
  369. distanceTo: function ( v ) {
  370. return Math.sqrt( this.distanceToSquared( v ) );
  371. },
  372. distanceToSquared: function ( v ) {
  373. return new THREE.Vector3().sub( this, v ).lengthSq();
  374. },
  375. getPositionFromMatrix: function ( m ) {
  376. this.x = m.elements[12];
  377. this.y = m.elements[13];
  378. this.z = m.elements[14];
  379. return this;
  380. },
  381. getRotationFromMatrix: function ( m, scale ) {
  382. var sx = scale ? scale.x : 1;
  383. var sy = scale ? scale.y : 1;
  384. var sz = scale ? scale.z : 1;
  385. var m11 = m.elements[0] / sx, m12 = m.elements[4] / sy, m13 = m.elements[8] / sz;
  386. var m21 = m.elements[1] / sx, m22 = m.elements[5] / sy, m23 = m.elements[9] / sz;
  387. var m33 = m.elements[10] / sz;
  388. this.y = Math.asin( m13 );
  389. var cosY = Math.cos( this.y );
  390. if ( Math.abs( cosY ) > 0.00001 ) {
  391. this.x = Math.atan2( - m23 / cosY, m33 / cosY );
  392. this.z = Math.atan2( - m12 / cosY, m11 / cosY );
  393. } else {
  394. this.x = 0;
  395. this.z = Math.atan2( m21, m22 );
  396. }
  397. return this;
  398. },
  399. /*
  400. // from http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m
  401. // order XYZ
  402. getEulerXYZFromQuaternion: function ( q ) {
  403. this.x = Math.atan2( 2 * ( q.x * q.w - q.y * q.z ), ( q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z ) );
  404. this.y = Math.asin( 2 * ( q.x * q.z + q.y * q.w ) );
  405. this.z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z ) );
  406. },
  407. // from http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm
  408. // order YZX (assuming heading == y, attitude == z, bank == x)
  409. getEulerYZXFromQuaternion: function ( q ) {
  410. var sqw = q.w * q.w;
  411. var sqx = q.x * q.x;
  412. var sqy = q.y * q.y;
  413. var sqz = q.z * q.z;
  414. var unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
  415. var test = q.x * q.y + q.z * q.w;
  416. if ( test > 0.499 * unit ) { // singularity at north pole
  417. this.y = 2 * Math.atan2( q.x, q.w );
  418. this.z = Math.PI / 2;
  419. this.x = 0;
  420. return;
  421. }
  422. if ( test < -0.499 * unit ) { // singularity at south pole
  423. this.y = -2 * Math.atan2( q.x, q.w );
  424. this.z = -Math.PI / 2;
  425. this.x = 0;
  426. return;
  427. }
  428. this.y = Math.atan2( 2 * q.y * q.w - 2 * q.x * q.z, sqx - sqy - sqz + sqw );
  429. this.z = Math.asin( 2 * test / unit );
  430. this.x = Math.atan2( 2 * q.x * q.w - 2 * q.y * q.z, -sqx + sqy - sqz + sqw );
  431. },
  432. */
  433. getScaleFromMatrix: function ( m ) {
  434. var sx = this.set( m.elements[0], m.elements[1], m.elements[2] ).length();
  435. var sy = this.set( m.elements[4], m.elements[5], m.elements[6] ).length();
  436. var sz = this.set( m.elements[8], m.elements[9], m.elements[10] ).length();
  437. this.x = sx;
  438. this.y = sy;
  439. this.z = sz;
  440. },
  441. equals: function ( v ) {
  442. return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );
  443. },
  444. isZero: function () {
  445. return ( this.lengthSq() < 0.0001 /* almostZero */ );
  446. },
  447. clone: function () {
  448. return new THREE.Vector3( this.x, this.y, this.z );
  449. }
  450. };
  451. /**
  452. * @author supereggbert / http://www.paulbrunt.co.uk/
  453. * @author philogb / http://blog.thejit.org/
  454. * @author mikael emtinger / http://gomo.se/
  455. * @author egraether / http://egraether.com/
  456. */
  457. THREE.Vector4 = function ( x, y, z, w ) {
  458. this.x = x || 0;
  459. this.y = y || 0;
  460. this.z = z || 0;
  461. this.w = ( w !== undefined ) ? w : 1;
  462. };
  463. THREE.Vector4.prototype = {
  464. constructor: THREE.Vector4,
  465. set: function ( x, y, z, w ) {
  466. this.x = x;
  467. this.y = y;
  468. this.z = z;
  469. this.w = w;
  470. return this;
  471. },
  472. copy: function ( v ) {
  473. this.x = v.x;
  474. this.y = v.y;
  475. this.z = v.z;
  476. this.w = ( v.w !== undefined ) ? v.w : 1;
  477. return this;
  478. },
  479. add: function ( a, b ) {
  480. this.x = a.x + b.x;
  481. this.y = a.y + b.y;
  482. this.z = a.z + b.z;
  483. this.w = a.w + b.w;
  484. return this;
  485. },
  486. addSelf: function ( v ) {
  487. this.x += v.x;
  488. this.y += v.y;
  489. this.z += v.z;
  490. this.w += v.w;
  491. return this;
  492. },
  493. sub: function ( a, b ) {
  494. this.x = a.x - b.x;
  495. this.y = a.y - b.y;
  496. this.z = a.z - b.z;
  497. this.w = a.w - b.w;
  498. return this;
  499. },
  500. subSelf: function ( v ) {
  501. this.x -= v.x;
  502. this.y -= v.y;
  503. this.z -= v.z;
  504. this.w -= v.w;
  505. return this;
  506. },
  507. multiplyScalar: function ( s ) {
  508. this.x *= s;
  509. this.y *= s;
  510. this.z *= s;
  511. this.w *= s;
  512. return this;
  513. },
  514. divideScalar: function ( s ) {
  515. if ( s ) {
  516. this.x /= s;
  517. this.y /= s;
  518. this.z /= s;
  519. this.w /= s;
  520. } else {
  521. this.x = 0;
  522. this.y = 0;
  523. this.z = 0;
  524. this.w = 1;
  525. }
  526. return this;
  527. },
  528. negate: function() {
  529. return this.multiplyScalar( -1 );
  530. },
  531. dot: function ( v ) {
  532. return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
  533. },
  534. lengthSq: function () {
  535. return this.dot( this );
  536. },
  537. length: function () {
  538. return Math.sqrt( this.lengthSq() );
  539. },
  540. normalize: function () {
  541. return this.divideScalar( this.length() );
  542. },
  543. setLength: function ( l ) {
  544. return this.normalize().multiplyScalar( l );
  545. },
  546. lerpSelf: function ( v, alpha ) {
  547. this.x += ( v.x - this.x ) * alpha;
  548. this.y += ( v.y - this.y ) * alpha;
  549. this.z += ( v.z - this.z ) * alpha;
  550. this.w += ( v.w - this.w ) * alpha;
  551. return this;
  552. },
  553. clone: function () {
  554. return new THREE.Vector4( this.x, this.y, this.z, this.w );
  555. }
  556. };
  557. /**
  558. * @author mrdoob / http://mrdoob.com/
  559. * @author alteredq / http://alteredqualia.com/
  560. */
  561. THREE.Frustum = function ( ) {
  562. this.planes = [
  563. new THREE.Vector4(),
  564. new THREE.Vector4(),
  565. new THREE.Vector4(),
  566. new THREE.Vector4(),
  567. new THREE.Vector4(),
  568. new THREE.Vector4()
  569. ];
  570. };
  571. THREE.Frustum.prototype.setFromMatrix = function ( m ) {
  572. var i, plane,
  573. planes = this.planes;
  574. var me = m.elements;
  575. var me0 = me[0], me1 = me[1], me2 = me[2], me3 = me[3];
  576. var me4 = me[4], me5 = me[5], me6 = me[6], me7 = me[7];
  577. var me8 = me[8], me9 = me[9], me10 = me[10], me11 = me[11];
  578. var me12 = me[12], me13 = me[13], me14 = me[14], me15 = me[15];
  579. planes[ 0 ].set( me3 - me0, me7 - me4, me11 - me8, me15 - me12 );
  580. planes[ 1 ].set( me3 + me0, me7 + me4, me11 + me8, me15 + me12 );
  581. planes[ 2 ].set( me3 + me1, me7 + me5, me11 + me9, me15 + me13 );
  582. planes[ 3 ].set( me3 - me1, me7 - me5, me11 - me9, me15 - me13 );
  583. planes[ 4 ].set( me3 - me2, me7 - me6, me11 - me10, me15 - me14 );
  584. planes[ 5 ].set( me3 + me2, me7 + me6, me11 + me10, me15 + me14 );
  585. for ( i = 0; i < 6; i ++ ) {
  586. plane = planes[ i ];
  587. plane.divideScalar( Math.sqrt( plane.x * plane.x + plane.y * plane.y + plane.z * plane.z ) );
  588. }
  589. };
  590. THREE.Frustum.prototype.contains = function ( object ) {
  591. var distance,
  592. planes = this.planes,
  593. matrix = object.matrixWorld,
  594. me = matrix.elements,
  595. scale = THREE.Frustum.__v1.set( matrix.getColumnX().length(), matrix.getColumnY().length(), matrix.getColumnZ().length() ),
  596. radius = - object.geometry.boundingSphere.radius * Math.max( scale.x, Math.max( scale.y, scale.z ) );
  597. for ( var i = 0; i < 6; i ++ ) {
  598. distance = planes[ i ].x * me[12] + planes[ i ].y * me[13] + planes[ i ].z * me[14] + planes[ i ].w;
  599. if ( distance <= radius ) return false;
  600. }
  601. return true;
  602. };
  603. THREE.Frustum.__v1 = new THREE.Vector3();
  604. /**
  605. * @author mr.doob / http://mrdoob.com/
  606. */
  607. THREE.Ray = function ( origin, direction ) {
  608. this.origin = origin || new THREE.Vector3();
  609. this.direction = direction || new THREE.Vector3();
  610. var precision = 0.0001;
  611. this.setPrecision = function ( value ) {
  612. precision = value;
  613. };
  614. var a = new THREE.Vector3();
  615. var b = new THREE.Vector3();
  616. var c = new THREE.Vector3();
  617. var d = new THREE.Vector3();
  618. var originCopy = new THREE.Vector3();
  619. var directionCopy = new THREE.Vector3();
  620. var vector = new THREE.Vector3();
  621. var normal = new THREE.Vector3();
  622. var intersectPoint = new THREE.Vector3()
  623. this.intersectObject = function ( object ) {
  624. var intersect, intersects = [];
  625. if ( object instanceof THREE.Particle ) {
  626. var distance = distanceFromIntersection( this.origin, this.direction, object.matrixWorld.getPosition() );
  627. if ( distance > object.scale.x ) {
  628. return [];
  629. }
  630. intersect = {
  631. distance: distance,
  632. point: object.position,
  633. face: null,
  634. object: object
  635. };
  636. intersects.push( intersect );
  637. } else if ( object instanceof THREE.Mesh ) {
  638. // Checking boundingSphere
  639. var distance = distanceFromIntersection( this.origin, this.direction, object.matrixWorld.getPosition() );
  640. var scale = THREE.Frustum.__v1.set( object.matrixWorld.getColumnX().length(), object.matrixWorld.getColumnY().length(), object.matrixWorld.getColumnZ().length() );
  641. if ( distance > object.geometry.boundingSphere.radius * Math.max( scale.x, Math.max( scale.y, scale.z ) ) ) {
  642. return intersects;
  643. }
  644. // Checking faces
  645. var f, fl, face, dot, scalar,
  646. geometry = object.geometry,
  647. vertices = geometry.vertices,
  648. objMatrix;
  649. object.matrixRotationWorld.extractRotation( object.matrixWorld );
  650. for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
  651. face = geometry.faces[ f ];
  652. originCopy.copy( this.origin );
  653. directionCopy.copy( this.direction );
  654. objMatrix = object.matrixWorld;
  655. // determine if ray intersects the plane of the face
  656. // note: this works regardless of the direction of the face normal
  657. vector = objMatrix.multiplyVector3( vector.copy( face.centroid ) ).subSelf( originCopy );
  658. normal = object.matrixRotationWorld.multiplyVector3( normal.copy( face.normal ) );
  659. dot = directionCopy.dot( normal );
  660. // bail if ray and plane are parallel
  661. if ( Math.abs( dot ) < precision ) continue;
  662. // calc distance to plane
  663. scalar = normal.dot( vector ) / dot;
  664. // if negative distance, then plane is behind ray
  665. if ( scalar < 0 ) continue;
  666. if ( object.doubleSided || ( object.flipSided ? dot > 0 : dot < 0 ) ) {
  667. intersectPoint.add( originCopy, directionCopy.multiplyScalar( scalar ) );
  668. if ( face instanceof THREE.Face3 ) {
  669. a = objMatrix.multiplyVector3( a.copy( vertices[ face.a ].position ) );
  670. b = objMatrix.multiplyVector3( b.copy( vertices[ face.b ].position ) );
  671. c = objMatrix.multiplyVector3( c.copy( vertices[ face.c ].position ) );
  672. if ( pointInFace3( intersectPoint, a, b, c ) ) {
  673. intersect = {
  674. distance: originCopy.distanceTo( intersectPoint ),
  675. point: intersectPoint.clone(),
  676. face: face,
  677. object: object
  678. };
  679. intersects.push( intersect );
  680. }
  681. } else if ( face instanceof THREE.Face4 ) {
  682. a = objMatrix.multiplyVector3( a.copy( vertices[ face.a ].position ) );
  683. b = objMatrix.multiplyVector3( b.copy( vertices[ face.b ].position ) );
  684. c = objMatrix.multiplyVector3( c.copy( vertices[ face.c ].position ) );
  685. d = objMatrix.multiplyVector3( d.copy( vertices[ face.d ].position ) );
  686. if ( pointInFace3( intersectPoint, a, b, d ) || pointInFace3( intersectPoint, b, c, d ) ) {
  687. intersect = {
  688. distance: originCopy.distanceTo( intersectPoint ),
  689. point: intersectPoint.clone(),
  690. face: face,
  691. object: object
  692. };
  693. intersects.push( intersect );
  694. }
  695. }
  696. }
  697. }
  698. }
  699. return intersects;
  700. }
  701. this.intersectObjects = function ( objects ) {
  702. var intersects = [];
  703. for ( var i = 0, l = objects.length; i < l; i ++ ) {
  704. Array.prototype.push.apply( intersects, this.intersectObject( objects[ i ] ) );
  705. }
  706. intersects.sort( function ( a, b ) { return a.distance - b.distance; } );
  707. return intersects;
  708. };
  709. var v0 = new THREE.Vector3(), v1 = new THREE.Vector3(), v2 = new THREE.Vector3();
  710. var dot, intersect, distance;
  711. function distanceFromIntersection( origin, direction, position ) {
  712. v0.sub( position, origin );
  713. dot = v0.dot( direction );
  714. intersect = v1.add( origin, v2.copy( direction ).multiplyScalar( dot ) );
  715. distance = position.distanceTo( intersect );
  716. return distance;
  717. }
  718. // http://www.blackpawn.com/texts/pointinpoly/default.html
  719. var dot00, dot01, dot02, dot11, dot12, invDenom, u, v;
  720. function pointInFace3( p, a, b, c ) {
  721. v0.sub( c, a );
  722. v1.sub( b, a );
  723. v2.sub( p, a );
  724. dot00 = v0.dot( v0 );
  725. dot01 = v0.dot( v1 );
  726. dot02 = v0.dot( v2 );
  727. dot11 = v1.dot( v1 );
  728. dot12 = v1.dot( v2 );
  729. invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 );
  730. u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
  731. v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
  732. return ( u >= 0 ) && ( v >= 0 ) && ( u + v < 1 );
  733. }
  734. };/**
  735. * @author mr.doob / http://mrdoob.com/
  736. */
  737. THREE.Rectangle = function () {
  738. var _left, _top, _right, _bottom,
  739. _width, _height, _isEmpty = true;
  740. function resize() {
  741. _width = _right - _left;
  742. _height = _bottom - _top;
  743. }
  744. this.getX = function () {
  745. return _left;
  746. };
  747. this.getY = function () {
  748. return _top;
  749. };
  750. this.getWidth = function () {
  751. return _width;
  752. };
  753. this.getHeight = function () {
  754. return _height;
  755. };
  756. this.getLeft = function() {
  757. return _left;
  758. };
  759. this.getTop = function() {
  760. return _top;
  761. };
  762. this.getRight = function() {
  763. return _right;
  764. };
  765. this.getBottom = function() {
  766. return _bottom;
  767. };
  768. this.set = function ( left, top, right, bottom ) {
  769. _isEmpty = false;
  770. _left = left; _top = top;
  771. _right = right; _bottom = bottom;
  772. resize();
  773. };
  774. this.addPoint = function ( x, y ) {
  775. if ( _isEmpty ) {
  776. _isEmpty = false;
  777. _left = x; _top = y;
  778. _right = x; _bottom = y;
  779. resize();
  780. } else {
  781. _left = _left < x ? _left : x; // Math.min( _left, x );
  782. _top = _top < y ? _top : y; // Math.min( _top, y );
  783. _right = _right > x ? _right : x; // Math.max( _right, x );
  784. _bottom = _bottom > y ? _bottom : y; // Math.max( _bottom, y );
  785. resize();
  786. }
  787. };
  788. this.add3Points = function ( x1, y1, x2, y2, x3, y3 ) {
  789. if (_isEmpty) {
  790. _isEmpty = false;
  791. _left = x1 < x2 ? ( x1 < x3 ? x1 : x3 ) : ( x2 < x3 ? x2 : x3 );
  792. _top = y1 < y2 ? ( y1 < y3 ? y1 : y3 ) : ( y2 < y3 ? y2 : y3 );
  793. _right = x1 > x2 ? ( x1 > x3 ? x1 : x3 ) : ( x2 > x3 ? x2 : x3 );
  794. _bottom = y1 > y2 ? ( y1 > y3 ? y1 : y3 ) : ( y2 > y3 ? y2 : y3 );
  795. resize();
  796. } else {
  797. _left = x1 < x2 ? ( x1 < x3 ? ( x1 < _left ? x1 : _left ) : ( x3 < _left ? x3 : _left ) ) : ( x2 < x3 ? ( x2 < _left ? x2 : _left ) : ( x3 < _left ? x3 : _left ) );
  798. _top = y1 < y2 ? ( y1 < y3 ? ( y1 < _top ? y1 : _top ) : ( y3 < _top ? y3 : _top ) ) : ( y2 < y3 ? ( y2 < _top ? y2 : _top ) : ( y3 < _top ? y3 : _top ) );
  799. _right = x1 > x2 ? ( x1 > x3 ? ( x1 > _right ? x1 : _right ) : ( x3 > _right ? x3 : _right ) ) : ( x2 > x3 ? ( x2 > _right ? x2 : _right ) : ( x3 > _right ? x3 : _right ) );
  800. _bottom = y1 > y2 ? ( y1 > y3 ? ( y1 > _bottom ? y1 : _bottom ) : ( y3 > _bottom ? y3 : _bottom ) ) : ( y2 > y3 ? ( y2 > _bottom ? y2 : _bottom ) : ( y3 > _bottom ? y3 : _bottom ) );
  801. resize();
  802. };
  803. };
  804. this.addRectangle = function ( r ) {
  805. if ( _isEmpty ) {
  806. _isEmpty = false;
  807. _left = r.getLeft(); _top = r.getTop();
  808. _right = r.getRight(); _bottom = r.getBottom();
  809. resize();
  810. } else {
  811. _left = _left < r.getLeft() ? _left : r.getLeft(); // Math.min(_left, r.getLeft() );
  812. _top = _top < r.getTop() ? _top : r.getTop(); // Math.min(_top, r.getTop() );
  813. _right = _right > r.getRight() ? _right : r.getRight(); // Math.max(_right, r.getRight() );
  814. _bottom = _bottom > r.getBottom() ? _bottom : r.getBottom(); // Math.max(_bottom, r.getBottom() );
  815. resize();
  816. }
  817. };
  818. this.inflate = function ( v ) {
  819. _left -= v; _top -= v;
  820. _right += v; _bottom += v;
  821. resize();
  822. };
  823. this.minSelf = function ( r ) {
  824. _left = _left > r.getLeft() ? _left : r.getLeft(); // Math.max( _left, r.getLeft() );
  825. _top = _top > r.getTop() ? _top : r.getTop(); // Math.max( _top, r.getTop() );
  826. _right = _right < r.getRight() ? _right : r.getRight(); // Math.min( _right, r.getRight() );
  827. _bottom = _bottom < r.getBottom() ? _bottom : r.getBottom(); // Math.min( _bottom, r.getBottom() );
  828. resize();
  829. };
  830. this.intersects = function ( r ) {
  831. // http://gamemath.com/2011/09/detecting-whether-two-boxes-overlap/
  832. if ( _right < r.getLeft() ) return false;
  833. if ( _left > r.getRight() ) return false;
  834. if ( _bottom < r.getTop() ) return false;
  835. if ( _top > r.getBottom() ) return false;
  836. return true;
  837. };
  838. this.empty = function () {
  839. _isEmpty = true;
  840. _left = 0; _top = 0;
  841. _right = 0; _bottom = 0;
  842. resize();
  843. };
  844. this.isEmpty = function () {
  845. return _isEmpty;
  846. };
  847. };
  848. /**
  849. * @author alteredq / http://alteredqualia.com/
  850. */
  851. THREE.Math = {
  852. // Clamp value to range <a, b>
  853. clamp: function ( x, a, b ) {
  854. return ( x < a ) ? a : ( ( x > b ) ? b : x );
  855. },
  856. // Clamp value to range <a, inf)
  857. clampBottom: function ( x, a ) {
  858. return x < a ? a : x;
  859. },
  860. // Linear mapping from range <a1, a2> to range <b1, b2>
  861. mapLinear: function ( x, a1, a2, b1, b2 ) {
  862. return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
  863. },
  864. // Random float from <0, 1> with 16 bits of randomness
  865. // (standard Math.random() creates repetitive patterns when applied over larger space)
  866. random16: function () {
  867. return ( 65280 * Math.random() + 255 * Math.random() ) / 65535;
  868. },
  869. // Random integer from <low, high> interval
  870. randInt: function ( low, high ) {
  871. return low + Math.floor( Math.random() * ( high - low + 1 ) );
  872. },
  873. // Random float from <low, high> interval
  874. randFloat: function ( low, high ) {
  875. return low + Math.random() * ( high - low );
  876. },
  877. // Random float from <-range/2, range/2> interval
  878. randFloatSpread: function ( range ) {
  879. return range * ( 0.5 - Math.random() );
  880. },
  881. sign: function ( x ) {
  882. return ( x < 0 ) ? -1 : ( ( x > 0 ) ? 1 : 0 );
  883. }
  884. };
  885. /**
  886. * @author alteredq / http://alteredqualia.com/
  887. */
  888. THREE.Matrix3 = function () {
  889. this.m = [];
  890. };
  891. THREE.Matrix3.prototype = {
  892. constructor: THREE.Matrix3,
  893. getInverse: function ( matrix ) {
  894. // input: THREE.Matrix4
  895. // ( based on http://code.google.com/p/webgl-mjs/ )
  896. var a11 = matrix.elements[10] * matrix.elements[5] - matrix.elements[6] * matrix.elements[9];
  897. var a21 = - matrix.elements[10] * matrix.elements[1] + matrix.elements[2] * matrix.elements[9];
  898. var a31 = matrix.elements[6] * matrix.elements[1] - matrix.elements[2] * matrix.elements[5];
  899. var a12 = - matrix.elements[10] * matrix.elements[4] + matrix.elements[6] * matrix.elements[8];
  900. var a22 = matrix.elements[10] * matrix.elements[0] - matrix.elements[2] * matrix.elements[8];
  901. var a32 = - matrix.elements[6] * matrix.elements[0] + matrix.elements[2] * matrix.elements[4];
  902. var a13 = matrix.elements[9] * matrix.elements[4] - matrix.elements[5] * matrix.elements[8];
  903. var a23 = - matrix.elements[9] * matrix.elements[0] + matrix.elements[1] * matrix.elements[8];
  904. var a33 = matrix.elements[5] * matrix.elements[0] - matrix.elements[1] * matrix.elements[4];
  905. var det = matrix.elements[0] * a11 + matrix.elements[1] * a12 + matrix.elements[2] * a13;
  906. // no inverse
  907. if ( det === 0 ) {
  908. console.warn( "Matrix3.getInverse(): determinant == 0" );
  909. }
  910. var idet = 1.0 / det;
  911. var m = this.m;
  912. m[ 0 ] = idet * a11; m[ 1 ] = idet * a21; m[ 2 ] = idet * a31;
  913. m[ 3 ] = idet * a12; m[ 4 ] = idet * a22; m[ 5 ] = idet * a32;
  914. m[ 6 ] = idet * a13; m[ 7 ] = idet * a23; m[ 8 ] = idet * a33;
  915. return this;
  916. },
  917. /*
  918. transpose: function () {
  919. var tmp, m = this.m;
  920. tmp = m[1]; m[1] = m[3]; m[3] = tmp;
  921. tmp = m[2]; m[2] = m[6]; m[6] = tmp;
  922. tmp = m[5]; m[5] = m[7]; m[7] = tmp;
  923. return this;
  924. },
  925. */
  926. transposeIntoArray: function ( r ) {
  927. var m = this.m;
  928. r[ 0 ] = m[ 0 ];
  929. r[ 1 ] = m[ 3 ];
  930. r[ 2 ] = m[ 6 ];
  931. r[ 3 ] = m[ 1 ];
  932. r[ 4 ] = m[ 4 ];
  933. r[ 5 ] = m[ 7 ];
  934. r[ 6 ] = m[ 2 ];
  935. r[ 7 ] = m[ 5 ];
  936. r[ 8 ] = m[ 8 ];
  937. return this;
  938. }
  939. };
  940. /**
  941. * @author mr.doob / http://mrdoob.com/
  942. * @author supereggbert / http://www.paulbrunt.co.uk/
  943. * @author philogb / http://blog.thejit.org/
  944. * @author jordi_ros / http://plattsoft.com
  945. * @author D1plo1d / http://github.com/D1plo1d
  946. * @author alteredq / http://alteredqualia.com/
  947. * @author mikael emtinger / http://gomo.se/
  948. * @author timknip / http://www.floorplanner.com/
  949. */
  950. THREE.Matrix4 = function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
  951. this.elements = new Float32Array(16);
  952. this.set(
  953. ( n11 !== undefined ) ? n11 : 1, n12 || 0, n13 || 0, n14 || 0,
  954. n21 || 0, ( n22 !== undefined ) ? n22 : 1, n23 || 0, n24 || 0,
  955. n31 || 0, n32 || 0, ( n33 !== undefined ) ? n33 : 1, n34 || 0,
  956. n41 || 0, n42 || 0, n43 || 0, ( n44 !== undefined ) ? n44 : 1
  957. );
  958. };
  959. THREE.Matrix4.prototype = {
  960. constructor: THREE.Matrix4,
  961. set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
  962. var te = this.elements;
  963. te[0] = n11; te[4] = n12; te[8] = n13; te[12] = n14;
  964. te[1] = n21; te[5] = n22; te[9] = n23; te[13] = n24;
  965. te[2] = n31; te[6] = n32; te[10] = n33; te[14] = n34;
  966. te[3] = n41; te[7] = n42; te[11] = n43; te[15] = n44;
  967. return this;
  968. },
  969. identity: function () {
  970. this.set(
  971. 1, 0, 0, 0,
  972. 0, 1, 0, 0,
  973. 0, 0, 1, 0,
  974. 0, 0, 0, 1
  975. );
  976. return this;
  977. },
  978. copy: function ( m ) {
  979. var me = m.elements;
  980. this.set(
  981. me[0], me[4], me[8], me[12],
  982. me[1], me[5], me[9], me[13],
  983. me[2], me[6], me[10], me[14],
  984. me[3], me[7], me[11], me[15]
  985. );
  986. return this;
  987. },
  988. lookAt: function ( eye, target, up ) {
  989. var te = this.elements;
  990. var x = THREE.Matrix4.__v1;
  991. var y = THREE.Matrix4.__v2;
  992. var z = THREE.Matrix4.__v3;
  993. z.sub( eye, target ).normalize();
  994. if ( z.length() === 0 ) {
  995. z.z = 1;
  996. }
  997. x.cross( up, z ).normalize();
  998. if ( x.length() === 0 ) {
  999. z.x += 0.0001;
  1000. x.cross( up, z ).normalize();
  1001. }
  1002. y.cross( z, x );
  1003. te[0] = x.x; te[4] = y.x; te[8] = z.x;
  1004. te[1] = x.y; te[5] = y.y; te[9] = z.y;
  1005. te[2] = x.z; te[6] = y.z; te[10] = z.z;
  1006. return this;
  1007. },
  1008. multiply: function ( a, b ) {
  1009. var ae = a.elements,
  1010. be = b.elements,
  1011. te = this.elements;
  1012. var a11 = ae[0], a12 = ae[4], a13 = ae[8], a14 = ae[12];
  1013. var a21 = ae[1], a22 = ae[5], a23 = ae[9], a24 = ae[13];
  1014. var a31 = ae[2], a32 = ae[6], a33 = ae[10], a34 = ae[14];
  1015. var a41 = ae[3], a42 = ae[7], a43 = ae[11], a44 = ae[15];
  1016. var b11 = be[0], b12 = be[4], b13 = be[8], b14 = be[12];
  1017. var b21 = be[1], b22 = be[5], b23 = be[9], b24 = be[13];
  1018. var b31 = be[2], b32 = be[6], b33 = be[10], b34 = be[14];
  1019. var b41 = be[3], b42 = be[7], b43 = be[11], b44 = be[15];
  1020. te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
  1021. te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
  1022. te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
  1023. te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
  1024. te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
  1025. te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
  1026. te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
  1027. te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
  1028. te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
  1029. te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
  1030. te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
  1031. te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
  1032. te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
  1033. te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
  1034. te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
  1035. te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
  1036. return this;
  1037. },
  1038. multiplySelf: function ( m ) {
  1039. return this.multiply( this, m );
  1040. },
  1041. multiplyToArray: function ( a, b, r ) {
  1042. var te = this.elements;
  1043. this.multiply( a, b );
  1044. r[ 0 ] = te[0]; r[ 1 ] = te[1]; r[ 2 ] = te[2]; r[ 3 ] = te[3];
  1045. r[ 4 ] = te[4]; r[ 5 ] = te[5]; r[ 6 ] = te[6]; r[ 7 ] = te[7];
  1046. r[ 8 ] = te[8]; r[ 9 ] = te[9]; r[ 10 ] = te[10]; r[ 11 ] = te[11];
  1047. r[ 12 ] = te[12]; r[ 13 ] = te[13]; r[ 14 ] = te[14]; r[ 15 ] = te[15];
  1048. return this;
  1049. },
  1050. multiplyScalar: function ( s ) {
  1051. var te = this.elements;
  1052. te[0] *= s; te[4] *= s; te[8] *= s; te[12] *= s;
  1053. te[1] *= s; te[5] *= s; te[9] *= s; te[13] *= s;
  1054. te[2] *= s; te[6] *= s; te[10] *= s; te[14] *= s;
  1055. te[3] *= s; te[7] *= s; te[11] *= s; te[15] *= s;
  1056. return this;
  1057. },
  1058. multiplyVector3: function ( v ) {
  1059. var te = this.elements;
  1060. var vx = v.x, vy = v.y, vz = v.z;
  1061. var d = 1 / ( te[3] * vx + te[7] * vy + te[11] * vz + te[15] );
  1062. v.x = ( te[0] * vx + te[4] * vy + te[8] * vz + te[12] ) * d;
  1063. v.y = ( te[1] * vx + te[5] * vy + te[9] * vz + te[13] ) * d;
  1064. v.z = ( te[2] * vx + te[6] * vy + te[10] * vz + te[14] ) * d;
  1065. return v;
  1066. },
  1067. multiplyVector4: function ( v ) {
  1068. var te = this.elements;
  1069. var vx = v.x, vy = v.y, vz = v.z, vw = v.w;
  1070. v.x = te[0] * vx + te[4] * vy + te[8] * vz + te[12] * vw;
  1071. v.y = te[1] * vx + te[5] * vy + te[9] * vz + te[13] * vw;
  1072. v.z = te[2] * vx + te[6] * vy + te[10] * vz + te[14] * vw;
  1073. v.w = te[3] * vx + te[7] * vy + te[11] * vz + te[15] * vw;
  1074. return v;
  1075. },
  1076. rotateAxis: function ( v ) {
  1077. var te = this.elements;
  1078. var vx = v.x, vy = v.y, vz = v.z;
  1079. v.x = vx * te[0] + vy * te[4] + vz * te[8];
  1080. v.y = vx * te[1] + vy * te[5] + vz * te[9];
  1081. v.z = vx * te[2] + vy * te[6] + vz * te[10];
  1082. v.normalize();
  1083. return v;
  1084. },
  1085. crossVector: function ( a ) {
  1086. var te = this.elements;
  1087. var v = new THREE.Vector4();
  1088. v.x = te[0] * a.x + te[4] * a.y + te[8] * a.z + te[12] * a.w;
  1089. v.y = te[1] * a.x + te[5] * a.y + te[9] * a.z + te[13] * a.w;
  1090. v.z = te[2] * a.x + te[6] * a.y + te[10] * a.z + te[14] * a.w;
  1091. v.w = ( a.w ) ? te[3] * a.x + te[7] * a.y + te[11] * a.z + te[15] * a.w : 1;
  1092. return v;
  1093. },
  1094. determinant: function () {
  1095. var te = this.elements;
  1096. var n11 = te[0], n12 = te[4], n13 = te[8], n14 = te[12];
  1097. var n21 = te[1], n22 = te[5], n23 = te[9], n24 = te[13];
  1098. var n31 = te[2], n32 = te[6], n33 = te[10], n34 = te[14];
  1099. var n41 = te[3], n42 = te[7], n43 = te[11], n44 = te[15];
  1100. //TODO: make this more efficient
  1101. //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
  1102. return (
  1103. n14 * n23 * n32 * n41-
  1104. n13 * n24 * n32 * n41-
  1105. n14 * n22 * n33 * n41+
  1106. n12 * n24 * n33 * n41+
  1107. n13 * n22 * n34 * n41-
  1108. n12 * n23 * n34 * n41-
  1109. n14 * n23 * n31 * n42+
  1110. n13 * n24 * n31 * n42+
  1111. n14 * n21 * n33 * n42-
  1112. n11 * n24 * n33 * n42-
  1113. n13 * n21 * n34 * n42+
  1114. n11 * n23 * n34 * n42+
  1115. n14 * n22 * n31 * n43-
  1116. n12 * n24 * n31 * n43-
  1117. n14 * n21 * n32 * n43+
  1118. n11 * n24 * n32 * n43+
  1119. n12 * n21 * n34 * n43-
  1120. n11 * n22 * n34 * n43-
  1121. n13 * n22 * n31 * n44+
  1122. n12 * n23 * n31 * n44+
  1123. n13 * n21 * n32 * n44-
  1124. n11 * n23 * n32 * n44-
  1125. n12 * n21 * n33 * n44+
  1126. n11 * n22 * n33 * n44
  1127. );
  1128. },
  1129. transpose: function () {
  1130. var te = this.elements;
  1131. var tmp;
  1132. tmp = te[1]; te[1] = te[4]; te[4] = tmp;
  1133. tmp = te[2]; te[2] = te[8]; te[8] = tmp;
  1134. tmp = te[6]; te[6] = te[9]; te[9] = tmp;
  1135. tmp = te[3]; te[3] = te[12]; te[12] = tmp;
  1136. tmp = te[7]; te[7] = te[13]; te[13] = tmp;
  1137. tmp = te[11]; te[11] = te[14]; te[14] = tmp;
  1138. return this;
  1139. },
  1140. flattenToArray: function ( flat ) {
  1141. var te = this.elements;
  1142. flat[ 0 ] = te[0]; flat[ 1 ] = te[1]; flat[ 2 ] = te[2]; flat[ 3 ] = te[3];
  1143. flat[ 4 ] = te[4]; flat[ 5 ] = te[5]; flat[ 6 ] = te[6]; flat[ 7 ] = te[7];
  1144. flat[ 8 ] = te[8]; flat[ 9 ] = te[9]; flat[ 10 ] = te[10]; flat[ 11 ] = te[11];
  1145. flat[ 12 ] = te[12]; flat[ 13 ] = te[13]; flat[ 14 ] = te[14]; flat[ 15 ] = te[15];
  1146. return flat;
  1147. },
  1148. flattenToArrayOffset: function( flat, offset ) {
  1149. var te = this.elements;
  1150. flat[ offset ] = te[0];
  1151. flat[ offset + 1 ] = te[1];
  1152. flat[ offset + 2 ] = te[2];
  1153. flat[ offset + 3 ] = te[3];
  1154. flat[ offset + 4 ] = te[4];
  1155. flat[ offset + 5 ] = te[5];
  1156. flat[ offset + 6 ] = te[6];
  1157. flat[ offset + 7 ] = te[7];
  1158. flat[ offset + 8 ] = te[8];
  1159. flat[ offset + 9 ] = te[9];
  1160. flat[ offset + 10 ] = te[10];
  1161. flat[ offset + 11 ] = te[11];
  1162. flat[ offset + 12 ] = te[12];
  1163. flat[ offset + 13 ] = te[13];
  1164. flat[ offset + 14 ] = te[14];
  1165. flat[ offset + 15 ] = te[15];
  1166. return flat;
  1167. },
  1168. getPosition: function () {
  1169. var te = this.elements;
  1170. return THREE.Matrix4.__v1.set( te[12], te[13], te[14] );
  1171. },
  1172. setPosition: function ( v ) {
  1173. var te = this.elements;
  1174. te[12] = v.x;
  1175. te[13] = v.y;
  1176. te[14] = v.z;
  1177. return this;
  1178. },
  1179. getColumnX: function () {
  1180. var te = this.elements;
  1181. return THREE.Matrix4.__v1.set( te[0], te[1], te[2] );
  1182. },
  1183. getColumnY: function () {
  1184. var te = this.elements;
  1185. return THREE.Matrix4.__v1.set( te[4], te[5], te[6] );
  1186. },
  1187. getColumnZ: function() {
  1188. var te = this.elements;
  1189. return THREE.Matrix4.__v1.set( te[8], te[9], te[10] );
  1190. },
  1191. getInverse: function ( m ) {
  1192. // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
  1193. var te = this.elements;
  1194. var me = m.elements;
  1195. var n11 = me[0], n12 = me[4], n13 = me[8], n14 = me[12];
  1196. var n21 = me[1], n22 = me[5], n23 = me[9], n24 = me[13];
  1197. var n31 = me[2], n32 = me[6], n33 = me[10], n34 = me[14];
  1198. var n41 = me[3], n42 = me[7], n43 = me[11], n44 = me[15];
  1199. te[0] = n23*n34*n42 - n24*n33*n42 + n24*n32*n43 - n22*n34*n43 - n23*n32*n44 + n22*n33*n44;
  1200. te[4] = n14*n33*n42 - n13*n34*n42 - n14*n32*n43 + n12*n34*n43 + n13*n32*n44 - n12*n33*n44;
  1201. te[8] = n13*n24*n42 - n14*n23*n42 + n14*n22*n43 - n12*n24*n43 - n13*n22*n44 + n12*n23*n44;
  1202. te[12] = n14*n23*n32 - n13*n24*n32 - n14*n22*n33 + n12*n24*n33 + n13*n22*n34 - n12*n23*n34;
  1203. te[1] = n24*n33*n41 - n23*n34*n41 - n24*n31*n43 + n21*n34*n43 + n23*n31*n44 - n21*n33*n44;
  1204. te[5] = n13*n34*n41 - n14*n33*n41 + n14*n31*n43 - n11*n34*n43 - n13*n31*n44 + n11*n33*n44;
  1205. te[9] = n14*n23*n41 - n13*n24*n41 - n14*n21*n43 + n11*n24*n43 + n13*n21*n44 - n11*n23*n44;
  1206. te[13] = n13*n24*n31 - n14*n23*n31 + n14*n21*n33 - n11*n24*n33 - n13*n21*n34 + n11*n23*n34;
  1207. te[2] = n22*n34*n41 - n24*n32*n41 + n24*n31*n42 - n21*n34*n42 - n22*n31*n44 + n21*n32*n44;
  1208. te[6] = n14*n32*n41 - n12*n34*n41 - n14*n31*n42 + n11*n34*n42 + n12*n31*n44 - n11*n32*n44;
  1209. te[10] = n12*n24*n41 - n14*n22*n41 + n14*n21*n42 - n11*n24*n42 - n12*n21*n44 + n11*n22*n44;
  1210. te[14] = n14*n22*n31 - n12*n24*n31 - n14*n21*n32 + n11*n24*n32 + n12*n21*n34 - n11*n22*n34;
  1211. te[3] = n23*n32*n41 - n22*n33*n41 - n23*n31*n42 + n21*n33*n42 + n22*n31*n43 - n21*n32*n43;
  1212. te[7] = n12*n33*n41 - n13*n32*n41 + n13*n31*n42 - n11*n33*n42 - n12*n31*n43 + n11*n32*n43;
  1213. te[11] = n13*n22*n41 - n12*n23*n41 - n13*n21*n42 + n11*n23*n42 + n12*n21*n43 - n11*n22*n43;
  1214. te[15] = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33;
  1215. this.multiplyScalar( 1 / m.determinant() );
  1216. return this;
  1217. },
  1218. setRotationFromEuler: function( v, order ) {
  1219. var te = this.elements;
  1220. var x = v.x, y = v.y, z = v.z;
  1221. var a = Math.cos( x ), b = Math.sin( x );
  1222. var c = Math.cos( y ), d = Math.sin( y );
  1223. var e = Math.cos( z ), f = Math.sin( z );
  1224. switch ( order ) {
  1225. case 'YXZ':
  1226. var ce = c * e, cf = c * f, de = d * e, df = d * f;
  1227. te[0] = ce + df * b;
  1228. te[4] = de * b - cf;
  1229. te[8] = a * d;
  1230. te[1] = a * f;
  1231. te[5] = a * e;
  1232. te[9] = - b;
  1233. te[2] = cf * b - de;
  1234. te[6] = df + ce * b;
  1235. te[10] = a * c;
  1236. break;
  1237. case 'ZXY':
  1238. var ce = c * e, cf = c * f, de = d * e, df = d * f;
  1239. te[0] = ce - df * b;
  1240. te[4] = - a * f;
  1241. te[8] = de + cf * b;
  1242. te[1] = cf + de * b;
  1243. te[5] = a * e;
  1244. te[9] = df - ce * b;
  1245. te[2] = - a * d;
  1246. te[6] = b;
  1247. te[10] = a * c;
  1248. break;
  1249. case 'ZYX':
  1250. var ae = a * e, af = a * f, be = b * e, bf = b * f;
  1251. te[0] = c * e;
  1252. te[4] = be * d - af;
  1253. te[8] = ae * d + bf;
  1254. te[1] = c * f;
  1255. te[5] = bf * d + ae;
  1256. te[9] = af * d - be;
  1257. te[2] = - d;
  1258. te[6] = b * c;
  1259. te[10] = a * c;
  1260. break;
  1261. case 'YZX':
  1262. var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
  1263. te[0] = c * e;
  1264. te[4] = bd - ac * f;
  1265. te[8] = bc * f + ad;
  1266. te[1] = f;
  1267. te[5] = a * e;
  1268. te[9] = - b * e;
  1269. te[2] = - d * e;
  1270. te[6] = ad * f + bc;
  1271. te[10] = ac - bd * f;
  1272. break;
  1273. case 'XZY':
  1274. var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
  1275. te[0] = c * e;
  1276. te[4] = - f;
  1277. te[8] = d * e;
  1278. te[1] = ac * f + bd;
  1279. te[5] = a * e;
  1280. te[9] = ad * f - bc;
  1281. te[2] = bc * f - ad;
  1282. te[6] = b * e;
  1283. te[10] = bd * f + ac;
  1284. break;
  1285. default: // 'XYZ'
  1286. var ae = a * e, af = a * f, be = b * e, bf = b * f;
  1287. te[0] = c * e;
  1288. te[4] = - c * f;
  1289. te[8] = d;
  1290. te[1] = af + be * d;
  1291. te[5] = ae - bf * d;
  1292. te[9] = - b * c;
  1293. te[2] = bf - ae * d;
  1294. te[6] = be + af * d;
  1295. te[10] = a * c;
  1296. break;
  1297. }
  1298. return this;
  1299. },
  1300. setRotationFromQuaternion: function( q ) {
  1301. var te = this.elements;
  1302. var x = q.x, y = q.y, z = q.z, w = q.w;
  1303. var x2 = x + x, y2 = y + y, z2 = z + z;
  1304. var xx = x * x2, xy = x * y2, xz = x * z2;
  1305. var yy = y * y2, yz = y * z2, zz = z * z2;
  1306. var wx = w * x2, wy = w * y2, wz = w * z2;
  1307. te[0] = 1 - ( yy + zz );
  1308. te[4] = xy - wz;
  1309. te[8] = xz + wy;
  1310. te[1] = xy + wz;
  1311. te[5] = 1 - ( xx + zz );
  1312. te[9] = yz - wx;
  1313. te[2] = xz - wy;
  1314. te[6] = yz + wx;
  1315. te[10] = 1 - ( xx + yy );
  1316. return this;
  1317. },
  1318. compose: function ( translation, rotation, scale ) {
  1319. var te = this.elements;
  1320. var mRotation = THREE.Matrix4.__m1;
  1321. var mScale = THREE.Matrix4.__m2;
  1322. mRotation.identity();
  1323. mRotation.setRotationFromQuaternion( rotation );
  1324. mScale.makeScale( scale.x, scale.y, scale.z );
  1325. this.multiply( mRotation, mScale );
  1326. te[12] = translation.x;
  1327. te[13] = translation.y;
  1328. te[14] = translation.z;
  1329. return this;
  1330. },
  1331. decompose: function ( translation, rotation, scale ) {
  1332. // grab the axis vectors
  1333. var te = this.elements;
  1334. var x = THREE.Matrix4.__v1;
  1335. var y = THREE.Matrix4.__v2;
  1336. var z = THREE.Matrix4.__v3;
  1337. x.set( te[0], te[1], te[2] );
  1338. y.set( te[4], te[5], te[6] );
  1339. z.set( te[8], te[9], te[10] );
  1340. translation = ( translation instanceof THREE.Vector3 ) ? translation : new THREE.Vector3();
  1341. rotation = ( rotation instanceof THREE.Quaternion ) ? rotation : new THREE.Quaternion();
  1342. scale = ( scale instanceof THREE.Vector3 ) ? scale : new THREE.Vector3();
  1343. scale.x = x.length();
  1344. scale.y = y.length();
  1345. scale.z = z.length();
  1346. translation.x = te[12];
  1347. translation.y = te[13];
  1348. translation.z = te[14];
  1349. // scale the rotation part
  1350. var matrix = THREE.Matrix4.__m1;
  1351. matrix.copy( this );
  1352. matrix.elements[0] /= scale.x;
  1353. matrix.elements[1] /= scale.x;
  1354. matrix.elements[2] /= scale.x;
  1355. matrix.elements[4] /= scale.y;
  1356. matrix.elements[5] /= scale.y;
  1357. matrix.elements[6] /= scale.y;
  1358. matrix.elements[8] /= scale.z;
  1359. matrix.elements[9] /= scale.z;
  1360. matrix.elements[10] /= scale.z;
  1361. rotation.setFromRotationMatrix( matrix );
  1362. return [ translation, rotation, scale ];
  1363. },
  1364. extractPosition: function ( m ) {
  1365. var te = this.elements;
  1366. var me = m.elements;
  1367. te[12] = me[12];
  1368. te[13] = me[13];
  1369. te[14] = me[14];
  1370. return this;
  1371. },
  1372. extractRotation: function ( m ) {
  1373. var te = this.elements;
  1374. var me = m.elements;
  1375. var vector = THREE.Matrix4.__v1;
  1376. var scaleX = 1 / vector.set( me[0], me[1], me[2] ).length();
  1377. var scaleY = 1 / vector.set( me[4], me[5], me[6] ).length();
  1378. var scaleZ = 1 / vector.set( me[8], me[9], me[10] ).length();
  1379. te[0] = me[0] * scaleX;
  1380. te[1] = me[1] * scaleX;
  1381. te[2] = me[2] * scaleX;
  1382. te[4] = me[4] * scaleY;
  1383. te[5] = me[5] * scaleY;
  1384. te[6] = me[6] * scaleY;
  1385. te[8] = me[8] * scaleZ;
  1386. te[9] = me[9] * scaleZ;
  1387. te[10] = me[10] * scaleZ;
  1388. return this;
  1389. },
  1390. //
  1391. translate: function ( v ) {
  1392. var te = this.elements;
  1393. var x = v.x, y = v.y, z = v.z;
  1394. te[12] = te[0] * x + te[4] * y + te[8] * z + te[12];
  1395. te[13] = te[1] * x + te[5] * y + te[9] * z + te[13];
  1396. te[14] = te[2] * x + te[6] * y + te[10] * z + te[14];
  1397. te[15] = te[3] * x + te[7] * y + te[11] * z + te[15];
  1398. return this;
  1399. },
  1400. rotateX: function ( angle ) {
  1401. var te = this.elements;
  1402. var m12 = te[4];
  1403. var m22 = te[5];
  1404. var m32 = te[6];
  1405. var m42 = te[7];
  1406. var m13 = te[8];
  1407. var m23 = te[9];
  1408. var m33 = te[10];
  1409. var m43 = te[11];
  1410. var c = Math.cos( angle );
  1411. var s = Math.sin( angle );
  1412. te[4] = c * m12 + s * m13;
  1413. te[5] = c * m22 + s * m23;
  1414. te[6] = c * m32 + s * m33;
  1415. te[7] = c * m42 + s * m43;
  1416. te[8] = c * m13 - s * m12;
  1417. te[9] = c * m23 - s * m22;
  1418. te[10] = c * m33 - s * m32;
  1419. te[11] = c * m43 - s * m42;
  1420. return this;
  1421. },
  1422. rotateY: function ( angle ) {
  1423. var te = this.elements;
  1424. var m11 = te[0];
  1425. var m21 = te[1];
  1426. var m31 = te[2];
  1427. var m41 = te[3];
  1428. var m13 = te[8];
  1429. var m23 = te[9];
  1430. var m33 = te[10];
  1431. var m43 = te[11];
  1432. var c = Math.cos( angle );
  1433. var s = Math.sin( angle );
  1434. te[0] = c * m11 - s * m13;
  1435. te[1] = c * m21 - s * m23;
  1436. te[2] = c * m31 - s * m33;
  1437. te[3] = c * m41 - s * m43;
  1438. te[8] = c * m13 + s * m11;
  1439. te[9] = c * m23 + s * m21;
  1440. te[10] = c * m33 + s * m31;
  1441. te[11] = c * m43 + s * m41;
  1442. return this;
  1443. },
  1444. rotateZ: function ( angle ) {
  1445. var te = this.elements;
  1446. var m11 = te[0];
  1447. var m21 = te[1];
  1448. var m31 = te[2];
  1449. var m41 = te[3];
  1450. var m12 = te[4];
  1451. var m22 = te[5];
  1452. var m32 = te[6];
  1453. var m42 = te[7];
  1454. var c = Math.cos( angle );
  1455. var s = Math.sin( angle );
  1456. te[0] = c * m11 + s * m12;
  1457. te[1] = c * m21 + s * m22;
  1458. te[2] = c * m31 + s * m32;
  1459. te[3] = c * m41 + s * m42;
  1460. te[4] = c * m12 - s * m11;
  1461. te[5] = c * m22 - s * m21;
  1462. te[6] = c * m32 - s * m31;
  1463. te[7] = c * m42 - s * m41;
  1464. return this;
  1465. },
  1466. rotateByAxis: function ( axis, angle ) {
  1467. var te = this.elements;
  1468. // optimize by checking axis
  1469. if ( axis.x === 1 && axis.y === 0 && axis.z === 0 ) {
  1470. return this.rotateX( angle );
  1471. } else if ( axis.x === 0 && axis.y === 1 && axis.z === 0 ) {
  1472. return this.rotateY( angle );
  1473. } else if ( axis.x === 0 && axis.y === 0 && axis.z === 1 ) {
  1474. return this.rotateZ( angle );
  1475. }
  1476. var x = axis.x, y = axis.y, z = axis.z;
  1477. var n = Math.sqrt(x * x + y * y + z * z);
  1478. x /= n;
  1479. y /= n;
  1480. z /= n;
  1481. var xx = x * x, yy = y * y, zz = z * z;
  1482. var c = Math.cos( angle );
  1483. var s = Math.sin( angle );
  1484. var oneMinusCosine = 1 - c;
  1485. var xy = x * y * oneMinusCosine;
  1486. var xz = x * z * oneMinusCosine;
  1487. var yz = y * z * oneMinusCosine;
  1488. var xs = x * s;
  1489. var ys = y * s;
  1490. var zs = z * s;
  1491. var r11 = xx + (1 - xx) * c;
  1492. var r21 = xy + zs;
  1493. var r31 = xz - ys;
  1494. var r12 = xy - zs;
  1495. var r22 = yy + (1 - yy) * c;
  1496. var r32 = yz + xs;
  1497. var r13 = xz + ys;
  1498. var r23 = yz - xs;
  1499. var r33 = zz + (1 - zz) * c;
  1500. var m11 = te[0], m21 = te[1], m31 = te[2], m41 = te[3];
  1501. var m12 = te[4], m22 = te[5], m32 = te[6], m42 = te[7];
  1502. var m13 = te[8], m23 = te[9], m33 = te[10], m43 = te[11];
  1503. var m14 = te[12], m24 = te[13], m34 = te[14], m44 = te[15];
  1504. te[0] = r11 * m11 + r21 * m12 + r31 * m13;
  1505. te[1] = r11 * m21 + r21 * m22 + r31 * m23;
  1506. te[2] = r11 * m31 + r21 * m32 + r31 * m33;
  1507. te[3] = r11 * m41 + r21 * m42 + r31 * m43;
  1508. te[4] = r12 * m11 + r22 * m12 + r32 * m13;
  1509. te[5] = r12 * m21 + r22 * m22 + r32 * m23;
  1510. te[6] = r12 * m31 + r22 * m32 + r32 * m33;
  1511. te[7] = r12 * m41 + r22 * m42 + r32 * m43;
  1512. te[8] = r13 * m11 + r23 * m12 + r33 * m13;
  1513. te[9] = r13 * m21 + r23 * m22 + r33 * m23;
  1514. te[10] = r13 * m31 + r23 * m32 + r33 * m33;
  1515. te[11] = r13 * m41 + r23 * m42 + r33 * m43;
  1516. return this;
  1517. },
  1518. scale: function ( v ) {
  1519. var te = this.elements;
  1520. var x = v.x, y = v.y, z = v.z;
  1521. te[0] *= x; te[4] *= y; te[8] *= z;
  1522. te[1] *= x; te[5] *= y; te[9] *= z;
  1523. te[2] *= x; te[6] *= y; te[10] *= z;
  1524. te[3] *= x; te[7] *= y; te[11] *= z;
  1525. return this;
  1526. },
  1527. //
  1528. makeTranslation: function ( x, y, z ) {
  1529. this.set(
  1530. 1, 0, 0, x,
  1531. 0, 1, 0, y,
  1532. 0, 0, 1, z,
  1533. 0, 0, 0, 1
  1534. );
  1535. return this;
  1536. },
  1537. makeRotationX: function ( theta ) {
  1538. var c = Math.cos( theta ), s = Math.sin( theta );
  1539. this.set(
  1540. 1, 0, 0, 0,
  1541. 0, c, -s, 0,
  1542. 0, s, c, 0,
  1543. 0, 0, 0, 1
  1544. );
  1545. return this;
  1546. },
  1547. makeRotationY: function ( theta ) {
  1548. var c = Math.cos( theta ), s = Math.sin( theta );
  1549. this.set(
  1550. c, 0, s, 0,
  1551. 0, 1, 0, 0,
  1552. -s, 0, c, 0,
  1553. 0, 0, 0, 1
  1554. );
  1555. return this;
  1556. },
  1557. makeRotationZ: function ( theta ) {
  1558. var c = Math.cos( theta ), s = Math.sin( theta );
  1559. this.set(
  1560. c, -s, 0, 0,
  1561. s, c, 0, 0,
  1562. 0, 0, 1, 0,
  1563. 0, 0, 0, 1
  1564. );
  1565. return this;
  1566. },
  1567. makeRotationAxis: function ( axis, angle ) {
  1568. // Based on http://www.gamedev.net/reference/articles/article1199.asp
  1569. var c = Math.cos( angle );
  1570. var s = Math.sin( angle );
  1571. var t = 1 - c;
  1572. var x = axis.x, y = axis.y, z = axis.z;
  1573. var tx = t * x, ty = t * y;
  1574. this.set(
  1575. tx * x + c, tx * y - s * z, tx * z + s * y, 0,
  1576. tx * y + s * z, ty * y + c, ty * z - s * x, 0,
  1577. tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
  1578. 0, 0, 0, 1
  1579. );
  1580. return this;
  1581. },
  1582. makeScale: function ( x, y, z ) {
  1583. this.set(
  1584. x, 0, 0, 0,
  1585. 0, y, 0, 0,
  1586. 0, 0, z, 0,
  1587. 0, 0, 0, 1
  1588. );
  1589. return this;
  1590. },
  1591. makeFrustum: function ( left, right, bottom, top, near, far ) {
  1592. var te = this.elements;
  1593. var x = 2 * near / ( right - left );
  1594. var y = 2 * near / ( top - bottom );
  1595. var a = ( right + left ) / ( right - left );
  1596. var b = ( top + bottom ) / ( top - bottom );
  1597. var c = - ( far + near ) / ( far - near );
  1598. var d = - 2 * far * near / ( far - near );
  1599. te[0] = x; te[4] = 0; te[8] = a; te[12] = 0;
  1600. te[1] = 0; te[5] = y; te[9] = b; te[13] = 0;
  1601. te[2] = 0; te[6] = 0; te[10] = c; te[14] = d;
  1602. te[3] = 0; te[7] = 0; te[11] = - 1; te[15] = 0;
  1603. return this;
  1604. },
  1605. makePerspective: function ( fov, aspect, near, far ) {
  1606. var ymax = near * Math.tan( fov * Math.PI / 360 );
  1607. var ymin = - ymax;
  1608. var xmin = ymin * aspect;
  1609. var xmax = ymax * aspect;
  1610. return this.makeFrustum( xmin, xmax, ymin, ymax, near, far );
  1611. },
  1612. makeOrthographic: function ( left, right, top, bottom, near, far ) {
  1613. var te = this.elements;
  1614. var w = right - left;
  1615. var h = top - bottom;
  1616. var p = far - near;
  1617. var x = ( right + left ) / w;
  1618. var y = ( top + bottom ) / h;
  1619. var z = ( far + near ) / p;
  1620. te[0] = 2 / w; te[4] = 0; te[8] = 0; te[12] = -x;
  1621. te[1] = 0; te[5] = 2 / h; te[9] = 0; te[13] = -y;
  1622. te[2] = 0; te[6] = 0; te[10] = -2 / p; te[14] = -z;
  1623. te[3] = 0; te[7] = 0; te[11] = 0; te[15] = 1;
  1624. return this;
  1625. },
  1626. clone: function () {
  1627. var te = this.elements;
  1628. return new THREE.Matrix4(
  1629. te[0], te[4], te[8], te[12],
  1630. te[1], te[5], te[9], te[13],
  1631. te[2], te[6], te[10], te[14],
  1632. te[3], te[7], te[11], te[15]
  1633. );
  1634. }
  1635. };
  1636. THREE.Matrix4.__v1 = new THREE.Vector3();
  1637. THREE.Matrix4.__v2 = new THREE.Vector3();
  1638. THREE.Matrix4.__v3 = new THREE.Vector3();
  1639. THREE.Matrix4.__m1 = new THREE.Matrix4();
  1640. THREE.Matrix4.__m2 = new THREE.Matrix4();
  1641. /**
  1642. * @author mr.doob / http://mrdoob.com/
  1643. * @author mikael emtinger / http://gomo.se/
  1644. * @author alteredq / http://alteredqualia.com/
  1645. */
  1646. THREE.Object3D = function () {
  1647. this.id = THREE.Object3DCount ++;
  1648. this.name = '';
  1649. this.parent = undefined;
  1650. this.children = [];
  1651. this.up = new THREE.Vector3( 0, 1, 0 );
  1652. this.position = new THREE.Vector3();
  1653. this.rotation = new THREE.Vector3();
  1654. this.eulerOrder = 'XYZ';
  1655. this.scale = new THREE.Vector3( 1, 1, 1 );
  1656. this.doubleSided = false;
  1657. this.flipSided = false;
  1658. this.renderDepth = null;
  1659. this.rotationAutoUpdate = true;
  1660. this.matrix = new THREE.Matrix4();
  1661. this.matrixWorld = new THREE.Matrix4();
  1662. this.matrixRotationWorld = new THREE.Matrix4();
  1663. this.matrixAutoUpdate = true;
  1664. this.matrixWorldNeedsUpdate = true;
  1665. this.quaternion = new THREE.Quaternion();
  1666. this.useQuaternion = false;
  1667. this.boundRadius = 0.0;
  1668. this.boundRadiusScale = 1.0;
  1669. this.visible = true;
  1670. this.castShadow = false;
  1671. this.receiveShadow = false;
  1672. this.frustumCulled = true;
  1673. this._vector = new THREE.Vector3();
  1674. };
  1675. THREE.Object3D.prototype = {
  1676. constructor: THREE.Object3D,
  1677. applyMatrix: function ( matrix ) {
  1678. this.matrix.multiply( matrix, this.matrix );
  1679. this.scale.getScaleFromMatrix( this.matrix );
  1680. this.rotation.getRotationFromMatrix( this.matrix, this.scale );
  1681. this.position.getPositionFromMatrix( this.matrix );
  1682. },
  1683. translate: function ( distance, axis ) {
  1684. this.matrix.rotateAxis( axis );
  1685. this.position.addSelf( axis.multiplyScalar( distance ) );
  1686. },
  1687. translateX: function ( distance ) {
  1688. this.translate( distance, this._vector.set( 1, 0, 0 ) );
  1689. },
  1690. translateY: function ( distance ) {
  1691. this.translate( distance, this._vector.set( 0, 1, 0 ) );
  1692. },
  1693. translateZ: function ( distance ) {
  1694. this.translate( distance, this._vector.set( 0, 0, 1 ) );
  1695. },
  1696. lookAt: function ( vector ) {
  1697. // TODO: Add hierarchy support.
  1698. this.matrix.lookAt( vector, this.position, this.up );
  1699. if ( this.rotationAutoUpdate ) {
  1700. this.rotation.getRotationFromMatrix( this.matrix );
  1701. }
  1702. },
  1703. add: function ( object ) {
  1704. if ( object === this ) {
  1705. console.warn( 'THREE.Object3D.add: An object can\'t be added as a child of itself.' );
  1706. return;
  1707. }
  1708. if ( this.children.indexOf( object ) === - 1 ) {
  1709. if ( object.parent !== undefined ) {
  1710. object.parent.remove( object );
  1711. }
  1712. object.parent = this;
  1713. this.children.push( object );
  1714. // add to scene
  1715. var scene = this;
  1716. while ( scene.parent !== undefined ) {
  1717. scene = scene.parent;
  1718. }
  1719. if ( scene !== undefined && scene instanceof THREE.Scene ) {
  1720. scene.__addObject( object );
  1721. }
  1722. }
  1723. },
  1724. remove: function ( object ) {
  1725. var index = this.children.indexOf( object );
  1726. if ( index !== - 1 ) {
  1727. object.parent = undefined;
  1728. this.children.splice( index, 1 );
  1729. // remove from scene
  1730. var scene = this;
  1731. while ( scene.parent !== undefined ) {
  1732. scene = scene.parent;
  1733. }
  1734. if ( scene !== undefined && scene instanceof THREE.Scene ) {
  1735. scene.__removeObject( object );
  1736. }
  1737. }
  1738. },
  1739. getChildByName: function ( name, recursive ) {
  1740. var c, cl, child;
  1741. for ( c = 0, cl = this.children.length; c < cl; c ++ ) {
  1742. child = this.children[ c ];
  1743. if ( child.name === name ) {
  1744. return child;
  1745. }
  1746. if ( recursive ) {
  1747. child = child.getChildByName( name, recursive );
  1748. if ( child !== undefined ) {
  1749. return child;
  1750. }
  1751. }
  1752. }
  1753. return undefined;
  1754. },
  1755. updateMatrix: function () {
  1756. this.matrix.setPosition( this.position );
  1757. if ( this.useQuaternion ) {
  1758. this.matrix.setRotationFromQuaternion( this.quaternion );
  1759. } else {
  1760. this.matrix.setRotationFromEuler( this.rotation, this.eulerOrder );
  1761. }
  1762. if ( this.scale.x !== 1 || this.scale.y !== 1 || this.scale.z !== 1 ) {
  1763. this.matrix.scale( this.scale );
  1764. this.boundRadiusScale = Math.max( this.scale.x, Math.max( this.scale.y, this.scale.z ) );
  1765. }
  1766. this.matrixWorldNeedsUpdate = true;
  1767. },
  1768. updateMatrixWorld: function ( force ) {
  1769. this.matrixAutoUpdate && this.updateMatrix();
  1770. // update matrixWorld
  1771. if ( this.matrixWorldNeedsUpdate || force ) {
  1772. if ( this.parent ) {
  1773. this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
  1774. } else {
  1775. this.matrixWorld.copy( this.matrix );
  1776. }
  1777. this.matrixWorldNeedsUpdate = false;
  1778. force = true;
  1779. }
  1780. // update children
  1781. for ( var i = 0, l = this.children.length; i < l; i ++ ) {
  1782. this.children[ i ].updateMatrixWorld( force );
  1783. }
  1784. }
  1785. };
  1786. THREE.Object3DCount = 0;
  1787. /**
  1788. * @author mr.doob / http://mrdoob.com/
  1789. * @author supereggbert / http://www.paulbrunt.co.uk/
  1790. * @author julianwa / https://github.com/julianwa
  1791. */
  1792. THREE.Projector = function() {
  1793. var _object, _objectCount, _objectPool = [],
  1794. _vertex, _vertexCount, _vertexPool = [],
  1795. _face, _face3Count, _face3Pool = [], _face4Count, _face4Pool = [],
  1796. _line, _lineCount, _linePool = [],
  1797. _particle, _particleCount, _particlePool = [],
  1798. _renderData = { objects: [], sprites: [], lights: [], elements: [] },
  1799. _vector3 = new THREE.Vector3(),
  1800. _vector4 = new THREE.Vector4(),
  1801. _projScreenMatrix = new THREE.Matrix4(),
  1802. _projScreenobjectMatrixWorld = new THREE.Matrix4(),
  1803. _frustum = new THREE.Frustum(),
  1804. _clippedVertex1PositionScreen = new THREE.Vector4(),
  1805. _clippedVertex2PositionScreen = new THREE.Vector4(),
  1806. _face3VertexNormals;
  1807. this.projectVector = function ( vector, camera ) {
  1808. camera.matrixWorldInverse.getInverse( camera.matrixWorld );
  1809. _projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
  1810. _projScreenMatrix.multiplyVector3( vector );
  1811. return vector;
  1812. };
  1813. this.unprojectVector = function ( vector, camera ) {
  1814. camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
  1815. _projScreenMatrix.multiply( camera.matrixWorld, camera.projectionMatrixInverse );
  1816. _projScreenMatrix.multiplyVector3( vector );
  1817. return vector;
  1818. };
  1819. this.pickingRay = function ( vector, camera ) {
  1820. var end, ray, t;
  1821. // set two vectors with opposing z values
  1822. vector.z = -1.0;
  1823. end = new THREE.Vector3( vector.x, vector.y, 1.0 );
  1824. this.unprojectVector( vector, camera );
  1825. this.unprojectVector( end, camera );
  1826. // find direction from vector to end
  1827. end.subSelf( vector ).normalize();
  1828. return new THREE.Ray( vector, end );
  1829. };
  1830. this.projectGraph = function ( root, sort ) {
  1831. _objectCount = 0;
  1832. _renderData.objects.length = 0;
  1833. _renderData.sprites.length = 0;
  1834. _renderData.lights.length = 0;
  1835. var projectObject = function ( object ) {
  1836. if ( object.visible === false ) return;
  1837. if ( ( object instanceof THREE.Mesh || object instanceof THREE.Line ) &&
  1838. ( object.frustumCulled === false || _frustum.contains( object ) ) ) {
  1839. _vector3.copy( object.matrixWorld.getPosition() );
  1840. _projScreenMatrix.multiplyVector3( _vector3 );
  1841. _object = getNextObjectInPool();
  1842. _object.object = object;
  1843. _object.z = _vector3.z;
  1844. _renderData.objects.push( _object );
  1845. } else if ( object instanceof THREE.Sprite || object instanceof THREE.Particle ) {
  1846. _vector3.copy( object.matrixWorld.getPosition() );
  1847. _projScreenMatrix.multiplyVector3( _vector3 );
  1848. _object = getNextObjectInPool();
  1849. _object.object = object;
  1850. _object.z = _vector3.z;
  1851. _renderData.sprites.push( _object );
  1852. } else if ( object instanceof THREE.Light ) {
  1853. _renderData.lights.push( object );
  1854. }
  1855. for ( var c = 0, cl = object.children.length; c < cl; c ++ ) {
  1856. projectObject( object.children[ c ] );
  1857. }
  1858. };
  1859. projectObject( root );
  1860. sort && _renderData.objects.sort( painterSort );
  1861. return _renderData;
  1862. };
  1863. this.projectScene = function ( scene, camera, sort ) {
  1864. var near = camera.near, far = camera.far, visible = false,
  1865. o, ol, v, vl, f, fl, n, nl, c, cl, u, ul, object,
  1866. objectMatrixWorld, objectMatrixWorldRotation,
  1867. geometry, geometryMaterials, vertices, vertex, vertexPositionScreen,
  1868. faces, face, faceVertexNormals, normal, faceVertexUvs, uvs,
  1869. v1, v2, v3, v4;
  1870. _face3Count = 0;
  1871. _face4Count = 0;
  1872. _lineCount = 0;
  1873. _particleCount = 0;
  1874. _renderData.elements.length = 0;
  1875. if ( camera.parent === undefined ) {
  1876. console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
  1877. scene.add( camera );
  1878. }
  1879. scene.updateMatrixWorld();
  1880. camera.matrixWorldInverse.getInverse( camera.matrixWorld );
  1881. _projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
  1882. _frustum.setFromMatrix( _projScreenMatrix );
  1883. _renderData = this.projectGraph( scene, false );
  1884. for ( o = 0, ol = _renderData.objects.length; o < ol; o++ ) {
  1885. object = _renderData.objects[ o ].object;
  1886. objectMatrixWorld = object.matrixWorld;
  1887. _vertexCount = 0;
  1888. if ( object instanceof THREE.Mesh ) {
  1889. geometry = object.geometry;
  1890. geometryMaterials = object.geometry.materials;
  1891. vertices = geometry.vertices;
  1892. faces = geometry.faces;
  1893. faceVertexUvs = geometry.faceVertexUvs;
  1894. objectMatrixWorldRotation = object.matrixRotationWorld.extractRotation( objectMatrixWorld );
  1895. for ( v = 0, vl = vertices.length; v < vl; v ++ ) {
  1896. _vertex = getNextVertexInPool();
  1897. _vertex.positionWorld.copy( vertices[ v ].position );
  1898. objectMatrixWorld.multiplyVector3( _vertex.positionWorld );
  1899. _vertex.positionScreen.copy( _vertex.positionWorld );
  1900. _projScreenMatrix.multiplyVector4( _vertex.positionScreen );
  1901. _vertex.positionScreen.x /= _vertex.positionScreen.w;
  1902. _vertex.positionScreen.y /= _vertex.positionScreen.w;
  1903. _vertex.visible = _vertex.positionScreen.z > near && _vertex.positionScreen.z < far;
  1904. }
  1905. for ( f = 0, fl = faces.length; f < fl; f ++ ) {
  1906. face = faces[ f ];
  1907. if ( face instanceof THREE.Face3 ) {
  1908. v1 = _vertexPool[ face.a ];
  1909. v2 = _vertexPool[ face.b ];
  1910. v3 = _vertexPool[ face.c ];
  1911. if ( v1.visible && v2.visible && v3.visible ) {
  1912. visible = ( ( v3.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) -
  1913. ( v3.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) ) < 0;
  1914. if ( object.doubleSided || visible != object.flipSided ) {
  1915. _face = getNextFace3InPool();
  1916. _face.v1.copy( v1 );
  1917. _face.v2.copy( v2 );
  1918. _face.v3.copy( v3 );
  1919. } else {
  1920. continue;
  1921. }
  1922. } else {
  1923. continue;
  1924. }
  1925. } else if ( face instanceof THREE.Face4 ) {
  1926. v1 = _vertexPool[ face.a ];
  1927. v2 = _vertexPool[ face.b ];
  1928. v3 = _vertexPool[ face.c ];
  1929. v4 = _vertexPool[ face.d ];
  1930. if ( v1.visible && v2.visible && v3.visible && v4.visible ) {
  1931. visible = ( v4.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) -
  1932. ( v4.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) < 0 ||
  1933. ( v2.positionScreen.x - v3.positionScreen.x ) * ( v4.positionScreen.y - v3.positionScreen.y ) -
  1934. ( v2.positionScreen.y - v3.positionScreen.y ) * ( v4.positionScreen.x - v3.positionScreen.x ) < 0;
  1935. if ( object.doubleSided || visible != object.flipSided ) {
  1936. _face = getNextFace4InPool();
  1937. _face.v1.copy( v1 );
  1938. _face.v2.copy( v2 );
  1939. _face.v3.copy( v3 );
  1940. _face.v4.copy( v4 );
  1941. } else {
  1942. continue;
  1943. }
  1944. } else {
  1945. continue;
  1946. }
  1947. }
  1948. _face.normalWorld.copy( face.normal );
  1949. if ( !visible && ( object.flipSided || object.doubleSided ) ) _face.normalWorld.negate();
  1950. objectMatrixWorldRotation.multiplyVector3( _face.normalWorld );
  1951. _face.centroidWorld.copy( face.centroid );
  1952. objectMatrixWorld.multiplyVector3( _face.centroidWorld );
  1953. _face.centroidScreen.copy( _face.centroidWorld );
  1954. _projScreenMatrix.multiplyVector3( _face.centroidScreen );
  1955. faceVertexNormals = face.vertexNormals;
  1956. for ( n = 0, nl = faceVertexNormals.length; n < nl; n ++ ) {
  1957. normal = _face.vertexNormalsWorld[ n ];
  1958. normal.copy( faceVertexNormals[ n ] );
  1959. if ( !visible && ( object.flipSided || object.doubleSided ) ) normal.negate();
  1960. objectMatrixWorldRotation.multiplyVector3( normal );
  1961. }
  1962. for ( c = 0, cl = faceVertexUvs.length; c < cl; c ++ ) {
  1963. uvs = faceVertexUvs[ c ][ f ];
  1964. if ( !uvs ) continue;
  1965. for ( u = 0, ul = uvs.length; u < ul; u ++ ) {
  1966. _face.uvs[ c ][ u ] = uvs[ u ];
  1967. }
  1968. }
  1969. _face.material = object.material;
  1970. _face.faceMaterial = face.materialIndex !== null ? geometryMaterials[ face.materialIndex ] : null;
  1971. _face.z = _face.centroidScreen.z;
  1972. _renderData.elements.push( _face );
  1973. }
  1974. } else if ( object instanceof THREE.Line ) {
  1975. _projScreenobjectMatrixWorld.multiply( _projScreenMatrix, objectMatrixWorld );
  1976. vertices = object.geometry.vertices;
  1977. v1 = getNextVertexInPool();
  1978. v1.positionScreen.copy( vertices[ 0 ].position );
  1979. _projScreenobjectMatrixWorld.multiplyVector4( v1.positionScreen );
  1980. // Handle LineStrip and LinePieces
  1981. var step = object.type === THREE.LinePieces ? 2 : 1;
  1982. for ( v = 1, vl = vertices.length; v < vl; v ++ ) {
  1983. v1 = getNextVertexInPool();
  1984. v1.positionScreen.copy( vertices[ v ].position );
  1985. _projScreenobjectMatrixWorld.multiplyVector4( v1.positionScreen );
  1986. if ( ( v + 1 ) % step > 0 ) continue;
  1987. v2 = _vertexPool[ _vertexCount - 2 ];
  1988. _clippedVertex1PositionScreen.copy( v1.positionScreen );
  1989. _clippedVertex2PositionScreen.copy( v2.positionScreen );
  1990. if ( clipLine( _clippedVertex1PositionScreen, _clippedVertex2PositionScreen ) ) {
  1991. // Perform the perspective divide
  1992. _clippedVertex1PositionScreen.multiplyScalar( 1 / _clippedVertex1PositionScreen.w );
  1993. _clippedVertex2PositionScreen.multiplyScalar( 1 / _clippedVertex2PositionScreen.w );
  1994. _line = getNextLineInPool();
  1995. _line.v1.positionScreen.copy( _clippedVertex1PositionScreen );
  1996. _line.v2.positionScreen.copy( _clippedVertex2PositionScreen );
  1997. _line.z = Math.max( _clippedVertex1PositionScreen.z, _clippedVertex2PositionScreen.z );
  1998. _line.material = object.material;
  1999. _renderData.elements.push( _line );
  2000. }
  2001. }
  2002. }
  2003. }
  2004. for ( o = 0, ol = _renderData.sprites.length; o < ol; o++ ) {
  2005. object = _renderData.sprites[ o ].object;
  2006. objectMatrixWorld = object.matrixWorld;
  2007. if ( object instanceof THREE.Particle ) {
  2008. _vector4.set( objectMatrixWorld.elements[12], objectMatrixWorld.elements[13], objectMatrixWorld.elements[14], 1 );
  2009. _projScreenMatrix.multiplyVector4( _vector4 );
  2010. _vector4.z /= _vector4.w;
  2011. if ( _vector4.z > 0 && _vector4.z < 1 ) {
  2012. _particle = getNextParticleInPool();
  2013. _particle.x = _vector4.x / _vector4.w;
  2014. _particle.y = _vector4.y / _vector4.w;
  2015. _particle.z = _vector4.z;
  2016. _particle.rotation = object.rotation.z;
  2017. _particle.scale.x = object.scale.x * Math.abs( _particle.x - ( _vector4.x + camera.projectionMatrix.elements[0] ) / ( _vector4.w + camera.projectionMatrix.elements[12] ) );
  2018. _particle.scale.y = object.scale.y * Math.abs( _particle.y - ( _vector4.y + camera.projectionMatrix.elements[5] ) / ( _vector4.w + camera.projectionMatrix.elements[13] ) );
  2019. _particle.material = object.material;
  2020. _renderData.elements.push( _particle );
  2021. }
  2022. }
  2023. }
  2024. sort && _renderData.elements.sort( painterSort );
  2025. return _renderData;
  2026. };
  2027. // Pools
  2028. function getNextObjectInPool() {
  2029. var object = _objectPool[ _objectCount ] = _objectPool[ _objectCount ] || new THREE.RenderableObject();
  2030. _objectCount ++;
  2031. return object;
  2032. }
  2033. function getNextVertexInPool() {
  2034. var vertex = _vertexPool[ _vertexCount ] = _vertexPool[ _vertexCount ] || new THREE.RenderableVertex();
  2035. _vertexCount ++;
  2036. return vertex;
  2037. }
  2038. function getNextFace3InPool() {
  2039. var face = _face3Pool[ _face3Count ] = _face3Pool[ _face3Count ] || new THREE.RenderableFace3();
  2040. _face3Count ++;
  2041. return face;
  2042. }
  2043. function getNextFace4InPool() {
  2044. var face = _face4Pool[ _face4Count ] = _face4Pool[ _face4Count ] || new THREE.RenderableFace4();
  2045. _face4Count ++;
  2046. return face;
  2047. }
  2048. function getNextLineInPool() {
  2049. var line = _linePool[ _lineCount ] = _linePool[ _lineCount ] || new THREE.RenderableLine();
  2050. _lineCount ++;
  2051. return line;
  2052. }
  2053. function getNextParticleInPool() {
  2054. var particle = _particlePool[ _particleCount ] = _particlePool[ _particleCount ] || new THREE.RenderableParticle();
  2055. _particleCount ++;
  2056. return particle;
  2057. }
  2058. //
  2059. function painterSort( a, b ) {
  2060. return b.z - a.z;
  2061. }
  2062. function clipLine( s1, s2 ) {
  2063. var alpha1 = 0, alpha2 = 1,
  2064. // Calculate the boundary coordinate of each vertex for the near and far clip planes,
  2065. // Z = -1 and Z = +1, respectively.
  2066. bc1near = s1.z + s1.w,
  2067. bc2near = s2.z + s2.w,
  2068. bc1far = - s1.z + s1.w,
  2069. bc2far = - s2.z + s2.w;
  2070. if ( bc1near >= 0 && bc2near >= 0 && bc1far >= 0 && bc2far >= 0 ) {
  2071. // Both vertices lie entirely within all clip planes.
  2072. return true;
  2073. } else if ( ( bc1near < 0 && bc2near < 0) || (bc1far < 0 && bc2far < 0 ) ) {
  2074. // Both vertices lie entirely outside one of the clip planes.
  2075. return false;
  2076. } else {
  2077. // The line segment spans at least one clip plane.
  2078. if ( bc1near < 0 ) {
  2079. // v1 lies outside the near plane, v2 inside
  2080. alpha1 = Math.max( alpha1, bc1near / ( bc1near - bc2near ) );
  2081. } else if ( bc2near < 0 ) {
  2082. // v2 lies outside the near plane, v1 inside
  2083. alpha2 = Math.min( alpha2, bc1near / ( bc1near - bc2near ) );
  2084. }
  2085. if ( bc1far < 0 ) {
  2086. // v1 lies outside the far plane, v2 inside
  2087. alpha1 = Math.max( alpha1, bc1far / ( bc1far - bc2far ) );
  2088. } else if ( bc2far < 0 ) {
  2089. // v2 lies outside the far plane, v2 inside
  2090. alpha2 = Math.min( alpha2, bc1far / ( bc1far - bc2far ) );
  2091. }
  2092. if ( alpha2 < alpha1 ) {
  2093. // The line segment spans two boundaries, but is outside both of them.
  2094. // (This can't happen when we're only clipping against just near/far but good
  2095. // to leave the check here for future usage if other clip planes are added.)
  2096. return false;
  2097. } else {
  2098. // Update the s1 and s2 vertices to match the clipped line segment.
  2099. s1.lerpSelf( s2, alpha1 );
  2100. s2.lerpSelf( s1, 1 - alpha2 );
  2101. return true;
  2102. }
  2103. }
  2104. }
  2105. };
  2106. /**
  2107. * @author mikael emtinger / http://gomo.se/
  2108. * @author alteredq / http://alteredqualia.com/
  2109. */
  2110. THREE.Quaternion = function( x, y, z, w ) {
  2111. this.x = x || 0;
  2112. this.y = y || 0;
  2113. this.z = z || 0;
  2114. this.w = ( w !== undefined ) ? w : 1;
  2115. };
  2116. THREE.Quaternion.prototype = {
  2117. constructor: THREE.Quaternion,
  2118. set: function ( x, y, z, w ) {
  2119. this.x = x;
  2120. this.y = y;
  2121. this.z = z;
  2122. this.w = w;
  2123. return this;
  2124. },
  2125. copy: function ( q ) {
  2126. this.x = q.x;
  2127. this.y = q.y;
  2128. this.z = q.z;
  2129. this.w = q.w;
  2130. return this;
  2131. },
  2132. setFromEuler: function ( vector ) {
  2133. var c = Math.PI / 360, // 0.5 * Math.PI / 360, // 0.5 is an optimization
  2134. x = vector.x * c,
  2135. y = vector.y * c,
  2136. z = vector.z * c,
  2137. c1 = Math.cos( y ),
  2138. s1 = Math.sin( y ),
  2139. c2 = Math.cos( -z ),
  2140. s2 = Math.sin( -z ),
  2141. c3 = Math.cos( x ),
  2142. s3 = Math.sin( x ),
  2143. c1c2 = c1 * c2,
  2144. s1s2 = s1 * s2;
  2145. this.w = c1c2 * c3 - s1s2 * s3;
  2146. this.x = c1c2 * s3 + s1s2 * c3;
  2147. this.y = s1 * c2 * c3 + c1 * s2 * s3;
  2148. this.z = c1 * s2 * c3 - s1 * c2 * s3;
  2149. return this;
  2150. },
  2151. setFromAxisAngle: function ( axis, angle ) {
  2152. // from http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
  2153. // axis have to be normalized
  2154. var halfAngle = angle / 2,
  2155. s = Math.sin( halfAngle );
  2156. this.x = axis.x * s;
  2157. this.y = axis.y * s;
  2158. this.z = axis.z * s;
  2159. this.w = Math.cos( halfAngle );
  2160. return this;
  2161. },
  2162. setFromRotationMatrix: function ( m ) {
  2163. // Adapted from: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
  2164. function copySign( a, b ) {
  2165. return b < 0 ? -Math.abs( a ) : Math.abs( a );
  2166. }
  2167. var absQ = Math.pow( m.determinant(), 1.0 / 3.0 );
  2168. this.w = Math.sqrt( Math.max( 0, absQ + m.elements[0] + m.elements[5] + m.elements[10] ) ) / 2;
  2169. this.x = Math.sqrt( Math.max( 0, absQ + m.elements[0] - m.elements[5] - m.elements[10] ) ) / 2;
  2170. this.y = Math.sqrt( Math.max( 0, absQ - m.elements[0] + m.elements[5] - m.elements[10] ) ) / 2;
  2171. this.z = Math.sqrt( Math.max( 0, absQ - m.elements[0] - m.elements[5] + m.elements[10] ) ) / 2;
  2172. this.x = copySign( this.x, ( m.elements[6] - m.elements[9] ) );
  2173. this.y = copySign( this.y, ( m.elements[8] - m.elements[2] ) );
  2174. this.z = copySign( this.z, ( m.elements[1] - m.elements[4] ) );
  2175. this.normalize();
  2176. return this;
  2177. },
  2178. calculateW : function () {
  2179. this.w = - Math.sqrt( Math.abs( 1.0 - this.x * this.x - this.y * this.y - this.z * this.z ) );
  2180. return this;
  2181. },
  2182. inverse: function () {
  2183. this.x *= -1;
  2184. this.y *= -1;
  2185. this.z *= -1;
  2186. return this;
  2187. },
  2188. length: function () {
  2189. return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
  2190. },
  2191. normalize: function () {
  2192. var l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
  2193. if ( l === 0 ) {
  2194. this.x = 0;
  2195. this.y = 0;
  2196. this.z = 0;
  2197. this.w = 0;
  2198. } else {
  2199. l = 1 / l;
  2200. this.x = this.x * l;
  2201. this.y = this.y * l;
  2202. this.z = this.z * l;
  2203. this.w = this.w * l;
  2204. }
  2205. return this;
  2206. },
  2207. multiply: function ( a, b ) {
  2208. // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
  2209. this.x = a.x * b.w + a.y * b.z - a.z * b.y + a.w * b.x;
  2210. this.y = -a.x * b.z + a.y * b.w + a.z * b.x + a.w * b.y;
  2211. this.z = a.x * b.y - a.y * b.x + a.z * b.w + a.w * b.z;
  2212. this.w = -a.x * b.x - a.y * b.y - a.z * b.z + a.w * b.w;
  2213. return this;
  2214. },
  2215. multiplySelf: function ( b ) {
  2216. var qax = this.x, qay = this.y, qaz = this.z, qaw = this.w,
  2217. qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w;
  2218. this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
  2219. this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
  2220. this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
  2221. this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
  2222. return this;
  2223. },
  2224. multiplyVector3: function ( vector, dest ) {
  2225. if ( !dest ) { dest = vector; }
  2226. var x = vector.x, y = vector.y, z = vector.z,
  2227. qx = this.x, qy = this.y, qz = this.z, qw = this.w;
  2228. // calculate quat * vector
  2229. var ix = qw * x + qy * z - qz * y,
  2230. iy = qw * y + qz * x - qx * z,
  2231. iz = qw * z + qx * y - qy * x,
  2232. iw = -qx * x - qy * y - qz * z;
  2233. // calculate result * inverse quat
  2234. dest.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
  2235. dest.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
  2236. dest.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
  2237. return dest;
  2238. },
  2239. clone: function () {
  2240. return new THREE.Quaternion( this.x, this.y, this.z, this.w );
  2241. }
  2242. }
  2243. THREE.Quaternion.slerp = function ( qa, qb, qm, t ) {
  2244. // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
  2245. var cosHalfTheta = qa.w * qb.w + qa.x * qb.x + qa.y * qb.y + qa.z * qb.z;
  2246. if (cosHalfTheta < 0) {
  2247. qm.w = -qb.w; qm.x = -qb.x; qm.y = -qb.y; qm.z = -qb.z;
  2248. cosHalfTheta = -cosHalfTheta;
  2249. } else {
  2250. qm.copy(qb);
  2251. }
  2252. if ( Math.abs( cosHalfTheta ) >= 1.0 ) {
  2253. qm.w = qa.w; qm.x = qa.x; qm.y = qa.y; qm.z = qa.z;
  2254. return qm;
  2255. }
  2256. var halfTheta = Math.acos( cosHalfTheta ),
  2257. sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
  2258. if ( Math.abs( sinHalfTheta ) < 0.001 ) {
  2259. qm.w = 0.5 * ( qa.w + qb.w );
  2260. qm.x = 0.5 * ( qa.x + qb.x );
  2261. qm.y = 0.5 * ( qa.y + qb.y );
  2262. qm.z = 0.5 * ( qa.z + qb.z );
  2263. return qm;
  2264. }
  2265. var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
  2266. ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
  2267. qm.w = ( qa.w * ratioA + qm.w * ratioB );
  2268. qm.x = ( qa.x * ratioA + qm.x * ratioB );
  2269. qm.y = ( qa.y * ratioA + qm.y * ratioB );
  2270. qm.z = ( qa.z * ratioA + qm.z * ratioB );
  2271. return qm;
  2272. }
  2273. /**
  2274. * @author mr.doob / http://mrdoob.com/
  2275. */
  2276. THREE.Vertex = function ( position ) {
  2277. this.position = position || new THREE.Vector3();
  2278. };
  2279. THREE.Vertex.prototype = {
  2280. constructor: THREE.Vertex,
  2281. clone: function () {
  2282. return new THREE.Vertex( this.position.clone() );
  2283. }
  2284. };
  2285. /**
  2286. * @author mr.doob / http://mrdoob.com/
  2287. * @author alteredq / http://alteredqualia.com/
  2288. */
  2289. THREE.Face3 = function ( a, b, c, normal, color, materialIndex ) {
  2290. this.a = a;
  2291. this.b = b;
  2292. this.c = c;
  2293. this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
  2294. this.vertexNormals = normal instanceof Array ? normal : [ ];
  2295. this.color = color instanceof THREE.Color ? color : new THREE.Color();
  2296. this.vertexColors = color instanceof Array ? color : [];
  2297. this.vertexTangents = [];
  2298. this.materialIndex = materialIndex;
  2299. this.centroid = new THREE.Vector3();
  2300. };
  2301. THREE.Face3.prototype = {
  2302. constructor: THREE.Face3,
  2303. clone: function () {
  2304. var face = new THREE.Face3( this.a, this.b, this.c );
  2305. face.normal.copy( this.normal );
  2306. face.color.copy( this.color );
  2307. face.centroid.copy( this.centroid );
  2308. face.materialIndex = this.materialIndex;
  2309. var i, il;
  2310. for ( i = 0, il = this.vertexNormals.length; i < il; i ++ ) face.vertexNormals[ i ] = this.vertexNormals[ i ].clone();
  2311. for ( i = 0, il = this.vertexColors.length; i < il; i ++ ) face.vertexColors[ i ] = this.vertexColors[ i ].clone();
  2312. for ( i = 0, il = this.vertexTangents.length; i < il; i ++ ) face.vertexTangents[ i ] = this.vertexTangents[ i ].clone();
  2313. return face;
  2314. }
  2315. };
  2316. /**
  2317. * @author mr.doob / http://mrdoob.com/
  2318. * @author alteredq / http://alteredqualia.com/
  2319. */
  2320. THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) {
  2321. this.a = a;
  2322. this.b = b;
  2323. this.c = c;
  2324. this.d = d;
  2325. this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
  2326. this.vertexNormals = normal instanceof Array ? normal : [ ];
  2327. this.color = color instanceof THREE.Color ? color : new THREE.Color();
  2328. this.vertexColors = color instanceof Array ? color : [];
  2329. this.vertexTangents = [];
  2330. this.materialIndex = materialIndex;
  2331. this.centroid = new THREE.Vector3();
  2332. };
  2333. THREE.Face4.prototype = {
  2334. constructor: THREE.Face4,
  2335. clone: function () {
  2336. var face = new THREE.Face4( this.a, this.b, this.c, this.d );
  2337. face.normal.copy( this.normal );
  2338. face.color.copy( this.color );
  2339. face.centroid.copy( this.centroid );
  2340. face.materialIndex = this.materialIndex;
  2341. var i, il;
  2342. for ( i = 0, il = this.vertexNormals.length; i < il; i ++ ) face.vertexNormals[ i ] = this.vertexNormals[ i ].clone();
  2343. for ( i = 0, il = this.vertexColors.length; i < il; i ++ ) face.vertexColors[ i ] = this.vertexColors[ i ].clone();
  2344. for ( i = 0, il = this.vertexTangents.length; i < il; i ++ ) face.vertexTangents[ i ] = this.vertexTangents[ i ].clone();
  2345. return face;
  2346. }
  2347. };
  2348. /**
  2349. * @author mr.doob / http://mrdoob.com/
  2350. */
  2351. THREE.UV = function ( u, v ) {
  2352. this.u = u || 0;
  2353. this.v = v || 0;
  2354. };
  2355. THREE.UV.prototype = {
  2356. constructor: THREE.UV,
  2357. set: function ( u, v ) {
  2358. this.u = u;
  2359. this.v = v;
  2360. return this;
  2361. },
  2362. copy: function ( uv ) {
  2363. this.u = uv.u;
  2364. this.v = uv.v;
  2365. return this;
  2366. },
  2367. lerpSelf: function ( uv, alpha ) {
  2368. this.u += ( uv.u - this.u ) * alpha;
  2369. this.v += ( uv.v - this.v ) * alpha;
  2370. return this;
  2371. },
  2372. clone: function () {
  2373. return new THREE.UV( this.u, this.v );
  2374. }
  2375. };
  2376. /**
  2377. * @author mr.doob / http://mrdoob.com/
  2378. * @author kile / http://kile.stravaganza.org/
  2379. * @author alteredq / http://alteredqualia.com/
  2380. * @author mikael emtinger / http://gomo.se/
  2381. * @author zz85 / http://www.lab4games.net/zz85/blog
  2382. */
  2383. THREE.Geometry = function () {
  2384. this.id = THREE.GeometryCount ++;
  2385. this.vertices = [];
  2386. this.colors = []; // one-to-one vertex colors, used in ParticleSystem, Line and Ribbon
  2387. this.materials = [];
  2388. this.faces = [];
  2389. this.faceUvs = [[]];
  2390. this.faceVertexUvs = [[]];
  2391. this.morphTargets = [];
  2392. this.morphColors = [];
  2393. this.morphNormals = [];
  2394. this.skinWeights = [];
  2395. this.skinIndices = [];
  2396. this.boundingBox = null;
  2397. this.boundingSphere = null;
  2398. this.hasTangents = false;
  2399. this.dynamic = false; // unless set to true the *Arrays will be deleted once sent to a buffer.
  2400. };
  2401. THREE.Geometry.prototype = {
  2402. constructor : THREE.Geometry,
  2403. applyMatrix: function ( matrix ) {
  2404. var matrixRotation = new THREE.Matrix4();
  2405. matrixRotation.extractRotation( matrix );
  2406. for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
  2407. var vertex = this.vertices[ i ];
  2408. matrix.multiplyVector3( vertex.position );
  2409. }
  2410. for ( var i = 0, il = this.faces.length; i < il; i ++ ) {
  2411. var face = this.faces[ i ];
  2412. matrixRotation.multiplyVector3( face.normal );
  2413. for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
  2414. matrixRotation.multiplyVector3( face.vertexNormals[ j ] );
  2415. }
  2416. matrix.multiplyVector3( face.centroid );
  2417. }
  2418. },
  2419. computeCentroids: function () {
  2420. var f, fl, face;
  2421. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2422. face = this.faces[ f ];
  2423. face.centroid.set( 0, 0, 0 );
  2424. if ( face instanceof THREE.Face3 ) {
  2425. face.centroid.addSelf( this.vertices[ face.a ].position );
  2426. face.centroid.addSelf( this.vertices[ face.b ].position );
  2427. face.centroid.addSelf( this.vertices[ face.c ].position );
  2428. face.centroid.divideScalar( 3 );
  2429. } else if ( face instanceof THREE.Face4 ) {
  2430. face.centroid.addSelf( this.vertices[ face.a ].position );
  2431. face.centroid.addSelf( this.vertices[ face.b ].position );
  2432. face.centroid.addSelf( this.vertices[ face.c ].position );
  2433. face.centroid.addSelf( this.vertices[ face.d ].position );
  2434. face.centroid.divideScalar( 4 );
  2435. }
  2436. }
  2437. },
  2438. computeFaceNormals: function () {
  2439. var n, nl, v, vl, vertex, f, fl, face, vA, vB, vC,
  2440. cb = new THREE.Vector3(), ab = new THREE.Vector3();
  2441. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2442. face = this.faces[ f ];
  2443. vA = this.vertices[ face.a ];
  2444. vB = this.vertices[ face.b ];
  2445. vC = this.vertices[ face.c ];
  2446. cb.sub( vC.position, vB.position );
  2447. ab.sub( vA.position, vB.position );
  2448. cb.crossSelf( ab );
  2449. if ( !cb.isZero() ) {
  2450. cb.normalize();
  2451. }
  2452. face.normal.copy( cb );
  2453. }
  2454. },
  2455. computeVertexNormals: function () {
  2456. var v, vl, f, fl, face, vertices;
  2457. // create internal buffers for reuse when calling this method repeatedly
  2458. // (otherwise memory allocation / deallocation every frame is big resource hog)
  2459. if ( this.__tmpVertices === undefined ) {
  2460. this.__tmpVertices = new Array( this.vertices.length );
  2461. vertices = this.__tmpVertices;
  2462. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  2463. vertices[ v ] = new THREE.Vector3();
  2464. }
  2465. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2466. face = this.faces[ f ];
  2467. if ( face instanceof THREE.Face3 ) {
  2468. face.vertexNormals = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
  2469. } else if ( face instanceof THREE.Face4 ) {
  2470. face.vertexNormals = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
  2471. }
  2472. }
  2473. } else {
  2474. vertices = this.__tmpVertices;
  2475. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  2476. vertices[ v ].set( 0, 0, 0 );
  2477. }
  2478. }
  2479. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2480. face = this.faces[ f ];
  2481. if ( face instanceof THREE.Face3 ) {
  2482. vertices[ face.a ].addSelf( face.normal );
  2483. vertices[ face.b ].addSelf( face.normal );
  2484. vertices[ face.c ].addSelf( face.normal );
  2485. } else if ( face instanceof THREE.Face4 ) {
  2486. vertices[ face.a ].addSelf( face.normal );
  2487. vertices[ face.b ].addSelf( face.normal );
  2488. vertices[ face.c ].addSelf( face.normal );
  2489. vertices[ face.d ].addSelf( face.normal );
  2490. }
  2491. }
  2492. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  2493. vertices[ v ].normalize();
  2494. }
  2495. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2496. face = this.faces[ f ];
  2497. if ( face instanceof THREE.Face3 ) {
  2498. face.vertexNormals[ 0 ].copy( vertices[ face.a ] );
  2499. face.vertexNormals[ 1 ].copy( vertices[ face.b ] );
  2500. face.vertexNormals[ 2 ].copy( vertices[ face.c ] );
  2501. } else if ( face instanceof THREE.Face4 ) {
  2502. face.vertexNormals[ 0 ].copy( vertices[ face.a ] );
  2503. face.vertexNormals[ 1 ].copy( vertices[ face.b ] );
  2504. face.vertexNormals[ 2 ].copy( vertices[ face.c ] );
  2505. face.vertexNormals[ 3 ].copy( vertices[ face.d ] );
  2506. }
  2507. }
  2508. },
  2509. computeMorphNormals: function () {
  2510. var i, il, f, fl, face;
  2511. // save original normals
  2512. // - create temp variables on first access
  2513. // otherwise just copy (for faster repeated calls)
  2514. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2515. face = this.faces[ f ];
  2516. if ( ! face.__originalFaceNormal ) {
  2517. face.__originalFaceNormal = face.normal.clone();
  2518. } else {
  2519. face.__originalFaceNormal.copy( face.normal );
  2520. }
  2521. if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];
  2522. for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {
  2523. if ( ! face.__originalVertexNormals[ i ] ) {
  2524. face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();
  2525. } else {
  2526. face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );
  2527. }
  2528. }
  2529. }
  2530. // use temp geometry to compute face and vertex normals for each morph
  2531. var tmpGeo = new THREE.Geometry();
  2532. tmpGeo.faces = this.faces;
  2533. for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {
  2534. // create on first access
  2535. if ( ! this.morphNormals[ i ] ) {
  2536. this.morphNormals[ i ] = {};
  2537. this.morphNormals[ i ].faceNormals = [];
  2538. this.morphNormals[ i ].vertexNormals = [];
  2539. var dstNormalsFace = this.morphNormals[ i ].faceNormals;
  2540. var dstNormalsVertex = this.morphNormals[ i ].vertexNormals;
  2541. var faceNormal, vertexNormals;
  2542. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2543. face = this.faces[ f ];
  2544. faceNormal = new THREE.Vector3();
  2545. if ( face instanceof THREE.Face3 ) {
  2546. vertexNormals = { a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3() };
  2547. } else {
  2548. vertexNormals = { a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3(), d: new THREE.Vector3() };
  2549. }
  2550. dstNormalsFace.push( faceNormal );
  2551. dstNormalsVertex.push( vertexNormals );
  2552. }
  2553. }
  2554. var morphNormals = this.morphNormals[ i ];
  2555. // set vertices to morph target
  2556. tmpGeo.vertices = this.morphTargets[ i ].vertices;
  2557. // compute morph normals
  2558. tmpGeo.computeFaceNormals();
  2559. tmpGeo.computeVertexNormals();
  2560. // store morph normals
  2561. var faceNormal, vertexNormals;
  2562. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2563. face = this.faces[ f ];
  2564. faceNormal = morphNormals.faceNormals[ f ];
  2565. vertexNormals = morphNormals.vertexNormals[ f ];
  2566. faceNormal.copy( face.normal );
  2567. if ( face instanceof THREE.Face3 ) {
  2568. vertexNormals.a.copy( face.vertexNormals[ 0 ] );
  2569. vertexNormals.b.copy( face.vertexNormals[ 1 ] );
  2570. vertexNormals.c.copy( face.vertexNormals[ 2 ] );
  2571. } else {
  2572. vertexNormals.a.copy( face.vertexNormals[ 0 ] );
  2573. vertexNormals.b.copy( face.vertexNormals[ 1 ] );
  2574. vertexNormals.c.copy( face.vertexNormals[ 2 ] );
  2575. vertexNormals.d.copy( face.vertexNormals[ 3 ] );
  2576. }
  2577. }
  2578. }
  2579. // restore original normals
  2580. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2581. face = this.faces[ f ];
  2582. face.normal = face.__originalFaceNormal;
  2583. face.vertexNormals = face.__originalVertexNormals;
  2584. }
  2585. },
  2586. computeTangents: function () {
  2587. // based on http://www.terathon.com/code/tangent.html
  2588. // tangents go to vertices
  2589. var f, fl, v, vl, i, il, vertexIndex,
  2590. face, uv, vA, vB, vC, uvA, uvB, uvC,
  2591. x1, x2, y1, y2, z1, z2,
  2592. s1, s2, t1, t2, r, t, test,
  2593. tan1 = [], tan2 = [],
  2594. sdir = new THREE.Vector3(), tdir = new THREE.Vector3(),
  2595. tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(),
  2596. n = new THREE.Vector3(), w;
  2597. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  2598. tan1[ v ] = new THREE.Vector3();
  2599. tan2[ v ] = new THREE.Vector3();
  2600. }
  2601. function handleTriangle( context, a, b, c, ua, ub, uc ) {
  2602. vA = context.vertices[ a ].position;
  2603. vB = context.vertices[ b ].position;
  2604. vC = context.vertices[ c ].position;
  2605. uvA = uv[ ua ];
  2606. uvB = uv[ ub ];
  2607. uvC = uv[ uc ];
  2608. x1 = vB.x - vA.x;
  2609. x2 = vC.x - vA.x;
  2610. y1 = vB.y - vA.y;
  2611. y2 = vC.y - vA.y;
  2612. z1 = vB.z - vA.z;
  2613. z2 = vC.z - vA.z;
  2614. s1 = uvB.u - uvA.u;
  2615. s2 = uvC.u - uvA.u;
  2616. t1 = uvB.v - uvA.v;
  2617. t2 = uvC.v - uvA.v;
  2618. r = 1.0 / ( s1 * t2 - s2 * t1 );
  2619. sdir.set( ( t2 * x1 - t1 * x2 ) * r,
  2620. ( t2 * y1 - t1 * y2 ) * r,
  2621. ( t2 * z1 - t1 * z2 ) * r );
  2622. tdir.set( ( s1 * x2 - s2 * x1 ) * r,
  2623. ( s1 * y2 - s2 * y1 ) * r,
  2624. ( s1 * z2 - s2 * z1 ) * r );
  2625. tan1[ a ].addSelf( sdir );
  2626. tan1[ b ].addSelf( sdir );
  2627. tan1[ c ].addSelf( sdir );
  2628. tan2[ a ].addSelf( tdir );
  2629. tan2[ b ].addSelf( tdir );
  2630. tan2[ c ].addSelf( tdir );
  2631. }
  2632. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2633. face = this.faces[ f ];
  2634. uv = this.faceVertexUvs[ 0 ][ f ]; // use UV layer 0 for tangents
  2635. if ( face instanceof THREE.Face3 ) {
  2636. handleTriangle( this, face.a, face.b, face.c, 0, 1, 2 );
  2637. } else if ( face instanceof THREE.Face4 ) {
  2638. handleTriangle( this, face.a, face.b, face.d, 0, 1, 3 );
  2639. handleTriangle( this, face.b, face.c, face.d, 1, 2, 3 );
  2640. }
  2641. }
  2642. var faceIndex = [ 'a', 'b', 'c', 'd' ];
  2643. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2644. face = this.faces[ f ];
  2645. for ( i = 0; i < face.vertexNormals.length; i++ ) {
  2646. n.copy( face.vertexNormals[ i ] );
  2647. vertexIndex = face[ faceIndex[ i ] ];
  2648. t = tan1[ vertexIndex ];
  2649. // Gram-Schmidt orthogonalize
  2650. tmp.copy( t );
  2651. tmp.subSelf( n.multiplyScalar( n.dot( t ) ) ).normalize();
  2652. // Calculate handedness
  2653. tmp2.cross( face.vertexNormals[ i ], t );
  2654. test = tmp2.dot( tan2[ vertexIndex ] );
  2655. w = (test < 0.0) ? -1.0 : 1.0;
  2656. face.vertexTangents[ i ] = new THREE.Vector4( tmp.x, tmp.y, tmp.z, w );
  2657. }
  2658. }
  2659. this.hasTangents = true;
  2660. },
  2661. computeBoundingBox: function () {
  2662. if ( ! this.boundingBox ) {
  2663. this.boundingBox = { min: new THREE.Vector3(), max: new THREE.Vector3() };
  2664. }
  2665. if ( this.vertices.length > 0 ) {
  2666. var position, firstPosition = this.vertices[ 0 ].position;
  2667. this.boundingBox.min.copy( firstPosition );
  2668. this.boundingBox.max.copy( firstPosition );
  2669. var min = this.boundingBox.min,
  2670. max = this.boundingBox.max;
  2671. for ( var v = 1, vl = this.vertices.length; v < vl; v ++ ) {
  2672. position = this.vertices[ v ].position;
  2673. if ( position.x < min.x ) {
  2674. min.x = position.x;
  2675. } else if ( position.x > max.x ) {
  2676. max.x = position.x;
  2677. }
  2678. if ( position.y < min.y ) {
  2679. min.y = position.y;
  2680. } else if ( position.y > max.y ) {
  2681. max.y = position.y;
  2682. }
  2683. if ( position.z < min.z ) {
  2684. min.z = position.z;
  2685. } else if ( position.z > max.z ) {
  2686. max.z = position.z;
  2687. }
  2688. }
  2689. } else {
  2690. this.boundingBox.min.set( 0, 0, 0 );
  2691. this.boundingBox.max.set( 0, 0, 0 );
  2692. }
  2693. },
  2694. computeBoundingSphere: function () {
  2695. if ( ! this.boundingSphere ) this.boundingSphere = { radius: 0 };
  2696. var radius, maxRadius = 0;
  2697. for ( var v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  2698. radius = this.vertices[ v ].position.length();
  2699. if ( radius > maxRadius ) maxRadius = radius;
  2700. }
  2701. this.boundingSphere.radius = maxRadius;
  2702. },
  2703. /*
  2704. * Checks for duplicate vertices with hashmap.
  2705. * Duplicated vertices are removed
  2706. * and faces' vertices are updated.
  2707. */
  2708. mergeVertices: function() {
  2709. var verticesMap = {}; // Hashmap for looking up vertice by position coordinates (and making sure they are unique)
  2710. var unique = [], changes = [];
  2711. var v, key;
  2712. var precisionPoints = 4; // number of decimal points, eg. 4 for epsilon of 0.0001
  2713. var precision = Math.pow( 10, precisionPoints );
  2714. var i,il, face;
  2715. for ( i = 0, il = this.vertices.length; i < il; i ++ ) {
  2716. v = this.vertices[ i ].position;
  2717. key = [ Math.round( v.x * precision ), Math.round( v.y * precision ), Math.round( v.z * precision ) ].join( '_' );
  2718. if ( verticesMap[ key ] === undefined ) {
  2719. verticesMap[ key ] = i;
  2720. unique.push( this.vertices[ i ] );
  2721. changes[ i ] = unique.length - 1;
  2722. } else {
  2723. //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
  2724. changes[ i ] = changes[ verticesMap[ key ] ];
  2725. }
  2726. };
  2727. // Start to patch face indices
  2728. for( i = 0, il = this.faces.length; i < il; i ++ ) {
  2729. face = this.faces[ i ];
  2730. if ( face instanceof THREE.Face3 ) {
  2731. face.a = changes[ face.a ];
  2732. face.b = changes[ face.b ];
  2733. face.c = changes[ face.c ];
  2734. } else if ( face instanceof THREE.Face4 ) {
  2735. face.a = changes[ face.a ];
  2736. face.b = changes[ face.b ];
  2737. face.c = changes[ face.c ];
  2738. face.d = changes[ face.d ];
  2739. }
  2740. }
  2741. // Use unique set of vertices
  2742. this.vertices = unique;
  2743. }
  2744. };
  2745. THREE.GeometryCount = 0;
  2746. /**
  2747. * Spline from Tween.js, slightly optimized (and trashed)
  2748. * http://sole.github.com/tween.js/examples/05_spline.html
  2749. *
  2750. * @author mrdoob / http://mrdoob.com/
  2751. * @author alteredq / http://alteredqualia.com/
  2752. */
  2753. THREE.Spline = function ( points ) {
  2754. this.points = points;
  2755. var c = [], v3 = { x: 0, y: 0, z: 0 },
  2756. point, intPoint, weight, w2, w3,
  2757. pa, pb, pc, pd;
  2758. this.initFromArray = function( a ) {
  2759. this.points = [];
  2760. for ( var i = 0; i < a.length; i++ ) {
  2761. this.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] };
  2762. }
  2763. };
  2764. this.getPoint = function ( k ) {
  2765. point = ( this.points.length - 1 ) * k;
  2766. intPoint = Math.floor( point );
  2767. weight = point - intPoint;
  2768. c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;
  2769. c[ 1 ] = intPoint;
  2770. c[ 2 ] = intPoint > this.points.length - 2 ? this.points.length - 1 : intPoint + 1;
  2771. c[ 3 ] = intPoint > this.points.length - 3 ? this.points.length - 1 : intPoint + 2;
  2772. pa = this.points[ c[ 0 ] ];
  2773. pb = this.points[ c[ 1 ] ];
  2774. pc = this.points[ c[ 2 ] ];
  2775. pd = this.points[ c[ 3 ] ];
  2776. w2 = weight * weight;
  2777. w3 = weight * w2;
  2778. v3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 );
  2779. v3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 );
  2780. v3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 );
  2781. return v3;
  2782. };
  2783. this.getControlPointsArray = function () {
  2784. var i, p, l = this.points.length,
  2785. coords = [];
  2786. for ( i = 0; i < l; i ++ ) {
  2787. p = this.points[ i ];
  2788. coords[ i ] = [ p.x, p.y, p.z ];
  2789. }
  2790. return coords;
  2791. };
  2792. // approximate length by summing linear segments
  2793. this.getLength = function ( nSubDivisions ) {
  2794. var i, index, nSamples, position,
  2795. point = 0, intPoint = 0, oldIntPoint = 0,
  2796. oldPosition = new THREE.Vector3(),
  2797. tmpVec = new THREE.Vector3(),
  2798. chunkLengths = [],
  2799. totalLength = 0;
  2800. // first point has 0 length
  2801. chunkLengths[ 0 ] = 0;
  2802. if ( !nSubDivisions ) nSubDivisions = 100;
  2803. nSamples = this.points.length * nSubDivisions;
  2804. oldPosition.copy( this.points[ 0 ] );
  2805. for ( i = 1; i < nSamples; i ++ ) {
  2806. index = i / nSamples;
  2807. position = this.getPoint( index );
  2808. tmpVec.copy( position );
  2809. totalLength += tmpVec.distanceTo( oldPosition );
  2810. oldPosition.copy( position );
  2811. point = ( this.points.length - 1 ) * index;
  2812. intPoint = Math.floor( point );
  2813. if ( intPoint != oldIntPoint ) {
  2814. chunkLengths[ intPoint ] = totalLength;
  2815. oldIntPoint = intPoint;
  2816. }
  2817. }
  2818. // last point ends with total length
  2819. chunkLengths[ chunkLengths.length ] = totalLength;
  2820. return { chunks: chunkLengths, total: totalLength };
  2821. };
  2822. this.reparametrizeByArcLength = function ( samplingCoef ) {
  2823. var i, j,
  2824. index, indexCurrent, indexNext,
  2825. linearDistance, realDistance,
  2826. sampling, position,
  2827. newpoints = [],
  2828. tmpVec = new THREE.Vector3(),
  2829. sl = this.getLength();
  2830. newpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() );
  2831. for ( i = 1; i < this.points.length; i++ ) {
  2832. //tmpVec.copy( this.points[ i - 1 ] );
  2833. //linearDistance = tmpVec.distanceTo( this.points[ i ] );
  2834. realDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ];
  2835. sampling = Math.ceil( samplingCoef * realDistance / sl.total );
  2836. indexCurrent = ( i - 1 ) / ( this.points.length - 1 );
  2837. indexNext = i / ( this.points.length - 1 );
  2838. for ( j = 1; j < sampling - 1; j++ ) {
  2839. index = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent );
  2840. position = this.getPoint( index );
  2841. newpoints.push( tmpVec.copy( position ).clone() );
  2842. }
  2843. newpoints.push( tmpVec.copy( this.points[ i ] ).clone() );
  2844. }
  2845. this.points = newpoints;
  2846. };
  2847. // Catmull-Rom
  2848. function interpolate( p0, p1, p2, p3, t, t2, t3 ) {
  2849. var v0 = ( p2 - p0 ) * 0.5,
  2850. v1 = ( p3 - p1 ) * 0.5;
  2851. return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;
  2852. };
  2853. };
  2854. /**
  2855. * @author mr.doob / http://mrdoob.com/
  2856. * @author mikael emtinger / http://gomo.se/
  2857. */
  2858. THREE.Camera = function () {
  2859. THREE.Object3D.call( this );
  2860. this.matrixWorldInverse = new THREE.Matrix4();
  2861. this.projectionMatrix = new THREE.Matrix4();
  2862. this.projectionMatrixInverse = new THREE.Matrix4();
  2863. };
  2864. THREE.Camera.prototype = new THREE.Object3D();
  2865. THREE.Camera.prototype.constructor = THREE.Camera;
  2866. THREE.Camera.prototype.lookAt = function ( vector ) {
  2867. // TODO: Add hierarchy support.
  2868. this.matrix.lookAt( this.position, vector, this.up );
  2869. if ( this.rotationAutoUpdate ) {
  2870. this.rotation.getRotationFromMatrix( this.matrix );
  2871. }
  2872. };
  2873. /**
  2874. * @author alteredq / http://alteredqualia.com/
  2875. */
  2876. THREE.OrthographicCamera = function ( left, right, top, bottom, near, far ) {
  2877. THREE.Camera.call( this );
  2878. this.left = left;
  2879. this.right = right;
  2880. this.top = top;
  2881. this.bottom = bottom;
  2882. this.near = ( near !== undefined ) ? near : 0.1;
  2883. this.far = ( far !== undefined ) ? far : 2000;
  2884. this.updateProjectionMatrix();
  2885. };
  2886. THREE.OrthographicCamera.prototype = new THREE.Camera();
  2887. THREE.OrthographicCamera.prototype.constructor = THREE.OrthographicCamera;
  2888. THREE.OrthographicCamera.prototype.updateProjectionMatrix = function () {
  2889. this.projectionMatrix.makeOrthographic( this.left, this.right, this.top, this.bottom, this.near, this.far );
  2890. };
  2891. /**
  2892. * @author mr.doob / http://mrdoob.com/
  2893. * @author greggman / http://games.greggman.com/
  2894. * @author zz85 / http://www.lab4games.net/zz85/blog
  2895. */
  2896. THREE.PerspectiveCamera = function ( fov, aspect, near, far ) {
  2897. THREE.Camera.call( this );
  2898. this.fov = fov !== undefined ? fov : 50;
  2899. this.aspect = aspect !== undefined ? aspect : 1;
  2900. this.near = near !== undefined ? near : 0.1;
  2901. this.far = far !== undefined ? far : 2000;
  2902. this.updateProjectionMatrix();
  2903. };
  2904. THREE.PerspectiveCamera.prototype = new THREE.Camera();
  2905. THREE.PerspectiveCamera.prototype.constructor = THREE.PerspectiveCamera;
  2906. /**
  2907. * Uses Focal Length (in mm) to estimate and set FOV
  2908. * 35mm (fullframe) camera is used if frame size is not specified;
  2909. * Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html
  2910. */
  2911. THREE.PerspectiveCamera.prototype.setLens = function ( focalLength, frameHeight ) {
  2912. frameHeight = frameHeight !== undefined ? frameHeight : 24;
  2913. this.fov = 2 * Math.atan( frameHeight / ( focalLength * 2 ) ) * ( 180 / Math.PI );
  2914. this.updateProjectionMatrix();
  2915. }
  2916. /**
  2917. * Sets an offset in a larger frustum. This is useful for multi-window or
  2918. * multi-monitor/multi-machine setups.
  2919. *
  2920. * For example, if you have 3x2 monitors and each monitor is 1920x1080 and
  2921. * the monitors are in grid like this
  2922. *
  2923. * +---+---+---+
  2924. * | A | B | C |
  2925. * +---+---+---+
  2926. * | D | E | F |
  2927. * +---+---+---+
  2928. *
  2929. * then for each monitor you would call it like this
  2930. *
  2931. * var w = 1920;
  2932. * var h = 1080;
  2933. * var fullWidth = w * 3;
  2934. * var fullHeight = h * 2;
  2935. *
  2936. * --A--
  2937. * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
  2938. * --B--
  2939. * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
  2940. * --C--
  2941. * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
  2942. * --D--
  2943. * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
  2944. * --E--
  2945. * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
  2946. * --F--
  2947. * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
  2948. *
  2949. * Note there is no reason monitors have to be the same size or in a grid.
  2950. */
  2951. THREE.PerspectiveCamera.prototype.setViewOffset = function ( fullWidth, fullHeight, x, y, width, height ) {
  2952. this.fullWidth = fullWidth;
  2953. this.fullHeight = fullHeight;
  2954. this.x = x;
  2955. this.y = y;
  2956. this.width = width;
  2957. this.height = height;
  2958. this.updateProjectionMatrix();
  2959. };
  2960. THREE.PerspectiveCamera.prototype.updateProjectionMatrix = function () {
  2961. if ( this.fullWidth ) {
  2962. var aspect = this.fullWidth / this.fullHeight;
  2963. var top = Math.tan( this.fov * Math.PI / 360 ) * this.near;
  2964. var bottom = -top;
  2965. var left = aspect * bottom;
  2966. var right = aspect * top;
  2967. var width = Math.abs( right - left );
  2968. var height = Math.abs( top - bottom );
  2969. this.projectionMatrix.makeFrustum(
  2970. left + this.x * width / this.fullWidth,
  2971. left + ( this.x + this.width ) * width / this.fullWidth,
  2972. top - ( this.y + this.height ) * height / this.fullHeight,
  2973. top - this.y * height / this.fullHeight,
  2974. this.near,
  2975. this.far
  2976. );
  2977. } else {
  2978. this.projectionMatrix.makePerspective( this.fov, this.aspect, this.near, this.far );
  2979. }
  2980. };
  2981. /**
  2982. * @author mr.doob / http://mrdoob.com/
  2983. * @author alteredq / http://alteredqualia.com/
  2984. */
  2985. THREE.Light = function ( hex ) {
  2986. THREE.Object3D.call( this );
  2987. this.color = new THREE.Color( hex );
  2988. };
  2989. THREE.Light.prototype = new THREE.Object3D();
  2990. THREE.Light.prototype.constructor = THREE.Light;
  2991. THREE.Light.prototype.supr = THREE.Object3D.prototype;
  2992. /**
  2993. * @author mr.doob / http://mrdoob.com/
  2994. */
  2995. THREE.AmbientLight = function ( hex ) {
  2996. THREE.Light.call( this, hex );
  2997. };
  2998. THREE.AmbientLight.prototype = new THREE.Light();
  2999. THREE.AmbientLight.prototype.constructor = THREE.AmbientLight;
  3000. /**
  3001. * @author mr.doob / http://mrdoob.com/
  3002. * @author alteredq / http://alteredqualia.com/
  3003. */
  3004. THREE.DirectionalLight = function ( hex, intensity, distance ) {
  3005. THREE.Light.call( this, hex );
  3006. this.position = new THREE.Vector3( 0, 1, 0 );
  3007. this.target = new THREE.Object3D();
  3008. this.intensity = ( intensity !== undefined ) ? intensity : 1;
  3009. this.distance = ( distance !== undefined ) ? distance : 0;
  3010. this.castShadow = false;
  3011. this.onlyShadow = false;
  3012. //
  3013. this.shadowCameraNear = 50;
  3014. this.shadowCameraFar = 5000;
  3015. this.shadowCameraLeft = -500;
  3016. this.shadowCameraRight = 500;
  3017. this.shadowCameraTop = 500;
  3018. this.shadowCameraBottom = -500;
  3019. this.shadowCameraVisible = false;
  3020. this.shadowBias = 0;
  3021. this.shadowDarkness = 0.5;
  3022. this.shadowMapWidth = 512;
  3023. this.shadowMapHeight = 512;
  3024. //
  3025. this.shadowCascade = false;
  3026. this.shadowCascadeOffset = new THREE.Vector3( 0, 0, -1000 );
  3027. this.shadowCascadeCount = 2;
  3028. this.shadowCascadeBias = [ 0, 0, 0 ];
  3029. this.shadowCascadeWidth = [ 512, 512, 512 ];
  3030. this.shadowCascadeHeight = [ 512, 512, 512 ];
  3031. this.shadowCascadeNearZ = [ -1.000, 0.990, 0.998 ];
  3032. this.shadowCascadeFarZ = [ 0.990, 0.998, 1.000 ];
  3033. this.shadowCascadeArray = [];
  3034. //
  3035. this.shadowMap = null;
  3036. this.shadowMapSize = null;
  3037. this.shadowCamera = null;
  3038. this.shadowMatrix = null;
  3039. };
  3040. THREE.DirectionalLight.prototype = new THREE.Light();
  3041. THREE.DirectionalLight.prototype.constructor = THREE.DirectionalLight;
  3042. /**
  3043. * @author mr.doob / http://mrdoob.com/
  3044. */
  3045. THREE.PointLight = function ( hex, intensity, distance ) {
  3046. THREE.Light.call( this, hex );
  3047. this.position = new THREE.Vector3( 0, 0, 0 );
  3048. this.intensity = ( intensity !== undefined ) ? intensity : 1;
  3049. this.distance = ( distance !== undefined ) ? distance : 0;
  3050. };
  3051. THREE.PointLight.prototype = new THREE.Light();
  3052. THREE.PointLight.prototype.constructor = THREE.PointLight;
  3053. /**
  3054. * @author alteredq / http://alteredqualia.com/
  3055. */
  3056. THREE.SpotLight = function ( hex, intensity, distance ) {
  3057. THREE.Light.call( this, hex );
  3058. this.position = new THREE.Vector3( 0, 1, 0 );
  3059. this.target = new THREE.Object3D();
  3060. this.intensity = ( intensity !== undefined ) ? intensity : 1;
  3061. this.distance = ( distance !== undefined ) ? distance : 0;
  3062. this.castShadow = false;
  3063. this.onlyShadow = false;
  3064. //
  3065. this.shadowCameraNear = 50;
  3066. this.shadowCameraFar = 5000;
  3067. this.shadowCameraFov = 50;
  3068. this.shadowCameraVisible = false;
  3069. this.shadowBias = 0;
  3070. this.shadowDarkness = 0.5;
  3071. this.shadowMapWidth = 512;
  3072. this.shadowMapHeight = 512;
  3073. //
  3074. this.shadowMap = null;
  3075. this.shadowMapSize = null;
  3076. this.shadowCamera = null;
  3077. this.shadowMatrix = null;
  3078. };
  3079. THREE.SpotLight.prototype = new THREE.Light();
  3080. THREE.SpotLight.prototype.constructor = THREE.SpotLight;
  3081. /**
  3082. * @author mr.doob / http://mrdoob.com/
  3083. * @author alteredq / http://alteredqualia.com/
  3084. */
  3085. THREE.Material = function ( parameters ) {
  3086. parameters = parameters || {};
  3087. this.id = THREE.MaterialCount ++;
  3088. this.name = '';
  3089. this.opacity = parameters.opacity !== undefined ? parameters.opacity : 1;
  3090. this.transparent = parameters.transparent !== undefined ? parameters.transparent : false;
  3091. this.blending = parameters.blending !== undefined ? parameters.blending : THREE.NormalBlending;
  3092. this.blendSrc = parameters.blendSrc !== undefined ? parameters.blendSrc : THREE.SrcAlphaFactor;
  3093. this.blendDst = parameters.blendDst !== undefined ? parameters.blendDst : THREE.OneMinusSrcAlphaFactor;
  3094. this.blendEquation = parameters.blendEquation !== undefined ? parameters.blendEquation : THREE.AddEquation;
  3095. this.depthTest = parameters.depthTest !== undefined ? parameters.depthTest : true;
  3096. this.depthWrite = parameters.depthWrite !== undefined ? parameters.depthWrite : true;
  3097. this.polygonOffset = parameters.polygonOffset !== undefined ? parameters.polygonOffset : false;
  3098. this.polygonOffsetFactor = parameters.polygonOffsetFactor !== undefined ? parameters.polygonOffsetFactor : 0;
  3099. this.polygonOffsetUnits = parameters.polygonOffsetUnits !== undefined ? parameters.polygonOffsetUnits : 0;
  3100. this.alphaTest = parameters.alphaTest !== undefined ? parameters.alphaTest : 0;
  3101. this.overdraw = parameters.overdraw !== undefined ? parameters.overdraw : false; // Boolean for fixing antialiasing gaps in CanvasRenderer
  3102. this.needsUpdate = true;
  3103. }
  3104. THREE.MaterialCount = 0;
  3105. // shading
  3106. THREE.NoShading = 0;
  3107. THREE.FlatShading = 1;
  3108. THREE.SmoothShading = 2;
  3109. // colors
  3110. THREE.NoColors = 0;
  3111. THREE.FaceColors = 1;
  3112. THREE.VertexColors = 2;
  3113. // blending modes
  3114. THREE.NoBlending = 0;
  3115. THREE.NormalBlending = 1;
  3116. THREE.AdditiveBlending = 2;
  3117. THREE.SubtractiveBlending = 3;
  3118. THREE.MultiplyBlending = 4;
  3119. THREE.AdditiveAlphaBlending = 5;
  3120. THREE.CustomBlending = 6;
  3121. // custom blending equations
  3122. // (numbers start from 100 not to clash with other
  3123. // mappings to OpenGL constants defined in Texture.js)
  3124. THREE.AddEquation = 100;
  3125. THREE.SubtractEquation = 101;
  3126. THREE.ReverseSubtractEquation = 102;
  3127. // custom blending destination factors
  3128. THREE.ZeroFactor = 200;
  3129. THREE.OneFactor = 201;
  3130. THREE.SrcColorFactor = 202;
  3131. THREE.OneMinusSrcColorFactor = 203;
  3132. THREE.SrcAlphaFactor = 204;
  3133. THREE.OneMinusSrcAlphaFactor = 205;
  3134. THREE.DstAlphaFactor = 206;
  3135. THREE.OneMinusDstAlphaFactor = 207;
  3136. // custom blending source factors
  3137. //THREE.ZeroFactor = 200;
  3138. //THREE.OneFactor = 201;
  3139. //THREE.SrcAlphaFactor = 204;
  3140. //THREE.OneMinusSrcAlphaFactor = 205;
  3141. //THREE.DstAlphaFactor = 206;
  3142. //THREE.OneMinusDstAlphaFactor = 207;
  3143. THREE.DstColorFactor = 208;
  3144. THREE.OneMinusDstColorFactor = 209;
  3145. THREE.SrcAlphaSaturateFactor = 210;
  3146. /**
  3147. * @author mr.doob / http://mrdoob.com/
  3148. * @author alteredq / http://alteredqualia.com/
  3149. *
  3150. * parameters = {
  3151. * color: <hex>,
  3152. * opacity: <float>,
  3153. *
  3154. * blending: THREE.NormalBlending,
  3155. * depthTest: <bool>,
  3156. *
  3157. * linewidth: <float>,
  3158. * linecap: "round",
  3159. * linejoin: "round",
  3160. *
  3161. * vertexColors: <bool>
  3162. *
  3163. * fog: <bool>
  3164. * }
  3165. */
  3166. THREE.LineBasicMaterial = function ( parameters ) {
  3167. THREE.Material.call( this, parameters );
  3168. parameters = parameters || {};
  3169. this.color = parameters.color !== undefined ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
  3170. this.linewidth = parameters.linewidth !== undefined ? parameters.linewidth : 1;
  3171. this.linecap = parameters.linecap !== undefined ? parameters.linecap : 'round';
  3172. this.linejoin = parameters.linejoin !== undefined ? parameters.linejoin : 'round';
  3173. this.vertexColors = parameters.vertexColors ? parameters.vertexColors : false;
  3174. this.fog = parameters.fog !== undefined ? parameters.fog : true;
  3175. };
  3176. THREE.LineBasicMaterial.prototype = new THREE.Material();
  3177. THREE.LineBasicMaterial.prototype.constructor = THREE.LineBasicMaterial;
  3178. /**
  3179. * @author mr.doob / http://mrdoob.com/
  3180. * @author alteredq / http://alteredqualia.com/
  3181. *
  3182. * parameters = {
  3183. * color: <hex>,
  3184. * opacity: <float>,
  3185. * map: new THREE.Texture( <Image> ),
  3186. *
  3187. * lightMap: new THREE.Texture( <Image> ),
  3188. *
  3189. * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
  3190. * combine: THREE.Multiply,
  3191. * reflectivity: <float>,
  3192. * refractionRatio: <float>,
  3193. *
  3194. * shading: THREE.SmoothShading,
  3195. * blending: THREE.NormalBlending,
  3196. * depthTest: <bool>,
  3197. *
  3198. * wireframe: <boolean>,
  3199. * wireframeLinewidth: <float>,
  3200. *
  3201. * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
  3202. *
  3203. * skinning: <bool>,
  3204. * morphTargets: <bool>,
  3205. *
  3206. * fog: <bool>
  3207. * }
  3208. */
  3209. THREE.MeshBasicMaterial = function ( parameters ) {
  3210. THREE.Material.call( this, parameters );
  3211. parameters = parameters || {};
  3212. // color property represents emissive for MeshBasicMaterial
  3213. this.color = parameters.color !== undefined ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
  3214. this.map = parameters.map !== undefined ? parameters.map : null;
  3215. this.lightMap = parameters.lightMap !== undefined ? parameters.lightMap : null;
  3216. this.envMap = parameters.envMap !== undefined ? parameters.envMap : null;
  3217. this.combine = parameters.combine !== undefined ? parameters.combine : THREE.MultiplyOperation;
  3218. this.reflectivity = parameters.reflectivity !== undefined ? parameters.reflectivity : 1;
  3219. this.refractionRatio = parameters.refractionRatio !== undefined ? parameters.refractionRatio : 0.98;
  3220. this.fog = parameters.fog !== undefined ? parameters.fog : true;
  3221. this.shading = parameters.shading !== undefined ? parameters.shading : THREE.SmoothShading;
  3222. this.wireframe = parameters.wireframe !== undefined ? parameters.wireframe : false;
  3223. this.wireframeLinewidth = parameters.wireframeLinewidth !== undefined ? parameters.wireframeLinewidth : 1;
  3224. this.wireframeLinecap = parameters.wireframeLinecap !== undefined ? parameters.wireframeLinecap : 'round';
  3225. this.wireframeLinejoin = parameters.wireframeLinejoin !== undefined ? parameters.wireframeLinejoin : 'round';
  3226. this.vertexColors = parameters.vertexColors !== undefined ? parameters.vertexColors : THREE.NoColors;
  3227. this.skinning = parameters.skinning !== undefined ? parameters.skinning : false;
  3228. this.morphTargets = parameters.morphTargets !== undefined ? parameters.morphTargets : false;
  3229. };
  3230. THREE.MeshBasicMaterial.prototype = new THREE.Material();
  3231. THREE.MeshBasicMaterial.prototype.constructor = THREE.MeshBasicMaterial;
  3232. /**
  3233. * @author mr.doob / http://mrdoob.com/
  3234. * @author alteredq / http://alteredqualia.com/
  3235. *
  3236. * parameters = {
  3237. * color: <hex>,
  3238. * ambient: <hex>,
  3239. * emissive: <hex>,
  3240. * opacity: <float>,
  3241. *
  3242. * map: new THREE.Texture( <Image> ),
  3243. *
  3244. * lightMap: new THREE.Texture( <Image> ),
  3245. *
  3246. * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
  3247. * combine: THREE.Multiply,
  3248. * reflectivity: <float>,
  3249. * refractionRatio: <float>,
  3250. *
  3251. * shading: THREE.SmoothShading,
  3252. * blending: THREE.NormalBlending,
  3253. * depthTest: <bool>,
  3254. *
  3255. * wireframe: <boolean>,
  3256. * wireframeLinewidth: <float>,
  3257. *
  3258. * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
  3259. *
  3260. * skinning: <bool>,
  3261. * morphTargets: <bool>,
  3262. * morphNormals: <bool>,
  3263. *
  3264. * fog: <bool>
  3265. * }
  3266. */
  3267. THREE.MeshLambertMaterial = function ( parameters ) {
  3268. THREE.Material.call( this, parameters );
  3269. parameters = parameters || {};
  3270. // color property represents diffuse for MeshLambertMaterial
  3271. this.color = parameters.color !== undefined ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
  3272. this.ambient = parameters.ambient !== undefined ? new THREE.Color( parameters.ambient ) : new THREE.Color( 0xffffff );
  3273. this.emissive = parameters.emissive !== undefined ? new THREE.Color( parameters.emissive ) : new THREE.Color( 0x000000 );
  3274. this.wrapAround = parameters.wrapAround !== undefined ? parameters.wrapAround: false;
  3275. this.wrapRGB = new THREE.Vector3( 1, 1, 1 );
  3276. this.map = parameters.map !== undefined ? parameters.map : null;
  3277. this.lightMap = parameters.lightMap !== undefined ? parameters.lightMap : null;
  3278. this.envMap = parameters.envMap !== undefined ? parameters.envMap : null;
  3279. this.combine = parameters.combine !== undefined ? parameters.combine : THREE.MultiplyOperation;
  3280. this.reflectivity = parameters.reflectivity !== undefined ? parameters.reflectivity : 1;
  3281. this.refractionRatio = parameters.refractionRatio !== undefined ? parameters.refractionRatio : 0.98;
  3282. this.fog = parameters.fog !== undefined ? parameters.fog : true;
  3283. this.shading = parameters.shading !== undefined ? parameters.shading : THREE.SmoothShading;
  3284. this.wireframe = parameters.wireframe !== undefined ? parameters.wireframe : false;
  3285. this.wireframeLinewidth = parameters.wireframeLinewidth !== undefined ? parameters.wireframeLinewidth : 1;
  3286. this.wireframeLinecap = parameters.wireframeLinecap !== undefined ? parameters.wireframeLinecap : 'round';
  3287. this.wireframeLinejoin = parameters.wireframeLinejoin !== undefined ? parameters.wireframeLinejoin : 'round';
  3288. this.vertexColors = parameters.vertexColors !== undefined ? parameters.vertexColors : THREE.NoColors;
  3289. this.skinning = parameters.skinning !== undefined ? parameters.skinning : false;
  3290. this.morphTargets = parameters.morphTargets !== undefined ? parameters.morphTargets : false;
  3291. this.morphNormals = parameters.morphNormals !== undefined ? parameters.morphNormals : false;
  3292. };
  3293. THREE.MeshLambertMaterial.prototype = new THREE.Material();
  3294. THREE.MeshLambertMaterial.prototype.constructor = THREE.MeshLambertMaterial;
  3295. /**
  3296. * @author mr.doob / http://mrdoob.com/
  3297. * @author alteredq / http://alteredqualia.com/
  3298. *
  3299. * parameters = {
  3300. * color: <hex>,
  3301. * ambient: <hex>,
  3302. * emissive: <hex>,
  3303. * specular: <hex>,
  3304. * shininess: <float>,
  3305. * opacity: <float>,
  3306. *
  3307. * map: new THREE.Texture( <Image> ),
  3308. *
  3309. * lightMap: new THREE.Texture( <Image> ),
  3310. *
  3311. * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
  3312. * combine: THREE.Multiply,
  3313. * reflectivity: <float>,
  3314. * refractionRatio: <float>,
  3315. *
  3316. * shading: THREE.SmoothShading,
  3317. * blending: THREE.NormalBlending,
  3318. * depthTest: <bool>,
  3319. *
  3320. * wireframe: <boolean>,
  3321. * wireframeLinewidth: <float>,
  3322. *
  3323. * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
  3324. *
  3325. * skinning: <bool>,
  3326. * morphTargets: <bool>,
  3327. * morphNormals: <bool>,
  3328. *
  3329. * fog: <bool>
  3330. * }
  3331. */
  3332. THREE.MeshPhongMaterial = function ( parameters ) {
  3333. THREE.Material.call( this, parameters );
  3334. parameters = parameters || {};
  3335. // color property represents diffuse for MeshPhongMaterial
  3336. this.color = parameters.color !== undefined ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
  3337. this.ambient = parameters.ambient !== undefined ? new THREE.Color( parameters.ambient ) : new THREE.Color( 0xffffff );
  3338. this.emissive = parameters.emissive !== undefined ? new THREE.Color( parameters.emissive ) : new THREE.Color( 0x000000 );
  3339. this.specular = parameters.specular !== undefined ? new THREE.Color( parameters.specular ) : new THREE.Color( 0x111111 );
  3340. this.shininess = parameters.shininess !== undefined ? parameters.shininess : 30;
  3341. this.metal = parameters.metal !== undefined ? parameters.metal : false;
  3342. this.perPixel = parameters.perPixel !== undefined ? parameters.perPixel : false;
  3343. this.wrapAround = parameters.wrapAround !== undefined ? parameters.wrapAround: false;
  3344. this.wrapRGB = new THREE.Vector3( 1, 1, 1 );
  3345. this.map = parameters.map !== undefined ? parameters.map : null;
  3346. this.lightMap = parameters.lightMap !== undefined ? parameters.lightMap : null;
  3347. this.envMap = parameters.envMap !== undefined ? parameters.envMap : null;
  3348. this.combine = parameters.combine !== undefined ? parameters.combine : THREE.MultiplyOperation;
  3349. this.reflectivity = parameters.reflectivity !== undefined ? parameters.reflectivity : 1;
  3350. this.refractionRatio = parameters.refractionRatio !== undefined ? parameters.refractionRatio : 0.98;
  3351. this.fog = parameters.fog !== undefined ? parameters.fog : true;
  3352. this.shading = parameters.shading !== undefined ? parameters.shading : THREE.SmoothShading;
  3353. this.wireframe = parameters.wireframe !== undefined ? parameters.wireframe : false;
  3354. this.wireframeLinewidth = parameters.wireframeLinewidth !== undefined ? parameters.wireframeLinewidth : 1;
  3355. this.wireframeLinecap = parameters.wireframeLinecap !== undefined ? parameters.wireframeLinecap : 'round';
  3356. this.wireframeLinejoin = parameters.wireframeLinejoin !== undefined ? parameters.wireframeLinejoin : 'round';
  3357. this.vertexColors = parameters.vertexColors !== undefined ? parameters.vertexColors : THREE.NoColors;
  3358. this.skinning = parameters.skinning !== undefined ? parameters.skinning : false;
  3359. this.morphTargets = parameters.morphTargets !== undefined ? parameters.morphTargets : false;
  3360. this.morphNormals = parameters.morphNormals !== undefined ? parameters.morphNormals : false;
  3361. };
  3362. THREE.MeshPhongMaterial.prototype = new THREE.Material();
  3363. THREE.MeshPhongMaterial.prototype.constructor = THREE.MeshPhongMaterial;
  3364. /**
  3365. * @author mr.doob / http://mrdoob.com/
  3366. * @author alteredq / http://alteredqualia.com/
  3367. *
  3368. * parameters = {
  3369. * opacity: <float>,
  3370. * blending: THREE.NormalBlending,
  3371. * depthTest: <bool>,
  3372. * wireframe: <boolean>,
  3373. * wireframeLinewidth: <float>
  3374. * }
  3375. */
  3376. THREE.MeshDepthMaterial = function ( parameters ) {
  3377. THREE.Material.call( this, parameters );
  3378. parameters = parameters || {};
  3379. this.shading = parameters.shading !== undefined ? parameters.shading : THREE.SmoothShading; // doesn't really apply here, normals are not used
  3380. this.wireframe = parameters.wireframe !== undefined ? parameters.wireframe : false;
  3381. this.wireframeLinewidth = parameters.wireframeLinewidth !== undefined ? parameters.wireframeLinewidth : 1;
  3382. };
  3383. THREE.MeshDepthMaterial.prototype = new THREE.Material();
  3384. THREE.MeshDepthMaterial.prototype.constructor = THREE.MeshDepthMaterial;
  3385. /**
  3386. * @author mr.doob / http://mrdoob.com/
  3387. *
  3388. * parameters = {
  3389. * opacity: <float>,
  3390. * shading: THREE.FlatShading,
  3391. * blending: THREE.NormalBlending,
  3392. * depthTest: <bool>,
  3393. * wireframe: <boolean>,
  3394. * wireframeLinewidth: <float>
  3395. * }
  3396. */
  3397. THREE.MeshNormalMaterial = function ( parameters ) {
  3398. THREE.Material.call( this, parameters );
  3399. parameters = parameters || {};
  3400. this.shading = parameters.shading ? parameters.shading : THREE.FlatShading;
  3401. this.wireframe = parameters.wireframe ? parameters.wireframe : false;
  3402. this.wireframeLinewidth = parameters.wireframeLinewidth ? parameters.wireframeLinewidth : 1;
  3403. };
  3404. THREE.MeshNormalMaterial.prototype = new THREE.Material();
  3405. THREE.MeshNormalMaterial.prototype.constructor = THREE.MeshNormalMaterial;
  3406. /**
  3407. * @author mr.doob / http://mrdoob.com/
  3408. */
  3409. THREE.MeshFaceMaterial = function () {
  3410. };
  3411. /**
  3412. * @author mr.doob / http://mrdoob.com/
  3413. * @author alteredq / http://alteredqualia.com/
  3414. *
  3415. * parameters = {
  3416. * color: <hex>,
  3417. * opacity: <float>,
  3418. * map: new THREE.Texture( <Image> ),
  3419. *
  3420. * size: <float>,
  3421. *
  3422. * blending: THREE.NormalBlending,
  3423. * depthTest: <bool>,
  3424. *
  3425. * vertexColors: <bool>,
  3426. *
  3427. * fog: <bool>
  3428. * }
  3429. */
  3430. THREE.ParticleBasicMaterial = function ( parameters ) {
  3431. THREE.Material.call( this, parameters );
  3432. parameters = parameters || {};
  3433. this.color = parameters.color !== undefined ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
  3434. this.map = parameters.map !== undefined ? parameters.map : null;
  3435. this.size = parameters.size !== undefined ? parameters.size : 1;
  3436. this.sizeAttenuation = parameters.sizeAttenuation !== undefined ? parameters.sizeAttenuation : true;
  3437. this.vertexColors = parameters.vertexColors !== undefined ? parameters.vertexColors : false;
  3438. this.fog = parameters.fog !== undefined ? parameters.fog : true;
  3439. };
  3440. THREE.ParticleBasicMaterial.prototype = new THREE.Material();
  3441. THREE.ParticleBasicMaterial.prototype.constructor = THREE.ParticleBasicMaterial;
  3442. /**
  3443. * @author alteredq / http://alteredqualia.com/
  3444. *
  3445. * parameters = {
  3446. * fragmentShader: <string>,
  3447. * vertexShader: <string>,
  3448. *
  3449. * uniforms: { "parameter1": { type: "f", value: 1.0 }, "parameter2": { type: "i" value2: 2 } },
  3450. *
  3451. * shading: THREE.SmoothShading,
  3452. * blending: THREE.NormalBlending,
  3453. * depthTest: <bool>,
  3454. *
  3455. * wireframe: <boolean>,
  3456. * wireframeLinewidth: <float>,
  3457. *
  3458. * lights: <bool>,
  3459. *
  3460. * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
  3461. *
  3462. * skinning: <bool>,
  3463. * morphTargets: <bool>,
  3464. * morphNormals: <bool>,
  3465. *
  3466. * fog: <bool>
  3467. * }
  3468. */
  3469. THREE.ShaderMaterial = function ( parameters ) {
  3470. THREE.Material.call( this, parameters );
  3471. parameters = parameters || {};
  3472. this.fragmentShader = parameters.fragmentShader !== undefined ? parameters.fragmentShader : "void main() {}";
  3473. this.vertexShader = parameters.vertexShader !== undefined ? parameters.vertexShader : "void main() {}";
  3474. this.uniforms = parameters.uniforms !== undefined ? parameters.uniforms : {};
  3475. this.attributes = parameters.attributes;
  3476. this.shading = parameters.shading !== undefined ? parameters.shading : THREE.SmoothShading;
  3477. this.wireframe = parameters.wireframe !== undefined ? parameters.wireframe : false;
  3478. this.wireframeLinewidth = parameters.wireframeLinewidth !== undefined ? parameters.wireframeLinewidth : 1;
  3479. this.fog = parameters.fog !== undefined ? parameters.fog : false; // set to use scene fog
  3480. this.lights = parameters.lights !== undefined ? parameters.lights : false; // set to use scene lights
  3481. this.vertexColors = parameters.vertexColors !== undefined ? parameters.vertexColors : THREE.NoColors; // set to use "color" attribute stream
  3482. this.skinning = parameters.skinning !== undefined ? parameters.skinning : false; // set to use skinning attribute streams
  3483. this.morphTargets = parameters.morphTargets !== undefined ? parameters.morphTargets : false; // set to use morph targets
  3484. this.morphNormals = parameters.morphNormals !== undefined ? parameters.morphNormals : false; // set to use morph normals
  3485. };
  3486. THREE.ShaderMaterial.prototype = new THREE.Material();
  3487. THREE.ShaderMaterial.prototype.constructor = THREE.ShaderMaterial;
  3488. /**
  3489. * @author mr.doob / http://mrdoob.com/
  3490. * @author alteredq / http://alteredqualia.com/
  3491. * @author szimek / https://github.com/szimek/
  3492. */
  3493. THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type ) {
  3494. this.id = THREE.TextureCount ++;
  3495. this.image = image;
  3496. this.mapping = mapping !== undefined ? mapping : new THREE.UVMapping();
  3497. this.wrapS = wrapS !== undefined ? wrapS : THREE.ClampToEdgeWrapping;
  3498. this.wrapT = wrapT !== undefined ? wrapT : THREE.ClampToEdgeWrapping;
  3499. this.magFilter = magFilter !== undefined ? magFilter : THREE.LinearFilter;
  3500. this.minFilter = minFilter !== undefined ? minFilter : THREE.LinearMipMapLinearFilter;
  3501. this.format = format !== undefined ? format : THREE.RGBAFormat;
  3502. this.type = type !== undefined ? type : THREE.UnsignedByteType;
  3503. this.offset = new THREE.Vector2( 0, 0 );
  3504. this.repeat = new THREE.Vector2( 1, 1 );
  3505. this.generateMipmaps = true;
  3506. this.premultiplyAlpha = false;
  3507. this.needsUpdate = false;
  3508. this.onUpdate = null;
  3509. };
  3510. THREE.Texture.prototype = {
  3511. constructor: THREE.Texture,
  3512. clone: function () {
  3513. var clonedTexture = new THREE.Texture( this.image, this.mapping, this.wrapS, this.wrapT, this.magFilter, this.minFilter, this.format, this.type );
  3514. clonedTexture.offset.copy( this.offset );
  3515. clonedTexture.repeat.copy( this.repeat );
  3516. return clonedTexture;
  3517. }
  3518. };
  3519. THREE.TextureCount = 0;
  3520. THREE.MultiplyOperation = 0;
  3521. THREE.MixOperation = 1;
  3522. // Mapping modes
  3523. THREE.UVMapping = function () {};
  3524. THREE.CubeReflectionMapping = function () {};
  3525. THREE.CubeRefractionMapping = function () {};
  3526. THREE.SphericalReflectionMapping = function () {};
  3527. THREE.SphericalRefractionMapping = function () {};
  3528. // Wrapping modes
  3529. THREE.RepeatWrapping = 0;
  3530. THREE.ClampToEdgeWrapping = 1;
  3531. THREE.MirroredRepeatWrapping = 2;
  3532. // Filters
  3533. THREE.NearestFilter = 3;
  3534. THREE.NearestMipMapNearestFilter = 4;
  3535. THREE.NearestMipMapLinearFilter = 5;
  3536. THREE.LinearFilter = 6;
  3537. THREE.LinearMipMapNearestFilter = 7;
  3538. THREE.LinearMipMapLinearFilter = 8;
  3539. // Types
  3540. THREE.ByteType = 9;
  3541. THREE.UnsignedByteType = 10;
  3542. THREE.ShortType = 11;
  3543. THREE.UnsignedShortType = 12;
  3544. THREE.IntType = 13;
  3545. THREE.UnsignedIntType = 14;
  3546. THREE.FloatType = 15;
  3547. // Formats
  3548. THREE.AlphaFormat = 16;
  3549. THREE.RGBFormat = 17;
  3550. THREE.RGBAFormat = 18;
  3551. THREE.LuminanceFormat = 19;
  3552. THREE.LuminanceAlphaFormat = 20;
  3553. /**
  3554. * @author alteredq / http://alteredqualia.com/
  3555. */
  3556. THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter ) {
  3557. THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type );
  3558. this.image = { data: data, width: width, height: height };
  3559. };
  3560. THREE.DataTexture.prototype = new THREE.Texture();
  3561. THREE.DataTexture.prototype.constructor = THREE.DataTexture;
  3562. THREE.DataTexture.prototype.clone = function () {
  3563. var clonedTexture = new THREE.DataTexture( this.image.data, this.image.width, this.image.height, this.format, this.type, this.mapping, this.wrapS, this.wrapT, this.magFilter, this.minFilter );
  3564. clonedTexture.offset.copy( this.offset );
  3565. clonedTexture.repeat.copy( this.repeat );
  3566. return clonedTexture;
  3567. };
  3568. /**
  3569. * @author mr.doob / http://mrdoob.com/
  3570. */
  3571. THREE.Particle = function ( material ) {
  3572. THREE.Object3D.call( this );
  3573. this.material = material;
  3574. };
  3575. THREE.Particle.prototype = new THREE.Object3D();
  3576. THREE.Particle.prototype.constructor = THREE.Particle;
  3577. /**
  3578. * @author alteredq / http://alteredqualia.com/
  3579. */
  3580. THREE.ParticleSystem = function ( geometry, material ) {
  3581. THREE.Object3D.call( this );
  3582. this.geometry = geometry;
  3583. this.material = ( material !== undefined ) ? material : new THREE.ParticleBasicMaterial( { color: Math.random() * 0xffffff } );
  3584. this.sortParticles = false;
  3585. if ( this.geometry ) {
  3586. // calc bound radius
  3587. if( !this.geometry.boundingSphere ) {
  3588. this.geometry.computeBoundingSphere();
  3589. }
  3590. this.boundRadius = geometry.boundingSphere.radius;
  3591. }
  3592. this.frustumCulled = false;
  3593. };
  3594. THREE.ParticleSystem.prototype = new THREE.Object3D();
  3595. THREE.ParticleSystem.prototype.constructor = THREE.ParticleSystem;
  3596. /**
  3597. * @author mr.doob / http://mrdoob.com/
  3598. */
  3599. THREE.Line = function ( geometry, material, type ) {
  3600. THREE.Object3D.call( this );
  3601. this.geometry = geometry;
  3602. this.material = ( material !== undefined ) ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } );
  3603. this.type = ( type !== undefined ) ? type : THREE.LineStrip;
  3604. if ( this.geometry ) {
  3605. if ( ! this.geometry.boundingSphere ) {
  3606. this.geometry.computeBoundingSphere();
  3607. }
  3608. }
  3609. };
  3610. THREE.LineStrip = 0;
  3611. THREE.LinePieces = 1;
  3612. THREE.Line.prototype = new THREE.Object3D();
  3613. THREE.Line.prototype.constructor = THREE.Line;
  3614. /**
  3615. * @author mr.doob / http://mrdoob.com/
  3616. * @author alteredq / http://alteredqualia.com/
  3617. * @author mikael emtinger / http://gomo.se/
  3618. */
  3619. THREE.Mesh = function ( geometry, material ) {
  3620. THREE.Object3D.call( this );
  3621. this.geometry = geometry;
  3622. this.material = ( material !== undefined ) ? material : new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, wireframe: true } );
  3623. if ( this.geometry ) {
  3624. // calc bound radius
  3625. if( ! this.geometry.boundingSphere ) {
  3626. this.geometry.computeBoundingSphere();
  3627. }
  3628. this.boundRadius = geometry.boundingSphere.radius;
  3629. // setup morph targets
  3630. if( this.geometry.morphTargets.length ) {
  3631. this.morphTargetBase = -1;
  3632. this.morphTargetForcedOrder = [];
  3633. this.morphTargetInfluences = [];
  3634. this.morphTargetDictionary = {};
  3635. for( var m = 0; m < this.geometry.morphTargets.length; m ++ ) {
  3636. this.morphTargetInfluences.push( 0 );
  3637. this.morphTargetDictionary[ this.geometry.morphTargets[ m ].name ] = m;
  3638. }
  3639. }
  3640. }
  3641. }
  3642. THREE.Mesh.prototype = new THREE.Object3D();
  3643. THREE.Mesh.prototype.constructor = THREE.Mesh;
  3644. THREE.Mesh.prototype.supr = THREE.Object3D.prototype;
  3645. /*
  3646. * Get Morph Target Index by Name
  3647. */
  3648. THREE.Mesh.prototype.getMorphTargetIndexByName = function( name ) {
  3649. if ( this.morphTargetDictionary[ name ] !== undefined ) {
  3650. return this.morphTargetDictionary[ name ];
  3651. }
  3652. console.log( "THREE.Mesh.getMorphTargetIndexByName: morph target " + name + " does not exist. Returning 0." );
  3653. return 0;
  3654. }
  3655. /**
  3656. * @author mikael emtinger / http://gomo.se/
  3657. * @author alteredq / http://alteredqualia.com/
  3658. */
  3659. THREE.Bone = function( belongsToSkin ) {
  3660. THREE.Object3D.call( this );
  3661. this.skin = belongsToSkin;
  3662. this.skinMatrix = new THREE.Matrix4();
  3663. };
  3664. THREE.Bone.prototype = new THREE.Object3D();
  3665. THREE.Bone.prototype.constructor = THREE.Bone;
  3666. THREE.Bone.prototype.supr = THREE.Object3D.prototype;
  3667. THREE.Bone.prototype.update = function( parentSkinMatrix, forceUpdate ) {
  3668. // update local
  3669. if ( this.matrixAutoUpdate ) {
  3670. forceUpdate |= this.updateMatrix();
  3671. }
  3672. // update skin matrix
  3673. if ( forceUpdate || this.matrixWorldNeedsUpdate ) {
  3674. if( parentSkinMatrix ) {
  3675. this.skinMatrix.multiply( parentSkinMatrix, this.matrix );
  3676. } else {
  3677. this.skinMatrix.copy( this.matrix );
  3678. }
  3679. this.matrixWorldNeedsUpdate = false;
  3680. forceUpdate = true;
  3681. }
  3682. // update children
  3683. var child, i, l = this.children.length;
  3684. for ( i = 0; i < l; i ++ ) {
  3685. this.children[ i ].update( this.skinMatrix, forceUpdate );
  3686. }
  3687. };
  3688. /**
  3689. * @author mikael emtinger / http://gomo.se/
  3690. * @author alteredq / http://alteredqualia.com/
  3691. */
  3692. THREE.SkinnedMesh = function ( geometry, material ) {
  3693. THREE.Mesh.call( this, geometry, material );
  3694. // init bones
  3695. this.identityMatrix = new THREE.Matrix4();
  3696. this.bones = [];
  3697. this.boneMatrices = [];
  3698. var b, bone, gbone, p, q, s;
  3699. if ( this.geometry.bones !== undefined ) {
  3700. for ( b = 0; b < this.geometry.bones.length; b ++ ) {
  3701. gbone = this.geometry.bones[ b ];
  3702. p = gbone.pos;
  3703. q = gbone.rotq;
  3704. s = gbone.scl;
  3705. bone = this.addBone();
  3706. bone.name = gbone.name;
  3707. bone.position.set( p[0], p[1], p[2] );
  3708. bone.quaternion.set( q[0], q[1], q[2], q[3] );
  3709. bone.useQuaternion = true;
  3710. if ( s !== undefined ) {
  3711. bone.scale.set( s[0], s[1], s[2] );
  3712. } else {
  3713. bone.scale.set( 1, 1, 1 );
  3714. }
  3715. }
  3716. for ( b = 0; b < this.bones.length; b ++ ) {
  3717. gbone = this.geometry.bones[ b ];
  3718. bone = this.bones[ b ];
  3719. if ( gbone.parent === -1 ) {
  3720. this.add( bone );
  3721. } else {
  3722. this.bones[ gbone.parent ].add( bone );
  3723. }
  3724. }
  3725. this.boneMatrices = new Float32Array( 16 * this.bones.length );
  3726. this.pose();
  3727. }
  3728. };
  3729. THREE.SkinnedMesh.prototype = new THREE.Mesh();
  3730. THREE.SkinnedMesh.prototype.constructor = THREE.SkinnedMesh;
  3731. THREE.SkinnedMesh.prototype.addBone = function( bone ) {
  3732. if ( bone === undefined ) {
  3733. bone = new THREE.Bone( this );
  3734. }
  3735. this.bones.push( bone );
  3736. return bone;
  3737. };
  3738. THREE.SkinnedMesh.prototype.updateMatrixWorld = function ( force ) {
  3739. this.matrixAutoUpdate && this.updateMatrix();
  3740. // update matrixWorld
  3741. if ( this.matrixWorldNeedsUpdate || force ) {
  3742. if ( this.parent ) {
  3743. this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
  3744. } else {
  3745. this.matrixWorld.copy( this.matrix );
  3746. }
  3747. this.matrixWorldNeedsUpdate = false;
  3748. force = true;
  3749. }
  3750. // update children
  3751. for ( var i = 0, l = this.children.length; i < l; i ++ ) {
  3752. var child = this.children[ i ];
  3753. if ( child instanceof THREE.Bone ) {
  3754. child.update( this.identityMatrix, false );
  3755. } else {
  3756. child.updateMatrixWorld( true );
  3757. }
  3758. }
  3759. // flatten bone matrices to array
  3760. var b, bl = this.bones.length,
  3761. ba = this.bones,
  3762. bm = this.boneMatrices;
  3763. for ( b = 0; b < bl; b ++ ) {
  3764. ba[ b ].skinMatrix.flattenToArrayOffset( bm, b * 16 );
  3765. }
  3766. };
  3767. /*
  3768. * Pose
  3769. */
  3770. THREE.SkinnedMesh.prototype.pose = function() {
  3771. this.updateMatrixWorld( true );
  3772. var bim, bone, boneInverses = [];
  3773. for ( var b = 0; b < this.bones.length; b ++ ) {
  3774. bone = this.bones[ b ];
  3775. var inverseMatrix = new THREE.Matrix4();
  3776. inverseMatrix.getInverse( bone.skinMatrix );
  3777. boneInverses.push( inverseMatrix );
  3778. bone.skinMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
  3779. }
  3780. // project vertices to local
  3781. if ( this.geometry.skinVerticesA === undefined ) {
  3782. this.geometry.skinVerticesA = [];
  3783. this.geometry.skinVerticesB = [];
  3784. var orgVertex, vertex;
  3785. for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) {
  3786. orgVertex = this.geometry.vertices[ i ].position;
  3787. var indexA = this.geometry.skinIndices[ i ].x;
  3788. var indexB = this.geometry.skinIndices[ i ].y;
  3789. vertex = new THREE.Vector3( orgVertex.x, orgVertex.y, orgVertex.z );
  3790. this.geometry.skinVerticesA.push( boneInverses[ indexA ].multiplyVector3( vertex ) );
  3791. vertex = new THREE.Vector3( orgVertex.x, orgVertex.y, orgVertex.z );
  3792. this.geometry.skinVerticesB.push( boneInverses[ indexB ].multiplyVector3( vertex ) );
  3793. // todo: add more influences
  3794. // normalize weights
  3795. if ( this.geometry.skinWeights[ i ].x + this.geometry.skinWeights[ i ].y !== 1 ) {
  3796. var len = ( 1.0 - ( this.geometry.skinWeights[ i ].x + this.geometry.skinWeights[ i ].y ) ) * 0.5;
  3797. this.geometry.skinWeights[ i ].x += len;
  3798. this.geometry.skinWeights[ i ].y += len;
  3799. }
  3800. }
  3801. }
  3802. };
  3803. /**
  3804. * @author alteredq / http://alteredqualia.com/
  3805. */
  3806. THREE.Ribbon = function ( geometry, material ) {
  3807. THREE.Object3D.call( this );
  3808. this.geometry = geometry;
  3809. this.material = material;
  3810. };
  3811. THREE.Ribbon.prototype = new THREE.Object3D();
  3812. THREE.Ribbon.prototype.constructor = THREE.Ribbon;
  3813. /**
  3814. * @author mikael emtinger / http://gomo.se/
  3815. * @author alteredq / http://alteredqualia.com/
  3816. * @author mr.doob / http://mrdoob.com/
  3817. */
  3818. THREE.LOD = function () {
  3819. THREE.Object3D.call( this );
  3820. this.LODs = [];
  3821. };
  3822. THREE.LOD.prototype = new THREE.Object3D();
  3823. THREE.LOD.prototype.constructor = THREE.LOD;
  3824. THREE.LOD.prototype.supr = THREE.Object3D.prototype;
  3825. THREE.LOD.prototype.addLevel = function ( object3D, visibleAtDistance ) {
  3826. if ( visibleAtDistance === undefined ) {
  3827. visibleAtDistance = 0;
  3828. }
  3829. visibleAtDistance = Math.abs( visibleAtDistance );
  3830. for ( var l = 0; l < this.LODs.length; l ++ ) {
  3831. if ( visibleAtDistance < this.LODs[ l ].visibleAtDistance ) {
  3832. break;
  3833. }
  3834. }
  3835. this.LODs.splice( l, 0, { visibleAtDistance: visibleAtDistance, object3D: object3D } );
  3836. this.add( object3D );
  3837. };
  3838. THREE.LOD.prototype.update = function ( camera ) {
  3839. if ( this.LODs.length > 1 ) {
  3840. camera.matrixWorldInverse.getInverse( camera.matrixWorld );
  3841. var inverse = camera.matrixWorldInverse;
  3842. var distance = -( inverse.elements[2] * this.matrixWorld.elements[12] + inverse.elements[6] * this.matrixWorld.elements[13] + inverse.elements[10] * this.matrixWorld.elements[14] + inverse.elements[14] );
  3843. this.LODs[ 0 ].object3D.visible = true;
  3844. for ( var l = 1; l < this.LODs.length; l ++ ) {
  3845. if( distance >= this.LODs[ l ].visibleAtDistance ) {
  3846. this.LODs[ l - 1 ].object3D.visible = false;
  3847. this.LODs[ l ].object3D.visible = true;
  3848. } else {
  3849. break;
  3850. }
  3851. }
  3852. for( ; l < this.LODs.length; l ++ ) {
  3853. this.LODs[ l ].object3D.visible = false;
  3854. }
  3855. }
  3856. };
  3857. /**
  3858. * @author mikael emtinger / http://gomo.se/
  3859. */
  3860. THREE.Sprite = function ( parameters ) {
  3861. THREE.Object3D.call( this );
  3862. this.color = ( parameters.color !== undefined ) ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
  3863. this.map = ( parameters.map !== undefined ) ? parameters.map : new THREE.Texture();
  3864. this.blending = ( parameters.blending !== undefined ) ? parameters.blending : THREE.NormalBlending;
  3865. this.blendSrc = parameters.blendSrc !== undefined ? parameters.blendSrc : THREE.SrcAlphaFactor;
  3866. this.blendDst = parameters.blendDst !== undefined ? parameters.blendDst : THREE.OneMinusSrcAlphaFactor;
  3867. this.blendEquation = parameters.blendEquation !== undefined ? parameters.blendEquation : THREE.AddEquation;
  3868. this.useScreenCoordinates = ( parameters.useScreenCoordinates !== undefined ) ? parameters.useScreenCoordinates : true;
  3869. this.mergeWith3D = ( parameters.mergeWith3D !== undefined ) ? parameters.mergeWith3D : !this.useScreenCoordinates;
  3870. this.affectedByDistance = ( parameters.affectedByDistance !== undefined ) ? parameters.affectedByDistance : !this.useScreenCoordinates;
  3871. this.scaleByViewport = ( parameters.scaleByViewport !== undefined ) ? parameters.scaleByViewport : !this.affectedByDistance;
  3872. this.alignment = ( parameters.alignment instanceof THREE.Vector2 ) ? parameters.alignment : THREE.SpriteAlignment.center;
  3873. this.rotation3d = this.rotation;
  3874. this.rotation = 0;
  3875. this.opacity = 1;
  3876. this.uvOffset = new THREE.Vector2( 0, 0 );
  3877. this.uvScale = new THREE.Vector2( 1, 1 );
  3878. };
  3879. THREE.Sprite.prototype = new THREE.Object3D();
  3880. THREE.Sprite.prototype.constructor = THREE.Sprite;
  3881. /*
  3882. * Custom update matrix
  3883. */
  3884. THREE.Sprite.prototype.updateMatrix = function () {
  3885. this.matrix.setPosition( this.position );
  3886. this.rotation3d.set( 0, 0, this.rotation );
  3887. this.matrix.setRotationFromEuler( this.rotation3d );
  3888. if ( this.scale.x !== 1 || this.scale.y !== 1 ) {
  3889. this.matrix.scale( this.scale );
  3890. this.boundRadiusScale = Math.max( this.scale.x, this.scale.y );
  3891. }
  3892. this.matrixWorldNeedsUpdate = true;
  3893. };
  3894. /*
  3895. * Alignment
  3896. */
  3897. THREE.SpriteAlignment = {};
  3898. THREE.SpriteAlignment.topLeft = new THREE.Vector2( 1, -1 );
  3899. THREE.SpriteAlignment.topCenter = new THREE.Vector2( 0, -1 );
  3900. THREE.SpriteAlignment.topRight = new THREE.Vector2( -1, -1 );
  3901. THREE.SpriteAlignment.centerLeft = new THREE.Vector2( 1, 0 );
  3902. THREE.SpriteAlignment.center = new THREE.Vector2( 0, 0 );
  3903. THREE.SpriteAlignment.centerRight = new THREE.Vector2( -1, 0 );
  3904. THREE.SpriteAlignment.bottomLeft = new THREE.Vector2( 1, 1 );
  3905. THREE.SpriteAlignment.bottomCenter = new THREE.Vector2( 0, 1 );
  3906. THREE.SpriteAlignment.bottomRight = new THREE.Vector2( -1, 1 );
  3907. /**
  3908. * @author mr.doob / http://mrdoob.com/
  3909. */
  3910. THREE.Scene = function () {
  3911. THREE.Object3D.call( this );
  3912. this.fog = null;
  3913. this.overrideMaterial = null;
  3914. this.matrixAutoUpdate = false;
  3915. this.__objects = [];
  3916. this.__lights = [];
  3917. this.__objectsAdded = [];
  3918. this.__objectsRemoved = [];
  3919. };
  3920. THREE.Scene.prototype = new THREE.Object3D();
  3921. THREE.Scene.prototype.constructor = THREE.Scene;
  3922. THREE.Scene.prototype.__addObject = function ( object ) {
  3923. if ( object instanceof THREE.Light ) {
  3924. if ( this.__lights.indexOf( object ) === - 1 ) {
  3925. this.__lights.push( object );
  3926. }
  3927. } else if ( !( object instanceof THREE.Camera || object instanceof THREE.Bone ) ) {
  3928. if ( this.__objects.indexOf( object ) === - 1 ) {
  3929. this.__objects.push( object );
  3930. this.__objectsAdded.push( object );
  3931. // check if previously removed
  3932. var i = this.__objectsRemoved.indexOf( object );
  3933. if ( i !== -1 ) {
  3934. this.__objectsRemoved.splice( i, 1 );
  3935. }
  3936. }
  3937. }
  3938. for ( var c = 0; c < object.children.length; c ++ ) {
  3939. this.__addObject( object.children[ c ] );
  3940. }
  3941. };
  3942. THREE.Scene.prototype.__removeObject = function ( object ) {
  3943. if ( object instanceof THREE.Light ) {
  3944. var i = this.__lights.indexOf( object );
  3945. if ( i !== -1 ) {
  3946. this.__lights.splice( i, 1 );
  3947. }
  3948. } else if ( !( object instanceof THREE.Camera ) ) {
  3949. var i = this.__objects.indexOf( object );
  3950. if( i !== -1 ) {
  3951. this.__objects.splice( i, 1 );
  3952. this.__objectsRemoved.push( object );
  3953. // check if previously added
  3954. var ai = this.__objectsAdded.indexOf( object );
  3955. if ( ai !== -1 ) {
  3956. this.__objectsAdded.splice( ai, 1 );
  3957. }
  3958. }
  3959. }
  3960. for ( var c = 0; c < object.children.length; c ++ ) {
  3961. this.__removeObject( object.children[ c ] );
  3962. }
  3963. };
  3964. /**
  3965. * @author mr.doob / http://mrdoob.com/
  3966. * @author alteredq / http://alteredqualia.com/
  3967. */
  3968. THREE.Fog = function ( hex, near, far ) {
  3969. this.color = new THREE.Color( hex );
  3970. this.near = ( near !== undefined ) ? near : 1;
  3971. this.far = ( far !== undefined ) ? far : 1000;
  3972. };
  3973. /**
  3974. * @author mr.doob / http://mrdoob.com/
  3975. * @author alteredq / http://alteredqualia.com/
  3976. */
  3977. THREE.FogExp2 = function ( hex, density ) {
  3978. this.color = new THREE.Color( hex );
  3979. this.density = ( density !== undefined ) ? density : 0.00025;
  3980. };
  3981. /**
  3982. * @author alteredq / http://alteredqualia.com/
  3983. * @author mrdoob / http://mrdoob.com/
  3984. * @author mikael emtinger / http://gomo.se/
  3985. */
  3986. THREE.ShaderChunk = {
  3987. // FOG
  3988. fog_pars_fragment: [
  3989. "#ifdef USE_FOG",
  3990. "uniform vec3 fogColor;",
  3991. "#ifdef FOG_EXP2",
  3992. "uniform float fogDensity;",
  3993. "#else",
  3994. "uniform float fogNear;",
  3995. "uniform float fogFar;",
  3996. "#endif",
  3997. "#endif"
  3998. ].join("\n"),
  3999. fog_fragment: [
  4000. "#ifdef USE_FOG",
  4001. "float depth = gl_FragCoord.z / gl_FragCoord.w;",
  4002. "#ifdef FOG_EXP2",
  4003. "const float LOG2 = 1.442695;",
  4004. "float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );",
  4005. "fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );",
  4006. "#else",
  4007. "float fogFactor = smoothstep( fogNear, fogFar, depth );",
  4008. "#endif",
  4009. "gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );",
  4010. "#endif"
  4011. ].join("\n"),
  4012. // ENVIRONMENT MAP
  4013. envmap_pars_fragment: [
  4014. "#ifdef USE_ENVMAP",
  4015. "varying vec3 vReflect;",
  4016. "uniform float reflectivity;",
  4017. "uniform samplerCube envMap;",
  4018. "uniform float flipEnvMap;",
  4019. "uniform int combine;",
  4020. "#endif"
  4021. ].join("\n"),
  4022. envmap_fragment: [
  4023. "#ifdef USE_ENVMAP",
  4024. "#ifdef DOUBLE_SIDED",
  4025. "float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );",
  4026. "vec4 cubeColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * vReflect.x, vReflect.yz ) );",
  4027. "#else",
  4028. "vec4 cubeColor = textureCube( envMap, vec3( flipEnvMap * vReflect.x, vReflect.yz ) );",
  4029. "#endif",
  4030. "#ifdef GAMMA_INPUT",
  4031. "cubeColor.xyz *= cubeColor.xyz;",
  4032. "#endif",
  4033. "if ( combine == 1 ) {",
  4034. "gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, reflectivity );",
  4035. "} else {",
  4036. "gl_FragColor.xyz = gl_FragColor.xyz * cubeColor.xyz;",
  4037. "}",
  4038. "#endif"
  4039. ].join("\n"),
  4040. envmap_pars_vertex: [
  4041. "#ifdef USE_ENVMAP",
  4042. "varying vec3 vReflect;",
  4043. "uniform float refractionRatio;",
  4044. "uniform bool useRefract;",
  4045. "#endif"
  4046. ].join("\n"),
  4047. envmap_vertex : [
  4048. "#ifdef USE_ENVMAP",
  4049. "vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
  4050. "vec3 nWorld = mat3( objectMatrix[ 0 ].xyz, objectMatrix[ 1 ].xyz, objectMatrix[ 2 ].xyz ) * normal;",
  4051. "if ( useRefract ) {",
  4052. "vReflect = refract( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ), refractionRatio );",
  4053. "} else {",
  4054. "vReflect = reflect( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ) );",
  4055. "}",
  4056. "#endif"
  4057. ].join("\n"),
  4058. // COLOR MAP (particles)
  4059. map_particle_pars_fragment: [
  4060. "#ifdef USE_MAP",
  4061. "uniform sampler2D map;",
  4062. "#endif"
  4063. ].join("\n"),
  4064. map_particle_fragment: [
  4065. "#ifdef USE_MAP",
  4066. "gl_FragColor = gl_FragColor * texture2D( map, gl_PointCoord );",
  4067. "#endif"
  4068. ].join("\n"),
  4069. // COLOR MAP (triangles)
  4070. map_pars_vertex: [
  4071. "#ifdef USE_MAP",
  4072. "varying vec2 vUv;",
  4073. "uniform vec4 offsetRepeat;",
  4074. "#endif"
  4075. ].join("\n"),
  4076. map_pars_fragment: [
  4077. "#ifdef USE_MAP",
  4078. "varying vec2 vUv;",
  4079. "uniform sampler2D map;",
  4080. "#endif"
  4081. ].join("\n"),
  4082. map_vertex: [
  4083. "#ifdef USE_MAP",
  4084. "vUv = uv * offsetRepeat.zw + offsetRepeat.xy;",
  4085. "#endif"
  4086. ].join("\n"),
  4087. map_fragment: [
  4088. "#ifdef USE_MAP",
  4089. "#ifdef GAMMA_INPUT",
  4090. "vec4 texelColor = texture2D( map, vUv );",
  4091. "texelColor.xyz *= texelColor.xyz;",
  4092. "gl_FragColor = gl_FragColor * texelColor;",
  4093. "#else",
  4094. "gl_FragColor = gl_FragColor * texture2D( map, vUv );",
  4095. "#endif",
  4096. "#endif"
  4097. ].join("\n"),
  4098. // LIGHT MAP
  4099. lightmap_pars_fragment: [
  4100. "#ifdef USE_LIGHTMAP",
  4101. "varying vec2 vUv2;",
  4102. "uniform sampler2D lightMap;",
  4103. "#endif"
  4104. ].join("\n"),
  4105. lightmap_pars_vertex: [
  4106. "#ifdef USE_LIGHTMAP",
  4107. "varying vec2 vUv2;",
  4108. "#endif"
  4109. ].join("\n"),
  4110. lightmap_fragment: [
  4111. "#ifdef USE_LIGHTMAP",
  4112. "gl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 );",
  4113. "#endif"
  4114. ].join("\n"),
  4115. lightmap_vertex: [
  4116. "#ifdef USE_LIGHTMAP",
  4117. "vUv2 = uv2;",
  4118. "#endif"
  4119. ].join("\n"),
  4120. // LIGHTS LAMBERT
  4121. lights_lambert_pars_vertex: [
  4122. "uniform vec3 ambient;",
  4123. "uniform vec3 diffuse;",
  4124. "uniform vec3 emissive;",
  4125. "uniform vec3 ambientLightColor;",
  4126. "#if MAX_DIR_LIGHTS > 0",
  4127. "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
  4128. "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
  4129. "#endif",
  4130. "#if MAX_POINT_LIGHTS > 0",
  4131. "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
  4132. "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
  4133. "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
  4134. "#endif",
  4135. "#ifdef WRAP_AROUND",
  4136. "uniform vec3 wrapRGB;",
  4137. "#endif",
  4138. ].join("\n"),
  4139. lights_lambert_vertex: [
  4140. "vLightFront = vec3( 0.0 );",
  4141. "#ifdef DOUBLE_SIDED",
  4142. "vLightBack = vec3( 0.0 );",
  4143. "#endif",
  4144. "transformedNormal = normalize( transformedNormal );",
  4145. "#if MAX_DIR_LIGHTS > 0",
  4146. "for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
  4147. "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
  4148. "vec3 dirVector = normalize( lDirection.xyz );",
  4149. "float dotProduct = dot( transformedNormal, dirVector );",
  4150. "vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );",
  4151. "#ifdef DOUBLE_SIDED",
  4152. "vec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );",
  4153. "#ifdef WRAP_AROUND",
  4154. "vec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );",
  4155. "#endif",
  4156. "#endif",
  4157. "#ifdef WRAP_AROUND",
  4158. "vec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );",
  4159. "directionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );",
  4160. "#ifdef DOUBLE_SIDED",
  4161. "directionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );",
  4162. "#endif",
  4163. "#endif",
  4164. "vLightFront += directionalLightColor[ i ] * directionalLightWeighting;",
  4165. "#ifdef DOUBLE_SIDED",
  4166. "vLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;",
  4167. "#endif",
  4168. "}",
  4169. "#endif",
  4170. "#if MAX_POINT_LIGHTS > 0",
  4171. "for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
  4172. "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
  4173. "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
  4174. "float lDistance = 1.0;",
  4175. "if ( pointLightDistance[ i ] > 0.0 )",
  4176. "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
  4177. "lVector = normalize( lVector );",
  4178. "float dotProduct = dot( transformedNormal, lVector );",
  4179. "vec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );",
  4180. "#ifdef DOUBLE_SIDED",
  4181. "vec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );",
  4182. "#ifdef WRAP_AROUND",
  4183. "vec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );",
  4184. "#endif",
  4185. "#endif",
  4186. "#ifdef WRAP_AROUND",
  4187. "vec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );",
  4188. "pointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );",
  4189. "#ifdef DOUBLE_SIDED",
  4190. "pointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );",
  4191. "#endif",
  4192. "#endif",
  4193. "vLightFront += pointLightColor[ i ] * pointLightWeighting * lDistance;",
  4194. "#ifdef DOUBLE_SIDED",
  4195. "vLightBack += pointLightColor[ i ] * pointLightWeightingBack * lDistance;",
  4196. "#endif",
  4197. "}",
  4198. "#endif",
  4199. "vLightFront = vLightFront * diffuse + ambient * ambientLightColor + emissive;",
  4200. "#ifdef DOUBLE_SIDED",
  4201. "vLightBack = vLightBack * diffuse + ambient * ambientLightColor + emissive;",
  4202. "#endif",
  4203. ].join("\n"),
  4204. // LIGHTS PHONG
  4205. lights_phong_pars_vertex: [
  4206. "#if MAX_POINT_LIGHTS > 0",
  4207. "#ifndef PHONG_PER_PIXEL",
  4208. "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
  4209. "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
  4210. "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
  4211. "#endif",
  4212. "#endif"
  4213. ].join("\n"),
  4214. lights_phong_vertex: [
  4215. "#if MAX_POINT_LIGHTS > 0",
  4216. "#ifndef PHONG_PER_PIXEL",
  4217. "for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
  4218. "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
  4219. "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
  4220. "float lDistance = 1.0;",
  4221. "if ( pointLightDistance[ i ] > 0.0 )",
  4222. "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
  4223. "vPointLight[ i ] = vec4( lVector, lDistance );",
  4224. "}",
  4225. "#endif",
  4226. "#endif"
  4227. ].join("\n"),
  4228. lights_phong_pars_fragment: [
  4229. "uniform vec3 ambientLightColor;",
  4230. "#if MAX_DIR_LIGHTS > 0",
  4231. "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
  4232. "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
  4233. "#endif",
  4234. "#if MAX_POINT_LIGHTS > 0",
  4235. "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
  4236. "#ifdef PHONG_PER_PIXEL",
  4237. "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
  4238. "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
  4239. "#else",
  4240. "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
  4241. "#endif",
  4242. "#endif",
  4243. "#ifdef WRAP_AROUND",
  4244. "uniform vec3 wrapRGB;",
  4245. "#endif",
  4246. "varying vec3 vViewPosition;",
  4247. "varying vec3 vNormal;"
  4248. ].join("\n"),
  4249. lights_phong_fragment: [
  4250. "vec3 normal = normalize( vNormal );",
  4251. "vec3 viewPosition = normalize( vViewPosition );",
  4252. "#ifdef DOUBLE_SIDED",
  4253. "normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );",
  4254. "#endif",
  4255. "#if MAX_POINT_LIGHTS > 0",
  4256. "vec3 pointDiffuse = vec3( 0.0 );",
  4257. "vec3 pointSpecular = vec3( 0.0 );",
  4258. "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
  4259. "#ifdef PHONG_PER_PIXEL",
  4260. "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
  4261. "vec3 lVector = lPosition.xyz + vViewPosition.xyz;",
  4262. "float lDistance = 1.0;",
  4263. "if ( pointLightDistance[ i ] > 0.0 )",
  4264. "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
  4265. "lVector = normalize( lVector );",
  4266. "#else",
  4267. "vec3 lVector = normalize( vPointLight[ i ].xyz );",
  4268. "float lDistance = vPointLight[ i ].w;",
  4269. "#endif",
  4270. // diffuse
  4271. "float dotProduct = dot( normal, lVector );",
  4272. "#ifdef WRAP_AROUND",
  4273. "float pointDiffuseWeightFull = max( dotProduct, 0.0 );",
  4274. "float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",
  4275. "vec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );",
  4276. "#else",
  4277. "float pointDiffuseWeight = max( dotProduct, 0.0 );",
  4278. "#endif",
  4279. "pointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;",
  4280. // specular
  4281. "vec3 pointHalfVector = normalize( lVector + viewPosition );",
  4282. "float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );",
  4283. "float pointSpecularWeight = max( pow( pointDotNormalHalf, shininess ), 0.0 );",
  4284. "#ifdef PHYSICALLY_BASED_SHADING",
  4285. // 2.0 => 2.0001 is hack to work around ANGLE bug
  4286. "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
  4287. "vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, pointHalfVector ), 5.0 );",
  4288. "pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;",
  4289. "#else",
  4290. "pointSpecular += specular * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance;",
  4291. "#endif",
  4292. "}",
  4293. "#endif",
  4294. "#if MAX_DIR_LIGHTS > 0",
  4295. "vec3 dirDiffuse = vec3( 0.0 );",
  4296. "vec3 dirSpecular = vec3( 0.0 );" ,
  4297. "for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
  4298. "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
  4299. "vec3 dirVector = normalize( lDirection.xyz );",
  4300. // diffuse
  4301. "float dotProduct = dot( normal, dirVector );",
  4302. "#ifdef WRAP_AROUND",
  4303. "float dirDiffuseWeightFull = max( dotProduct, 0.0 );",
  4304. "float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",
  4305. "vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );",
  4306. "#else",
  4307. "float dirDiffuseWeight = max( dotProduct, 0.0 );",
  4308. "#endif",
  4309. "dirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;",
  4310. // specular
  4311. "vec3 dirHalfVector = normalize( dirVector + viewPosition );",
  4312. "float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
  4313. "float dirSpecularWeight = max( pow( dirDotNormalHalf, shininess ), 0.0 );",
  4314. "#ifdef PHYSICALLY_BASED_SHADING",
  4315. /*
  4316. // fresnel term from skin shader
  4317. "const float F0 = 0.128;",
  4318. "float base = 1.0 - dot( viewPosition, dirHalfVector );",
  4319. "float exponential = pow( base, 5.0 );",
  4320. "float fresnel = exponential + F0 * ( 1.0 - exponential );",
  4321. */
  4322. /*
  4323. // fresnel term from fresnel shader
  4324. "const float mFresnelBias = 0.08;",
  4325. "const float mFresnelScale = 0.3;",
  4326. "const float mFresnelPower = 5.0;",
  4327. "float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );",
  4328. */
  4329. // 2.0 => 2.0001 is hack to work around ANGLE bug
  4330. "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
  4331. //"dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;",
  4332. "vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );",
  4333. "dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;",
  4334. "#else",
  4335. "dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight;",
  4336. "#endif",
  4337. "}",
  4338. "#endif",
  4339. "vec3 totalDiffuse = vec3( 0.0 );",
  4340. "vec3 totalSpecular = vec3( 0.0 );",
  4341. "#if MAX_DIR_LIGHTS > 0",
  4342. "totalDiffuse += dirDiffuse;",
  4343. "totalSpecular += dirSpecular;",
  4344. "#endif",
  4345. "#if MAX_POINT_LIGHTS > 0",
  4346. "totalDiffuse += pointDiffuse;",
  4347. "totalSpecular += pointSpecular;",
  4348. "#endif",
  4349. "#ifdef METAL",
  4350. "gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular );",
  4351. "#else",
  4352. "gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular;",
  4353. "#endif"
  4354. ].join("\n"),
  4355. // VERTEX COLORS
  4356. color_pars_fragment: [
  4357. "#ifdef USE_COLOR",
  4358. "varying vec3 vColor;",
  4359. "#endif"
  4360. ].join("\n"),
  4361. color_fragment: [
  4362. "#ifdef USE_COLOR",
  4363. "gl_FragColor = gl_FragColor * vec4( vColor, opacity );",
  4364. "#endif"
  4365. ].join("\n"),
  4366. color_pars_vertex: [
  4367. "#ifdef USE_COLOR",
  4368. "varying vec3 vColor;",
  4369. "#endif"
  4370. ].join("\n"),
  4371. color_vertex: [
  4372. "#ifdef USE_COLOR",
  4373. "#ifdef GAMMA_INPUT",
  4374. "vColor = color * color;",
  4375. "#else",
  4376. "vColor = color;",
  4377. "#endif",
  4378. "#endif"
  4379. ].join("\n"),
  4380. // SKINNING
  4381. skinning_pars_vertex: [
  4382. "#ifdef USE_SKINNING",
  4383. "uniform mat4 boneGlobalMatrices[ MAX_BONES ];",
  4384. "#endif"
  4385. ].join("\n"),
  4386. skinning_vertex: [
  4387. "#ifdef USE_SKINNING",
  4388. "gl_Position = ( boneGlobalMatrices[ int( skinIndex.x ) ] * skinVertexA ) * skinWeight.x;",
  4389. "gl_Position += ( boneGlobalMatrices[ int( skinIndex.y ) ] * skinVertexB ) * skinWeight.y;",
  4390. "gl_Position = projectionMatrix * modelViewMatrix * gl_Position;",
  4391. "#endif"
  4392. ].join("\n"),
  4393. // MORPHING
  4394. morphtarget_pars_vertex: [
  4395. "#ifdef USE_MORPHTARGETS",
  4396. "#ifndef USE_MORPHNORMALS",
  4397. "uniform float morphTargetInfluences[ 8 ];",
  4398. "#else",
  4399. "uniform float morphTargetInfluences[ 4 ];",
  4400. "#endif",
  4401. "#endif"
  4402. ].join("\n"),
  4403. morphtarget_vertex: [
  4404. "#ifdef USE_MORPHTARGETS",
  4405. "vec3 morphed = vec3( 0.0 );",
  4406. "morphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];",
  4407. "morphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];",
  4408. "morphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];",
  4409. "morphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];",
  4410. "#ifndef USE_MORPHNORMALS",
  4411. "morphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];",
  4412. "morphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];",
  4413. "morphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];",
  4414. "morphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];",
  4415. "#endif",
  4416. "morphed += position;",
  4417. "gl_Position = projectionMatrix * modelViewMatrix * vec4( morphed, 1.0 );",
  4418. "#endif"
  4419. ].join("\n"),
  4420. default_vertex : [
  4421. "#ifndef USE_MORPHTARGETS",
  4422. "#ifndef USE_SKINNING",
  4423. "gl_Position = projectionMatrix * mvPosition;",
  4424. "#endif",
  4425. "#endif"
  4426. ].join("\n"),
  4427. morphnormal_vertex: [
  4428. "#ifdef USE_MORPHNORMALS",
  4429. "vec3 morphedNormal = vec3( 0.0 );",
  4430. "morphedNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];",
  4431. "morphedNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];",
  4432. "morphedNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];",
  4433. "morphedNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];",
  4434. "morphedNormal += normal;",
  4435. "vec3 transformedNormal = normalMatrix * morphedNormal;",
  4436. "#else",
  4437. "vec3 transformedNormal = normalMatrix * normal;",
  4438. "#endif"
  4439. ].join("\n"),
  4440. // SHADOW MAP
  4441. // based on SpiderGL shadow map and Fabien Sanglard's GLSL shadow mapping examples
  4442. // http://spidergl.org/example.php?id=6
  4443. // http://fabiensanglard.net/shadowmapping
  4444. shadowmap_pars_fragment: [
  4445. "#ifdef USE_SHADOWMAP",
  4446. "uniform sampler2D shadowMap[ MAX_SHADOWS ];",
  4447. "uniform vec2 shadowMapSize[ MAX_SHADOWS ];",
  4448. "uniform float shadowDarkness[ MAX_SHADOWS ];",
  4449. "uniform float shadowBias[ MAX_SHADOWS ];",
  4450. "varying vec4 vShadowCoord[ MAX_SHADOWS ];",
  4451. "float unpackDepth( const in vec4 rgba_depth ) {",
  4452. "const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );",
  4453. "float depth = dot( rgba_depth, bit_shift );",
  4454. "return depth;",
  4455. "}",
  4456. "#endif"
  4457. ].join("\n"),
  4458. shadowmap_fragment: [
  4459. "#ifdef USE_SHADOWMAP",
  4460. "#ifdef SHADOWMAP_DEBUG",
  4461. "vec3 frustumColors[3];",
  4462. "frustumColors[0] = vec3( 1.0, 0.5, 0.0 );",
  4463. "frustumColors[1] = vec3( 0.0, 1.0, 0.8 );",
  4464. "frustumColors[2] = vec3( 0.0, 0.5, 1.0 );",
  4465. "#endif",
  4466. "#ifdef SHADOWMAP_CASCADE",
  4467. "int inFrustumCount = 0;",
  4468. "#endif",
  4469. "float fDepth;",
  4470. "vec3 shadowColor = vec3( 1.0 );",
  4471. "for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
  4472. "vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;",
  4473. // "if ( something && something )" breaks ATI OpenGL shader compiler
  4474. // "if ( all( something, something ) )" using this instead
  4475. "bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );",
  4476. "bool inFrustum = all( inFrustumVec );",
  4477. // don't shadow pixels outside of light frustum
  4478. // use just first frustum (for cascades)
  4479. // don't shadow pixels behind far plane of light frustum
  4480. "#ifdef SHADOWMAP_CASCADE",
  4481. "inFrustumCount += int( inFrustum );",
  4482. "bvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );",
  4483. "#else",
  4484. "bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );",
  4485. "#endif",
  4486. "bool frustumTest = all( frustumTestVec );",
  4487. "if ( frustumTest ) {",
  4488. "shadowCoord.z += shadowBias[ i ];",
  4489. "#ifdef SHADOWMAP_SOFT",
  4490. // Percentage-close filtering
  4491. // (9 pixel kernel)
  4492. // http://fabiensanglard.net/shadowmappingPCF/
  4493. "float shadow = 0.0;",
  4494. /*
  4495. // nested loops breaks shader compiler / validator on some ATI cards when using OpenGL
  4496. // must enroll loop manually
  4497. "for ( float y = -1.25; y <= 1.25; y += 1.25 )",
  4498. "for ( float x = -1.25; x <= 1.25; x += 1.25 ) {",
  4499. "vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );",
  4500. // doesn't seem to produce any noticeable visual difference compared to simple "texture2D" lookup
  4501. //"vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );",
  4502. "float fDepth = unpackDepth( rgbaDepth );",
  4503. "if ( fDepth < shadowCoord.z )",
  4504. "shadow += 1.0;",
  4505. "}",
  4506. "shadow /= 9.0;",
  4507. */
  4508. "const float shadowDelta = 1.0 / 9.0;",
  4509. "float xPixelOffset = 1.0 / shadowMapSize[ i ].x;",
  4510. "float yPixelOffset = 1.0 / shadowMapSize[ i ].y;",
  4511. "float dx0 = -1.25 * xPixelOffset;",
  4512. "float dy0 = -1.25 * yPixelOffset;",
  4513. "float dx1 = 1.25 * xPixelOffset;",
  4514. "float dy1 = 1.25 * yPixelOffset;",
  4515. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );",
  4516. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  4517. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );",
  4518. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  4519. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );",
  4520. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  4521. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );",
  4522. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  4523. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );",
  4524. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  4525. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );",
  4526. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  4527. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );",
  4528. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  4529. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );",
  4530. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  4531. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );",
  4532. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  4533. "shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );",
  4534. "#else",
  4535. "vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );",
  4536. "float fDepth = unpackDepth( rgbaDepth );",
  4537. "if ( fDepth < shadowCoord.z )",
  4538. // spot with multiple shadows is darker
  4539. "shadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );",
  4540. // spot with multiple shadows has the same color as single shadow spot
  4541. //"shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );",
  4542. "#endif",
  4543. "}",
  4544. "#ifdef SHADOWMAP_DEBUG",
  4545. "#ifdef SHADOWMAP_CASCADE",
  4546. "if ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];",
  4547. "#else",
  4548. "if ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];",
  4549. "#endif",
  4550. "#endif",
  4551. "}",
  4552. "#ifdef GAMMA_OUTPUT",
  4553. "shadowColor *= shadowColor;",
  4554. "#endif",
  4555. "gl_FragColor.xyz = gl_FragColor.xyz * shadowColor;",
  4556. "#endif"
  4557. ].join("\n"),
  4558. shadowmap_pars_vertex: [
  4559. "#ifdef USE_SHADOWMAP",
  4560. "varying vec4 vShadowCoord[ MAX_SHADOWS ];",
  4561. "uniform mat4 shadowMatrix[ MAX_SHADOWS ];",
  4562. "#endif"
  4563. ].join("\n"),
  4564. shadowmap_vertex: [
  4565. "#ifdef USE_SHADOWMAP",
  4566. "for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
  4567. "#ifdef USE_MORPHTARGETS",
  4568. "vShadowCoord[ i ] = shadowMatrix[ i ] * objectMatrix * vec4( morphed, 1.0 );",
  4569. "#else",
  4570. "vShadowCoord[ i ] = shadowMatrix[ i ] * objectMatrix * vec4( position, 1.0 );",
  4571. "#endif",
  4572. "}",
  4573. "#endif"
  4574. ].join("\n"),
  4575. // ALPHATEST
  4576. alphatest_fragment: [
  4577. "#ifdef ALPHATEST",
  4578. "if ( gl_FragColor.a < ALPHATEST ) discard;",
  4579. "#endif"
  4580. ].join("\n"),
  4581. // LINEAR SPACE
  4582. linear_to_gamma_fragment: [
  4583. "#ifdef GAMMA_OUTPUT",
  4584. "gl_FragColor.xyz = sqrt( gl_FragColor.xyz );",
  4585. "#endif"
  4586. ].join("\n"),
  4587. };
  4588. THREE.UniformsUtils = {
  4589. merge: function ( uniforms ) {
  4590. var u, p, tmp, merged = {};
  4591. for ( u = 0; u < uniforms.length; u++ ) {
  4592. tmp = this.clone( uniforms[ u ] );
  4593. for ( p in tmp ) {
  4594. merged[ p ] = tmp[ p ];
  4595. }
  4596. }
  4597. return merged;
  4598. },
  4599. clone: function ( uniforms_src ) {
  4600. var u, p, parameter, parameter_src, uniforms_dst = {};
  4601. for ( u in uniforms_src ) {
  4602. uniforms_dst[ u ] = {};
  4603. for ( p in uniforms_src[ u ] ) {
  4604. parameter_src = uniforms_src[ u ][ p ];
  4605. if ( parameter_src instanceof THREE.Color ||
  4606. parameter_src instanceof THREE.Vector2 ||
  4607. parameter_src instanceof THREE.Vector3 ||
  4608. parameter_src instanceof THREE.Vector4 ||
  4609. parameter_src instanceof THREE.Matrix4 ||
  4610. parameter_src instanceof THREE.Texture ) {
  4611. uniforms_dst[ u ][ p ] = parameter_src.clone();
  4612. } else if ( parameter_src instanceof Array ) {
  4613. uniforms_dst[ u ][ p ] = parameter_src.slice();
  4614. } else {
  4615. uniforms_dst[ u ][ p ] = parameter_src;
  4616. }
  4617. }
  4618. }
  4619. return uniforms_dst;
  4620. }
  4621. };
  4622. THREE.UniformsLib = {
  4623. common: {
  4624. "diffuse" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
  4625. "opacity" : { type: "f", value: 1.0 },
  4626. "map" : { type: "t", value: 0, texture: null },
  4627. "offsetRepeat" : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) },
  4628. "lightMap" : { type: "t", value: 2, texture: null },
  4629. "envMap" : { type: "t", value: 1, texture: null },
  4630. "flipEnvMap" : { type: "f", value: -1 },
  4631. "useRefract" : { type: "i", value: 0 },
  4632. "reflectivity" : { type: "f", value: 1.0 },
  4633. "refractionRatio" : { type: "f", value: 0.98 },
  4634. "combine" : { type: "i", value: 0 },
  4635. "morphTargetInfluences" : { type: "f", value: 0 }
  4636. },
  4637. fog : {
  4638. "fogDensity" : { type: "f", value: 0.00025 },
  4639. "fogNear" : { type: "f", value: 1 },
  4640. "fogFar" : { type: "f", value: 2000 },
  4641. "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) }
  4642. },
  4643. lights: {
  4644. "ambientLightColor" : { type: "fv", value: [] },
  4645. "directionalLightDirection" : { type: "fv", value: [] },
  4646. "directionalLightColor" : { type: "fv", value: [] },
  4647. "pointLightColor" : { type: "fv", value: [] },
  4648. "pointLightPosition" : { type: "fv", value: [] },
  4649. "pointLightDistance" : { type: "fv1", value: [] }
  4650. },
  4651. particle: {
  4652. "psColor" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
  4653. "opacity" : { type: "f", value: 1.0 },
  4654. "size" : { type: "f", value: 1.0 },
  4655. "scale" : { type: "f", value: 1.0 },
  4656. "map" : { type: "t", value: 0, texture: null },
  4657. "fogDensity" : { type: "f", value: 0.00025 },
  4658. "fogNear" : { type: "f", value: 1 },
  4659. "fogFar" : { type: "f", value: 2000 },
  4660. "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) }
  4661. },
  4662. shadowmap: {
  4663. "shadowMap": { type: "tv", value: 6, texture: [] },
  4664. "shadowMapSize": { type: "v2v", value: [] },
  4665. "shadowBias" : { type: "fv1", value: [] },
  4666. "shadowDarkness": { type: "fv1", value: [] },
  4667. "shadowMatrix" : { type: "m4v", value: [] },
  4668. }
  4669. };
  4670. THREE.ShaderLib = {
  4671. 'depth': {
  4672. uniforms: {
  4673. "mNear": { type: "f", value: 1.0 },
  4674. "mFar" : { type: "f", value: 2000.0 },
  4675. "opacity" : { type: "f", value: 1.0 }
  4676. },
  4677. vertexShader: [
  4678. "void main() {",
  4679. "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
  4680. "}"
  4681. ].join("\n"),
  4682. fragmentShader: [
  4683. "uniform float mNear;",
  4684. "uniform float mFar;",
  4685. "uniform float opacity;",
  4686. "void main() {",
  4687. "float depth = gl_FragCoord.z / gl_FragCoord.w;",
  4688. "float color = 1.0 - smoothstep( mNear, mFar, depth );",
  4689. "gl_FragColor = vec4( vec3( color ), opacity );",
  4690. "}"
  4691. ].join("\n")
  4692. },
  4693. 'normal': {
  4694. uniforms: {
  4695. "opacity" : { type: "f", value: 1.0 }
  4696. },
  4697. vertexShader: [
  4698. "varying vec3 vNormal;",
  4699. "void main() {",
  4700. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  4701. "vNormal = normalMatrix * normal;",
  4702. "gl_Position = projectionMatrix * mvPosition;",
  4703. "}"
  4704. ].join("\n"),
  4705. fragmentShader: [
  4706. "uniform float opacity;",
  4707. "varying vec3 vNormal;",
  4708. "void main() {",
  4709. "gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",
  4710. "}"
  4711. ].join("\n")
  4712. },
  4713. 'basic': {
  4714. uniforms: THREE.UniformsUtils.merge( [
  4715. THREE.UniformsLib[ "common" ],
  4716. THREE.UniformsLib[ "fog" ],
  4717. THREE.UniformsLib[ "shadowmap" ]
  4718. ] ),
  4719. vertexShader: [
  4720. THREE.ShaderChunk[ "map_pars_vertex" ],
  4721. THREE.ShaderChunk[ "lightmap_pars_vertex" ],
  4722. THREE.ShaderChunk[ "envmap_pars_vertex" ],
  4723. THREE.ShaderChunk[ "color_pars_vertex" ],
  4724. THREE.ShaderChunk[ "skinning_pars_vertex" ],
  4725. THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
  4726. THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
  4727. "void main() {",
  4728. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  4729. THREE.ShaderChunk[ "map_vertex" ],
  4730. THREE.ShaderChunk[ "lightmap_vertex" ],
  4731. THREE.ShaderChunk[ "envmap_vertex" ],
  4732. THREE.ShaderChunk[ "color_vertex" ],
  4733. THREE.ShaderChunk[ "skinning_vertex" ],
  4734. THREE.ShaderChunk[ "morphtarget_vertex" ],
  4735. THREE.ShaderChunk[ "default_vertex" ],
  4736. THREE.ShaderChunk[ "shadowmap_vertex" ],
  4737. "}"
  4738. ].join("\n"),
  4739. fragmentShader: [
  4740. "uniform vec3 diffuse;",
  4741. "uniform float opacity;",
  4742. THREE.ShaderChunk[ "color_pars_fragment" ],
  4743. THREE.ShaderChunk[ "map_pars_fragment" ],
  4744. THREE.ShaderChunk[ "lightmap_pars_fragment" ],
  4745. THREE.ShaderChunk[ "envmap_pars_fragment" ],
  4746. THREE.ShaderChunk[ "fog_pars_fragment" ],
  4747. THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
  4748. "void main() {",
  4749. "gl_FragColor = vec4( diffuse, opacity );",
  4750. THREE.ShaderChunk[ "map_fragment" ],
  4751. THREE.ShaderChunk[ "alphatest_fragment" ],
  4752. THREE.ShaderChunk[ "lightmap_fragment" ],
  4753. THREE.ShaderChunk[ "color_fragment" ],
  4754. THREE.ShaderChunk[ "envmap_fragment" ],
  4755. THREE.ShaderChunk[ "shadowmap_fragment" ],
  4756. THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
  4757. THREE.ShaderChunk[ "fog_fragment" ],
  4758. "}"
  4759. ].join("\n")
  4760. },
  4761. 'lambert': {
  4762. uniforms: THREE.UniformsUtils.merge( [
  4763. THREE.UniformsLib[ "common" ],
  4764. THREE.UniformsLib[ "fog" ],
  4765. THREE.UniformsLib[ "lights" ],
  4766. THREE.UniformsLib[ "shadowmap" ],
  4767. {
  4768. "ambient" : { type: "c", value: new THREE.Color( 0xffffff ) },
  4769. "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
  4770. "wrapRGB" : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
  4771. }
  4772. ] ),
  4773. vertexShader: [
  4774. "varying vec3 vLightFront;",
  4775. "#ifdef DOUBLE_SIDED",
  4776. "varying vec3 vLightBack;",
  4777. "#endif",
  4778. THREE.ShaderChunk[ "map_pars_vertex" ],
  4779. THREE.ShaderChunk[ "lightmap_pars_vertex" ],
  4780. THREE.ShaderChunk[ "envmap_pars_vertex" ],
  4781. THREE.ShaderChunk[ "lights_lambert_pars_vertex" ],
  4782. THREE.ShaderChunk[ "color_pars_vertex" ],
  4783. THREE.ShaderChunk[ "skinning_pars_vertex" ],
  4784. THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
  4785. THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
  4786. "void main() {",
  4787. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  4788. THREE.ShaderChunk[ "map_vertex" ],
  4789. THREE.ShaderChunk[ "lightmap_vertex" ],
  4790. THREE.ShaderChunk[ "envmap_vertex" ],
  4791. THREE.ShaderChunk[ "color_vertex" ],
  4792. THREE.ShaderChunk[ "morphnormal_vertex" ],
  4793. THREE.ShaderChunk[ "lights_lambert_vertex" ],
  4794. THREE.ShaderChunk[ "skinning_vertex" ],
  4795. THREE.ShaderChunk[ "morphtarget_vertex" ],
  4796. THREE.ShaderChunk[ "default_vertex" ],
  4797. THREE.ShaderChunk[ "shadowmap_vertex" ],
  4798. "}"
  4799. ].join("\n"),
  4800. fragmentShader: [
  4801. "uniform float opacity;",
  4802. "varying vec3 vLightFront;",
  4803. "#ifdef DOUBLE_SIDED",
  4804. "varying vec3 vLightBack;",
  4805. "#endif",
  4806. THREE.ShaderChunk[ "color_pars_fragment" ],
  4807. THREE.ShaderChunk[ "map_pars_fragment" ],
  4808. THREE.ShaderChunk[ "lightmap_pars_fragment" ],
  4809. THREE.ShaderChunk[ "envmap_pars_fragment" ],
  4810. THREE.ShaderChunk[ "fog_pars_fragment" ],
  4811. THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
  4812. "void main() {",
  4813. "gl_FragColor = vec4( vec3 ( 1.0 ), opacity );",
  4814. THREE.ShaderChunk[ "map_fragment" ],
  4815. THREE.ShaderChunk[ "alphatest_fragment" ],
  4816. "#ifdef DOUBLE_SIDED",
  4817. //"float isFront = float( gl_FrontFacing );",
  4818. //"gl_FragColor.xyz *= isFront * vLightFront + ( 1.0 - isFront ) * vLightBack;",
  4819. "if ( gl_FrontFacing )",
  4820. "gl_FragColor.xyz *= vLightFront;",
  4821. "else",
  4822. "gl_FragColor.xyz *= vLightBack;",
  4823. "#else",
  4824. "gl_FragColor.xyz *= vLightFront;",
  4825. "#endif",
  4826. THREE.ShaderChunk[ "lightmap_fragment" ],
  4827. THREE.ShaderChunk[ "color_fragment" ],
  4828. THREE.ShaderChunk[ "envmap_fragment" ],
  4829. THREE.ShaderChunk[ "shadowmap_fragment" ],
  4830. THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
  4831. THREE.ShaderChunk[ "fog_fragment" ],
  4832. "}"
  4833. ].join("\n")
  4834. },
  4835. 'phong': {
  4836. uniforms: THREE.UniformsUtils.merge( [
  4837. THREE.UniformsLib[ "common" ],
  4838. THREE.UniformsLib[ "fog" ],
  4839. THREE.UniformsLib[ "lights" ],
  4840. THREE.UniformsLib[ "shadowmap" ],
  4841. {
  4842. "ambient" : { type: "c", value: new THREE.Color( 0xffffff ) },
  4843. "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
  4844. "specular" : { type: "c", value: new THREE.Color( 0x111111 ) },
  4845. "shininess": { type: "f", value: 30 },
  4846. "wrapRGB" : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
  4847. }
  4848. ] ),
  4849. vertexShader: [
  4850. "varying vec3 vViewPosition;",
  4851. "varying vec3 vNormal;",
  4852. THREE.ShaderChunk[ "map_pars_vertex" ],
  4853. THREE.ShaderChunk[ "lightmap_pars_vertex" ],
  4854. THREE.ShaderChunk[ "envmap_pars_vertex" ],
  4855. THREE.ShaderChunk[ "lights_phong_pars_vertex" ],
  4856. THREE.ShaderChunk[ "color_pars_vertex" ],
  4857. THREE.ShaderChunk[ "skinning_pars_vertex" ],
  4858. THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
  4859. THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
  4860. "void main() {",
  4861. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  4862. THREE.ShaderChunk[ "map_vertex" ],
  4863. THREE.ShaderChunk[ "lightmap_vertex" ],
  4864. THREE.ShaderChunk[ "envmap_vertex" ],
  4865. THREE.ShaderChunk[ "color_vertex" ],
  4866. "#ifndef USE_ENVMAP",
  4867. "vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
  4868. "#endif",
  4869. "vViewPosition = -mvPosition.xyz;",
  4870. THREE.ShaderChunk[ "morphnormal_vertex" ],
  4871. "vNormal = transformedNormal;",
  4872. THREE.ShaderChunk[ "lights_phong_vertex" ],
  4873. THREE.ShaderChunk[ "skinning_vertex" ],
  4874. THREE.ShaderChunk[ "morphtarget_vertex" ],
  4875. THREE.ShaderChunk[ "default_vertex" ],
  4876. THREE.ShaderChunk[ "shadowmap_vertex" ],
  4877. "}"
  4878. ].join("\n"),
  4879. fragmentShader: [
  4880. "uniform vec3 diffuse;",
  4881. "uniform float opacity;",
  4882. "uniform vec3 ambient;",
  4883. "uniform vec3 emissive;",
  4884. "uniform vec3 specular;",
  4885. "uniform float shininess;",
  4886. THREE.ShaderChunk[ "color_pars_fragment" ],
  4887. THREE.ShaderChunk[ "map_pars_fragment" ],
  4888. THREE.ShaderChunk[ "lightmap_pars_fragment" ],
  4889. THREE.ShaderChunk[ "envmap_pars_fragment" ],
  4890. THREE.ShaderChunk[ "fog_pars_fragment" ],
  4891. THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
  4892. THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
  4893. "void main() {",
  4894. "gl_FragColor = vec4( vec3 ( 1.0 ), opacity );",
  4895. THREE.ShaderChunk[ "map_fragment" ],
  4896. THREE.ShaderChunk[ "alphatest_fragment" ],
  4897. THREE.ShaderChunk[ "lights_phong_fragment" ],
  4898. THREE.ShaderChunk[ "lightmap_fragment" ],
  4899. THREE.ShaderChunk[ "color_fragment" ],
  4900. THREE.ShaderChunk[ "envmap_fragment" ],
  4901. THREE.ShaderChunk[ "shadowmap_fragment" ],
  4902. THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
  4903. THREE.ShaderChunk[ "fog_fragment" ],
  4904. "}"
  4905. ].join("\n")
  4906. },
  4907. 'particle_basic': {
  4908. uniforms: THREE.UniformsUtils.merge( [
  4909. THREE.UniformsLib[ "particle" ],
  4910. THREE.UniformsLib[ "shadowmap" ]
  4911. ] ),
  4912. vertexShader: [
  4913. "uniform float size;",
  4914. "uniform float scale;",
  4915. THREE.ShaderChunk[ "color_pars_vertex" ],
  4916. THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
  4917. "void main() {",
  4918. THREE.ShaderChunk[ "color_vertex" ],
  4919. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  4920. "#ifdef USE_SIZEATTENUATION",
  4921. "gl_PointSize = size * ( scale / length( mvPosition.xyz ) );",
  4922. "#else",
  4923. "gl_PointSize = size;",
  4924. "#endif",
  4925. "gl_Position = projectionMatrix * mvPosition;",
  4926. THREE.ShaderChunk[ "shadowmap_vertex" ],
  4927. "}"
  4928. ].join("\n"),
  4929. fragmentShader: [
  4930. "uniform vec3 psColor;",
  4931. "uniform float opacity;",
  4932. THREE.ShaderChunk[ "color_pars_fragment" ],
  4933. THREE.ShaderChunk[ "map_particle_pars_fragment" ],
  4934. THREE.ShaderChunk[ "fog_pars_fragment" ],
  4935. THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
  4936. "void main() {",
  4937. "gl_FragColor = vec4( psColor, opacity );",
  4938. THREE.ShaderChunk[ "map_particle_fragment" ],
  4939. THREE.ShaderChunk[ "alphatest_fragment" ],
  4940. THREE.ShaderChunk[ "color_fragment" ],
  4941. THREE.ShaderChunk[ "shadowmap_fragment" ],
  4942. THREE.ShaderChunk[ "fog_fragment" ],
  4943. "}"
  4944. ].join("\n")
  4945. },
  4946. // Depth encoding into RGBA texture
  4947. // based on SpiderGL shadow map example
  4948. // http://spidergl.org/example.php?id=6
  4949. // originally from
  4950. // http://www.gamedev.net/topic/442138-packing-a-float-into-a-a8r8g8b8-texture-shader/page__whichpage__1%25EF%25BF%25BD
  4951. // see also here:
  4952. // http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/
  4953. 'depthRGBA': {
  4954. uniforms: {},
  4955. vertexShader: [
  4956. THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
  4957. "void main() {",
  4958. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  4959. THREE.ShaderChunk[ "morphtarget_vertex" ],
  4960. THREE.ShaderChunk[ "default_vertex" ],
  4961. "}"
  4962. ].join("\n"),
  4963. fragmentShader: [
  4964. "vec4 pack_depth( const in float depth ) {",
  4965. "const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );",
  4966. "const vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );",
  4967. "vec4 res = fract( depth * bit_shift );",
  4968. "res -= res.xxyz * bit_mask;",
  4969. "return res;",
  4970. "}",
  4971. "void main() {",
  4972. "gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );",
  4973. //"gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z / gl_FragCoord.w );",
  4974. //"float z = ( ( gl_FragCoord.z / gl_FragCoord.w ) - 3.0 ) / ( 4000.0 - 3.0 );",
  4975. //"gl_FragData[ 0 ] = pack_depth( z );",
  4976. //"gl_FragData[ 0 ] = vec4( z, z, z, 1.0 );",
  4977. "}"
  4978. ].join("\n")
  4979. }
  4980. };/**
  4981. * @author supereggbert / http://www.paulbrunt.co.uk/
  4982. * @author mrdoob / http://mrdoob.com/
  4983. * @author alteredq / http://alteredqualia.com/
  4984. * @author szimek / https://github.com/szimek/
  4985. */
  4986. THREE.WebGLRenderer = function ( parameters ) {
  4987. // constructor parameters
  4988. parameters = parameters || {};
  4989. var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ),
  4990. _precision = parameters.precision !== undefined ? parameters.precision : 'highp',
  4991. _alpha = parameters.alpha !== undefined ? parameters.alpha : true,
  4992. _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
  4993. _antialias = parameters.antialias !== undefined ? parameters.antialias : false,
  4994. _stencil = parameters.stencil !== undefined ? parameters.stencil : true,
  4995. _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
  4996. _clearColor = parameters.clearColor !== undefined ? new THREE.Color( parameters.clearColor ) : new THREE.Color( 0x000000 ),
  4997. _clearAlpha = parameters.clearAlpha !== undefined ? parameters.clearAlpha : 0,
  4998. _maxLights = parameters.maxLights !== undefined ? parameters.maxLights : 4;
  4999. // public properties
  5000. this.domElement = _canvas;
  5001. this.context = null;
  5002. // clearing
  5003. this.autoClear = true;
  5004. this.autoClearColor = true;
  5005. this.autoClearDepth = true;
  5006. this.autoClearStencil = true;
  5007. // scene graph
  5008. this.sortObjects = true;
  5009. this.autoUpdateObjects = true;
  5010. this.autoUpdateScene = true;
  5011. // physically based shading
  5012. this.gammaInput = false;
  5013. this.gammaOutput = false;
  5014. this.physicallyBasedShading = false;
  5015. // shadow map
  5016. this.shadowMapEnabled = false;
  5017. this.shadowMapAutoUpdate = true;
  5018. this.shadowMapSoft = true;
  5019. this.shadowMapCullFrontFaces = true;
  5020. this.shadowMapDebug = false;
  5021. this.shadowMapCascade = false;
  5022. // morphs
  5023. this.maxMorphTargets = 8;
  5024. this.maxMorphNormals = 4;
  5025. // flags
  5026. this.autoScaleCubemaps = true;
  5027. // custom render plugins
  5028. this.renderPluginsPre = [];
  5029. this.renderPluginsPost = [];
  5030. // info
  5031. this.info = {
  5032. memory: {
  5033. programs: 0,
  5034. geometries: 0,
  5035. textures: 0
  5036. },
  5037. render: {
  5038. calls: 0,
  5039. vertices: 0,
  5040. faces: 0,
  5041. points: 0
  5042. }
  5043. };
  5044. // internal properties
  5045. var _this = this,
  5046. _gl,
  5047. _programs = [],
  5048. // internal state cache
  5049. _currentProgram = null,
  5050. _currentFramebuffer = null,
  5051. _currentMaterialId = -1,
  5052. _currentGeometryGroupHash = null,
  5053. _currentCamera = null,
  5054. _geometryGroupCounter = 0,
  5055. // GL state cache
  5056. _oldDoubleSided = null,
  5057. _oldFlipSided = null,
  5058. _oldBlending = null,
  5059. _oldBlendEquation = null,
  5060. _oldBlendSrc = null,
  5061. _oldBlendDst = null,
  5062. _oldDepthTest = null,
  5063. _oldDepthWrite = null,
  5064. _oldPolygonOffset = null,
  5065. _oldPolygonOffsetFactor = null,
  5066. _oldPolygonOffsetUnits = null,
  5067. _oldLineWidth = null,
  5068. _viewportX = 0,
  5069. _viewportY = 0,
  5070. _viewportWidth = 0,
  5071. _viewportHeight = 0,
  5072. _currentWidth = 0,
  5073. _currentHeight = 0,
  5074. // frustum
  5075. _frustum = new THREE.Frustum(),
  5076. // camera matrices cache
  5077. _projScreenMatrix = new THREE.Matrix4(),
  5078. _projScreenMatrixPS = new THREE.Matrix4(),
  5079. _vector3 = new THREE.Vector4(),
  5080. // light arrays cache
  5081. _direction = new THREE.Vector3(),
  5082. _lights = {
  5083. ambient: [ 0, 0, 0 ],
  5084. directional: { length: 0, colors: new Array(), positions: new Array() },
  5085. point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() }
  5086. };
  5087. // initialize
  5088. _gl = initGL();
  5089. setDefaultGLState();
  5090. this.context = _gl;
  5091. // GPU capabilities
  5092. var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ),
  5093. _maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE ),
  5094. _maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
  5095. // API
  5096. this.getContext = function () {
  5097. return _gl;
  5098. };
  5099. this.supportsVertexTextures = function () {
  5100. return _maxVertexTextures > 0;
  5101. };
  5102. this.setSize = function ( width, height ) {
  5103. _canvas.width = width;
  5104. _canvas.height = height;
  5105. this.setViewport( 0, 0, _canvas.width, _canvas.height );
  5106. };
  5107. this.setViewport = function ( x, y, width, height ) {
  5108. _viewportX = x;
  5109. _viewportY = y;
  5110. _viewportWidth = width;
  5111. _viewportHeight = height;
  5112. _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
  5113. };
  5114. this.setScissor = function ( x, y, width, height ) {
  5115. _gl.scissor( x, y, width, height );
  5116. };
  5117. this.enableScissorTest = function ( enable ) {
  5118. enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
  5119. };
  5120. // Clearing
  5121. this.setClearColorHex = function ( hex, alpha ) {
  5122. _clearColor.setHex( hex );
  5123. _clearAlpha = alpha;
  5124. _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
  5125. };
  5126. this.setClearColor = function ( color, alpha ) {
  5127. _clearColor.copy( color );
  5128. _clearAlpha = alpha;
  5129. _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
  5130. };
  5131. this.getClearColor = function () {
  5132. return _clearColor;
  5133. };
  5134. this.getClearAlpha = function () {
  5135. return _clearAlpha;
  5136. };
  5137. this.clear = function ( color, depth, stencil ) {
  5138. var bits = 0;
  5139. if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;
  5140. if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;
  5141. if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;
  5142. _gl.clear( bits );
  5143. };
  5144. this.clearTarget = function ( renderTarget, color, depth, stencil ) {
  5145. this.setRenderTarget( renderTarget );
  5146. this.clear( color, depth, stencil );
  5147. };
  5148. // Plugins
  5149. this.addPostPlugin = function ( plugin ) {
  5150. plugin.init( this );
  5151. this.renderPluginsPost.push( plugin );
  5152. };
  5153. this.addPrePlugin = function ( plugin ) {
  5154. plugin.init( this );
  5155. this.renderPluginsPre.push( plugin );
  5156. };
  5157. // Deallocation
  5158. this.deallocateObject = function ( object ) {
  5159. if ( ! object.__webglInit ) return;
  5160. object.__webglInit = false;
  5161. delete object._modelViewMatrix;
  5162. delete object._normalMatrix;
  5163. delete object._normalMatrixArray;
  5164. delete object._modelViewMatrixArray;
  5165. delete object._objectMatrixArray;
  5166. if ( object instanceof THREE.Mesh ) {
  5167. for ( var g in object.geometry.geometryGroups ) {
  5168. deleteMeshBuffers( object.geometry.geometryGroups[ g ] );
  5169. }
  5170. } else if ( object instanceof THREE.Ribbon ) {
  5171. deleteRibbonBuffers( object.geometry );
  5172. } else if ( object instanceof THREE.Line ) {
  5173. deleteLineBuffers( object.geometry );
  5174. } else if ( object instanceof THREE.ParticleSystem ) {
  5175. deleteParticleBuffers( object.geometry );
  5176. }
  5177. };
  5178. this.deallocateTexture = function ( texture ) {
  5179. if ( ! texture.__webglInit ) return;
  5180. texture.__webglInit = false;
  5181. _gl.deleteTexture( texture.__webglTexture );
  5182. _this.info.memory.textures --;
  5183. };
  5184. this.deallocateRenderTarget = function ( renderTarget ) {
  5185. if ( !renderTarget || ! renderTarget.__webglTexture ) return;
  5186. _gl.deleteTexture( renderTarget.__webglTexture );
  5187. if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
  5188. for ( var i = 0; i < 6; i ++ ) {
  5189. _gl.deleteFramebuffer( renderTarget.__webglFramebuffer[ i ] );
  5190. _gl.deleteRenderbuffer( renderTarget.__webglRenderbuffer[ i ] );
  5191. }
  5192. } else {
  5193. _gl.deleteFramebuffer( renderTarget.__webglFramebuffer );
  5194. _gl.deleteRenderbuffer( renderTarget.__webglRenderbuffer );
  5195. }
  5196. };
  5197. // Rendering
  5198. this.updateShadowMap = function ( scene, camera ) {
  5199. _currentProgram = null;
  5200. _oldBlending = -1;
  5201. _oldDepthTest = -1;
  5202. _oldDepthWrite = -1;
  5203. _currentGeometryGroupHash = -1;
  5204. _currentMaterialId = -1;
  5205. this.shadowMapPlugin.update( scene, camera );
  5206. };
  5207. // Internal functions
  5208. // Buffer allocation
  5209. function createParticleBuffers ( geometry ) {
  5210. geometry.__webglVertexBuffer = _gl.createBuffer();
  5211. geometry.__webglColorBuffer = _gl.createBuffer();
  5212. _this.info.geometries ++;
  5213. };
  5214. function createLineBuffers ( geometry ) {
  5215. geometry.__webglVertexBuffer = _gl.createBuffer();
  5216. geometry.__webglColorBuffer = _gl.createBuffer();
  5217. _this.info.memory.geometries ++;
  5218. };
  5219. function createRibbonBuffers ( geometry ) {
  5220. geometry.__webglVertexBuffer = _gl.createBuffer();
  5221. geometry.__webglColorBuffer = _gl.createBuffer();
  5222. _this.info.memory.geometries ++;
  5223. };
  5224. function createMeshBuffers ( geometryGroup ) {
  5225. geometryGroup.__webglVertexBuffer = _gl.createBuffer();
  5226. geometryGroup.__webglNormalBuffer = _gl.createBuffer();
  5227. geometryGroup.__webglTangentBuffer = _gl.createBuffer();
  5228. geometryGroup.__webglColorBuffer = _gl.createBuffer();
  5229. geometryGroup.__webglUVBuffer = _gl.createBuffer();
  5230. geometryGroup.__webglUV2Buffer = _gl.createBuffer();
  5231. geometryGroup.__webglSkinVertexABuffer = _gl.createBuffer();
  5232. geometryGroup.__webglSkinVertexBBuffer = _gl.createBuffer();
  5233. geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
  5234. geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
  5235. geometryGroup.__webglFaceBuffer = _gl.createBuffer();
  5236. geometryGroup.__webglLineBuffer = _gl.createBuffer();
  5237. var m, ml;
  5238. if ( geometryGroup.numMorphTargets ) {
  5239. geometryGroup.__webglMorphTargetsBuffers = [];
  5240. for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
  5241. geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
  5242. }
  5243. }
  5244. if ( geometryGroup.numMorphNormals ) {
  5245. geometryGroup.__webglMorphNormalsBuffers = [];
  5246. for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
  5247. geometryGroup.__webglMorphNormalsBuffers.push( _gl.createBuffer() );
  5248. }
  5249. }
  5250. _this.info.memory.geometries ++;
  5251. };
  5252. // Buffer deallocation
  5253. function deleteParticleBuffers ( geometry ) {
  5254. _gl.deleteBuffer( geometry.__webglVertexBuffer );
  5255. _gl.deleteBuffer( geometry.__webglColorBuffer );
  5256. _this.info.memory.geometries --;
  5257. };
  5258. function deleteLineBuffers ( geometry ) {
  5259. _gl.deleteBuffer( geometry.__webglVertexBuffer );
  5260. _gl.deleteBuffer( geometry.__webglColorBuffer );
  5261. _this.info.memory.geometries --;
  5262. };
  5263. function deleteRibbonBuffers ( geometry ) {
  5264. _gl.deleteBuffer( geometry.__webglVertexBuffer );
  5265. _gl.deleteBuffer( geometry.__webglColorBuffer );
  5266. _this.info.memory.geometries --;
  5267. };
  5268. function deleteMeshBuffers ( geometryGroup ) {
  5269. _gl.deleteBuffer( geometryGroup.__webglVertexBuffer );
  5270. _gl.deleteBuffer( geometryGroup.__webglNormalBuffer );
  5271. _gl.deleteBuffer( geometryGroup.__webglTangentBuffer );
  5272. _gl.deleteBuffer( geometryGroup.__webglColorBuffer );
  5273. _gl.deleteBuffer( geometryGroup.__webglUVBuffer );
  5274. _gl.deleteBuffer( geometryGroup.__webglUV2Buffer );
  5275. _gl.deleteBuffer( geometryGroup.__webglSkinVertexABuffer );
  5276. _gl.deleteBuffer( geometryGroup.__webglSkinVertexBBuffer );
  5277. _gl.deleteBuffer( geometryGroup.__webglSkinIndicesBuffer );
  5278. _gl.deleteBuffer( geometryGroup.__webglSkinWeightsBuffer );
  5279. _gl.deleteBuffer( geometryGroup.__webglFaceBuffer );
  5280. _gl.deleteBuffer( geometryGroup.__webglLineBuffer );
  5281. var m, ml;
  5282. if ( geometryGroup.numMorphTargets ) {
  5283. for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
  5284. _gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
  5285. }
  5286. }
  5287. if ( geometryGroup.numMorphNormals ) {
  5288. for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
  5289. _gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
  5290. }
  5291. }
  5292. if ( geometryGroup.__webglCustomAttributesList ) {
  5293. for ( var id in geometryGroup.__webglCustomAttributesList ) {
  5294. _gl.deleteBuffer( geometryGroup.__webglCustomAttributesList[ id ].buffer );
  5295. }
  5296. }
  5297. _this.info.memory.geometries --;
  5298. };
  5299. // Buffer initialization
  5300. function initCustomAttributes ( geometry, object ) {
  5301. var nvertices = geometry.vertices.length;
  5302. var material = object.material;
  5303. if ( material.attributes ) {
  5304. if ( geometry.__webglCustomAttributesList === undefined ) {
  5305. geometry.__webglCustomAttributesList = [];
  5306. }
  5307. for ( var a in material.attributes ) {
  5308. var attribute = material.attributes[ a ];
  5309. if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
  5310. attribute.__webglInitialized = true;
  5311. var size = 1; // "f" and "i"
  5312. if ( attribute.type === "v2" ) size = 2;
  5313. else if ( attribute.type === "v3" ) size = 3;
  5314. else if ( attribute.type === "v4" ) size = 4;
  5315. else if ( attribute.type === "c" ) size = 3;
  5316. attribute.size = size;
  5317. attribute.array = new Float32Array( nvertices * size );
  5318. attribute.buffer = _gl.createBuffer();
  5319. attribute.buffer.belongsToAttribute = a;
  5320. attribute.needsUpdate = true;
  5321. }
  5322. geometry.__webglCustomAttributesList.push( attribute );
  5323. }
  5324. }
  5325. };
  5326. function initParticleBuffers ( geometry, object ) {
  5327. var nvertices = geometry.vertices.length;
  5328. geometry.__vertexArray = new Float32Array( nvertices * 3 );
  5329. geometry.__colorArray = new Float32Array( nvertices * 3 );
  5330. geometry.__sortArray = [];
  5331. geometry.__webglParticleCount = nvertices;
  5332. initCustomAttributes ( geometry, object );
  5333. };
  5334. function initLineBuffers ( geometry, object ) {
  5335. var nvertices = geometry.vertices.length;
  5336. geometry.__vertexArray = new Float32Array( nvertices * 3 );
  5337. geometry.__colorArray = new Float32Array( nvertices * 3 );
  5338. geometry.__webglLineCount = nvertices;
  5339. initCustomAttributes ( geometry, object );
  5340. };
  5341. function initRibbonBuffers ( geometry ) {
  5342. var nvertices = geometry.vertices.length;
  5343. geometry.__vertexArray = new Float32Array( nvertices * 3 );
  5344. geometry.__colorArray = new Float32Array( nvertices * 3 );
  5345. geometry.__webglVertexCount = nvertices;
  5346. };
  5347. function initMeshBuffers ( geometryGroup, object ) {
  5348. var geometry = object.geometry,
  5349. faces3 = geometryGroup.faces3,
  5350. faces4 = geometryGroup.faces4,
  5351. nvertices = faces3.length * 3 + faces4.length * 4,
  5352. ntris = faces3.length * 1 + faces4.length * 2,
  5353. nlines = faces3.length * 3 + faces4.length * 4,
  5354. material = getBufferMaterial( object, geometryGroup ),
  5355. uvType = bufferGuessUVType( material ),
  5356. normalType = bufferGuessNormalType( material ),
  5357. vertexColorType = bufferGuessVertexColorType( material );
  5358. //console.log( "uvType", uvType, "normalType", normalType, "vertexColorType", vertexColorType, object, geometryGroup, material );
  5359. geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
  5360. if ( normalType ) {
  5361. geometryGroup.__normalArray = new Float32Array( nvertices * 3 );
  5362. }
  5363. if ( geometry.hasTangents ) {
  5364. geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
  5365. }
  5366. if ( vertexColorType ) {
  5367. geometryGroup.__colorArray = new Float32Array( nvertices * 3 );
  5368. }
  5369. if ( uvType ) {
  5370. if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
  5371. geometryGroup.__uvArray = new Float32Array( nvertices * 2 );
  5372. }
  5373. if ( geometry.faceUvs.length > 1 || geometry.faceVertexUvs.length > 1 ) {
  5374. geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );
  5375. }
  5376. }
  5377. if ( object.geometry.skinWeights.length && object.geometry.skinIndices.length ) {
  5378. geometryGroup.__skinVertexAArray = new Float32Array( nvertices * 4 );
  5379. geometryGroup.__skinVertexBArray = new Float32Array( nvertices * 4 );
  5380. geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 );
  5381. geometryGroup.__skinWeightArray = new Float32Array( nvertices * 4 );
  5382. }
  5383. geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
  5384. geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
  5385. var m, ml;
  5386. if ( geometryGroup.numMorphTargets ) {
  5387. geometryGroup.__morphTargetsArrays = [];
  5388. for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
  5389. geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );
  5390. }
  5391. }
  5392. if ( geometryGroup.numMorphNormals ) {
  5393. geometryGroup.__morphNormalsArrays = [];
  5394. for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
  5395. geometryGroup.__morphNormalsArrays.push( new Float32Array( nvertices * 3 ) );
  5396. }
  5397. }
  5398. geometryGroup.__webglFaceCount = ntris * 3;
  5399. geometryGroup.__webglLineCount = nlines * 2;
  5400. // custom attributes
  5401. if ( material.attributes ) {
  5402. if ( geometryGroup.__webglCustomAttributesList === undefined ) {
  5403. geometryGroup.__webglCustomAttributesList = [];
  5404. }
  5405. for ( var a in material.attributes ) {
  5406. // Do a shallow copy of the attribute object so different geometryGroup chunks use different
  5407. // attribute buffers which are correctly indexed in the setMeshBuffers function
  5408. var originalAttribute = material.attributes[ a ];
  5409. var attribute = {};
  5410. for ( var property in originalAttribute ) {
  5411. attribute[ property ] = originalAttribute[ property ];
  5412. }
  5413. if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
  5414. attribute.__webglInitialized = true;
  5415. var size = 1; // "f" and "i"
  5416. if( attribute.type === "v2" ) size = 2;
  5417. else if( attribute.type === "v3" ) size = 3;
  5418. else if( attribute.type === "v4" ) size = 4;
  5419. else if( attribute.type === "c" ) size = 3;
  5420. attribute.size = size;
  5421. attribute.array = new Float32Array( nvertices * size );
  5422. attribute.buffer = _gl.createBuffer();
  5423. attribute.buffer.belongsToAttribute = a;
  5424. originalAttribute.needsUpdate = true;
  5425. attribute.__original = originalAttribute;
  5426. }
  5427. geometryGroup.__webglCustomAttributesList.push( attribute );
  5428. }
  5429. }
  5430. geometryGroup.__inittedArrays = true;
  5431. };
  5432. function getBufferMaterial( object, geometryGroup ) {
  5433. if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
  5434. return object.material;
  5435. } else if ( geometryGroup.materialIndex >= 0 ) {
  5436. return object.geometry.materials[ geometryGroup.materialIndex ];
  5437. }
  5438. };
  5439. function materialNeedsSmoothNormals ( material ) {
  5440. return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
  5441. };
  5442. function bufferGuessNormalType ( material ) {
  5443. // only MeshBasicMaterial and MeshDepthMaterial don't need normals
  5444. if ( ( material instanceof THREE.MeshBasicMaterial && !material.envMap ) || material instanceof THREE.MeshDepthMaterial ) {
  5445. return false;
  5446. }
  5447. if ( materialNeedsSmoothNormals( material ) ) {
  5448. return THREE.SmoothShading;
  5449. } else {
  5450. return THREE.FlatShading;
  5451. }
  5452. };
  5453. function bufferGuessVertexColorType ( material ) {
  5454. if ( material.vertexColors ) {
  5455. return material.vertexColors;
  5456. }
  5457. return false;
  5458. };
  5459. function bufferGuessUVType ( material ) {
  5460. // material must use some texture to require uvs
  5461. if ( material.map || material.lightMap || material instanceof THREE.ShaderMaterial ) {
  5462. return true;
  5463. }
  5464. return false;
  5465. };
  5466. // Buffer setting
  5467. function setParticleBuffers ( geometry, hint, object ) {
  5468. var v, c, vertex, offset, index, color,
  5469. vertices = geometry.vertices,
  5470. vl = vertices.length,
  5471. colors = geometry.colors,
  5472. cl = colors.length,
  5473. vertexArray = geometry.__vertexArray,
  5474. colorArray = geometry.__colorArray,
  5475. sortArray = geometry.__sortArray,
  5476. dirtyVertices = geometry.__dirtyVertices,
  5477. dirtyElements = geometry.__dirtyElements,
  5478. dirtyColors = geometry.__dirtyColors,
  5479. customAttributes = geometry.__webglCustomAttributesList,
  5480. i, il,
  5481. a, ca, cal, value,
  5482. customAttribute;
  5483. if ( object.sortParticles ) {
  5484. _projScreenMatrixPS.copy( _projScreenMatrix );
  5485. _projScreenMatrixPS.multiplySelf( object.matrixWorld );
  5486. for ( v = 0; v < vl; v ++ ) {
  5487. vertex = vertices[ v ].position;
  5488. _vector3.copy( vertex );
  5489. _projScreenMatrixPS.multiplyVector3( _vector3 );
  5490. sortArray[ v ] = [ _vector3.z, v ];
  5491. }
  5492. sortArray.sort( function( a, b ) { return b[ 0 ] - a[ 0 ]; } );
  5493. for ( v = 0; v < vl; v ++ ) {
  5494. vertex = vertices[ sortArray[v][1] ].position;
  5495. offset = v * 3;
  5496. vertexArray[ offset ] = vertex.x;
  5497. vertexArray[ offset + 1 ] = vertex.y;
  5498. vertexArray[ offset + 2 ] = vertex.z;
  5499. }
  5500. for ( c = 0; c < cl; c ++ ) {
  5501. offset = c * 3;
  5502. color = colors[ sortArray[c][1] ];
  5503. colorArray[ offset ] = color.r;
  5504. colorArray[ offset + 1 ] = color.g;
  5505. colorArray[ offset + 2 ] = color.b;
  5506. }
  5507. if ( customAttributes ) {
  5508. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  5509. customAttribute = customAttributes[ i ];
  5510. if ( ! ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) ) continue;
  5511. offset = 0;
  5512. cal = customAttribute.value.length;
  5513. if ( customAttribute.size === 1 ) {
  5514. for ( ca = 0; ca < cal; ca ++ ) {
  5515. index = sortArray[ ca ][ 1 ];
  5516. customAttribute.array[ ca ] = customAttribute.value[ index ];
  5517. }
  5518. } else if ( customAttribute.size === 2 ) {
  5519. for ( ca = 0; ca < cal; ca ++ ) {
  5520. index = sortArray[ ca ][ 1 ];
  5521. value = customAttribute.value[ index ];
  5522. customAttribute.array[ offset ] = value.x;
  5523. customAttribute.array[ offset + 1 ] = value.y;
  5524. offset += 2;
  5525. }
  5526. } else if ( customAttribute.size === 3 ) {
  5527. if ( customAttribute.type === "c" ) {
  5528. for ( ca = 0; ca < cal; ca ++ ) {
  5529. index = sortArray[ ca ][ 1 ];
  5530. value = customAttribute.value[ index ];
  5531. customAttribute.array[ offset ] = value.r;
  5532. customAttribute.array[ offset + 1 ] = value.g;
  5533. customAttribute.array[ offset + 2 ] = value.b;
  5534. offset += 3;
  5535. }
  5536. } else {
  5537. for ( ca = 0; ca < cal; ca ++ ) {
  5538. index = sortArray[ ca ][ 1 ];
  5539. value = customAttribute.value[ index ];
  5540. customAttribute.array[ offset ] = value.x;
  5541. customAttribute.array[ offset + 1 ] = value.y;
  5542. customAttribute.array[ offset + 2 ] = value.z;
  5543. offset += 3;
  5544. }
  5545. }
  5546. } else if ( customAttribute.size === 4 ) {
  5547. for ( ca = 0; ca < cal; ca ++ ) {
  5548. index = sortArray[ ca ][ 1 ];
  5549. value = customAttribute.value[ index ];
  5550. customAttribute.array[ offset ] = value.x;
  5551. customAttribute.array[ offset + 1 ] = value.y;
  5552. customAttribute.array[ offset + 2 ] = value.z;
  5553. customAttribute.array[ offset + 3 ] = value.w;
  5554. offset += 4;
  5555. }
  5556. }
  5557. }
  5558. }
  5559. } else {
  5560. if ( dirtyVertices ) {
  5561. for ( v = 0; v < vl; v ++ ) {
  5562. vertex = vertices[ v ].position;
  5563. offset = v * 3;
  5564. vertexArray[ offset ] = vertex.x;
  5565. vertexArray[ offset + 1 ] = vertex.y;
  5566. vertexArray[ offset + 2 ] = vertex.z;
  5567. }
  5568. }
  5569. if ( dirtyColors ) {
  5570. for ( c = 0; c < cl; c ++ ) {
  5571. color = colors[ c ];
  5572. offset = c * 3;
  5573. colorArray[ offset ] = color.r;
  5574. colorArray[ offset + 1 ] = color.g;
  5575. colorArray[ offset + 2 ] = color.b;
  5576. }
  5577. }
  5578. if ( customAttributes ) {
  5579. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  5580. customAttribute = customAttributes[ i ];
  5581. if ( customAttribute.needsUpdate &&
  5582. ( customAttribute.boundTo === undefined ||
  5583. customAttribute.boundTo === "vertices") ) {
  5584. cal = customAttribute.value.length;
  5585. offset = 0;
  5586. if ( customAttribute.size === 1 ) {
  5587. for ( ca = 0; ca < cal; ca ++ ) {
  5588. customAttribute.array[ ca ] = customAttribute.value[ ca ];
  5589. }
  5590. } else if ( customAttribute.size === 2 ) {
  5591. for ( ca = 0; ca < cal; ca ++ ) {
  5592. value = customAttribute.value[ ca ];
  5593. customAttribute.array[ offset ] = value.x;
  5594. customAttribute.array[ offset + 1 ] = value.y;
  5595. offset += 2;
  5596. }
  5597. } else if ( customAttribute.size === 3 ) {
  5598. if ( customAttribute.type === "c" ) {
  5599. for ( ca = 0; ca < cal; ca ++ ) {
  5600. value = customAttribute.value[ ca ];
  5601. customAttribute.array[ offset ] = value.r;
  5602. customAttribute.array[ offset + 1 ] = value.g;
  5603. customAttribute.array[ offset + 2 ] = value.b;
  5604. offset += 3;
  5605. }
  5606. } else {
  5607. for ( ca = 0; ca < cal; ca ++ ) {
  5608. value = customAttribute.value[ ca ];
  5609. customAttribute.array[ offset ] = value.x;
  5610. customAttribute.array[ offset + 1 ] = value.y;
  5611. customAttribute.array[ offset + 2 ] = value.z;
  5612. offset += 3;
  5613. }
  5614. }
  5615. } else if ( customAttribute.size === 4 ) {
  5616. for ( ca = 0; ca < cal; ca ++ ) {
  5617. value = customAttribute.value[ ca ];
  5618. customAttribute.array[ offset ] = value.x;
  5619. customAttribute.array[ offset + 1 ] = value.y;
  5620. customAttribute.array[ offset + 2 ] = value.z;
  5621. customAttribute.array[ offset + 3 ] = value.w;
  5622. offset += 4;
  5623. }
  5624. }
  5625. }
  5626. }
  5627. }
  5628. }
  5629. if ( dirtyVertices || object.sortParticles ) {
  5630. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
  5631. _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
  5632. }
  5633. if ( dirtyColors || object.sortParticles ) {
  5634. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
  5635. _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
  5636. }
  5637. if ( customAttributes ) {
  5638. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  5639. customAttribute = customAttributes[ i ];
  5640. if ( customAttribute.needsUpdate || object.sortParticles ) {
  5641. _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
  5642. _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
  5643. }
  5644. }
  5645. }
  5646. };
  5647. function setLineBuffers ( geometry, hint ) {
  5648. var v, c, vertex, offset, color,
  5649. vertices = geometry.vertices,
  5650. colors = geometry.colors,
  5651. vl = vertices.length,
  5652. cl = colors.length,
  5653. vertexArray = geometry.__vertexArray,
  5654. colorArray = geometry.__colorArray,
  5655. dirtyVertices = geometry.__dirtyVertices,
  5656. dirtyColors = geometry.__dirtyColors,
  5657. customAttributes = geometry.__webglCustomAttributesList,
  5658. i, il,
  5659. a, ca, cal, value,
  5660. customAttribute;
  5661. if ( dirtyVertices ) {
  5662. for ( v = 0; v < vl; v ++ ) {
  5663. vertex = vertices[ v ].position;
  5664. offset = v * 3;
  5665. vertexArray[ offset ] = vertex.x;
  5666. vertexArray[ offset + 1 ] = vertex.y;
  5667. vertexArray[ offset + 2 ] = vertex.z;
  5668. }
  5669. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
  5670. _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
  5671. }
  5672. if ( dirtyColors ) {
  5673. for ( c = 0; c < cl; c ++ ) {
  5674. color = colors[ c ];
  5675. offset = c * 3;
  5676. colorArray[ offset ] = color.r;
  5677. colorArray[ offset + 1 ] = color.g;
  5678. colorArray[ offset + 2 ] = color.b;
  5679. }
  5680. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
  5681. _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
  5682. }
  5683. if ( customAttributes ) {
  5684. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  5685. customAttribute = customAttributes[ i ];
  5686. if ( customAttribute.needsUpdate &&
  5687. ( customAttribute.boundTo === undefined ||
  5688. customAttribute.boundTo === "vertices" ) ) {
  5689. offset = 0;
  5690. cal = customAttribute.value.length;
  5691. if ( customAttribute.size === 1 ) {
  5692. for ( ca = 0; ca < cal; ca ++ ) {
  5693. customAttribute.array[ ca ] = customAttribute.value[ ca ];
  5694. }
  5695. } else if ( customAttribute.size === 2 ) {
  5696. for ( ca = 0; ca < cal; ca ++ ) {
  5697. value = customAttribute.value[ ca ];
  5698. customAttribute.array[ offset ] = value.x;
  5699. customAttribute.array[ offset + 1 ] = value.y;
  5700. offset += 2;
  5701. }
  5702. } else if ( customAttribute.size === 3 ) {
  5703. if ( customAttribute.type === "c" ) {
  5704. for ( ca = 0; ca < cal; ca ++ ) {
  5705. value = customAttribute.value[ ca ];
  5706. customAttribute.array[ offset ] = value.r;
  5707. customAttribute.array[ offset + 1 ] = value.g;
  5708. customAttribute.array[ offset + 2 ] = value.b;
  5709. offset += 3;
  5710. }
  5711. } else {
  5712. for ( ca = 0; ca < cal; ca ++ ) {
  5713. value = customAttribute.value[ ca ];
  5714. customAttribute.array[ offset ] = value.x;
  5715. customAttribute.array[ offset + 1 ] = value.y;
  5716. customAttribute.array[ offset + 2 ] = value.z;
  5717. offset += 3;
  5718. }
  5719. }
  5720. } else if ( customAttribute.size === 4 ) {
  5721. for ( ca = 0; ca < cal; ca ++ ) {
  5722. value = customAttribute.value[ ca ];
  5723. customAttribute.array[ offset ] = value.x;
  5724. customAttribute.array[ offset + 1 ] = value.y;
  5725. customAttribute.array[ offset + 2 ] = value.z;
  5726. customAttribute.array[ offset + 3 ] = value.w;
  5727. offset += 4;
  5728. }
  5729. }
  5730. _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
  5731. _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
  5732. }
  5733. }
  5734. }
  5735. };
  5736. function setRibbonBuffers ( geometry, hint ) {
  5737. var v, c, vertex, offset, color,
  5738. vertices = geometry.vertices,
  5739. colors = geometry.colors,
  5740. vl = vertices.length,
  5741. cl = colors.length,
  5742. vertexArray = geometry.__vertexArray,
  5743. colorArray = geometry.__colorArray,
  5744. dirtyVertices = geometry.__dirtyVertices,
  5745. dirtyColors = geometry.__dirtyColors;
  5746. if ( dirtyVertices ) {
  5747. for ( v = 0; v < vl; v ++ ) {
  5748. vertex = vertices[ v ].position;
  5749. offset = v * 3;
  5750. vertexArray[ offset ] = vertex.x;
  5751. vertexArray[ offset + 1 ] = vertex.y;
  5752. vertexArray[ offset + 2 ] = vertex.z;
  5753. }
  5754. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
  5755. _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
  5756. }
  5757. if ( dirtyColors ) {
  5758. for ( c = 0; c < cl; c ++ ) {
  5759. color = colors[ c ];
  5760. offset = c * 3;
  5761. colorArray[ offset ] = color.r;
  5762. colorArray[ offset + 1 ] = color.g;
  5763. colorArray[ offset + 2 ] = color.b;
  5764. }
  5765. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
  5766. _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
  5767. }
  5768. };
  5769. function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
  5770. if ( ! geometryGroup.__inittedArrays ) {
  5771. // console.log( object );
  5772. return;
  5773. }
  5774. var normalType = bufferGuessNormalType( material ),
  5775. vertexColorType = bufferGuessVertexColorType( material ),
  5776. uvType = bufferGuessUVType( material ),
  5777. needsSmoothNormals = ( normalType === THREE.SmoothShading );
  5778. var f, fl, fi, face,
  5779. vertexNormals, faceNormal, normal,
  5780. vertexColors, faceColor,
  5781. vertexTangents,
  5782. uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4,
  5783. c1, c2, c3, c4,
  5784. sw1, sw2, sw3, sw4,
  5785. si1, si2, si3, si4,
  5786. sa1, sa2, sa3, sa4,
  5787. sb1, sb2, sb3, sb4,
  5788. m, ml, i, il,
  5789. vn, uvi, uv2i,
  5790. vk, vkl, vka,
  5791. nka, chf, faceVertexNormals,
  5792. a,
  5793. vertexIndex = 0,
  5794. offset = 0,
  5795. offset_uv = 0,
  5796. offset_uv2 = 0,
  5797. offset_face = 0,
  5798. offset_normal = 0,
  5799. offset_tangent = 0,
  5800. offset_line = 0,
  5801. offset_color = 0,
  5802. offset_skin = 0,
  5803. offset_morphTarget = 0,
  5804. offset_custom = 0,
  5805. offset_customSrc = 0,
  5806. value,
  5807. vertexArray = geometryGroup.__vertexArray,
  5808. uvArray = geometryGroup.__uvArray,
  5809. uv2Array = geometryGroup.__uv2Array,
  5810. normalArray = geometryGroup.__normalArray,
  5811. tangentArray = geometryGroup.__tangentArray,
  5812. colorArray = geometryGroup.__colorArray,
  5813. skinVertexAArray = geometryGroup.__skinVertexAArray,
  5814. skinVertexBArray = geometryGroup.__skinVertexBArray,
  5815. skinIndexArray = geometryGroup.__skinIndexArray,
  5816. skinWeightArray = geometryGroup.__skinWeightArray,
  5817. morphTargetsArrays = geometryGroup.__morphTargetsArrays,
  5818. morphNormalsArrays = geometryGroup.__morphNormalsArrays,
  5819. customAttributes = geometryGroup.__webglCustomAttributesList,
  5820. customAttribute,
  5821. faceArray = geometryGroup.__faceArray,
  5822. lineArray = geometryGroup.__lineArray,
  5823. geometry = object.geometry, // this is shared for all chunks
  5824. dirtyVertices = geometry.__dirtyVertices,
  5825. dirtyElements = geometry.__dirtyElements,
  5826. dirtyUvs = geometry.__dirtyUvs,
  5827. dirtyNormals = geometry.__dirtyNormals,
  5828. dirtyTangents = geometry.__dirtyTangents,
  5829. dirtyColors = geometry.__dirtyColors,
  5830. dirtyMorphTargets = geometry.__dirtyMorphTargets,
  5831. vertices = geometry.vertices,
  5832. chunk_faces3 = geometryGroup.faces3,
  5833. chunk_faces4 = geometryGroup.faces4,
  5834. obj_faces = geometry.faces,
  5835. obj_uvs = geometry.faceVertexUvs[ 0 ],
  5836. obj_uvs2 = geometry.faceVertexUvs[ 1 ],
  5837. obj_colors = geometry.colors,
  5838. obj_skinVerticesA = geometry.skinVerticesA,
  5839. obj_skinVerticesB = geometry.skinVerticesB,
  5840. obj_skinIndices = geometry.skinIndices,
  5841. obj_skinWeights = geometry.skinWeights,
  5842. morphTargets = geometry.morphTargets,
  5843. morphNormals = geometry.morphNormals;
  5844. if ( dirtyVertices ) {
  5845. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  5846. face = obj_faces[ chunk_faces3[ f ] ];
  5847. v1 = vertices[ face.a ].position;
  5848. v2 = vertices[ face.b ].position;
  5849. v3 = vertices[ face.c ].position;
  5850. vertexArray[ offset ] = v1.x;
  5851. vertexArray[ offset + 1 ] = v1.y;
  5852. vertexArray[ offset + 2 ] = v1.z;
  5853. vertexArray[ offset + 3 ] = v2.x;
  5854. vertexArray[ offset + 4 ] = v2.y;
  5855. vertexArray[ offset + 5 ] = v2.z;
  5856. vertexArray[ offset + 6 ] = v3.x;
  5857. vertexArray[ offset + 7 ] = v3.y;
  5858. vertexArray[ offset + 8 ] = v3.z;
  5859. offset += 9;
  5860. }
  5861. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  5862. face = obj_faces[ chunk_faces4[ f ] ];
  5863. v1 = vertices[ face.a ].position;
  5864. v2 = vertices[ face.b ].position;
  5865. v3 = vertices[ face.c ].position;
  5866. v4 = vertices[ face.d ].position;
  5867. vertexArray[ offset ] = v1.x;
  5868. vertexArray[ offset + 1 ] = v1.y;
  5869. vertexArray[ offset + 2 ] = v1.z;
  5870. vertexArray[ offset + 3 ] = v2.x;
  5871. vertexArray[ offset + 4 ] = v2.y;
  5872. vertexArray[ offset + 5 ] = v2.z;
  5873. vertexArray[ offset + 6 ] = v3.x;
  5874. vertexArray[ offset + 7 ] = v3.y;
  5875. vertexArray[ offset + 8 ] = v3.z;
  5876. vertexArray[ offset + 9 ] = v4.x;
  5877. vertexArray[ offset + 10 ] = v4.y;
  5878. vertexArray[ offset + 11 ] = v4.z;
  5879. offset += 12;
  5880. }
  5881. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
  5882. _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
  5883. }
  5884. if ( dirtyMorphTargets ) {
  5885. for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
  5886. offset_morphTarget = 0;
  5887. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  5888. chf = chunk_faces3[ f ];
  5889. face = obj_faces[ chf ];
  5890. // morph positions
  5891. v1 = morphTargets[ vk ].vertices[ face.a ].position;
  5892. v2 = morphTargets[ vk ].vertices[ face.b ].position;
  5893. v3 = morphTargets[ vk ].vertices[ face.c ].position;
  5894. vka = morphTargetsArrays[ vk ];
  5895. vka[ offset_morphTarget ] = v1.x;
  5896. vka[ offset_morphTarget + 1 ] = v1.y;
  5897. vka[ offset_morphTarget + 2 ] = v1.z;
  5898. vka[ offset_morphTarget + 3 ] = v2.x;
  5899. vka[ offset_morphTarget + 4 ] = v2.y;
  5900. vka[ offset_morphTarget + 5 ] = v2.z;
  5901. vka[ offset_morphTarget + 6 ] = v3.x;
  5902. vka[ offset_morphTarget + 7 ] = v3.y;
  5903. vka[ offset_morphTarget + 8 ] = v3.z;
  5904. // morph normals
  5905. if ( material.morphNormals ) {
  5906. if ( needsSmoothNormals ) {
  5907. faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ];
  5908. n1 = faceVertexNormals.a;
  5909. n2 = faceVertexNormals.b;
  5910. n3 = faceVertexNormals.c;
  5911. } else {
  5912. n1 = morphNormals[ vk ].faceNormals[ chf ];
  5913. n2 = n1;
  5914. n3 = n1;
  5915. }
  5916. nka = morphNormalsArrays[ vk ];
  5917. nka[ offset_morphTarget ] = n1.x;
  5918. nka[ offset_morphTarget + 1 ] = n1.y;
  5919. nka[ offset_morphTarget + 2 ] = n1.z;
  5920. nka[ offset_morphTarget + 3 ] = n2.x;
  5921. nka[ offset_morphTarget + 4 ] = n2.y;
  5922. nka[ offset_morphTarget + 5 ] = n2.z;
  5923. nka[ offset_morphTarget + 6 ] = n3.x;
  5924. nka[ offset_morphTarget + 7 ] = n3.y;
  5925. nka[ offset_morphTarget + 8 ] = n3.z;
  5926. }
  5927. //
  5928. offset_morphTarget += 9;
  5929. }
  5930. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  5931. chf = chunk_faces4[ f ];
  5932. face = obj_faces[ chf ];
  5933. // morph positions
  5934. v1 = morphTargets[ vk ].vertices[ face.a ].position;
  5935. v2 = morphTargets[ vk ].vertices[ face.b ].position;
  5936. v3 = morphTargets[ vk ].vertices[ face.c ].position;
  5937. v4 = morphTargets[ vk ].vertices[ face.d ].position;
  5938. vka = morphTargetsArrays[ vk ];
  5939. vka[ offset_morphTarget ] = v1.x;
  5940. vka[ offset_morphTarget + 1 ] = v1.y;
  5941. vka[ offset_morphTarget + 2 ] = v1.z;
  5942. vka[ offset_morphTarget + 3 ] = v2.x;
  5943. vka[ offset_morphTarget + 4 ] = v2.y;
  5944. vka[ offset_morphTarget + 5 ] = v2.z;
  5945. vka[ offset_morphTarget + 6 ] = v3.x;
  5946. vka[ offset_morphTarget + 7 ] = v3.y;
  5947. vka[ offset_morphTarget + 8 ] = v3.z;
  5948. vka[ offset_morphTarget + 9 ] = v4.x;
  5949. vka[ offset_morphTarget + 10 ] = v4.y;
  5950. vka[ offset_morphTarget + 11 ] = v4.z;
  5951. // morph normals
  5952. if ( material.morphNormals ) {
  5953. if ( needsSmoothNormals ) {
  5954. faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ];
  5955. n1 = faceVertexNormals.a;
  5956. n2 = faceVertexNormals.b;
  5957. n3 = faceVertexNormals.c;
  5958. n4 = faceVertexNormals.d;
  5959. } else {
  5960. n1 = morphNormals[ vk ].faceNormals[ chf ];
  5961. n2 = n1;
  5962. n3 = n1;
  5963. n4 = n1;
  5964. }
  5965. nka = morphNormalsArrays[ vk ];
  5966. nka[ offset_morphTarget ] = n1.x;
  5967. nka[ offset_morphTarget + 1 ] = n1.y;
  5968. nka[ offset_morphTarget + 2 ] = n1.z;
  5969. nka[ offset_morphTarget + 3 ] = n2.x;
  5970. nka[ offset_morphTarget + 4 ] = n2.y;
  5971. nka[ offset_morphTarget + 5 ] = n2.z;
  5972. nka[ offset_morphTarget + 6 ] = n3.x;
  5973. nka[ offset_morphTarget + 7 ] = n3.y;
  5974. nka[ offset_morphTarget + 8 ] = n3.z;
  5975. nka[ offset_morphTarget + 9 ] = n4.x;
  5976. nka[ offset_morphTarget + 10 ] = n4.y;
  5977. nka[ offset_morphTarget + 11 ] = n4.z;
  5978. }
  5979. //
  5980. offset_morphTarget += 12;
  5981. }
  5982. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ vk ] );
  5983. _gl.bufferData( _gl.ARRAY_BUFFER, morphTargetsArrays[ vk ], hint );
  5984. if ( material.morphNormals ) {
  5985. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ vk ] );
  5986. _gl.bufferData( _gl.ARRAY_BUFFER, morphNormalsArrays[ vk ], hint );
  5987. }
  5988. }
  5989. }
  5990. if ( obj_skinWeights.length ) {
  5991. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  5992. face = obj_faces[ chunk_faces3[ f ] ];
  5993. // weights
  5994. sw1 = obj_skinWeights[ face.a ];
  5995. sw2 = obj_skinWeights[ face.b ];
  5996. sw3 = obj_skinWeights[ face.c ];
  5997. skinWeightArray[ offset_skin ] = sw1.x;
  5998. skinWeightArray[ offset_skin + 1 ] = sw1.y;
  5999. skinWeightArray[ offset_skin + 2 ] = sw1.z;
  6000. skinWeightArray[ offset_skin + 3 ] = sw1.w;
  6001. skinWeightArray[ offset_skin + 4 ] = sw2.x;
  6002. skinWeightArray[ offset_skin + 5 ] = sw2.y;
  6003. skinWeightArray[ offset_skin + 6 ] = sw2.z;
  6004. skinWeightArray[ offset_skin + 7 ] = sw2.w;
  6005. skinWeightArray[ offset_skin + 8 ] = sw3.x;
  6006. skinWeightArray[ offset_skin + 9 ] = sw3.y;
  6007. skinWeightArray[ offset_skin + 10 ] = sw3.z;
  6008. skinWeightArray[ offset_skin + 11 ] = sw3.w;
  6009. // indices
  6010. si1 = obj_skinIndices[ face.a ];
  6011. si2 = obj_skinIndices[ face.b ];
  6012. si3 = obj_skinIndices[ face.c ];
  6013. skinIndexArray[ offset_skin ] = si1.x;
  6014. skinIndexArray[ offset_skin + 1 ] = si1.y;
  6015. skinIndexArray[ offset_skin + 2 ] = si1.z;
  6016. skinIndexArray[ offset_skin + 3 ] = si1.w;
  6017. skinIndexArray[ offset_skin + 4 ] = si2.x;
  6018. skinIndexArray[ offset_skin + 5 ] = si2.y;
  6019. skinIndexArray[ offset_skin + 6 ] = si2.z;
  6020. skinIndexArray[ offset_skin + 7 ] = si2.w;
  6021. skinIndexArray[ offset_skin + 8 ] = si3.x;
  6022. skinIndexArray[ offset_skin + 9 ] = si3.y;
  6023. skinIndexArray[ offset_skin + 10 ] = si3.z;
  6024. skinIndexArray[ offset_skin + 11 ] = si3.w;
  6025. // vertices A
  6026. sa1 = obj_skinVerticesA[ face.a ];
  6027. sa2 = obj_skinVerticesA[ face.b ];
  6028. sa3 = obj_skinVerticesA[ face.c ];
  6029. skinVertexAArray[ offset_skin ] = sa1.x;
  6030. skinVertexAArray[ offset_skin + 1 ] = sa1.y;
  6031. skinVertexAArray[ offset_skin + 2 ] = sa1.z;
  6032. skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
  6033. skinVertexAArray[ offset_skin + 4 ] = sa2.x;
  6034. skinVertexAArray[ offset_skin + 5 ] = sa2.y;
  6035. skinVertexAArray[ offset_skin + 6 ] = sa2.z;
  6036. skinVertexAArray[ offset_skin + 7 ] = 1;
  6037. skinVertexAArray[ offset_skin + 8 ] = sa3.x;
  6038. skinVertexAArray[ offset_skin + 9 ] = sa3.y;
  6039. skinVertexAArray[ offset_skin + 10 ] = sa3.z;
  6040. skinVertexAArray[ offset_skin + 11 ] = 1;
  6041. // vertices B
  6042. sb1 = obj_skinVerticesB[ face.a ];
  6043. sb2 = obj_skinVerticesB[ face.b ];
  6044. sb3 = obj_skinVerticesB[ face.c ];
  6045. skinVertexBArray[ offset_skin ] = sb1.x;
  6046. skinVertexBArray[ offset_skin + 1 ] = sb1.y;
  6047. skinVertexBArray[ offset_skin + 2 ] = sb1.z;
  6048. skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
  6049. skinVertexBArray[ offset_skin + 4 ] = sb2.x;
  6050. skinVertexBArray[ offset_skin + 5 ] = sb2.y;
  6051. skinVertexBArray[ offset_skin + 6 ] = sb2.z;
  6052. skinVertexBArray[ offset_skin + 7 ] = 1;
  6053. skinVertexBArray[ offset_skin + 8 ] = sb3.x;
  6054. skinVertexBArray[ offset_skin + 9 ] = sb3.y;
  6055. skinVertexBArray[ offset_skin + 10 ] = sb3.z;
  6056. skinVertexBArray[ offset_skin + 11 ] = 1;
  6057. offset_skin += 12;
  6058. }
  6059. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6060. face = obj_faces[ chunk_faces4[ f ] ];
  6061. // weights
  6062. sw1 = obj_skinWeights[ face.a ];
  6063. sw2 = obj_skinWeights[ face.b ];
  6064. sw3 = obj_skinWeights[ face.c ];
  6065. sw4 = obj_skinWeights[ face.d ];
  6066. skinWeightArray[ offset_skin ] = sw1.x;
  6067. skinWeightArray[ offset_skin + 1 ] = sw1.y;
  6068. skinWeightArray[ offset_skin + 2 ] = sw1.z;
  6069. skinWeightArray[ offset_skin + 3 ] = sw1.w;
  6070. skinWeightArray[ offset_skin + 4 ] = sw2.x;
  6071. skinWeightArray[ offset_skin + 5 ] = sw2.y;
  6072. skinWeightArray[ offset_skin + 6 ] = sw2.z;
  6073. skinWeightArray[ offset_skin + 7 ] = sw2.w;
  6074. skinWeightArray[ offset_skin + 8 ] = sw3.x;
  6075. skinWeightArray[ offset_skin + 9 ] = sw3.y;
  6076. skinWeightArray[ offset_skin + 10 ] = sw3.z;
  6077. skinWeightArray[ offset_skin + 11 ] = sw3.w;
  6078. skinWeightArray[ offset_skin + 12 ] = sw4.x;
  6079. skinWeightArray[ offset_skin + 13 ] = sw4.y;
  6080. skinWeightArray[ offset_skin + 14 ] = sw4.z;
  6081. skinWeightArray[ offset_skin + 15 ] = sw4.w;
  6082. // indices
  6083. si1 = obj_skinIndices[ face.a ];
  6084. si2 = obj_skinIndices[ face.b ];
  6085. si3 = obj_skinIndices[ face.c ];
  6086. si4 = obj_skinIndices[ face.d ];
  6087. skinIndexArray[ offset_skin ] = si1.x;
  6088. skinIndexArray[ offset_skin + 1 ] = si1.y;
  6089. skinIndexArray[ offset_skin + 2 ] = si1.z;
  6090. skinIndexArray[ offset_skin + 3 ] = si1.w;
  6091. skinIndexArray[ offset_skin + 4 ] = si2.x;
  6092. skinIndexArray[ offset_skin + 5 ] = si2.y;
  6093. skinIndexArray[ offset_skin + 6 ] = si2.z;
  6094. skinIndexArray[ offset_skin + 7 ] = si2.w;
  6095. skinIndexArray[ offset_skin + 8 ] = si3.x;
  6096. skinIndexArray[ offset_skin + 9 ] = si3.y;
  6097. skinIndexArray[ offset_skin + 10 ] = si3.z;
  6098. skinIndexArray[ offset_skin + 11 ] = si3.w;
  6099. skinIndexArray[ offset_skin + 12 ] = si4.x;
  6100. skinIndexArray[ offset_skin + 13 ] = si4.y;
  6101. skinIndexArray[ offset_skin + 14 ] = si4.z;
  6102. skinIndexArray[ offset_skin + 15 ] = si4.w;
  6103. // vertices A
  6104. sa1 = obj_skinVerticesA[ face.a ];
  6105. sa2 = obj_skinVerticesA[ face.b ];
  6106. sa3 = obj_skinVerticesA[ face.c ];
  6107. sa4 = obj_skinVerticesA[ face.d ];
  6108. skinVertexAArray[ offset_skin ] = sa1.x;
  6109. skinVertexAArray[ offset_skin + 1 ] = sa1.y;
  6110. skinVertexAArray[ offset_skin + 2 ] = sa1.z;
  6111. skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
  6112. skinVertexAArray[ offset_skin + 4 ] = sa2.x;
  6113. skinVertexAArray[ offset_skin + 5 ] = sa2.y;
  6114. skinVertexAArray[ offset_skin + 6 ] = sa2.z;
  6115. skinVertexAArray[ offset_skin + 7 ] = 1;
  6116. skinVertexAArray[ offset_skin + 8 ] = sa3.x;
  6117. skinVertexAArray[ offset_skin + 9 ] = sa3.y;
  6118. skinVertexAArray[ offset_skin + 10 ] = sa3.z;
  6119. skinVertexAArray[ offset_skin + 11 ] = 1;
  6120. skinVertexAArray[ offset_skin + 12 ] = sa4.x;
  6121. skinVertexAArray[ offset_skin + 13 ] = sa4.y;
  6122. skinVertexAArray[ offset_skin + 14 ] = sa4.z;
  6123. skinVertexAArray[ offset_skin + 15 ] = 1;
  6124. // vertices B
  6125. sb1 = obj_skinVerticesB[ face.a ];
  6126. sb2 = obj_skinVerticesB[ face.b ];
  6127. sb3 = obj_skinVerticesB[ face.c ];
  6128. sb4 = obj_skinVerticesB[ face.d ];
  6129. skinVertexBArray[ offset_skin ] = sb1.x;
  6130. skinVertexBArray[ offset_skin + 1 ] = sb1.y;
  6131. skinVertexBArray[ offset_skin + 2 ] = sb1.z;
  6132. skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
  6133. skinVertexBArray[ offset_skin + 4 ] = sb2.x;
  6134. skinVertexBArray[ offset_skin + 5 ] = sb2.y;
  6135. skinVertexBArray[ offset_skin + 6 ] = sb2.z;
  6136. skinVertexBArray[ offset_skin + 7 ] = 1;
  6137. skinVertexBArray[ offset_skin + 8 ] = sb3.x;
  6138. skinVertexBArray[ offset_skin + 9 ] = sb3.y;
  6139. skinVertexBArray[ offset_skin + 10 ] = sb3.z;
  6140. skinVertexBArray[ offset_skin + 11 ] = 1;
  6141. skinVertexBArray[ offset_skin + 12 ] = sb4.x;
  6142. skinVertexBArray[ offset_skin + 13 ] = sb4.y;
  6143. skinVertexBArray[ offset_skin + 14 ] = sb4.z;
  6144. skinVertexBArray[ offset_skin + 15 ] = 1;
  6145. offset_skin += 16;
  6146. }
  6147. if ( offset_skin > 0 ) {
  6148. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
  6149. _gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );
  6150. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
  6151. _gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );
  6152. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
  6153. _gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );
  6154. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
  6155. _gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
  6156. }
  6157. }
  6158. if ( dirtyColors && vertexColorType ) {
  6159. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  6160. face = obj_faces[ chunk_faces3[ f ] ];
  6161. vertexColors = face.vertexColors;
  6162. faceColor = face.color;
  6163. if ( vertexColors.length === 3 && vertexColorType === THREE.VertexColors ) {
  6164. c1 = vertexColors[ 0 ];
  6165. c2 = vertexColors[ 1 ];
  6166. c3 = vertexColors[ 2 ];
  6167. } else {
  6168. c1 = faceColor;
  6169. c2 = faceColor;
  6170. c3 = faceColor;
  6171. }
  6172. colorArray[ offset_color ] = c1.r;
  6173. colorArray[ offset_color + 1 ] = c1.g;
  6174. colorArray[ offset_color + 2 ] = c1.b;
  6175. colorArray[ offset_color + 3 ] = c2.r;
  6176. colorArray[ offset_color + 4 ] = c2.g;
  6177. colorArray[ offset_color + 5 ] = c2.b;
  6178. colorArray[ offset_color + 6 ] = c3.r;
  6179. colorArray[ offset_color + 7 ] = c3.g;
  6180. colorArray[ offset_color + 8 ] = c3.b;
  6181. offset_color += 9;
  6182. }
  6183. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6184. face = obj_faces[ chunk_faces4[ f ] ];
  6185. vertexColors = face.vertexColors;
  6186. faceColor = face.color;
  6187. if ( vertexColors.length === 4 && vertexColorType === THREE.VertexColors ) {
  6188. c1 = vertexColors[ 0 ];
  6189. c2 = vertexColors[ 1 ];
  6190. c3 = vertexColors[ 2 ];
  6191. c4 = vertexColors[ 3 ];
  6192. } else {
  6193. c1 = faceColor;
  6194. c2 = faceColor;
  6195. c3 = faceColor;
  6196. c4 = faceColor;
  6197. }
  6198. colorArray[ offset_color ] = c1.r;
  6199. colorArray[ offset_color + 1 ] = c1.g;
  6200. colorArray[ offset_color + 2 ] = c1.b;
  6201. colorArray[ offset_color + 3 ] = c2.r;
  6202. colorArray[ offset_color + 4 ] = c2.g;
  6203. colorArray[ offset_color + 5 ] = c2.b;
  6204. colorArray[ offset_color + 6 ] = c3.r;
  6205. colorArray[ offset_color + 7 ] = c3.g;
  6206. colorArray[ offset_color + 8 ] = c3.b;
  6207. colorArray[ offset_color + 9 ] = c4.r;
  6208. colorArray[ offset_color + 10 ] = c4.g;
  6209. colorArray[ offset_color + 11 ] = c4.b;
  6210. offset_color += 12;
  6211. }
  6212. if ( offset_color > 0 ) {
  6213. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
  6214. _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
  6215. }
  6216. }
  6217. if ( dirtyTangents && geometry.hasTangents ) {
  6218. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  6219. face = obj_faces[ chunk_faces3[ f ] ];
  6220. vertexTangents = face.vertexTangents;
  6221. t1 = vertexTangents[ 0 ];
  6222. t2 = vertexTangents[ 1 ];
  6223. t3 = vertexTangents[ 2 ];
  6224. tangentArray[ offset_tangent ] = t1.x;
  6225. tangentArray[ offset_tangent + 1 ] = t1.y;
  6226. tangentArray[ offset_tangent + 2 ] = t1.z;
  6227. tangentArray[ offset_tangent + 3 ] = t1.w;
  6228. tangentArray[ offset_tangent + 4 ] = t2.x;
  6229. tangentArray[ offset_tangent + 5 ] = t2.y;
  6230. tangentArray[ offset_tangent + 6 ] = t2.z;
  6231. tangentArray[ offset_tangent + 7 ] = t2.w;
  6232. tangentArray[ offset_tangent + 8 ] = t3.x;
  6233. tangentArray[ offset_tangent + 9 ] = t3.y;
  6234. tangentArray[ offset_tangent + 10 ] = t3.z;
  6235. tangentArray[ offset_tangent + 11 ] = t3.w;
  6236. offset_tangent += 12;
  6237. }
  6238. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6239. face = obj_faces[ chunk_faces4[ f ] ];
  6240. vertexTangents = face.vertexTangents;
  6241. t1 = vertexTangents[ 0 ];
  6242. t2 = vertexTangents[ 1 ];
  6243. t3 = vertexTangents[ 2 ];
  6244. t4 = vertexTangents[ 3 ];
  6245. tangentArray[ offset_tangent ] = t1.x;
  6246. tangentArray[ offset_tangent + 1 ] = t1.y;
  6247. tangentArray[ offset_tangent + 2 ] = t1.z;
  6248. tangentArray[ offset_tangent + 3 ] = t1.w;
  6249. tangentArray[ offset_tangent + 4 ] = t2.x;
  6250. tangentArray[ offset_tangent + 5 ] = t2.y;
  6251. tangentArray[ offset_tangent + 6 ] = t2.z;
  6252. tangentArray[ offset_tangent + 7 ] = t2.w;
  6253. tangentArray[ offset_tangent + 8 ] = t3.x;
  6254. tangentArray[ offset_tangent + 9 ] = t3.y;
  6255. tangentArray[ offset_tangent + 10 ] = t3.z;
  6256. tangentArray[ offset_tangent + 11 ] = t3.w;
  6257. tangentArray[ offset_tangent + 12 ] = t4.x;
  6258. tangentArray[ offset_tangent + 13 ] = t4.y;
  6259. tangentArray[ offset_tangent + 14 ] = t4.z;
  6260. tangentArray[ offset_tangent + 15 ] = t4.w;
  6261. offset_tangent += 16;
  6262. }
  6263. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
  6264. _gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
  6265. }
  6266. if ( dirtyNormals && normalType ) {
  6267. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  6268. face = obj_faces[ chunk_faces3[ f ] ];
  6269. vertexNormals = face.vertexNormals;
  6270. faceNormal = face.normal;
  6271. if ( vertexNormals.length === 3 && needsSmoothNormals ) {
  6272. for ( i = 0; i < 3; i ++ ) {
  6273. vn = vertexNormals[ i ];
  6274. normalArray[ offset_normal ] = vn.x;
  6275. normalArray[ offset_normal + 1 ] = vn.y;
  6276. normalArray[ offset_normal + 2 ] = vn.z;
  6277. offset_normal += 3;
  6278. }
  6279. } else {
  6280. for ( i = 0; i < 3; i ++ ) {
  6281. normalArray[ offset_normal ] = faceNormal.x;
  6282. normalArray[ offset_normal + 1 ] = faceNormal.y;
  6283. normalArray[ offset_normal + 2 ] = faceNormal.z;
  6284. offset_normal += 3;
  6285. }
  6286. }
  6287. }
  6288. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6289. face = obj_faces[ chunk_faces4[ f ] ];
  6290. vertexNormals = face.vertexNormals;
  6291. faceNormal = face.normal;
  6292. if ( vertexNormals.length === 4 && needsSmoothNormals ) {
  6293. for ( i = 0; i < 4; i ++ ) {
  6294. vn = vertexNormals[ i ];
  6295. normalArray[ offset_normal ] = vn.x;
  6296. normalArray[ offset_normal + 1 ] = vn.y;
  6297. normalArray[ offset_normal + 2 ] = vn.z;
  6298. offset_normal += 3;
  6299. }
  6300. } else {
  6301. for ( i = 0; i < 4; i ++ ) {
  6302. normalArray[ offset_normal ] = faceNormal.x;
  6303. normalArray[ offset_normal + 1 ] = faceNormal.y;
  6304. normalArray[ offset_normal + 2 ] = faceNormal.z;
  6305. offset_normal += 3;
  6306. }
  6307. }
  6308. }
  6309. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
  6310. _gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
  6311. }
  6312. if ( dirtyUvs && obj_uvs && uvType ) {
  6313. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  6314. fi = chunk_faces3[ f ];
  6315. face = obj_faces[ fi ];
  6316. uv = obj_uvs[ fi ];
  6317. if ( uv === undefined ) continue;
  6318. for ( i = 0; i < 3; i ++ ) {
  6319. uvi = uv[ i ];
  6320. uvArray[ offset_uv ] = uvi.u;
  6321. uvArray[ offset_uv + 1 ] = uvi.v;
  6322. offset_uv += 2;
  6323. }
  6324. }
  6325. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6326. fi = chunk_faces4[ f ];
  6327. face = obj_faces[ fi ];
  6328. uv = obj_uvs[ fi ];
  6329. if ( uv === undefined ) continue;
  6330. for ( i = 0; i < 4; i ++ ) {
  6331. uvi = uv[ i ];
  6332. uvArray[ offset_uv ] = uvi.u;
  6333. uvArray[ offset_uv + 1 ] = uvi.v;
  6334. offset_uv += 2;
  6335. }
  6336. }
  6337. if ( offset_uv > 0 ) {
  6338. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
  6339. _gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
  6340. }
  6341. }
  6342. if ( dirtyUvs && obj_uvs2 && uvType ) {
  6343. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  6344. fi = chunk_faces3[ f ];
  6345. face = obj_faces[ fi ];
  6346. uv2 = obj_uvs2[ fi ];
  6347. if ( uv2 === undefined ) continue;
  6348. for ( i = 0; i < 3; i ++ ) {
  6349. uv2i = uv2[ i ];
  6350. uv2Array[ offset_uv2 ] = uv2i.u;
  6351. uv2Array[ offset_uv2 + 1 ] = uv2i.v;
  6352. offset_uv2 += 2;
  6353. }
  6354. }
  6355. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6356. fi = chunk_faces4[ f ];
  6357. face = obj_faces[ fi ];
  6358. uv2 = obj_uvs2[ fi ];
  6359. if ( uv2 === undefined ) continue;
  6360. for ( i = 0; i < 4; i ++ ) {
  6361. uv2i = uv2[ i ];
  6362. uv2Array[ offset_uv2 ] = uv2i.u;
  6363. uv2Array[ offset_uv2 + 1 ] = uv2i.v;
  6364. offset_uv2 += 2;
  6365. }
  6366. }
  6367. if ( offset_uv2 > 0 ) {
  6368. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
  6369. _gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
  6370. }
  6371. }
  6372. if ( dirtyElements ) {
  6373. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  6374. face = obj_faces[ chunk_faces3[ f ] ];
  6375. faceArray[ offset_face ] = vertexIndex;
  6376. faceArray[ offset_face + 1 ] = vertexIndex + 1;
  6377. faceArray[ offset_face + 2 ] = vertexIndex + 2;
  6378. offset_face += 3;
  6379. lineArray[ offset_line ] = vertexIndex;
  6380. lineArray[ offset_line + 1 ] = vertexIndex + 1;
  6381. lineArray[ offset_line + 2 ] = vertexIndex;
  6382. lineArray[ offset_line + 3 ] = vertexIndex + 2;
  6383. lineArray[ offset_line + 4 ] = vertexIndex + 1;
  6384. lineArray[ offset_line + 5 ] = vertexIndex + 2;
  6385. offset_line += 6;
  6386. vertexIndex += 3;
  6387. }
  6388. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6389. face = obj_faces[ chunk_faces4[ f ] ];
  6390. faceArray[ offset_face ] = vertexIndex;
  6391. faceArray[ offset_face + 1 ] = vertexIndex + 1;
  6392. faceArray[ offset_face + 2 ] = vertexIndex + 3;
  6393. faceArray[ offset_face + 3 ] = vertexIndex + 1;
  6394. faceArray[ offset_face + 4 ] = vertexIndex + 2;
  6395. faceArray[ offset_face + 5 ] = vertexIndex + 3;
  6396. offset_face += 6;
  6397. lineArray[ offset_line ] = vertexIndex;
  6398. lineArray[ offset_line + 1 ] = vertexIndex + 1;
  6399. lineArray[ offset_line + 2 ] = vertexIndex;
  6400. lineArray[ offset_line + 3 ] = vertexIndex + 3;
  6401. lineArray[ offset_line + 4 ] = vertexIndex + 1;
  6402. lineArray[ offset_line + 5 ] = vertexIndex + 2;
  6403. lineArray[ offset_line + 6 ] = vertexIndex + 2;
  6404. lineArray[ offset_line + 7 ] = vertexIndex + 3;
  6405. offset_line += 8;
  6406. vertexIndex += 4;
  6407. }
  6408. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
  6409. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
  6410. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
  6411. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
  6412. }
  6413. if ( customAttributes ) {
  6414. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  6415. customAttribute = customAttributes[ i ];
  6416. if ( ! customAttribute.__original.needsUpdate ) continue;
  6417. offset_custom = 0;
  6418. offset_customSrc = 0;
  6419. if ( customAttribute.size === 1 ) {
  6420. if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
  6421. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  6422. face = obj_faces[ chunk_faces3[ f ] ];
  6423. customAttribute.array[ offset_custom ] = customAttribute.value[ face.a ];
  6424. customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
  6425. customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
  6426. offset_custom += 3;
  6427. }
  6428. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6429. face = obj_faces[ chunk_faces4[ f ] ];
  6430. customAttribute.array[ offset_custom ] = customAttribute.value[ face.a ];
  6431. customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
  6432. customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
  6433. customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ face.d ];
  6434. offset_custom += 4;
  6435. }
  6436. } else if ( customAttribute.boundTo === "faces" ) {
  6437. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  6438. value = customAttribute.value[ chunk_faces3[ f ] ];
  6439. customAttribute.array[ offset_custom ] = value;
  6440. customAttribute.array[ offset_custom + 1 ] = value;
  6441. customAttribute.array[ offset_custom + 2 ] = value;
  6442. offset_custom += 3;
  6443. }
  6444. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6445. value = customAttribute.value[ chunk_faces4[ f ] ];
  6446. customAttribute.array[ offset_custom ] = value;
  6447. customAttribute.array[ offset_custom + 1 ] = value;
  6448. customAttribute.array[ offset_custom + 2 ] = value;
  6449. customAttribute.array[ offset_custom + 3 ] = value;
  6450. offset_custom += 4;
  6451. }
  6452. }
  6453. } else if ( customAttribute.size === 2 ) {
  6454. if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
  6455. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  6456. face = obj_faces[ chunk_faces3[ f ] ];
  6457. v1 = customAttribute.value[ face.a ];
  6458. v2 = customAttribute.value[ face.b ];
  6459. v3 = customAttribute.value[ face.c ];
  6460. customAttribute.array[ offset_custom ] = v1.x;
  6461. customAttribute.array[ offset_custom + 1 ] = v1.y;
  6462. customAttribute.array[ offset_custom + 2 ] = v2.x;
  6463. customAttribute.array[ offset_custom + 3 ] = v2.y;
  6464. customAttribute.array[ offset_custom + 4 ] = v3.x;
  6465. customAttribute.array[ offset_custom + 5 ] = v3.y;
  6466. offset_custom += 6;
  6467. }
  6468. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6469. face = obj_faces[ chunk_faces4[ f ] ];
  6470. v1 = customAttribute.value[ face.a ];
  6471. v2 = customAttribute.value[ face.b ];
  6472. v3 = customAttribute.value[ face.c ];
  6473. v4 = customAttribute.value[ face.d ];
  6474. customAttribute.array[ offset_custom ] = v1.x;
  6475. customAttribute.array[ offset_custom + 1 ] = v1.y;
  6476. customAttribute.array[ offset_custom + 2 ] = v2.x;
  6477. customAttribute.array[ offset_custom + 3 ] = v2.y;
  6478. customAttribute.array[ offset_custom + 4 ] = v3.x;
  6479. customAttribute.array[ offset_custom + 5 ] = v3.y;
  6480. customAttribute.array[ offset_custom + 6 ] = v4.x;
  6481. customAttribute.array[ offset_custom + 7 ] = v4.y;
  6482. offset_custom += 8;
  6483. }
  6484. } else if ( customAttribute.boundTo === "faces" ) {
  6485. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  6486. value = customAttribute.value[ chunk_faces3[ f ] ];
  6487. v1 = value;
  6488. v2 = value;
  6489. v3 = value;
  6490. customAttribute.array[ offset_custom ] = v1.x;
  6491. customAttribute.array[ offset_custom + 1 ] = v1.y;
  6492. customAttribute.array[ offset_custom + 2 ] = v2.x;
  6493. customAttribute.array[ offset_custom + 3 ] = v2.y;
  6494. customAttribute.array[ offset_custom + 4 ] = v3.x;
  6495. customAttribute.array[ offset_custom + 5 ] = v3.y;
  6496. offset_custom += 6;
  6497. }
  6498. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6499. value = customAttribute.value[ chunk_faces4[ f ] ];
  6500. v1 = value;
  6501. v2 = value;
  6502. v3 = value;
  6503. v4 = value;
  6504. customAttribute.array[ offset_custom ] = v1.x;
  6505. customAttribute.array[ offset_custom + 1 ] = v1.y;
  6506. customAttribute.array[ offset_custom + 2 ] = v2.x;
  6507. customAttribute.array[ offset_custom + 3 ] = v2.y;
  6508. customAttribute.array[ offset_custom + 4 ] = v3.x;
  6509. customAttribute.array[ offset_custom + 5 ] = v3.y;
  6510. customAttribute.array[ offset_custom + 6 ] = v4.x;
  6511. customAttribute.array[ offset_custom + 7 ] = v4.y;
  6512. offset_custom += 8;
  6513. }
  6514. }
  6515. } else if ( customAttribute.size === 3 ) {
  6516. var pp;
  6517. if ( customAttribute.type === "c" ) {
  6518. pp = [ "r", "g", "b" ];
  6519. } else {
  6520. pp = [ "x", "y", "z" ];
  6521. }
  6522. if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
  6523. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  6524. face = obj_faces[ chunk_faces3[ f ] ];
  6525. v1 = customAttribute.value[ face.a ];
  6526. v2 = customAttribute.value[ face.b ];
  6527. v3 = customAttribute.value[ face.c ];
  6528. customAttribute.array[ offset_custom ] = v1[ pp[ 0 ] ];
  6529. customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
  6530. customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
  6531. customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
  6532. customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
  6533. customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
  6534. customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
  6535. customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
  6536. customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
  6537. offset_custom += 9;
  6538. }
  6539. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6540. face = obj_faces[ chunk_faces4[ f ] ];
  6541. v1 = customAttribute.value[ face.a ];
  6542. v2 = customAttribute.value[ face.b ];
  6543. v3 = customAttribute.value[ face.c ];
  6544. v4 = customAttribute.value[ face.d ];
  6545. customAttribute.array[ offset_custom ] = v1[ pp[ 0 ] ];
  6546. customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
  6547. customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
  6548. customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
  6549. customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
  6550. customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
  6551. customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
  6552. customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
  6553. customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
  6554. customAttribute.array[ offset_custom + 9 ] = v4[ pp[ 0 ] ];
  6555. customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
  6556. customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
  6557. offset_custom += 12;
  6558. }
  6559. } else if ( customAttribute.boundTo === "faces" ) {
  6560. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  6561. value = customAttribute.value[ chunk_faces3[ f ] ];
  6562. v1 = value;
  6563. v2 = value;
  6564. v3 = value;
  6565. customAttribute.array[ offset_custom ] = v1[ pp[ 0 ] ];
  6566. customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
  6567. customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
  6568. customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
  6569. customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
  6570. customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
  6571. customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
  6572. customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
  6573. customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
  6574. offset_custom += 9;
  6575. }
  6576. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6577. value = customAttribute.value[ chunk_faces4[ f ] ];
  6578. v1 = value;
  6579. v2 = value;
  6580. v3 = value;
  6581. v4 = value;
  6582. customAttribute.array[ offset_custom ] = v1[ pp[ 0 ] ];
  6583. customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
  6584. customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
  6585. customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
  6586. customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
  6587. customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
  6588. customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
  6589. customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
  6590. customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
  6591. customAttribute.array[ offset_custom + 9 ] = v4[ pp[ 0 ] ];
  6592. customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
  6593. customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
  6594. offset_custom += 12;
  6595. }
  6596. }
  6597. } else if ( customAttribute.size === 4 ) {
  6598. if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
  6599. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  6600. face = obj_faces[ chunk_faces3[ f ] ];
  6601. v1 = customAttribute.value[ face.a ];
  6602. v2 = customAttribute.value[ face.b ];
  6603. v3 = customAttribute.value[ face.c ];
  6604. customAttribute.array[ offset_custom ] = v1.x;
  6605. customAttribute.array[ offset_custom + 1 ] = v1.y;
  6606. customAttribute.array[ offset_custom + 2 ] = v1.z;
  6607. customAttribute.array[ offset_custom + 3 ] = v1.w;
  6608. customAttribute.array[ offset_custom + 4 ] = v2.x;
  6609. customAttribute.array[ offset_custom + 5 ] = v2.y;
  6610. customAttribute.array[ offset_custom + 6 ] = v2.z;
  6611. customAttribute.array[ offset_custom + 7 ] = v2.w;
  6612. customAttribute.array[ offset_custom + 8 ] = v3.x;
  6613. customAttribute.array[ offset_custom + 9 ] = v3.y;
  6614. customAttribute.array[ offset_custom + 10 ] = v3.z;
  6615. customAttribute.array[ offset_custom + 11 ] = v3.w;
  6616. offset_custom += 12;
  6617. }
  6618. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6619. face = obj_faces[ chunk_faces4[ f ] ];
  6620. v1 = customAttribute.value[ face.a ];
  6621. v2 = customAttribute.value[ face.b ];
  6622. v3 = customAttribute.value[ face.c ];
  6623. v4 = customAttribute.value[ face.d ];
  6624. customAttribute.array[ offset_custom ] = v1.x;
  6625. customAttribute.array[ offset_custom + 1 ] = v1.y;
  6626. customAttribute.array[ offset_custom + 2 ] = v1.z;
  6627. customAttribute.array[ offset_custom + 3 ] = v1.w;
  6628. customAttribute.array[ offset_custom + 4 ] = v2.x;
  6629. customAttribute.array[ offset_custom + 5 ] = v2.y;
  6630. customAttribute.array[ offset_custom + 6 ] = v2.z;
  6631. customAttribute.array[ offset_custom + 7 ] = v2.w;
  6632. customAttribute.array[ offset_custom + 8 ] = v3.x;
  6633. customAttribute.array[ offset_custom + 9 ] = v3.y;
  6634. customAttribute.array[ offset_custom + 10 ] = v3.z;
  6635. customAttribute.array[ offset_custom + 11 ] = v3.w;
  6636. customAttribute.array[ offset_custom + 12 ] = v4.x;
  6637. customAttribute.array[ offset_custom + 13 ] = v4.y;
  6638. customAttribute.array[ offset_custom + 14 ] = v4.z;
  6639. customAttribute.array[ offset_custom + 15 ] = v4.w;
  6640. offset_custom += 16;
  6641. }
  6642. } else if ( customAttribute.boundTo === "faces" ) {
  6643. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  6644. value = customAttribute.value[ chunk_faces3[ f ] ];
  6645. v1 = value;
  6646. v2 = value;
  6647. v3 = value;
  6648. customAttribute.array[ offset_custom ] = v1.x;
  6649. customAttribute.array[ offset_custom + 1 ] = v1.y;
  6650. customAttribute.array[ offset_custom + 2 ] = v1.z;
  6651. customAttribute.array[ offset_custom + 3 ] = v1.w;
  6652. customAttribute.array[ offset_custom + 4 ] = v2.x;
  6653. customAttribute.array[ offset_custom + 5 ] = v2.y;
  6654. customAttribute.array[ offset_custom + 6 ] = v2.z;
  6655. customAttribute.array[ offset_custom + 7 ] = v2.w;
  6656. customAttribute.array[ offset_custom + 8 ] = v3.x;
  6657. customAttribute.array[ offset_custom + 9 ] = v3.y;
  6658. customAttribute.array[ offset_custom + 10 ] = v3.z;
  6659. customAttribute.array[ offset_custom + 11 ] = v3.w;
  6660. offset_custom += 12;
  6661. }
  6662. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  6663. value = customAttribute.value[ chunk_faces4[ f ] ];
  6664. v1 = value;
  6665. v2 = value;
  6666. v3 = value;
  6667. v4 = value;
  6668. customAttribute.array[ offset_custom ] = v1.x;
  6669. customAttribute.array[ offset_custom + 1 ] = v1.y;
  6670. customAttribute.array[ offset_custom + 2 ] = v1.z;
  6671. customAttribute.array[ offset_custom + 3 ] = v1.w;
  6672. customAttribute.array[ offset_custom + 4 ] = v2.x;
  6673. customAttribute.array[ offset_custom + 5 ] = v2.y;
  6674. customAttribute.array[ offset_custom + 6 ] = v2.z;
  6675. customAttribute.array[ offset_custom + 7 ] = v2.w;
  6676. customAttribute.array[ offset_custom + 8 ] = v3.x;
  6677. customAttribute.array[ offset_custom + 9 ] = v3.y;
  6678. customAttribute.array[ offset_custom + 10 ] = v3.z;
  6679. customAttribute.array[ offset_custom + 11 ] = v3.w;
  6680. customAttribute.array[ offset_custom + 12 ] = v4.x;
  6681. customAttribute.array[ offset_custom + 13 ] = v4.y;
  6682. customAttribute.array[ offset_custom + 14 ] = v4.z;
  6683. customAttribute.array[ offset_custom + 15 ] = v4.w;
  6684. offset_custom += 16;
  6685. }
  6686. }
  6687. }
  6688. _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
  6689. _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
  6690. }
  6691. }
  6692. if ( dispose ) {
  6693. delete geometryGroup.__inittedArrays;
  6694. delete geometryGroup.__colorArray;
  6695. delete geometryGroup.__normalArray;
  6696. delete geometryGroup.__tangentArray;
  6697. delete geometryGroup.__uvArray;
  6698. delete geometryGroup.__uv2Array;
  6699. delete geometryGroup.__faceArray;
  6700. delete geometryGroup.__vertexArray;
  6701. delete geometryGroup.__lineArray;
  6702. delete geometryGroup.__skinVertexAArray;
  6703. delete geometryGroup.__skinVertexBArray;
  6704. delete geometryGroup.__skinIndexArray;
  6705. delete geometryGroup.__skinWeightArray;
  6706. }
  6707. };
  6708. // Buffer rendering
  6709. this.renderBufferImmediate = function ( object, program, shading ) {
  6710. if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
  6711. if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
  6712. if ( object.hasPos ) {
  6713. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglVertexBuffer );
  6714. _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
  6715. _gl.enableVertexAttribArray( program.attributes.position );
  6716. _gl.vertexAttribPointer( program.attributes.position, 3, _gl.FLOAT, false, 0, 0 );
  6717. }
  6718. if ( object.hasNormal ) {
  6719. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
  6720. if ( shading === THREE.FlatShading ) {
  6721. var nx, ny, nz,
  6722. nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz,
  6723. normalArray,
  6724. i, il = object.count * 3;
  6725. for( i = 0; i < il; i += 9 ) {
  6726. normalArray = object.normalArray;
  6727. nax = normalArray[ i ];
  6728. nay = normalArray[ i + 1 ];
  6729. naz = normalArray[ i + 2 ];
  6730. nbx = normalArray[ i + 3 ];
  6731. nby = normalArray[ i + 4 ];
  6732. nbz = normalArray[ i + 5 ];
  6733. ncx = normalArray[ i + 6 ];
  6734. ncy = normalArray[ i + 7 ];
  6735. ncz = normalArray[ i + 8 ];
  6736. nx = ( nax + nbx + ncx ) / 3;
  6737. ny = ( nay + nby + ncy ) / 3;
  6738. nz = ( naz + nbz + ncz ) / 3;
  6739. normalArray[ i ] = nx;
  6740. normalArray[ i + 1 ] = ny;
  6741. normalArray[ i + 2 ] = nz;
  6742. normalArray[ i + 3 ] = nx;
  6743. normalArray[ i + 4 ] = ny;
  6744. normalArray[ i + 5 ] = nz;
  6745. normalArray[ i + 6 ] = nx;
  6746. normalArray[ i + 7 ] = ny;
  6747. normalArray[ i + 8 ] = nz;
  6748. }
  6749. }
  6750. _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
  6751. _gl.enableVertexAttribArray( program.attributes.normal );
  6752. _gl.vertexAttribPointer( program.attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
  6753. }
  6754. _gl.drawArrays( _gl.TRIANGLES, 0, object.count );
  6755. object.count = 0;
  6756. };
  6757. this.renderBufferDirect = function ( camera, lights, fog, material, geometryGroup, object ) {
  6758. if ( material.opacity === 0 ) return;
  6759. var program, attributes, linewidth, primitives, a, attribute;
  6760. program = setProgram( camera, lights, fog, material, object );
  6761. attributes = program.attributes;
  6762. var updateBuffers = false,
  6763. wireframeBit = material.wireframe ? 1 : 0,
  6764. geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
  6765. if ( geometryGroupHash !== _currentGeometryGroupHash ) {
  6766. _currentGeometryGroupHash = geometryGroupHash;
  6767. updateBuffers = true;
  6768. }
  6769. // render mesh
  6770. if ( object instanceof THREE.Mesh ) {
  6771. var offsets = geometryGroup.offsets;
  6772. for ( var i = 0, il = offsets.length; i < il; ++ i ) {
  6773. if ( updateBuffers ) {
  6774. // vertices
  6775. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.vertexPositionBuffer );
  6776. _gl.vertexAttribPointer( attributes.position, geometryGroup.vertexPositionBuffer.itemSize, _gl.FLOAT, false, 0, offsets[ i ].index * 4 * 3 );
  6777. // normals
  6778. if ( attributes.normal >= 0 && geometryGroup.vertexNormalBuffer ) {
  6779. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.vertexNormalBuffer );
  6780. _gl.vertexAttribPointer( attributes.normal, geometryGroup.vertexNormalBuffer.itemSize, _gl.FLOAT, false, 0, offsets[ i ].index * 4 * 3 );
  6781. }
  6782. // uvs
  6783. if ( attributes.uv >= 0 && geometryGroup.vertexUvBuffer ) {
  6784. if ( geometryGroup.vertexUvBuffer ) {
  6785. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.vertexUvBuffer );
  6786. _gl.vertexAttribPointer( attributes.uv, geometryGroup.vertexUvBuffer.itemSize, _gl.FLOAT, false, 0, offsets[ i ].index * 4 * 2 );
  6787. _gl.enableVertexAttribArray( attributes.uv );
  6788. } else {
  6789. _gl.disableVertexAttribArray( attributes.uv );
  6790. }
  6791. }
  6792. // colors
  6793. if ( attributes.color >= 0 && geometryGroup.vertexColorBuffer ) {
  6794. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.vertexColorBuffer );
  6795. _gl.vertexAttribPointer( attributes.color, geometryGroup.vertexColorBuffer.itemSize, _gl.FLOAT, false, 0, offsets[ i ].index * 4 * 4 );
  6796. }
  6797. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.vertexIndexBuffer );
  6798. }
  6799. // render indexed triangles
  6800. _gl.drawElements( _gl.TRIANGLES, offsets[ i ].count, _gl.UNSIGNED_SHORT, offsets[ i ].start * 2 ); // 2 = Uint16
  6801. _this.info.render.calls ++;
  6802. _this.info.render.vertices += offsets[ i ].count; // not really true, here vertices can be shared
  6803. _this.info.render.faces += offsets[ i ].count / 3;
  6804. }
  6805. }
  6806. };
  6807. this.renderBuffer = function ( camera, lights, fog, material, geometryGroup, object ) {
  6808. if ( material.opacity === 0 ) return;
  6809. var program, attributes, linewidth, primitives, a, attribute, i, il;
  6810. program = setProgram( camera, lights, fog, material, object );
  6811. attributes = program.attributes;
  6812. var updateBuffers = false,
  6813. wireframeBit = material.wireframe ? 1 : 0,
  6814. geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
  6815. if ( geometryGroupHash !== _currentGeometryGroupHash ) {
  6816. _currentGeometryGroupHash = geometryGroupHash;
  6817. updateBuffers = true;
  6818. }
  6819. // vertices
  6820. if ( !material.morphTargets && attributes.position >= 0 ) {
  6821. if ( updateBuffers ) {
  6822. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
  6823. _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
  6824. }
  6825. } else {
  6826. if ( object.morphTargetBase ) {
  6827. setupMorphTargets( material, geometryGroup, object );
  6828. }
  6829. }
  6830. if ( updateBuffers ) {
  6831. // custom attributes
  6832. // Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
  6833. if ( geometryGroup.__webglCustomAttributesList ) {
  6834. for ( i = 0, il = geometryGroup.__webglCustomAttributesList.length; i < il; i ++ ) {
  6835. attribute = geometryGroup.__webglCustomAttributesList[ i ];
  6836. if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
  6837. _gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
  6838. _gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
  6839. }
  6840. }
  6841. }
  6842. // colors
  6843. if ( attributes.color >= 0 ) {
  6844. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
  6845. _gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
  6846. }
  6847. // normals
  6848. if ( attributes.normal >= 0 ) {
  6849. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
  6850. _gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
  6851. }
  6852. // tangents
  6853. if ( attributes.tangent >= 0 ) {
  6854. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
  6855. _gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
  6856. }
  6857. // uvs
  6858. if ( attributes.uv >= 0 ) {
  6859. if ( geometryGroup.__webglUVBuffer ) {
  6860. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
  6861. _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
  6862. _gl.enableVertexAttribArray( attributes.uv );
  6863. } else {
  6864. _gl.disableVertexAttribArray( attributes.uv );
  6865. }
  6866. }
  6867. if ( attributes.uv2 >= 0 ) {
  6868. if ( geometryGroup.__webglUV2Buffer ) {
  6869. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
  6870. _gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
  6871. _gl.enableVertexAttribArray( attributes.uv2 );
  6872. } else {
  6873. _gl.disableVertexAttribArray( attributes.uv2 );
  6874. }
  6875. }
  6876. if ( material.skinning &&
  6877. attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
  6878. attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
  6879. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
  6880. _gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
  6881. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
  6882. _gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
  6883. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
  6884. _gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
  6885. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
  6886. _gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
  6887. }
  6888. }
  6889. // render mesh
  6890. if ( object instanceof THREE.Mesh ) {
  6891. // wireframe
  6892. if ( material.wireframe ) {
  6893. setLineWidth( material.wireframeLinewidth );
  6894. if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
  6895. _gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
  6896. // triangles
  6897. } else {
  6898. if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
  6899. _gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
  6900. }
  6901. _this.info.render.calls ++;
  6902. _this.info.render.vertices += geometryGroup.__webglFaceCount;
  6903. _this.info.render.faces += geometryGroup.__webglFaceCount / 3;
  6904. // render lines
  6905. } else if ( object instanceof THREE.Line ) {
  6906. primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
  6907. setLineWidth( material.linewidth );
  6908. _gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
  6909. _this.info.render.calls ++;
  6910. // render particles
  6911. } else if ( object instanceof THREE.ParticleSystem ) {
  6912. _gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
  6913. _this.info.render.calls ++;
  6914. _this.info.render.points += geometryGroup.__webglParticleCount;
  6915. // render ribbon
  6916. } else if ( object instanceof THREE.Ribbon ) {
  6917. _gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
  6918. _this.info.render.calls ++;
  6919. }
  6920. };
  6921. function setupMorphTargets ( material, geometryGroup, object ) {
  6922. // set base
  6923. var attributes = material.program.attributes;
  6924. if ( object.morphTargetBase !== - 1 ) {
  6925. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
  6926. _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
  6927. } else if ( attributes.position >= 0 ) {
  6928. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
  6929. _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
  6930. }
  6931. if ( object.morphTargetForcedOrder.length ) {
  6932. // set forced order
  6933. var m = 0;
  6934. var order = object.morphTargetForcedOrder;
  6935. var influences = object.morphTargetInfluences;
  6936. while ( m < material.numSupportedMorphTargets && m < order.length ) {
  6937. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
  6938. _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
  6939. if ( material.morphNormals ) {
  6940. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ order[ m ] ] );
  6941. _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
  6942. }
  6943. object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];
  6944. m ++;
  6945. }
  6946. } else {
  6947. // find most influencing
  6948. var used = [];
  6949. var candidateInfluence = - 1;
  6950. var candidate = 0;
  6951. var influences = object.morphTargetInfluences;
  6952. var i, il = influences.length;
  6953. var m = 0;
  6954. if ( object.morphTargetBase !== - 1 ) {
  6955. used[ object.morphTargetBase ] = true;
  6956. }
  6957. while ( m < material.numSupportedMorphTargets ) {
  6958. for ( i = 0; i < il; i ++ ) {
  6959. if ( !used[ i ] && influences[ i ] > candidateInfluence ) {
  6960. candidate = i;
  6961. candidateInfluence = influences[ candidate ];
  6962. }
  6963. }
  6964. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
  6965. _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
  6966. if ( material.morphNormals ) {
  6967. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ candidate ] );
  6968. _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
  6969. }
  6970. object.__webglMorphTargetInfluences[ m ] = candidateInfluence;
  6971. used[ candidate ] = 1;
  6972. candidateInfluence = -1;
  6973. m ++;
  6974. }
  6975. }
  6976. // load updated influences uniform
  6977. if( material.program.uniforms.morphTargetInfluences !== null ) {
  6978. _gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
  6979. }
  6980. };
  6981. function painterSort ( a, b ) {
  6982. return b.z - a.z;
  6983. };
  6984. // Rendering
  6985. this.render = function ( scene, camera, renderTarget, forceClear ) {
  6986. var i, il,
  6987. webglObject, object,
  6988. renderList,
  6989. lights = scene.__lights,
  6990. fog = scene.fog;
  6991. _currentMaterialId = -1;
  6992. // update scene graph
  6993. if ( camera.parent === undefined ) {
  6994. console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
  6995. scene.add( camera );
  6996. }
  6997. if ( this.autoUpdateScene ) scene.updateMatrixWorld();
  6998. // update camera matrices and frustum
  6999. if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
  7000. if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
  7001. camera.matrixWorldInverse.getInverse( camera.matrixWorld );
  7002. camera.matrixWorldInverse.flattenToArray( camera._viewMatrixArray );
  7003. camera.projectionMatrix.flattenToArray( camera._projectionMatrixArray );
  7004. _projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
  7005. _frustum.setFromMatrix( _projScreenMatrix );
  7006. // update WebGL objects
  7007. if ( this.autoUpdateObjects ) this.initWebGLObjects( scene );
  7008. // custom render plugins (pre pass)
  7009. renderPlugins( this.renderPluginsPre, scene, camera );
  7010. //
  7011. _this.info.render.calls = 0;
  7012. _this.info.render.vertices = 0;
  7013. _this.info.render.faces = 0;
  7014. _this.info.render.points = 0;
  7015. this.setRenderTarget( renderTarget );
  7016. if ( this.autoClear || forceClear ) {
  7017. this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
  7018. }
  7019. // set matrices for regular objects (frustum culled)
  7020. renderList = scene.__webglObjects;
  7021. for ( i = 0, il = renderList.length; i < il; i ++ ) {
  7022. webglObject = renderList[ i ];
  7023. object = webglObject.object;
  7024. webglObject.render = false;
  7025. if ( object.visible ) {
  7026. if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
  7027. //object.matrixWorld.flattenToArray( object._objectMatrixArray );
  7028. setupMatrices( object, camera );
  7029. unrollBufferMaterial( webglObject );
  7030. webglObject.render = true;
  7031. if ( this.sortObjects ) {
  7032. if ( object.renderDepth ) {
  7033. webglObject.z = object.renderDepth;
  7034. } else {
  7035. _vector3.copy( object.matrixWorld.getPosition() );
  7036. _projScreenMatrix.multiplyVector3( _vector3 );
  7037. webglObject.z = _vector3.z;
  7038. }
  7039. }
  7040. }
  7041. }
  7042. }
  7043. if ( this.sortObjects ) {
  7044. renderList.sort( painterSort );
  7045. }
  7046. // set matrices for immediate objects
  7047. renderList = scene.__webglObjectsImmediate;
  7048. for ( i = 0, il = renderList.length; i < il; i ++ ) {
  7049. webglObject = renderList[ i ];
  7050. object = webglObject.object;
  7051. if ( object.visible ) {
  7052. if( object.matrixAutoUpdate ) {
  7053. //object.matrixWorld.flattenToArray( object._objectMatrixArray );
  7054. }
  7055. setupMatrices( object, camera );
  7056. unrollImmediateBufferMaterial( webglObject );
  7057. }
  7058. }
  7059. if ( scene.overrideMaterial ) {
  7060. var material = scene.overrideMaterial;
  7061. this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
  7062. this.setDepthTest( material.depthTest );
  7063. this.setDepthWrite( material.depthWrite );
  7064. setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
  7065. renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, material );
  7066. renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, material );
  7067. } else {
  7068. // opaque pass (front-to-back order)
  7069. this.setBlending( THREE.NormalBlending );
  7070. renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
  7071. renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
  7072. // transparent pass (back-to-front order)
  7073. renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
  7074. renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
  7075. }
  7076. // custom render plugins (post pass)
  7077. renderPlugins( this.renderPluginsPost, scene, camera );
  7078. // Generate mipmap if we're using any kind of mipmap filtering
  7079. if ( renderTarget && renderTarget.generateMipmaps && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
  7080. updateRenderTargetMipmap( renderTarget );
  7081. }
  7082. // Ensure depth buffer writing is enabled so it can be cleared on next render
  7083. this.setDepthTest( true );
  7084. this.setDepthWrite( true );
  7085. // _gl.finish();
  7086. };
  7087. function renderPlugins( plugins, scene, camera ) {
  7088. if ( ! plugins.length ) return;
  7089. for ( var i = 0, il = plugins.length; i < il; i ++ ) {
  7090. _currentProgram = null;
  7091. _currentCamera = null;
  7092. _oldBlending = -1;
  7093. _oldDepthTest = -1;
  7094. _oldDepthWrite = -1;
  7095. _currentGeometryGroupHash = -1;
  7096. _currentMaterialId = -1;
  7097. plugins[ i ].render( scene, camera, _currentWidth, _currentHeight );
  7098. _currentProgram = null;
  7099. _currentCamera = null;
  7100. _oldBlending = -1;
  7101. _oldDepthTest = -1;
  7102. _oldDepthWrite = -1;
  7103. _currentGeometryGroupHash = -1;
  7104. _currentMaterialId = -1;
  7105. }
  7106. };
  7107. function renderObjects ( renderList, reverse, materialType, camera, lights, fog, useBlending, overrideMaterial ) {
  7108. var webglObject, object, buffer, material, start, end, delta;
  7109. if ( reverse ) {
  7110. start = renderList.length - 1;
  7111. end = -1;
  7112. delta = -1;
  7113. } else {
  7114. start = 0;
  7115. end = renderList.length;
  7116. delta = 1;
  7117. }
  7118. for ( var i = start; i !== end; i += delta ) {
  7119. webglObject = renderList[ i ];
  7120. if ( webglObject.render ) {
  7121. object = webglObject.object;
  7122. buffer = webglObject.buffer;
  7123. if ( overrideMaterial ) {
  7124. material = overrideMaterial;
  7125. } else {
  7126. material = webglObject[ materialType ];
  7127. if ( ! material ) continue;
  7128. if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
  7129. _this.setDepthTest( material.depthTest );
  7130. _this.setDepthWrite( material.depthWrite );
  7131. setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
  7132. }
  7133. _this.setObjectFaces( object );
  7134. if ( buffer instanceof THREE.BufferGeometry ) {
  7135. _this.renderBufferDirect( camera, lights, fog, material, buffer, object );
  7136. } else {
  7137. _this.renderBuffer( camera, lights, fog, material, buffer, object );
  7138. }
  7139. }
  7140. }
  7141. };
  7142. function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, useBlending, overrideMaterial ) {
  7143. var webglObject, object, material, program;
  7144. for ( var i = 0, il = renderList.length; i < il; i ++ ) {
  7145. webglObject = renderList[ i ];
  7146. object = webglObject.object;
  7147. if ( object.visible ) {
  7148. if ( overrideMaterial ) {
  7149. material = overrideMaterial;
  7150. } else {
  7151. material = webglObject[ materialType ];
  7152. if ( ! material ) continue;
  7153. if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
  7154. _this.setDepthTest( material.depthTest );
  7155. _this.setDepthWrite( material.depthWrite );
  7156. setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
  7157. }
  7158. _this.renderImmediateObject( camera, lights, fog, material, object );
  7159. }
  7160. }
  7161. };
  7162. this.renderImmediateObject = function ( camera, lights, fog, material, object ) {
  7163. var program = setProgram( camera, lights, fog, material, object );
  7164. _currentGeometryGroupHash = -1;
  7165. _this.setObjectFaces( object );
  7166. if ( object.immediateRenderCallback ) {
  7167. object.immediateRenderCallback( program, _gl, _frustum );
  7168. } else {
  7169. object.render( function( object ) { _this.renderBufferImmediate( object, program, material.shading ); } );
  7170. }
  7171. };
  7172. function unrollImmediateBufferMaterial ( globject ) {
  7173. var object = globject.object,
  7174. material = object.material;
  7175. if ( material.transparent ) {
  7176. globject.transparent = material;
  7177. globject.opaque = null;
  7178. } else {
  7179. globject.opaque = material;
  7180. globject.transparent = null;
  7181. }
  7182. };
  7183. function unrollBufferMaterial ( globject ) {
  7184. var object = globject.object,
  7185. buffer = globject.buffer,
  7186. material, materialIndex, meshMaterial;
  7187. meshMaterial = object.material;
  7188. if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
  7189. materialIndex = buffer.materialIndex;
  7190. if ( materialIndex >= 0 ) {
  7191. material = object.geometry.materials[ materialIndex ];
  7192. if ( material.transparent ) {
  7193. globject.transparent = material;
  7194. globject.opaque = null;
  7195. } else {
  7196. globject.opaque = material;
  7197. globject.transparent = null;
  7198. }
  7199. }
  7200. } else {
  7201. material = meshMaterial;
  7202. if ( material ) {
  7203. if ( material.transparent ) {
  7204. globject.transparent = material;
  7205. globject.opaque = null;
  7206. } else {
  7207. globject.opaque = material;
  7208. globject.transparent = null;
  7209. }
  7210. }
  7211. }
  7212. };
  7213. // Geometry splitting
  7214. function sortFacesByMaterial ( geometry ) {
  7215. var f, fl, face, materialIndex, vertices,
  7216. materialHash, groupHash,
  7217. hash_map = {};
  7218. var numMorphTargets = geometry.morphTargets.length;
  7219. var numMorphNormals = geometry.morphNormals.length;
  7220. geometry.geometryGroups = {};
  7221. for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
  7222. face = geometry.faces[ f ];
  7223. materialIndex = face.materialIndex;
  7224. materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
  7225. if ( hash_map[ materialHash ] === undefined ) {
  7226. hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
  7227. }
  7228. groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
  7229. if ( geometry.geometryGroups[ groupHash ] === undefined ) {
  7230. geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals };
  7231. }
  7232. vertices = face instanceof THREE.Face3 ? 3 : 4;
  7233. if ( geometry.geometryGroups[ groupHash ].vertices + vertices > 65535 ) {
  7234. hash_map[ materialHash ].counter += 1;
  7235. groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
  7236. if ( geometry.geometryGroups[ groupHash ] === undefined ) {
  7237. geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals };
  7238. }
  7239. }
  7240. if ( face instanceof THREE.Face3 ) {
  7241. geometry.geometryGroups[ groupHash ].faces3.push( f );
  7242. } else {
  7243. geometry.geometryGroups[ groupHash ].faces4.push( f );
  7244. }
  7245. geometry.geometryGroups[ groupHash ].vertices += vertices;
  7246. }
  7247. geometry.geometryGroupsList = [];
  7248. for ( var g in geometry.geometryGroups ) {
  7249. geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
  7250. geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
  7251. }
  7252. };
  7253. // Objects refresh
  7254. this.initWebGLObjects = function ( scene ) {
  7255. if ( !scene.__webglObjects ) {
  7256. scene.__webglObjects = [];
  7257. scene.__webglObjectsImmediate = [];
  7258. scene.__webglSprites = [];
  7259. scene.__webglFlares = [];
  7260. }
  7261. while ( scene.__objectsAdded.length ) {
  7262. addObject( scene.__objectsAdded[ 0 ], scene );
  7263. scene.__objectsAdded.splice( 0, 1 );
  7264. }
  7265. while ( scene.__objectsRemoved.length ) {
  7266. removeObject( scene.__objectsRemoved[ 0 ], scene );
  7267. scene.__objectsRemoved.splice( 0, 1 );
  7268. }
  7269. // update must be called after objects adding / removal
  7270. for ( var o = 0, ol = scene.__webglObjects.length; o < ol; o ++ ) {
  7271. updateObject( scene.__webglObjects[ o ].object );
  7272. }
  7273. };
  7274. // Objects adding
  7275. function addObject ( object, scene ) {
  7276. var g, geometry, geometryGroup;
  7277. if ( ! object.__webglInit ) {
  7278. object.__webglInit = true;
  7279. object._modelViewMatrix = new THREE.Matrix4();
  7280. object._normalMatrix = new THREE.Matrix3();
  7281. object._normalMatrixArray = new Float32Array( 9 );
  7282. object._modelViewMatrixArray = new Float32Array( 16 );
  7283. object._objectMatrixArray = new Float32Array( 16 );
  7284. //object.matrixWorld.flattenToArray( object._objectMatrixArray );
  7285. if ( object instanceof THREE.Mesh ) {
  7286. geometry = object.geometry;
  7287. if ( geometry instanceof THREE.Geometry ) {
  7288. if ( geometry.geometryGroups === undefined ) {
  7289. sortFacesByMaterial( geometry );
  7290. }
  7291. // create separate VBOs per geometry chunk
  7292. for ( g in geometry.geometryGroups ) {
  7293. geometryGroup = geometry.geometryGroups[ g ];
  7294. // initialise VBO on the first access
  7295. if ( ! geometryGroup.__webglVertexBuffer ) {
  7296. createMeshBuffers( geometryGroup );
  7297. initMeshBuffers( geometryGroup, object );
  7298. geometry.__dirtyVertices = true;
  7299. geometry.__dirtyMorphTargets = true;
  7300. geometry.__dirtyElements = true;
  7301. geometry.__dirtyUvs = true;
  7302. geometry.__dirtyNormals = true;
  7303. geometry.__dirtyTangents = true;
  7304. geometry.__dirtyColors = true;
  7305. }
  7306. }
  7307. }
  7308. } else if ( object instanceof THREE.Ribbon ) {
  7309. geometry = object.geometry;
  7310. if( ! geometry.__webglVertexBuffer ) {
  7311. createRibbonBuffers( geometry );
  7312. initRibbonBuffers( geometry );
  7313. geometry.__dirtyVertices = true;
  7314. geometry.__dirtyColors = true;
  7315. }
  7316. } else if ( object instanceof THREE.Line ) {
  7317. geometry = object.geometry;
  7318. if( ! geometry.__webglVertexBuffer ) {
  7319. createLineBuffers( geometry );
  7320. initLineBuffers( geometry, object );
  7321. geometry.__dirtyVertices = true;
  7322. geometry.__dirtyColors = true;
  7323. }
  7324. } else if ( object instanceof THREE.ParticleSystem ) {
  7325. geometry = object.geometry;
  7326. if ( ! geometry.__webglVertexBuffer ) {
  7327. createParticleBuffers( geometry );
  7328. initParticleBuffers( geometry, object );
  7329. geometry.__dirtyVertices = true;
  7330. geometry.__dirtyColors = true;
  7331. }
  7332. }
  7333. }
  7334. if ( ! object.__webglActive ) {
  7335. if ( object instanceof THREE.Mesh ) {
  7336. geometry = object.geometry;
  7337. if ( geometry instanceof THREE.BufferGeometry ) {
  7338. addBuffer( scene.__webglObjects, geometry, object );
  7339. } else {
  7340. for ( g in geometry.geometryGroups ) {
  7341. geometryGroup = geometry.geometryGroups[ g ];
  7342. addBuffer( scene.__webglObjects, geometryGroup, object );
  7343. }
  7344. }
  7345. } else if ( object instanceof THREE.Ribbon ||
  7346. object instanceof THREE.Line ||
  7347. object instanceof THREE.ParticleSystem ) {
  7348. geometry = object.geometry;
  7349. addBuffer( scene.__webglObjects, geometry, object );
  7350. } else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
  7351. addBufferImmediate( scene.__webglObjectsImmediate, object );
  7352. } else if ( object instanceof THREE.Sprite ) {
  7353. scene.__webglSprites.push( object );
  7354. } else if ( object instanceof THREE.LensFlare ) {
  7355. scene.__webglFlares.push( object );
  7356. }
  7357. object.__webglActive = true;
  7358. }
  7359. };
  7360. function addBuffer ( objlist, buffer, object ) {
  7361. objlist.push(
  7362. {
  7363. buffer: buffer,
  7364. object: object,
  7365. opaque: null,
  7366. transparent: null
  7367. }
  7368. );
  7369. };
  7370. function addBufferImmediate ( objlist, object ) {
  7371. objlist.push(
  7372. {
  7373. object: object,
  7374. opaque: null,
  7375. transparent: null
  7376. }
  7377. );
  7378. };
  7379. // Objects updates
  7380. function updateObject ( object ) {
  7381. var geometry = object.geometry,
  7382. geometryGroup, customAttributesDirty, material;
  7383. if ( object instanceof THREE.Mesh ) {
  7384. if ( geometry instanceof THREE.BufferGeometry ) {
  7385. /*
  7386. if ( geometry.__dirtyVertices || geometry.__dirtyElements ||
  7387. geometry.__dirtyUvs || geometry.__dirtyNormals ||
  7388. geometry.__dirtyColors ) {
  7389. // TODO
  7390. // set buffers from typed arrays
  7391. }
  7392. */
  7393. geometry.__dirtyVertices = false;
  7394. geometry.__dirtyElements = false;
  7395. geometry.__dirtyUvs = false;
  7396. geometry.__dirtyNormals = false;
  7397. geometry.__dirtyColors = false;
  7398. } else {
  7399. // check all geometry groups
  7400. for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {
  7401. geometryGroup = geometry.geometryGroupsList[ i ];
  7402. material = getBufferMaterial( object, geometryGroup );
  7403. customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
  7404. if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
  7405. geometry.__dirtyUvs || geometry.__dirtyNormals ||
  7406. geometry.__dirtyColors || geometry.__dirtyTangents || customAttributesDirty ) {
  7407. setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW, !geometry.dynamic, material );
  7408. }
  7409. }
  7410. geometry.__dirtyVertices = false;
  7411. geometry.__dirtyMorphTargets = false;
  7412. geometry.__dirtyElements = false;
  7413. geometry.__dirtyUvs = false;
  7414. geometry.__dirtyNormals = false;
  7415. geometry.__dirtyColors = false;
  7416. geometry.__dirtyTangents = false;
  7417. material.attributes && clearCustomAttributes( material );
  7418. }
  7419. } else if ( object instanceof THREE.Ribbon ) {
  7420. if ( geometry.__dirtyVertices || geometry.__dirtyColors ) {
  7421. setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
  7422. }
  7423. geometry.__dirtyVertices = false;
  7424. geometry.__dirtyColors = false;
  7425. } else if ( object instanceof THREE.Line ) {
  7426. material = getBufferMaterial( object, geometryGroup );
  7427. customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
  7428. if ( geometry.__dirtyVertices || geometry.__dirtyColors || customAttributesDirty ) {
  7429. setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
  7430. }
  7431. geometry.__dirtyVertices = false;
  7432. geometry.__dirtyColors = false;
  7433. material.attributes && clearCustomAttributes( material );
  7434. } else if ( object instanceof THREE.ParticleSystem ) {
  7435. material = getBufferMaterial( object, geometryGroup );
  7436. customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
  7437. if ( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles || customAttributesDirty ) {
  7438. setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
  7439. }
  7440. geometry.__dirtyVertices = false;
  7441. geometry.__dirtyColors = false;
  7442. material.attributes && clearCustomAttributes( material );
  7443. }
  7444. };
  7445. // Objects updates - custom attributes check
  7446. function areCustomAttributesDirty ( material ) {
  7447. for ( var a in material.attributes ) {
  7448. if ( material.attributes[ a ].needsUpdate ) return true;
  7449. }
  7450. return false;
  7451. };
  7452. function clearCustomAttributes ( material ) {
  7453. for ( var a in material.attributes ) {
  7454. material.attributes[ a ].needsUpdate = false;
  7455. }
  7456. };
  7457. // Objects removal
  7458. function removeObject ( object, scene ) {
  7459. if ( object instanceof THREE.Mesh ||
  7460. object instanceof THREE.ParticleSystem ||
  7461. object instanceof THREE.Ribbon ||
  7462. object instanceof THREE.Line ) {
  7463. removeInstances( scene.__webglObjects, object );
  7464. } else if ( object instanceof THREE.Sprite ) {
  7465. removeInstancesDirect( scene.__webglSprites, object );
  7466. } else if ( object instanceof THREE.LensFlare ) {
  7467. removeInstancesDirect( scene.__webglFlares, object );
  7468. } else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
  7469. removeInstances( scene.__webglObjectsImmediate, object );
  7470. }
  7471. object.__webglActive = false;
  7472. };
  7473. function removeInstances ( objlist, object ) {
  7474. for ( var o = objlist.length - 1; o >= 0; o -- ) {
  7475. if ( objlist[ o ].object === object ) {
  7476. objlist.splice( o, 1 );
  7477. }
  7478. }
  7479. };
  7480. function removeInstancesDirect ( objlist, object ) {
  7481. for ( var o = objlist.length - 1; o >= 0; o -- ) {
  7482. if ( objlist[ o ] === object ) {
  7483. objlist.splice( o, 1 );
  7484. }
  7485. }
  7486. };
  7487. // Materials
  7488. this.initMaterial = function ( material, lights, fog, object ) {
  7489. var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
  7490. if ( material instanceof THREE.MeshDepthMaterial ) {
  7491. shaderID = 'depth';
  7492. } else if ( material instanceof THREE.MeshNormalMaterial ) {
  7493. shaderID = 'normal';
  7494. } else if ( material instanceof THREE.MeshBasicMaterial ) {
  7495. shaderID = 'basic';
  7496. } else if ( material instanceof THREE.MeshLambertMaterial ) {
  7497. shaderID = 'lambert';
  7498. } else if ( material instanceof THREE.MeshPhongMaterial ) {
  7499. shaderID = 'phong';
  7500. } else if ( material instanceof THREE.LineBasicMaterial ) {
  7501. shaderID = 'basic';
  7502. } else if ( material instanceof THREE.ParticleBasicMaterial ) {
  7503. shaderID = 'particle_basic';
  7504. }
  7505. if ( shaderID ) {
  7506. setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
  7507. }
  7508. // heuristics to create shader parameters according to lights in the scene
  7509. // (not to blow over maxLights budget)
  7510. maxLightCount = allocateLights( lights );
  7511. maxShadows = allocateShadows( lights );
  7512. maxBones = allocateBones( object );
  7513. parameters = {
  7514. map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap,
  7515. vertexColors: material.vertexColors,
  7516. fog: fog, useFog: material.fog,
  7517. sizeAttenuation: material.sizeAttenuation,
  7518. skinning: material.skinning,
  7519. morphTargets: material.morphTargets,
  7520. morphNormals: material.morphNormals,
  7521. maxMorphTargets: this.maxMorphTargets,
  7522. maxMorphNormals: this.maxMorphNormals,
  7523. maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
  7524. maxBones: maxBones,
  7525. shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
  7526. shadowMapSoft: this.shadowMapSoft,
  7527. shadowMapDebug: this.shadowMapDebug,
  7528. shadowMapCascade: this.shadowMapCascade,
  7529. maxShadows: maxShadows,
  7530. alphaTest: material.alphaTest,
  7531. metal: material.metal,
  7532. perPixel: material.perPixel,
  7533. wrapAround: material.wrapAround,
  7534. doubleSided: object && object.doubleSided
  7535. };
  7536. material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
  7537. var attributes = material.program.attributes;
  7538. if ( attributes.position >= 0 ) _gl.enableVertexAttribArray( attributes.position );
  7539. if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
  7540. if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
  7541. if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
  7542. if ( material.skinning &&
  7543. attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
  7544. attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
  7545. _gl.enableVertexAttribArray( attributes.skinVertexA );
  7546. _gl.enableVertexAttribArray( attributes.skinVertexB );
  7547. _gl.enableVertexAttribArray( attributes.skinIndex );
  7548. _gl.enableVertexAttribArray( attributes.skinWeight );
  7549. }
  7550. if ( material.attributes ) {
  7551. for ( a in material.attributes ) {
  7552. if( attributes[ a ] !== undefined && attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] );
  7553. }
  7554. }
  7555. if ( material.morphTargets ) {
  7556. material.numSupportedMorphTargets = 0;
  7557. var id, base = "morphTarget";
  7558. for ( i = 0; i < this.maxMorphTargets; i ++ ) {
  7559. id = base + i;
  7560. if ( attributes[ id ] >= 0 ) {
  7561. _gl.enableVertexAttribArray( attributes[ id ] );
  7562. material.numSupportedMorphTargets ++;
  7563. }
  7564. }
  7565. }
  7566. if ( material.morphNormals ) {
  7567. material.numSupportedMorphNormals = 0;
  7568. var id, base = "morphNormal";
  7569. for ( i = 0; i < this.maxMorphNormals; i ++ ) {
  7570. id = base + i;
  7571. if ( attributes[ id ] >= 0 ) {
  7572. _gl.enableVertexAttribArray( attributes[ id ] );
  7573. material.numSupportedMorphNormals ++;
  7574. }
  7575. }
  7576. }
  7577. material.uniformsList = [];
  7578. for ( u in material.uniforms ) {
  7579. material.uniformsList.push( [ material.uniforms[ u ], u ] );
  7580. }
  7581. };
  7582. function setMaterialShaders( material, shaders ) {
  7583. material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
  7584. material.vertexShader = shaders.vertexShader;
  7585. material.fragmentShader = shaders.fragmentShader;
  7586. };
  7587. function setProgram( camera, lights, fog, material, object ) {
  7588. if ( ! material.program || material.needsUpdate ) {
  7589. _this.initMaterial( material, lights, fog, object );
  7590. material.needsUpdate = false;
  7591. }
  7592. if ( material.morphTargets ) {
  7593. if ( ! object.__webglMorphTargetInfluences ) {
  7594. object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
  7595. for ( var i = 0, il = _this.maxMorphTargets; i < il; i ++ ) {
  7596. object.__webglMorphTargetInfluences[ i ] = 0;
  7597. }
  7598. }
  7599. }
  7600. var refreshMaterial = false;
  7601. var program = material.program,
  7602. p_uniforms = program.uniforms,
  7603. m_uniforms = material.uniforms;
  7604. if ( program !== _currentProgram ) {
  7605. _gl.useProgram( program );
  7606. _currentProgram = program;
  7607. refreshMaterial = true;
  7608. }
  7609. if ( material.id !== _currentMaterialId ) {
  7610. _currentMaterialId = material.id;
  7611. refreshMaterial = true;
  7612. }
  7613. if ( refreshMaterial || camera !== _currentCamera ) {
  7614. _gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera._projectionMatrixArray );
  7615. if ( camera !== _currentCamera ) _currentCamera = camera;
  7616. }
  7617. if ( refreshMaterial ) {
  7618. // refresh uniforms common to several materials
  7619. if ( fog && material.fog ) {
  7620. refreshUniformsFog( m_uniforms, fog );
  7621. }
  7622. if ( material instanceof THREE.MeshPhongMaterial ||
  7623. material instanceof THREE.MeshLambertMaterial ||
  7624. material.lights ) {
  7625. setupLights( program, lights );
  7626. refreshUniformsLights( m_uniforms, _lights );
  7627. }
  7628. if ( material instanceof THREE.MeshBasicMaterial ||
  7629. material instanceof THREE.MeshLambertMaterial ||
  7630. material instanceof THREE.MeshPhongMaterial ) {
  7631. refreshUniformsCommon( m_uniforms, material );
  7632. }
  7633. // refresh single material specific uniforms
  7634. if ( material instanceof THREE.LineBasicMaterial ) {
  7635. refreshUniformsLine( m_uniforms, material );
  7636. } else if ( material instanceof THREE.ParticleBasicMaterial ) {
  7637. refreshUniformsParticle( m_uniforms, material );
  7638. } else if ( material instanceof THREE.MeshPhongMaterial ) {
  7639. refreshUniformsPhong( m_uniforms, material );
  7640. } else if ( material instanceof THREE.MeshLambertMaterial ) {
  7641. refreshUniformsLambert( m_uniforms, material );
  7642. } else if ( material instanceof THREE.MeshDepthMaterial ) {
  7643. m_uniforms.mNear.value = camera.near;
  7644. m_uniforms.mFar.value = camera.far;
  7645. m_uniforms.opacity.value = material.opacity;
  7646. } else if ( material instanceof THREE.MeshNormalMaterial ) {
  7647. m_uniforms.opacity.value = material.opacity;
  7648. }
  7649. if ( object.receiveShadow && ! material._shadowPass ) {
  7650. refreshUniformsShadow( m_uniforms, lights );
  7651. }
  7652. // load common uniforms
  7653. loadUniformsGeneric( program, material.uniformsList );
  7654. // load material specific uniforms
  7655. // (shader material also gets them for the sake of genericity)
  7656. if ( material instanceof THREE.ShaderMaterial ||
  7657. material instanceof THREE.MeshPhongMaterial ||
  7658. material.envMap ) {
  7659. if ( p_uniforms.cameraPosition !== null ) {
  7660. var position = camera.matrixWorld.getPosition();
  7661. _gl.uniform3f( p_uniforms.cameraPosition, position.x, position.y, position.z );
  7662. }
  7663. }
  7664. if ( material instanceof THREE.MeshPhongMaterial ||
  7665. material instanceof THREE.MeshLambertMaterial ||
  7666. material instanceof THREE.ShaderMaterial ||
  7667. material.skinning ) {
  7668. if ( p_uniforms.viewMatrix !== null ) {
  7669. _gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera._viewMatrixArray );
  7670. }
  7671. }
  7672. if ( material.skinning ) {
  7673. _gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );
  7674. }
  7675. }
  7676. loadUniformsMatrices( p_uniforms, object );
  7677. if ( material instanceof THREE.ShaderMaterial ||
  7678. material.envMap ||
  7679. material.skinning ||
  7680. object.receiveShadow ) {
  7681. if ( p_uniforms.objectMatrix !== null ) {
  7682. _gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object.matrixWorld.elements );
  7683. }
  7684. }
  7685. return program;
  7686. };
  7687. // Uniforms (refresh uniforms objects)
  7688. function refreshUniformsCommon ( uniforms, material ) {
  7689. uniforms.opacity.value = material.opacity;
  7690. if ( _this.gammaInput ) {
  7691. uniforms.diffuse.value.copyGammaToLinear( material.color );
  7692. } else {
  7693. uniforms.diffuse.value = material.color;
  7694. }
  7695. uniforms.map.texture = material.map;
  7696. if ( material.map ) {
  7697. uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y );
  7698. }
  7699. uniforms.lightMap.texture = material.lightMap;
  7700. uniforms.envMap.texture = material.envMap;
  7701. uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
  7702. if ( _this.gammaInput ) {
  7703. //uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
  7704. uniforms.reflectivity.value = material.reflectivity;
  7705. } else {
  7706. uniforms.reflectivity.value = material.reflectivity;
  7707. }
  7708. uniforms.refractionRatio.value = material.refractionRatio;
  7709. uniforms.combine.value = material.combine;
  7710. uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
  7711. };
  7712. function refreshUniformsLine ( uniforms, material ) {
  7713. uniforms.diffuse.value = material.color;
  7714. uniforms.opacity.value = material.opacity;
  7715. };
  7716. function refreshUniformsParticle ( uniforms, material ) {
  7717. uniforms.psColor.value = material.color;
  7718. uniforms.opacity.value = material.opacity;
  7719. uniforms.size.value = material.size;
  7720. uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
  7721. uniforms.map.texture = material.map;
  7722. };
  7723. function refreshUniformsFog ( uniforms, fog ) {
  7724. uniforms.fogColor.value = fog.color;
  7725. if ( fog instanceof THREE.Fog ) {
  7726. uniforms.fogNear.value = fog.near;
  7727. uniforms.fogFar.value = fog.far;
  7728. } else if ( fog instanceof THREE.FogExp2 ) {
  7729. uniforms.fogDensity.value = fog.density;
  7730. }
  7731. };
  7732. function refreshUniformsPhong ( uniforms, material ) {
  7733. uniforms.shininess.value = material.shininess;
  7734. if ( _this.gammaInput ) {
  7735. uniforms.ambient.value.copyGammaToLinear( material.ambient );
  7736. uniforms.emissive.value.copyGammaToLinear( material.emissive );
  7737. uniforms.specular.value.copyGammaToLinear( material.specular );
  7738. } else {
  7739. uniforms.ambient.value = material.ambient;
  7740. uniforms.emissive.value = material.emissive;
  7741. uniforms.specular.value = material.specular;
  7742. }
  7743. if ( material.wrapAround ) {
  7744. uniforms.wrapRGB.value.copy( material.wrapRGB );
  7745. }
  7746. };
  7747. function refreshUniformsLambert ( uniforms, material ) {
  7748. if ( _this.gammaInput ) {
  7749. uniforms.ambient.value.copyGammaToLinear( material.ambient );
  7750. uniforms.emissive.value.copyGammaToLinear( material.emissive );
  7751. } else {
  7752. uniforms.ambient.value = material.ambient;
  7753. uniforms.emissive.value = material.emissive;
  7754. }
  7755. if ( material.wrapAround ) {
  7756. uniforms.wrapRGB.value.copy( material.wrapRGB );
  7757. }
  7758. };
  7759. function refreshUniformsLights ( uniforms, lights ) {
  7760. uniforms.ambientLightColor.value = lights.ambient;
  7761. uniforms.directionalLightColor.value = lights.directional.colors;
  7762. uniforms.directionalLightDirection.value = lights.directional.positions;
  7763. uniforms.pointLightColor.value = lights.point.colors;
  7764. uniforms.pointLightPosition.value = lights.point.positions;
  7765. uniforms.pointLightDistance.value = lights.point.distances;
  7766. };
  7767. function refreshUniformsShadow ( uniforms, lights ) {
  7768. if ( uniforms.shadowMatrix ) {
  7769. var j = 0;
  7770. for ( var i = 0, il = lights.length; i < il; i ++ ) {
  7771. var light = lights[ i ];
  7772. if ( ! light.castShadow ) continue;
  7773. if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) {
  7774. uniforms.shadowMap.texture[ j ] = light.shadowMap;
  7775. uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
  7776. uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;
  7777. uniforms.shadowDarkness.value[ j ] = light.shadowDarkness;
  7778. uniforms.shadowBias.value[ j ] = light.shadowBias;
  7779. j ++;
  7780. }
  7781. }
  7782. }
  7783. };
  7784. // Uniforms (load to GPU)
  7785. function loadUniformsMatrices ( uniforms, object ) {
  7786. _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrix.elements );
  7787. if ( uniforms.normalMatrix ) {
  7788. _gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );
  7789. }
  7790. };
  7791. function loadUniformsGeneric ( program, uniforms ) {
  7792. var uniform, value, type, location, texture, i, il, j, jl, offset;
  7793. for( j = 0, jl = uniforms.length; j < jl; j ++ ) {
  7794. location = program.uniforms[ uniforms[ j ][ 1 ] ];
  7795. if ( !location ) continue;
  7796. uniform = uniforms[ j ][ 0 ];
  7797. type = uniform.type;
  7798. value = uniform.value;
  7799. // single integer
  7800. if( type === "i" ) {
  7801. _gl.uniform1i( location, value );
  7802. // single float
  7803. } else if( type === "f" ) {
  7804. _gl.uniform1f( location, value );
  7805. // single THREE.Vector2
  7806. } else if( type === "v2" ) {
  7807. _gl.uniform2f( location, value.x, value.y );
  7808. // single THREE.Vector3
  7809. } else if( type === "v3" ) {
  7810. _gl.uniform3f( location, value.x, value.y, value.z );
  7811. // single THREE.Vector4
  7812. } else if( type === "v4" ) {
  7813. _gl.uniform4f( location, value.x, value.y, value.z, value.w );
  7814. // single THREE.Color
  7815. } else if( type === "c" ) {
  7816. _gl.uniform3f( location, value.r, value.g, value.b );
  7817. // flat array of floats (JS or typed array)
  7818. } else if( type === "fv1" ) {
  7819. _gl.uniform1fv( location, value );
  7820. // flat array of floats with 3 x N size (JS or typed array)
  7821. } else if( type === "fv" ) {
  7822. _gl.uniform3fv( location, value );
  7823. // array of THREE.Vector2
  7824. } else if( type === "v2v" ) {
  7825. if ( ! uniform._array ) {
  7826. uniform._array = new Float32Array( 2 * value.length );
  7827. }
  7828. for ( i = 0, il = value.length; i < il; i ++ ) {
  7829. offset = i * 2;
  7830. uniform._array[ offset ] = value[ i ].x;
  7831. uniform._array[ offset + 1 ] = value[ i ].y;
  7832. }
  7833. _gl.uniform2fv( location, uniform._array );
  7834. // array of THREE.Vector3
  7835. } else if( type === "v3v" ) {
  7836. if ( ! uniform._array ) {
  7837. uniform._array = new Float32Array( 3 * value.length );
  7838. }
  7839. for ( i = 0, il = value.length; i < il; i ++ ) {
  7840. offset = i * 3;
  7841. uniform._array[ offset ] = value[ i ].x;
  7842. uniform._array[ offset + 1 ] = value[ i ].y;
  7843. uniform._array[ offset + 2 ] = value[ i ].z;
  7844. }
  7845. _gl.uniform3fv( location, uniform._array );
  7846. // array of THREE.Vector4
  7847. } else if( type == "v4v" ) {
  7848. if ( ! uniform._array ) {
  7849. uniform._array = new Float32Array( 4 * value.length );
  7850. }
  7851. for ( i = 0, il = value.length; i < il; i ++ ) {
  7852. offset = i * 4;
  7853. uniform._array[ offset ] = value[ i ].x;
  7854. uniform._array[ offset + 1 ] = value[ i ].y;
  7855. uniform._array[ offset + 2 ] = value[ i ].z;
  7856. uniform._array[ offset + 3 ] = value[ i ].w;
  7857. }
  7858. _gl.uniform4fv( location, uniform._array );
  7859. // single THREE.Matrix4
  7860. } else if( type === "m4" ) {
  7861. if ( ! uniform._array ) {
  7862. uniform._array = new Float32Array( 16 );
  7863. }
  7864. value.flattenToArray( uniform._array );
  7865. _gl.uniformMatrix4fv( location, false, uniform._array );
  7866. // array of THREE.Matrix4
  7867. } else if( type === "m4v" ) {
  7868. if ( ! uniform._array ) {
  7869. uniform._array = new Float32Array( 16 * value.length );
  7870. }
  7871. for ( i = 0, il = value.length; i < il; i ++ ) {
  7872. value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
  7873. }
  7874. _gl.uniformMatrix4fv( location, false, uniform._array );
  7875. // single THREE.Texture (2d or cube)
  7876. } else if( type === "t" ) {
  7877. _gl.uniform1i( location, value );
  7878. texture = uniform.texture;
  7879. if ( !texture ) continue;
  7880. if ( texture.image instanceof Array && texture.image.length === 6 ) {
  7881. setCubeTexture( texture, value );
  7882. } else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
  7883. setCubeTextureDynamic( texture, value );
  7884. } else {
  7885. _this.setTexture( texture, value );
  7886. }
  7887. // array of THREE.Texture (2d)
  7888. } else if( type === "tv" ) {
  7889. if ( ! uniform._array ) {
  7890. uniform._array = [];
  7891. for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
  7892. uniform._array[ i ] = value + i;
  7893. }
  7894. }
  7895. _gl.uniform1iv( location, uniform._array );
  7896. for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
  7897. texture = uniform.texture[ i ];
  7898. if ( !texture ) continue;
  7899. _this.setTexture( texture, uniform._array[ i ] );
  7900. }
  7901. }
  7902. }
  7903. };
  7904. function setupMatrices ( object, camera ) {
  7905. object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld);
  7906. object._normalMatrix.getInverse( object._modelViewMatrix );
  7907. object._normalMatrix.transposeIntoArray( object._normalMatrixArray );
  7908. };
  7909. function setupLights ( program, lights ) {
  7910. var l, ll, light, n,
  7911. r = 0, g = 0, b = 0,
  7912. color, position, intensity, distance,
  7913. zlights = _lights,
  7914. dcolors = zlights.directional.colors,
  7915. dpositions = zlights.directional.positions,
  7916. pcolors = zlights.point.colors,
  7917. ppositions = zlights.point.positions,
  7918. pdistances = zlights.point.distances,
  7919. dlength = 0,
  7920. plength = 0,
  7921. doffset = 0,
  7922. poffset = 0;
  7923. for ( l = 0, ll = lights.length; l < ll; l ++ ) {
  7924. light = lights[ l ];
  7925. if ( light.onlyShadow ) continue;
  7926. color = light.color;
  7927. intensity = light.intensity;
  7928. distance = light.distance;
  7929. if ( light instanceof THREE.AmbientLight ) {
  7930. if ( _this.gammaInput ) {
  7931. r += color.r * color.r;
  7932. g += color.g * color.g;
  7933. b += color.b * color.b;
  7934. } else {
  7935. r += color.r;
  7936. g += color.g;
  7937. b += color.b;
  7938. }
  7939. } else if ( light instanceof THREE.DirectionalLight ) {
  7940. doffset = dlength * 3;
  7941. if ( _this.gammaInput ) {
  7942. dcolors[ doffset ] = color.r * color.r * intensity * intensity;
  7943. dcolors[ doffset + 1 ] = color.g * color.g * intensity * intensity;
  7944. dcolors[ doffset + 2 ] = color.b * color.b * intensity * intensity;
  7945. } else {
  7946. dcolors[ doffset ] = color.r * intensity;
  7947. dcolors[ doffset + 1 ] = color.g * intensity;
  7948. dcolors[ doffset + 2 ] = color.b * intensity;
  7949. }
  7950. _direction.copy( light.matrixWorld.getPosition() );
  7951. _direction.subSelf( light.target.matrixWorld.getPosition() );
  7952. _direction.normalize();
  7953. dpositions[ doffset ] = _direction.x;
  7954. dpositions[ doffset + 1 ] = _direction.y;
  7955. dpositions[ doffset + 2 ] = _direction.z;
  7956. dlength += 1;
  7957. } else if( light instanceof THREE.PointLight || light instanceof THREE.SpotLight ) {
  7958. poffset = plength * 3;
  7959. if ( _this.gammaInput ) {
  7960. pcolors[ poffset ] = color.r * color.r * intensity * intensity;
  7961. pcolors[ poffset + 1 ] = color.g * color.g * intensity * intensity;
  7962. pcolors[ poffset + 2 ] = color.b * color.b * intensity * intensity;
  7963. } else {
  7964. pcolors[ poffset ] = color.r * intensity;
  7965. pcolors[ poffset + 1 ] = color.g * intensity;
  7966. pcolors[ poffset + 2 ] = color.b * intensity;
  7967. }
  7968. position = light.matrixWorld.getPosition();
  7969. ppositions[ poffset ] = position.x;
  7970. ppositions[ poffset + 1 ] = position.y;
  7971. ppositions[ poffset + 2 ] = position.z;
  7972. pdistances[ plength ] = distance;
  7973. plength += 1;
  7974. }
  7975. }
  7976. // null eventual remains from removed lights
  7977. // (this is to avoid if in shader)
  7978. for ( l = dlength * 3, ll = dcolors.length; l < ll; l ++ ) dcolors[ l ] = 0.0;
  7979. for ( l = plength * 3, ll = pcolors.length; l < ll; l ++ ) pcolors[ l ] = 0.0;
  7980. zlights.point.length = plength;
  7981. zlights.directional.length = dlength;
  7982. zlights.ambient[ 0 ] = r;
  7983. zlights.ambient[ 1 ] = g;
  7984. zlights.ambient[ 2 ] = b;
  7985. };
  7986. // GL state setting
  7987. this.setFaceCulling = function ( cullFace, frontFace ) {
  7988. if ( cullFace ) {
  7989. if ( !frontFace || frontFace === "ccw" ) {
  7990. _gl.frontFace( _gl.CCW );
  7991. } else {
  7992. _gl.frontFace( _gl.CW );
  7993. }
  7994. if( cullFace === "back" ) {
  7995. _gl.cullFace( _gl.BACK );
  7996. } else if( cullFace === "front" ) {
  7997. _gl.cullFace( _gl.FRONT );
  7998. } else {
  7999. _gl.cullFace( _gl.FRONT_AND_BACK );
  8000. }
  8001. _gl.enable( _gl.CULL_FACE );
  8002. } else {
  8003. _gl.disable( _gl.CULL_FACE );
  8004. }
  8005. };
  8006. this.setObjectFaces = function ( object ) {
  8007. if ( _oldDoubleSided !== object.doubleSided ) {
  8008. if( object.doubleSided ) {
  8009. _gl.disable( _gl.CULL_FACE );
  8010. } else {
  8011. _gl.enable( _gl.CULL_FACE );
  8012. }
  8013. _oldDoubleSided = object.doubleSided;
  8014. }
  8015. if ( _oldFlipSided !== object.flipSided ) {
  8016. if( object.flipSided ) {
  8017. _gl.frontFace( _gl.CW );
  8018. } else {
  8019. _gl.frontFace( _gl.CCW );
  8020. }
  8021. _oldFlipSided = object.flipSided;
  8022. }
  8023. };
  8024. this.setDepthTest = function ( depthTest ) {
  8025. if ( _oldDepthTest !== depthTest ) {
  8026. if ( depthTest ) {
  8027. _gl.enable( _gl.DEPTH_TEST );
  8028. } else {
  8029. _gl.disable( _gl.DEPTH_TEST );
  8030. }
  8031. _oldDepthTest = depthTest;
  8032. }
  8033. };
  8034. this.setDepthWrite = function ( depthWrite ) {
  8035. if ( _oldDepthWrite !== depthWrite ) {
  8036. _gl.depthMask( depthWrite );
  8037. _oldDepthWrite = depthWrite;
  8038. }
  8039. };
  8040. function setLineWidth ( width ) {
  8041. if ( width !== _oldLineWidth ) {
  8042. _gl.lineWidth( width );
  8043. _oldLineWidth = width;
  8044. }
  8045. };
  8046. function setPolygonOffset ( polygonoffset, factor, units ) {
  8047. if ( _oldPolygonOffset !== polygonoffset ) {
  8048. if ( polygonoffset ) {
  8049. _gl.enable( _gl.POLYGON_OFFSET_FILL );
  8050. } else {
  8051. _gl.disable( _gl.POLYGON_OFFSET_FILL );
  8052. }
  8053. _oldPolygonOffset = polygonoffset;
  8054. }
  8055. if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
  8056. _gl.polygonOffset( factor, units );
  8057. _oldPolygonOffsetFactor = factor;
  8058. _oldPolygonOffsetUnits = units;
  8059. }
  8060. };
  8061. this.setBlending = function ( blending, blendEquation, blendSrc, blendDst ) {
  8062. if ( blending !== _oldBlending ) {
  8063. switch ( blending ) {
  8064. case THREE.NoBlending:
  8065. _gl.disable( _gl.BLEND );
  8066. break;
  8067. case THREE.AdditiveBlending:
  8068. _gl.enable( _gl.BLEND );
  8069. _gl.blendEquation( _gl.FUNC_ADD );
  8070. _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
  8071. break;
  8072. case THREE.SubtractiveBlending:
  8073. // TODO: Find blendFuncSeparate() combination
  8074. _gl.enable( _gl.BLEND );
  8075. _gl.blendEquation( _gl.FUNC_ADD );
  8076. _gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
  8077. break;
  8078. case THREE.MultiplyBlending:
  8079. // TODO: Find blendFuncSeparate() combination
  8080. _gl.enable( _gl.BLEND );
  8081. _gl.blendEquation( _gl.FUNC_ADD );
  8082. _gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
  8083. break;
  8084. case THREE.CustomBlending:
  8085. _gl.enable( _gl.BLEND );
  8086. break;
  8087. default:
  8088. _gl.enable( _gl.BLEND );
  8089. _gl.blendEquationSeparate( _gl.FUNC_ADD, _gl.FUNC_ADD );
  8090. _gl.blendFuncSeparate( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
  8091. break;
  8092. }
  8093. _oldBlending = blending;
  8094. }
  8095. if ( blending === THREE.CustomBlending ) {
  8096. if ( blendEquation !== _oldBlendEquation ) {
  8097. _gl.blendEquation( paramThreeToGL( blendEquation ) );
  8098. _oldBlendEquation = blendEquation;
  8099. }
  8100. if ( blendSrc !== _oldBlendSrc || blendDst !== _oldBlendDst ) {
  8101. _gl.blendFunc( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ) );
  8102. _oldBlendSrc = blendSrc;
  8103. _oldBlendDst = blendDst;
  8104. }
  8105. } else {
  8106. _oldBlendEquation = null;
  8107. _oldBlendSrc = null;
  8108. _oldBlendDst = null;
  8109. }
  8110. };
  8111. // Shaders
  8112. function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
  8113. var p, pl, program, code;
  8114. var chunks = [];
  8115. // Generate code
  8116. if ( shaderID ) {
  8117. chunks.push( shaderID );
  8118. } else {
  8119. chunks.push( fragmentShader );
  8120. chunks.push( vertexShader );
  8121. }
  8122. for ( p in parameters ) {
  8123. chunks.push( p );
  8124. chunks.push( parameters[ p ] );
  8125. }
  8126. code = chunks.join();
  8127. // Check if code has been already compiled
  8128. for ( p = 0, pl = _programs.length; p < pl; p ++ ) {
  8129. if ( _programs[ p ].code === code ) {
  8130. // console.log( "Code already compiled." /*: \n\n" + code*/ );
  8131. return _programs[ p ].program;
  8132. }
  8133. }
  8134. //console.log( "building new program " );
  8135. //
  8136. program = _gl.createProgram();
  8137. var prefix_vertex = [
  8138. "precision " + _precision + " float;",
  8139. ( _maxVertexTextures > 0 ) ? "#define VERTEX_TEXTURES" : "",
  8140. _this.gammaInput ? "#define GAMMA_INPUT" : "",
  8141. _this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
  8142. _this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",
  8143. "#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
  8144. "#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
  8145. "#define MAX_SHADOWS " + parameters.maxShadows,
  8146. "#define MAX_BONES " + parameters.maxBones,
  8147. parameters.map ? "#define USE_MAP" : "",
  8148. parameters.envMap ? "#define USE_ENVMAP" : "",
  8149. parameters.lightMap ? "#define USE_LIGHTMAP" : "",
  8150. parameters.vertexColors ? "#define USE_COLOR" : "",
  8151. parameters.skinning ? "#define USE_SKINNING" : "",
  8152. parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
  8153. parameters.morphNormals ? "#define USE_MORPHNORMALS" : "",
  8154. parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
  8155. parameters.wrapAround ? "#define WRAP_AROUND" : "",
  8156. parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
  8157. parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
  8158. parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
  8159. parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
  8160. parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
  8161. parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",
  8162. "uniform mat4 objectMatrix;",
  8163. "uniform mat4 modelViewMatrix;",
  8164. "uniform mat4 projectionMatrix;",
  8165. "uniform mat4 viewMatrix;",
  8166. "uniform mat3 normalMatrix;",
  8167. "uniform vec3 cameraPosition;",
  8168. "attribute vec3 position;",
  8169. "attribute vec3 normal;",
  8170. "attribute vec2 uv;",
  8171. "attribute vec2 uv2;",
  8172. "#ifdef USE_COLOR",
  8173. "attribute vec3 color;",
  8174. "#endif",
  8175. "#ifdef USE_MORPHTARGETS",
  8176. "attribute vec3 morphTarget0;",
  8177. "attribute vec3 morphTarget1;",
  8178. "attribute vec3 morphTarget2;",
  8179. "attribute vec3 morphTarget3;",
  8180. "#ifdef USE_MORPHNORMALS",
  8181. "attribute vec3 morphNormal0;",
  8182. "attribute vec3 morphNormal1;",
  8183. "attribute vec3 morphNormal2;",
  8184. "attribute vec3 morphNormal3;",
  8185. "#else",
  8186. "attribute vec3 morphTarget4;",
  8187. "attribute vec3 morphTarget5;",
  8188. "attribute vec3 morphTarget6;",
  8189. "attribute vec3 morphTarget7;",
  8190. "#endif",
  8191. "#endif",
  8192. "#ifdef USE_SKINNING",
  8193. "attribute vec4 skinVertexA;",
  8194. "attribute vec4 skinVertexB;",
  8195. "attribute vec4 skinIndex;",
  8196. "attribute vec4 skinWeight;",
  8197. "#endif",
  8198. ""
  8199. ].join("\n");
  8200. var prefix_fragment = [
  8201. "precision " + _precision + " float;",
  8202. "#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
  8203. "#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
  8204. "#define MAX_SHADOWS " + parameters.maxShadows,
  8205. parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",
  8206. _this.gammaInput ? "#define GAMMA_INPUT" : "",
  8207. _this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
  8208. _this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",
  8209. ( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
  8210. ( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
  8211. parameters.map ? "#define USE_MAP" : "",
  8212. parameters.envMap ? "#define USE_ENVMAP" : "",
  8213. parameters.lightMap ? "#define USE_LIGHTMAP" : "",
  8214. parameters.vertexColors ? "#define USE_COLOR" : "",
  8215. parameters.metal ? "#define METAL" : "",
  8216. parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
  8217. parameters.wrapAround ? "#define WRAP_AROUND" : "",
  8218. parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
  8219. parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
  8220. parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
  8221. parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
  8222. parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
  8223. "uniform mat4 viewMatrix;",
  8224. "uniform vec3 cameraPosition;",
  8225. ""
  8226. ].join("\n");
  8227. _gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
  8228. _gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
  8229. _gl.linkProgram( program );
  8230. if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
  8231. console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
  8232. }
  8233. //console.log( prefix_fragment + fragmentShader );
  8234. //console.log( prefix_vertex + vertexShader );
  8235. program.uniforms = {};
  8236. program.attributes = {};
  8237. var identifiers, u, a, i;
  8238. // cache uniform locations
  8239. identifiers = [
  8240. 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
  8241. 'boneGlobalMatrices', 'morphTargetInfluences'
  8242. ];
  8243. for ( u in uniforms ) {
  8244. identifiers.push( u );
  8245. }
  8246. cacheUniformLocations( program, identifiers );
  8247. // cache attributes locations
  8248. identifiers = [
  8249. "position", "normal", "uv", "uv2", "tangent", "color",
  8250. "skinVertexA", "skinVertexB", "skinIndex", "skinWeight"
  8251. ];
  8252. for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
  8253. identifiers.push( "morphTarget" + i );
  8254. }
  8255. for ( i = 0; i < parameters.maxMorphNormals; i ++ ) {
  8256. identifiers.push( "morphNormal" + i );
  8257. }
  8258. for ( a in attributes ) {
  8259. identifiers.push( a );
  8260. }
  8261. cacheAttributeLocations( program, identifiers );
  8262. program.id = _programs.length;
  8263. _programs.push( { program: program, code: code } );
  8264. _this.info.memory.programs = _programs.length;
  8265. return program;
  8266. };
  8267. // Shader parameters cache
  8268. function cacheUniformLocations ( program, identifiers ) {
  8269. var i, l, id;
  8270. for( i = 0, l = identifiers.length; i < l; i ++ ) {
  8271. id = identifiers[ i ];
  8272. program.uniforms[ id ] = _gl.getUniformLocation( program, id );
  8273. }
  8274. };
  8275. function cacheAttributeLocations ( program, identifiers ) {
  8276. var i, l, id;
  8277. for( i = 0, l = identifiers.length; i < l; i ++ ) {
  8278. id = identifiers[ i ];
  8279. program.attributes[ id ] = _gl.getAttribLocation( program, id );
  8280. }
  8281. };
  8282. function getShader ( type, string ) {
  8283. var shader;
  8284. if ( type === "fragment" ) {
  8285. shader = _gl.createShader( _gl.FRAGMENT_SHADER );
  8286. } else if ( type === "vertex" ) {
  8287. shader = _gl.createShader( _gl.VERTEX_SHADER );
  8288. }
  8289. _gl.shaderSource( shader, string );
  8290. _gl.compileShader( shader );
  8291. if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
  8292. console.error( _gl.getShaderInfoLog( shader ) );
  8293. console.error( string );
  8294. return null;
  8295. }
  8296. return shader;
  8297. };
  8298. // Textures
  8299. function isPowerOfTwo ( value ) {
  8300. return ( value & ( value - 1 ) ) === 0;
  8301. };
  8302. function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
  8303. if ( isImagePowerOfTwo ) {
  8304. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
  8305. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
  8306. _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
  8307. _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
  8308. } else {
  8309. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
  8310. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
  8311. _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
  8312. _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
  8313. }
  8314. };
  8315. this.setTexture = function ( texture, slot ) {
  8316. if ( texture.needsUpdate ) {
  8317. if ( ! texture.__webglInit ) {
  8318. texture.__webglInit = true;
  8319. texture.__webglTexture = _gl.createTexture();
  8320. _this.info.memory.textures ++;
  8321. }
  8322. _gl.activeTexture( _gl.TEXTURE0 + slot );
  8323. _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
  8324. _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
  8325. var image = texture.image,
  8326. isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
  8327. glFormat = paramThreeToGL( texture.format ),
  8328. glType = paramThreeToGL( texture.type );
  8329. setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );
  8330. if ( texture instanceof THREE.DataTexture ) {
  8331. _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
  8332. } else {
  8333. _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
  8334. }
  8335. if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
  8336. texture.needsUpdate = false;
  8337. if ( texture.onUpdate ) texture.onUpdate();
  8338. } else {
  8339. _gl.activeTexture( _gl.TEXTURE0 + slot );
  8340. _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
  8341. }
  8342. };
  8343. function clampToMaxSize ( image, maxSize ) {
  8344. if ( image.width <= maxSize && image.height <= maxSize ) {
  8345. return image;
  8346. }
  8347. // Warning: Scaling through the canvas will only work with images that use
  8348. // premultiplied alpha.
  8349. var maxDimension = Math.max( image.width, image.height );
  8350. var newWidth = Math.floor( image.width * maxSize / maxDimension );
  8351. var newHeight = Math.floor( image.height * maxSize / maxDimension );
  8352. var canvas = document.createElement( 'canvas' );
  8353. canvas.width = newWidth;
  8354. canvas.height = newHeight;
  8355. var ctx = canvas.getContext( "2d" );
  8356. ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight );
  8357. return canvas;
  8358. }
  8359. function setCubeTexture ( texture, slot ) {
  8360. if ( texture.image.length === 6 ) {
  8361. if ( texture.needsUpdate ) {
  8362. if ( ! texture.image.__webglTextureCube ) {
  8363. texture.image.__webglTextureCube = _gl.createTexture();
  8364. }
  8365. _gl.activeTexture( _gl.TEXTURE0 + slot );
  8366. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
  8367. var cubeImage = [];
  8368. for ( var i = 0; i < 6; i ++ ) {
  8369. if ( _this.autoScaleCubemaps ) {
  8370. cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );
  8371. } else {
  8372. cubeImage[ i ] = texture.image[ i ];
  8373. }
  8374. }
  8375. var image = cubeImage[ 0 ],
  8376. isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
  8377. glFormat = paramThreeToGL( texture.format ),
  8378. glType = paramThreeToGL( texture.type );
  8379. setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );
  8380. for ( var i = 0; i < 6; i ++ ) {
  8381. _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
  8382. }
  8383. if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
  8384. texture.needsUpdate = false;
  8385. if ( texture.onUpdate ) texture.onUpdate();
  8386. } else {
  8387. _gl.activeTexture( _gl.TEXTURE0 + slot );
  8388. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
  8389. }
  8390. }
  8391. };
  8392. function setCubeTextureDynamic ( texture, slot ) {
  8393. _gl.activeTexture( _gl.TEXTURE0 + slot );
  8394. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
  8395. };
  8396. // Render targets
  8397. function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
  8398. _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
  8399. _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
  8400. };
  8401. function setupRenderBuffer ( renderbuffer, renderTarget ) {
  8402. _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
  8403. if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
  8404. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
  8405. _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
  8406. /* For some reason this is not working. Defaulting to RGBA4.
  8407. } else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
  8408. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTarget.width, renderTarget.height );
  8409. _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
  8410. */
  8411. } else if( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
  8412. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
  8413. _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
  8414. } else {
  8415. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
  8416. }
  8417. };
  8418. this.setRenderTarget = function ( renderTarget ) {
  8419. var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
  8420. if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
  8421. if( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
  8422. if( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
  8423. renderTarget.__webglTexture = _gl.createTexture();
  8424. // Setup texture, create render and frame buffers
  8425. var isTargetPowerOfTwo = isPowerOfTwo( renderTarget.width ) && isPowerOfTwo( renderTarget.height ),
  8426. glFormat = paramThreeToGL( renderTarget.format ),
  8427. glType = paramThreeToGL( renderTarget.type );
  8428. if ( isCube ) {
  8429. renderTarget.__webglFramebuffer = [];
  8430. renderTarget.__webglRenderbuffer = [];
  8431. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
  8432. setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
  8433. for ( var i = 0; i < 6; i ++ ) {
  8434. renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
  8435. renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
  8436. _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
  8437. setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
  8438. setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
  8439. }
  8440. if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
  8441. } else {
  8442. renderTarget.__webglFramebuffer = _gl.createFramebuffer();
  8443. renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
  8444. _gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
  8445. setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
  8446. _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
  8447. setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
  8448. setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
  8449. if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
  8450. }
  8451. // Release everything
  8452. if ( isCube ) {
  8453. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
  8454. } else {
  8455. _gl.bindTexture( _gl.TEXTURE_2D, null );
  8456. }
  8457. _gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
  8458. _gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
  8459. }
  8460. var framebuffer, width, height, vx, vy;
  8461. if ( renderTarget ) {
  8462. if ( isCube ) {
  8463. framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
  8464. } else {
  8465. framebuffer = renderTarget.__webglFramebuffer;
  8466. }
  8467. width = renderTarget.width;
  8468. height = renderTarget.height;
  8469. vx = 0;
  8470. vy = 0;
  8471. } else {
  8472. framebuffer = null;
  8473. width = _viewportWidth;
  8474. height = _viewportHeight;
  8475. vx = _viewportX;
  8476. vy = _viewportY;
  8477. }
  8478. if ( framebuffer !== _currentFramebuffer ) {
  8479. _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
  8480. _gl.viewport( vx, vy, width, height );
  8481. _currentFramebuffer = framebuffer;
  8482. }
  8483. _currentWidth = width;
  8484. _currentHeight = height;
  8485. };
  8486. function updateRenderTargetMipmap ( renderTarget ) {
  8487. if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
  8488. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
  8489. _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
  8490. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
  8491. } else {
  8492. _gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
  8493. _gl.generateMipmap( _gl.TEXTURE_2D );
  8494. _gl.bindTexture( _gl.TEXTURE_2D, null );
  8495. }
  8496. };
  8497. // Fallback filters for non-power-of-2 textures
  8498. function filterFallback ( f ) {
  8499. switch ( f ) {
  8500. case THREE.NearestFilter:
  8501. case THREE.NearestMipMapNearestFilter:
  8502. case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;
  8503. case THREE.LinearFilter:
  8504. case THREE.LinearMipMapNearestFilter:
  8505. case THREE.LinearMipMapLinearFilter:
  8506. default:
  8507. return _gl.LINEAR; break;
  8508. }
  8509. };
  8510. // Map three.js constants to WebGL constants
  8511. function paramThreeToGL ( p ) {
  8512. switch ( p ) {
  8513. case THREE.RepeatWrapping: return _gl.REPEAT; break;
  8514. case THREE.ClampToEdgeWrapping: return _gl.CLAMP_TO_EDGE; break;
  8515. case THREE.MirroredRepeatWrapping: return _gl.MIRRORED_REPEAT; break;
  8516. case THREE.NearestFilter: return _gl.NEAREST; break;
  8517. case THREE.NearestMipMapNearestFilter: return _gl.NEAREST_MIPMAP_NEAREST; break;
  8518. case THREE.NearestMipMapLinearFilter: return _gl.NEAREST_MIPMAP_LINEAR; break;
  8519. case THREE.LinearFilter: return _gl.LINEAR; break;
  8520. case THREE.LinearMipMapNearestFilter: return _gl.LINEAR_MIPMAP_NEAREST; break;
  8521. case THREE.LinearMipMapLinearFilter: return _gl.LINEAR_MIPMAP_LINEAR; break;
  8522. case THREE.ByteType: return _gl.BYTE; break;
  8523. case THREE.UnsignedByteType: return _gl.UNSIGNED_BYTE; break;
  8524. case THREE.ShortType: return _gl.SHORT; break;
  8525. case THREE.UnsignedShortType: return _gl.UNSIGNED_SHORT; break;
  8526. case THREE.IntType: return _gl.INT; break;
  8527. case THREE.UnsignedIntType: return _gl.UNSIGNED_INT; break;
  8528. case THREE.FloatType: return _gl.FLOAT; break;
  8529. case THREE.AlphaFormat: return _gl.ALPHA; break;
  8530. case THREE.RGBFormat: return _gl.RGB; break;
  8531. case THREE.RGBAFormat: return _gl.RGBA; break;
  8532. case THREE.LuminanceFormat: return _gl.LUMINANCE; break;
  8533. case THREE.LuminanceAlphaFormat: return _gl.LUMINANCE_ALPHA; break;
  8534. case THREE.AddEquation: return _gl.FUNC_ADD; break;
  8535. case THREE.SubtractEquation: return _gl.FUNC_SUBTRACT; break;
  8536. case THREE.ReverseSubtractEquation: return _gl.FUNC_REVERSE_SUBTRACT; break;
  8537. case THREE.ZeroFactor: return _gl.ZERO; break;
  8538. case THREE.OneFactor: return _gl.ONE; break;
  8539. case THREE.SrcColorFactor: return _gl.SRC_COLOR; break;
  8540. case THREE.OneMinusSrcColorFactor: return _gl.ONE_MINUS_SRC_COLOR; break;
  8541. case THREE.SrcAlphaFactor: return _gl.SRC_ALPHA; break;
  8542. case THREE.OneMinusSrcAlphaFactor: return _gl.ONE_MINUS_SRC_ALPHA; break;
  8543. case THREE.DstAlphaFactor: return _gl.DST_ALPHA; break;
  8544. case THREE.OneMinusDstAlphaFactor: return _gl.ONE_MINUS_DST_ALPHA; break;
  8545. case THREE.DstColorFactor: return _gl.DST_COLOR; break;
  8546. case THREE.OneMinusDstColorFactor: return _gl.ONE_MINUS_DST_COLOR; break;
  8547. case THREE.SrcAlphaSaturateFactor: return _gl.SRC_ALPHA_SATURATE; break;
  8548. }
  8549. return 0;
  8550. };
  8551. // Allocations
  8552. function allocateBones ( object ) {
  8553. // default for when object is not specified
  8554. // ( for example when prebuilding shader
  8555. // to be used with multiple objects )
  8556. //
  8557. // - leave some extra space for other uniforms
  8558. // - limit here is ANGLE's 254 max uniform vectors
  8559. // (up to 54 should be safe)
  8560. var maxBones = 50;
  8561. if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
  8562. maxBones = object.bones.length;
  8563. }
  8564. return maxBones;
  8565. };
  8566. function allocateLights ( lights ) {
  8567. var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
  8568. dirLights = pointLights = maxDirLights = maxPointLights = 0;
  8569. for ( l = 0, ll = lights.length; l < ll; l++ ) {
  8570. light = lights[ l ];
  8571. if ( light.onlyShadow ) continue;
  8572. if ( light instanceof THREE.DirectionalLight ) dirLights ++;
  8573. if ( light instanceof THREE.PointLight ) pointLights ++;
  8574. if ( light instanceof THREE.SpotLight ) pointLights ++;
  8575. }
  8576. if ( ( pointLights + dirLights ) <= _maxLights ) {
  8577. maxDirLights = dirLights;
  8578. maxPointLights = pointLights;
  8579. } else {
  8580. maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
  8581. maxPointLights = _maxLights - maxDirLights;
  8582. }
  8583. return { 'directional' : maxDirLights, 'point' : maxPointLights };
  8584. };
  8585. function allocateShadows ( lights ) {
  8586. var l, ll, light, maxShadows = 0;
  8587. for ( l = 0, ll = lights.length; l < ll; l++ ) {
  8588. light = lights[ l ];
  8589. if ( ! light.castShadow ) continue;
  8590. if ( light instanceof THREE.SpotLight ) maxShadows ++;
  8591. if ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) maxShadows ++;
  8592. }
  8593. return maxShadows;
  8594. };
  8595. // Initialization
  8596. function initGL () {
  8597. var gl;
  8598. try {
  8599. if ( ! ( gl = _canvas.getContext( 'experimental-webgl', { alpha: _alpha, premultipliedAlpha: _premultipliedAlpha, antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {
  8600. throw 'Error creating WebGL context.';
  8601. }
  8602. console.log(
  8603. navigator.userAgent + " | " +
  8604. gl.getParameter( gl.VERSION ) + " | " +
  8605. gl.getParameter( gl.VENDOR ) + " | " +
  8606. gl.getParameter( gl.RENDERER ) + " | " +
  8607. gl.getParameter( gl.SHADING_LANGUAGE_VERSION )
  8608. );
  8609. } catch ( error ) {
  8610. console.error( error );
  8611. }
  8612. return gl;
  8613. };
  8614. function setDefaultGLState () {
  8615. _gl.clearColor( 0, 0, 0, 1 );
  8616. _gl.clearDepth( 1 );
  8617. _gl.clearStencil( 0 );
  8618. _gl.enable( _gl.DEPTH_TEST );
  8619. _gl.depthFunc( _gl.LEQUAL );
  8620. _gl.frontFace( _gl.CCW );
  8621. _gl.cullFace( _gl.BACK );
  8622. _gl.enable( _gl.CULL_FACE );
  8623. _gl.enable( _gl.BLEND );
  8624. _gl.blendEquation( _gl.FUNC_ADD );
  8625. _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );
  8626. _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
  8627. };
  8628. // default plugins (order is important)
  8629. this.shadowMapPlugin = new THREE.ShadowMapPlugin();
  8630. this.addPrePlugin( this.shadowMapPlugin );
  8631. this.addPostPlugin( new THREE.SpritePlugin() );
  8632. this.addPostPlugin( new THREE.LensFlarePlugin() );
  8633. };
  8634. /**
  8635. * @author szimek / https://github.com/szimek/
  8636. */
  8637. THREE.WebGLRenderTarget = function ( width, height, options ) {
  8638. this.width = width;
  8639. this.height = height;
  8640. options = options || {};
  8641. this.wrapS = options.wrapS !== undefined ? options.wrapS : THREE.ClampToEdgeWrapping;
  8642. this.wrapT = options.wrapT !== undefined ? options.wrapT : THREE.ClampToEdgeWrapping;
  8643. this.magFilter = options.magFilter !== undefined ? options.magFilter : THREE.LinearFilter;
  8644. this.minFilter = options.minFilter !== undefined ? options.minFilter : THREE.LinearMipMapLinearFilter;
  8645. this.offset = new THREE.Vector2( 0, 0 );
  8646. this.repeat = new THREE.Vector2( 1, 1 );
  8647. this.format = options.format !== undefined ? options.format : THREE.RGBAFormat;
  8648. this.type = options.type !== undefined ? options.type : THREE.UnsignedByteType;
  8649. this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
  8650. this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;
  8651. this.generateMipmaps = true;
  8652. };
  8653. THREE.WebGLRenderTarget.prototype.clone = function() {
  8654. var tmp = new THREE.WebGLRenderTarget( this.width, this.height );
  8655. tmp.wrapS = this.wrapS;
  8656. tmp.wrapT = this.wrapT;
  8657. tmp.magFilter = this.magFilter;
  8658. tmp.minFilter = this.minFilter;
  8659. tmp.offset.copy( this.offset );
  8660. tmp.repeat.copy( this.repeat );
  8661. tmp.format = this.format;
  8662. tmp.type = this.type;
  8663. tmp.depthBuffer = this.depthBuffer;
  8664. tmp.stencilBuffer = this.stencilBuffer;
  8665. return tmp;
  8666. };
  8667. /**
  8668. * @author alteredq / http://alteredqualia.com
  8669. */
  8670. THREE.WebGLRenderTargetCube = function ( width, height, options ) {
  8671. THREE.WebGLRenderTarget.call( this, width, height, options );
  8672. this.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5
  8673. };
  8674. THREE.WebGLRenderTargetCube.prototype = new THREE.WebGLRenderTarget();
  8675. THREE.WebGLRenderTargetCube.prototype.constructor = THREE.WebGLRenderTargetCube;
  8676. /**
  8677. * @author mr.doob / http://mrdoob.com/
  8678. */
  8679. THREE.RenderableVertex = function () {
  8680. this.positionWorld = new THREE.Vector3();
  8681. this.positionScreen = new THREE.Vector4();
  8682. this.visible = true;
  8683. };
  8684. THREE.RenderableVertex.prototype.copy = function ( vertex ) {
  8685. this.positionWorld.copy( vertex.positionWorld );
  8686. this.positionScreen.copy( vertex.positionScreen );
  8687. }
  8688. /**
  8689. * @author mr.doob / http://mrdoob.com/
  8690. */
  8691. THREE.RenderableFace3 = function () {
  8692. this.v1 = new THREE.RenderableVertex();
  8693. this.v2 = new THREE.RenderableVertex();
  8694. this.v3 = new THREE.RenderableVertex();
  8695. this.centroidWorld = new THREE.Vector3();
  8696. this.centroidScreen = new THREE.Vector3();
  8697. this.normalWorld = new THREE.Vector3();
  8698. this.vertexNormalsWorld = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
  8699. this.material = null;
  8700. this.faceMaterial = null;
  8701. this.uvs = [[]];
  8702. this.z = null;
  8703. };
  8704. /**
  8705. * @author mr.doob / http://mrdoob.com/
  8706. */
  8707. THREE.RenderableFace4 = function () {
  8708. this.v1 = new THREE.RenderableVertex();
  8709. this.v2 = new THREE.RenderableVertex();
  8710. this.v3 = new THREE.RenderableVertex();
  8711. this.v4 = new THREE.RenderableVertex();
  8712. this.centroidWorld = new THREE.Vector3();
  8713. this.centroidScreen = new THREE.Vector3();
  8714. this.normalWorld = new THREE.Vector3();
  8715. this.vertexNormalsWorld = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
  8716. this.material = null;
  8717. this.faceMaterial = null;
  8718. this.uvs = [[]];
  8719. this.z = null;
  8720. };
  8721. /**
  8722. * @author mr.doob / http://mrdoob.com/
  8723. */
  8724. THREE.RenderableObject = function () {
  8725. this.object = null;
  8726. this.z = null;
  8727. };
  8728. /**
  8729. * @author mr.doob / http://mrdoob.com/
  8730. */
  8731. THREE.RenderableParticle = function () {
  8732. this.x = null;
  8733. this.y = null;
  8734. this.z = null;
  8735. this.rotation = null;
  8736. this.scale = new THREE.Vector2();
  8737. this.material = null;
  8738. };
  8739. /**
  8740. * @author mr.doob / http://mrdoob.com/
  8741. */
  8742. THREE.RenderableLine = function () {
  8743. this.z = null;
  8744. this.v1 = new THREE.RenderableVertex();
  8745. this.v2 = new THREE.RenderableVertex();
  8746. this.material = null;
  8747. };
  8748. /**
  8749. * @author alteredq / http://alteredqualia.com/
  8750. */
  8751. THREE.BufferGeometry = function () {
  8752. this.id = THREE.GeometryCount ++;
  8753. // GL buffers
  8754. this.vertexIndexBuffer = null;
  8755. this.vertexPositionBuffer = null;
  8756. this.vertexNormalBuffer = null;
  8757. this.vertexUvBuffer = null;
  8758. this.vertexColorBuffer = null;
  8759. // typed arrays (kept only if dynamic flag is set)
  8760. this.vertexIndexArray = null;
  8761. this.vertexPositionArray = null;
  8762. this.vertexNormalArray = null;
  8763. this.vertexUvArray = null;
  8764. this.vertexColorArray = null;
  8765. this.dynamic = false;
  8766. // boundings
  8767. this.boundingBox = null;
  8768. this.boundingSphere = null;
  8769. // for compatibility
  8770. this.morphTargets = [];
  8771. };
  8772. THREE.BufferGeometry.prototype = {
  8773. constructor : THREE.BufferGeometry,
  8774. // for compatibility
  8775. computeBoundingBox: function () {
  8776. },
  8777. // for compatibility
  8778. computeBoundingSphere: function () {
  8779. }
  8780. };
  8781. /**
  8782. * @author alteredq / http://alteredqualia.com/
  8783. */
  8784. THREE.Gyroscope = function () {
  8785. THREE.Object3D.call( this );
  8786. };
  8787. THREE.Gyroscope.prototype = new THREE.Object3D();
  8788. THREE.Gyroscope.prototype.constructor = THREE.Gyroscope;
  8789. THREE.Gyroscope.prototype.updateMatrixWorld = function ( force ) {
  8790. this.matrixAutoUpdate && this.updateMatrix();
  8791. // update matrixWorld
  8792. if ( this.matrixWorldNeedsUpdate || force ) {
  8793. if ( this.parent ) {
  8794. this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
  8795. this.matrixWorld.decompose( this.translationWorld, this.rotationWorld, this.scaleWorld );
  8796. this.matrix.decompose( this.translationObject, this.rotationObject, this.scaleObject );
  8797. this.matrixWorld.compose( this.translationWorld, this.rotationObject, this.scaleWorld );
  8798. } else {
  8799. this.matrixWorld.copy( this.matrix );
  8800. }
  8801. this.matrixWorldNeedsUpdate = false;
  8802. force = true;
  8803. }
  8804. // update children
  8805. for ( var i = 0, l = this.children.length; i < l; i ++ ) {
  8806. this.children[ i ].updateMatrixWorld( force );
  8807. }
  8808. };
  8809. THREE.Gyroscope.prototype.translationWorld = new THREE.Vector3();
  8810. THREE.Gyroscope.prototype.translationObject = new THREE.Vector3();
  8811. THREE.Gyroscope.prototype.rotationWorld = new THREE.Quaternion();
  8812. THREE.Gyroscope.prototype.rotationObject = new THREE.Quaternion();
  8813. THREE.Gyroscope.prototype.scaleWorld = new THREE.Vector3();
  8814. THREE.Gyroscope.prototype.scaleObject = new THREE.Vector3();
  8815. /**
  8816. * @author alteredq / http://alteredqualia.com/
  8817. *
  8818. * - shows frustum, line of sight and up of the camera
  8819. * - suitable for fast updates
  8820. * - based on frustum visualization in lightgl.js shadowmap example
  8821. * http://evanw.github.com/lightgl.js/tests/shadowmap.html
  8822. */
  8823. THREE.CameraHelper = function ( camera ) {
  8824. THREE.Object3D.call( this );
  8825. var _this = this;
  8826. this.lineGeometry = new THREE.Geometry();
  8827. this.lineMaterial = new THREE.LineBasicMaterial( { color: 0xffffff, vertexColors: THREE.FaceColors } );
  8828. this.pointMap = {};
  8829. // colors
  8830. var hexFrustum = 0xffaa00,
  8831. hexCone = 0xff0000,
  8832. hexUp = 0x00aaff,
  8833. hexTarget = 0xffffff,
  8834. hexCross = 0x333333;
  8835. // near
  8836. addLine( "n1", "n2", hexFrustum );
  8837. addLine( "n2", "n4", hexFrustum );
  8838. addLine( "n4", "n3", hexFrustum );
  8839. addLine( "n3", "n1", hexFrustum );
  8840. // far
  8841. addLine( "f1", "f2", hexFrustum );
  8842. addLine( "f2", "f4", hexFrustum );
  8843. addLine( "f4", "f3", hexFrustum );
  8844. addLine( "f3", "f1", hexFrustum );
  8845. // sides
  8846. addLine( "n1", "f1", hexFrustum );
  8847. addLine( "n2", "f2", hexFrustum );
  8848. addLine( "n3", "f3", hexFrustum );
  8849. addLine( "n4", "f4", hexFrustum );
  8850. // cone
  8851. addLine( "p", "n1", hexCone );
  8852. addLine( "p", "n2", hexCone );
  8853. addLine( "p", "n3", hexCone );
  8854. addLine( "p", "n4", hexCone );
  8855. // up
  8856. addLine( "u1", "u2", hexUp );
  8857. addLine( "u2", "u3", hexUp );
  8858. addLine( "u3", "u1", hexUp );
  8859. // target
  8860. addLine( "c", "t", hexTarget );
  8861. addLine( "p", "c", hexCross );
  8862. // cross
  8863. addLine( "cn1", "cn2", hexCross );
  8864. addLine( "cn3", "cn4", hexCross );
  8865. addLine( "cf1", "cf2", hexCross );
  8866. addLine( "cf3", "cf4", hexCross );
  8867. this.camera = camera;
  8868. function addLine( a, b, hex ) {
  8869. addPoint( a, hex );
  8870. addPoint( b, hex );
  8871. }
  8872. function addPoint( id, hex ) {
  8873. _this.lineGeometry.vertices.push( new THREE.Vertex( new THREE.Vector3() ) );
  8874. _this.lineGeometry.colors.push( new THREE.Color( hex ) );
  8875. if ( _this.pointMap[ id ] === undefined ) _this.pointMap[ id ] = [];
  8876. _this.pointMap[ id ].push( _this.lineGeometry.vertices.length - 1 );
  8877. }
  8878. this.update( camera );
  8879. this.lines = new THREE.Line( this.lineGeometry, this.lineMaterial, THREE.LinePieces );
  8880. this.add( this.lines );
  8881. };
  8882. THREE.CameraHelper.prototype = new THREE.Object3D();
  8883. THREE.CameraHelper.prototype.constructor = THREE.CameraHelper;
  8884. THREE.CameraHelper.prototype.update = function () {
  8885. var camera = this.camera;
  8886. var w = 1;
  8887. var h = 1;
  8888. var _this = this;
  8889. // we need just camera projection matrix
  8890. // world matrix must be identity
  8891. THREE.CameraHelper.__c.projectionMatrix.copy( camera.projectionMatrix );
  8892. // center / target
  8893. setPoint( "c", 0, 0, -1 );
  8894. setPoint( "t", 0, 0, 1 );
  8895. // near
  8896. setPoint( "n1", -w, -h, -1 );
  8897. setPoint( "n2", w, -h, -1 );
  8898. setPoint( "n3", -w, h, -1 );
  8899. setPoint( "n4", w, h, -1 );
  8900. // far
  8901. setPoint( "f1", -w, -h, 1 );
  8902. setPoint( "f2", w, -h, 1 );
  8903. setPoint( "f3", -w, h, 1 );
  8904. setPoint( "f4", w, h, 1 );
  8905. // up
  8906. setPoint( "u1", w * 0.7, h * 1.1, -1 );
  8907. setPoint( "u2", -w * 0.7, h * 1.1, -1 );
  8908. setPoint( "u3", 0, h * 2, -1 );
  8909. // cross
  8910. setPoint( "cf1", -w, 0, 1 );
  8911. setPoint( "cf2", w, 0, 1 );
  8912. setPoint( "cf3", 0, -h, 1 );
  8913. setPoint( "cf4", 0, h, 1 );
  8914. setPoint( "cn1", -w, 0, -1 );
  8915. setPoint( "cn2", w, 0, -1 );
  8916. setPoint( "cn3", 0, -h, -1 );
  8917. setPoint( "cn4", 0, h, -1 );
  8918. function setPoint( point, x, y, z ) {
  8919. THREE.CameraHelper.__v.set( x, y, z );
  8920. THREE.CameraHelper.__projector.unprojectVector( THREE.CameraHelper.__v, THREE.CameraHelper.__c );
  8921. var points = _this.pointMap[ point ];
  8922. if ( points !== undefined ) {
  8923. for ( var i = 0, il = points.length; i < il; i ++ ) {
  8924. var j = points[ i ];
  8925. _this.lineGeometry.vertices[ j ].position.copy( THREE.CameraHelper.__v );
  8926. }
  8927. }
  8928. }
  8929. this.lineGeometry.__dirtyVertices = true;
  8930. };
  8931. THREE.CameraHelper.__projector = new THREE.Projector();
  8932. THREE.CameraHelper.__v = new THREE.Vector3();
  8933. THREE.CameraHelper.__c = new THREE.Camera();
  8934. /**
  8935. * @author mikael emtinger / http://gomo.se/
  8936. * @author alteredq / http://alteredqualia.com/
  8937. */
  8938. THREE.LensFlare = function ( texture, size, distance, blending, color ) {
  8939. THREE.Object3D.call( this );
  8940. this.lensFlares = [];
  8941. this.positionScreen = new THREE.Vector3();
  8942. this.customUpdateCallback = undefined;
  8943. if( texture !== undefined ) {
  8944. this.add( texture, size, distance, blending, color );
  8945. }
  8946. };
  8947. THREE.LensFlare.prototype = new THREE.Object3D();
  8948. THREE.LensFlare.prototype.constructor = THREE.LensFlare;
  8949. THREE.LensFlare.prototype.supr = THREE.Object3D.prototype;
  8950. /*
  8951. * Add: adds another flare
  8952. */
  8953. THREE.LensFlare.prototype.add = function ( texture, size, distance, blending, color, opacity ) {
  8954. if( size === undefined ) size = -1;
  8955. if( distance === undefined ) distance = 0;
  8956. if( opacity === undefined ) opacity = 1;
  8957. if( color === undefined ) color = new THREE.Color( 0xffffff );
  8958. if( blending === undefined ) blending = THREE.NormalBlending;
  8959. distance = Math.min( distance, Math.max( 0, distance ) );
  8960. this.lensFlares.push( { texture: texture, // THREE.Texture
  8961. size: size, // size in pixels (-1 = use texture.width)
  8962. distance: distance, // distance (0-1) from light source (0=at light source)
  8963. x: 0, y: 0, z: 0, // screen position (-1 => 1) z = 0 is ontop z = 1 is back
  8964. scale: 1, // scale
  8965. rotation: 1, // rotation
  8966. opacity: opacity, // opacity
  8967. color: color, // color
  8968. blending: blending } ); // blending
  8969. };
  8970. /*
  8971. * Update lens flares update positions on all flares based on the screen position
  8972. * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.
  8973. */
  8974. THREE.LensFlare.prototype.updateLensFlares = function () {
  8975. var f, fl = this.lensFlares.length;
  8976. var flare;
  8977. var vecX = -this.positionScreen.x * 2;
  8978. var vecY = -this.positionScreen.y * 2;
  8979. for( f = 0; f < fl; f ++ ) {
  8980. flare = this.lensFlares[ f ];
  8981. flare.x = this.positionScreen.x + vecX * flare.distance;
  8982. flare.y = this.positionScreen.y + vecY * flare.distance;
  8983. flare.wantedRotation = flare.x * Math.PI * 0.25;
  8984. flare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;
  8985. }
  8986. };
  8987. /**
  8988. * @author alteredq / http://alteredqualia.com/
  8989. */
  8990. THREE.ImmediateRenderObject = function ( ) {
  8991. THREE.Object3D.call( this );
  8992. this.render = function( renderCallback ) {
  8993. };
  8994. };
  8995. THREE.ImmediateRenderObject.prototype = new THREE.Object3D();
  8996. THREE.ImmediateRenderObject.prototype.constructor = THREE.ImmediateRenderObject;
  8997. /**
  8998. * @author mikael emtinger / http://gomo.se/
  8999. * @author alteredq / http://alteredqualia.com/
  9000. */
  9001. THREE.LensFlarePlugin = function ( ) {
  9002. var _gl, _renderer, _lensFlare = {};
  9003. this.init = function ( renderer ) {
  9004. _gl = renderer.context;
  9005. _renderer = renderer;
  9006. _lensFlare.vertices = new Float32Array( 8 + 8 );
  9007. _lensFlare.faces = new Uint16Array( 6 );
  9008. var i = 0;
  9009. _lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = -1; // vertex
  9010. _lensFlare.vertices[ i++ ] = 0; _lensFlare.vertices[ i++ ] = 0; // uv... etc.
  9011. _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = -1;
  9012. _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 0;
  9013. _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 1;
  9014. _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 1;
  9015. _lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = 1;
  9016. _lensFlare.vertices[ i++ ] = 0; _lensFlare.vertices[ i++ ] = 1;
  9017. i = 0;
  9018. _lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 1; _lensFlare.faces[ i++ ] = 2;
  9019. _lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 2; _lensFlare.faces[ i++ ] = 3;
  9020. // buffers
  9021. _lensFlare.vertexBuffer = _gl.createBuffer();
  9022. _lensFlare.elementBuffer = _gl.createBuffer();
  9023. _gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
  9024. _gl.bufferData( _gl.ARRAY_BUFFER, _lensFlare.vertices, _gl.STATIC_DRAW );
  9025. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
  9026. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.faces, _gl.STATIC_DRAW );
  9027. // textures
  9028. _lensFlare.tempTexture = _gl.createTexture();
  9029. _lensFlare.occlusionTexture = _gl.createTexture();
  9030. _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
  9031. _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, 16, 16, 0, _gl.RGB, _gl.UNSIGNED_BYTE, null );
  9032. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
  9033. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
  9034. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
  9035. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
  9036. _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
  9037. _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, 16, 16, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, null );
  9038. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
  9039. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
  9040. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
  9041. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
  9042. if ( _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ) <= 0 ) {
  9043. _lensFlare.hasVertexTexture = false;
  9044. _lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlare" ] );
  9045. } else {
  9046. _lensFlare.hasVertexTexture = true;
  9047. _lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlareVertexTexture" ] );
  9048. }
  9049. _lensFlare.attributes = {};
  9050. _lensFlare.uniforms = {};
  9051. _lensFlare.attributes.vertex = _gl.getAttribLocation ( _lensFlare.program, "position" );
  9052. _lensFlare.attributes.uv = _gl.getAttribLocation ( _lensFlare.program, "uv" );
  9053. _lensFlare.uniforms.renderType = _gl.getUniformLocation( _lensFlare.program, "renderType" );
  9054. _lensFlare.uniforms.map = _gl.getUniformLocation( _lensFlare.program, "map" );
  9055. _lensFlare.uniforms.occlusionMap = _gl.getUniformLocation( _lensFlare.program, "occlusionMap" );
  9056. _lensFlare.uniforms.opacity = _gl.getUniformLocation( _lensFlare.program, "opacity" );
  9057. _lensFlare.uniforms.color = _gl.getUniformLocation( _lensFlare.program, "color" );
  9058. _lensFlare.uniforms.scale = _gl.getUniformLocation( _lensFlare.program, "scale" );
  9059. _lensFlare.uniforms.rotation = _gl.getUniformLocation( _lensFlare.program, "rotation" );
  9060. _lensFlare.uniforms.screenPosition = _gl.getUniformLocation( _lensFlare.program, "screenPosition" );
  9061. _lensFlare.attributesEnabled = false;
  9062. };
  9063. /*
  9064. * Render lens flares
  9065. * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,
  9066. * reads these back and calculates occlusion.
  9067. * Then _lensFlare.update_lensFlares() is called to re-position and
  9068. * update transparency of flares. Then they are rendered.
  9069. *
  9070. */
  9071. this.render = function ( scene, camera, viewportWidth, viewportHeight ) {
  9072. var flares = scene.__webglFlares,
  9073. nFlares = flares.length;
  9074. if ( ! nFlares ) return;
  9075. var tempPosition = new THREE.Vector3();
  9076. var invAspect = viewportHeight / viewportWidth,
  9077. halfViewportWidth = viewportWidth * 0.5,
  9078. halfViewportHeight = viewportHeight * 0.5;
  9079. var size = 16 / viewportHeight,
  9080. scale = new THREE.Vector2( size * invAspect, size );
  9081. var screenPosition = new THREE.Vector3( 1, 1, 0 ),
  9082. screenPositionPixels = new THREE.Vector2( 1, 1 );
  9083. var uniforms = _lensFlare.uniforms,
  9084. attributes = _lensFlare.attributes;
  9085. // set _lensFlare program and reset blending
  9086. _gl.useProgram( _lensFlare.program );
  9087. if ( ! _lensFlare.attributesEnabled ) {
  9088. _gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
  9089. _gl.enableVertexAttribArray( _lensFlare.attributes.uv );
  9090. _lensFlare.attributesEnabled = true;
  9091. }
  9092. // loop through all lens flares to update their occlusion and positions
  9093. // setup gl and common used attribs/unforms
  9094. _gl.uniform1i( uniforms.occlusionMap, 0 );
  9095. _gl.uniform1i( uniforms.map, 1 );
  9096. _gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
  9097. _gl.vertexAttribPointer( attributes.vertex, 2, _gl.FLOAT, false, 2 * 8, 0 );
  9098. _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );
  9099. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
  9100. _gl.disable( _gl.CULL_FACE );
  9101. _gl.depthMask( false );
  9102. var i, j, jl, flare, sprite;
  9103. for ( i = 0; i < nFlares; i ++ ) {
  9104. size = 16 / viewportHeight;
  9105. scale.set( size * invAspect, size );
  9106. // calc object screen position
  9107. flare = flares[ i ];
  9108. tempPosition.set( flare.matrixWorld.elements[12], flare.matrixWorld.elements[13], flare.matrixWorld.elements[14] );
  9109. camera.matrixWorldInverse.multiplyVector3( tempPosition );
  9110. camera.projectionMatrix.multiplyVector3( tempPosition );
  9111. // setup arrays for gl programs
  9112. screenPosition.copy( tempPosition )
  9113. screenPositionPixels.x = screenPosition.x * halfViewportWidth + halfViewportWidth;
  9114. screenPositionPixels.y = screenPosition.y * halfViewportHeight + halfViewportHeight;
  9115. // screen cull
  9116. if ( _lensFlare.hasVertexTexture || (
  9117. screenPositionPixels.x > 0 &&
  9118. screenPositionPixels.x < viewportWidth &&
  9119. screenPositionPixels.y > 0 &&
  9120. screenPositionPixels.y < viewportHeight ) ) {
  9121. // save current RGB to temp texture
  9122. _gl.activeTexture( _gl.TEXTURE1 );
  9123. _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
  9124. _gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 );
  9125. // render pink quad
  9126. _gl.uniform1i( uniforms.renderType, 0 );
  9127. _gl.uniform2f( uniforms.scale, scale.x, scale.y );
  9128. _gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
  9129. _gl.disable( _gl.BLEND );
  9130. _gl.enable( _gl.DEPTH_TEST );
  9131. _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
  9132. // copy result to occlusionMap
  9133. _gl.activeTexture( _gl.TEXTURE0 );
  9134. _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
  9135. _gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 );
  9136. // restore graphics
  9137. _gl.uniform1i( uniforms.renderType, 1 );
  9138. _gl.disable( _gl.DEPTH_TEST );
  9139. _gl.activeTexture( _gl.TEXTURE1 );
  9140. _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
  9141. _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
  9142. // update object positions
  9143. flare.positionScreen.copy( screenPosition )
  9144. if ( flare.customUpdateCallback ) {
  9145. flare.customUpdateCallback( flare );
  9146. } else {
  9147. flare.updateLensFlares();
  9148. }
  9149. // render flares
  9150. _gl.uniform1i( uniforms.renderType, 2 );
  9151. _gl.enable( _gl.BLEND );
  9152. for ( j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {
  9153. sprite = flare.lensFlares[ j ];
  9154. if ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {
  9155. screenPosition.x = sprite.x;
  9156. screenPosition.y = sprite.y;
  9157. screenPosition.z = sprite.z;
  9158. size = sprite.size * sprite.scale / viewportHeight;
  9159. scale.x = size * invAspect;
  9160. scale.y = size;
  9161. _gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
  9162. _gl.uniform2f( uniforms.scale, scale.x, scale.y );
  9163. _gl.uniform1f( uniforms.rotation, sprite.rotation );
  9164. _gl.uniform1f( uniforms.opacity, sprite.opacity );
  9165. _gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );
  9166. _renderer.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );
  9167. _renderer.setTexture( sprite.texture, 1 );
  9168. _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
  9169. }
  9170. }
  9171. }
  9172. }
  9173. // restore gl
  9174. _gl.enable( _gl.CULL_FACE );
  9175. _gl.enable( _gl.DEPTH_TEST );
  9176. _gl.depthMask( true );
  9177. };
  9178. function createProgram ( shader ) {
  9179. var program = _gl.createProgram();
  9180. var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
  9181. var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
  9182. _gl.shaderSource( fragmentShader, shader.fragmentShader );
  9183. _gl.shaderSource( vertexShader, shader.vertexShader );
  9184. _gl.compileShader( fragmentShader );
  9185. _gl.compileShader( vertexShader );
  9186. _gl.attachShader( program, fragmentShader );
  9187. _gl.attachShader( program, vertexShader );
  9188. _gl.linkProgram( program );
  9189. return program;
  9190. };
  9191. };/**
  9192. * @author alteredq / http://alteredqualia.com/
  9193. */
  9194. THREE.ShadowMapPlugin = function ( ) {
  9195. var _gl,
  9196. _renderer,
  9197. _depthMaterial, _depthMaterialMorph,
  9198. _frustum = new THREE.Frustum(),
  9199. _projScreenMatrix = new THREE.Matrix4(),
  9200. _min = new THREE.Vector3(),
  9201. _max = new THREE.Vector3();
  9202. this.init = function ( renderer ) {
  9203. _gl = renderer.context;
  9204. _renderer = renderer;
  9205. var depthShader = THREE.ShaderLib[ "depthRGBA" ];
  9206. var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
  9207. _depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
  9208. _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } );
  9209. _depthMaterial._shadowPass = true;
  9210. _depthMaterialMorph._shadowPass = true;
  9211. };
  9212. this.render = function ( scene, camera ) {
  9213. if ( ! ( _renderer.shadowMapEnabled && _renderer.shadowMapAutoUpdate ) ) return;
  9214. this.update( scene, camera );
  9215. };
  9216. this.update = function ( scene, camera ) {
  9217. var i, il, j, jl, n,
  9218. shadowMap, shadowMatrix, shadowCamera,
  9219. program, buffer, material,
  9220. webglObject, object, light,
  9221. renderList,
  9222. lights = [],
  9223. k = 0,
  9224. fog = null;
  9225. // set GL state for depth map
  9226. _gl.clearColor( 1, 1, 1, 1 );
  9227. _gl.disable( _gl.BLEND );
  9228. if ( _renderer.shadowMapCullFrontFaces ) _gl.cullFace( _gl.FRONT );
  9229. _renderer.setDepthTest( true );
  9230. // preprocess lights
  9231. // - skip lights that are not casting shadows
  9232. // - create virtual lights for cascaded shadow maps
  9233. for ( i = 0, il = scene.__lights.length; i < il; i ++ ) {
  9234. light = scene.__lights[ i ];
  9235. if ( ! light.castShadow ) continue;
  9236. if ( ( light instanceof THREE.DirectionalLight ) && light.shadowCascade ) {
  9237. for ( n = 0; n < light.shadowCascadeCount; n ++ ) {
  9238. var virtualLight;
  9239. if ( ! light.shadowCascadeArray[ n ] ) {
  9240. virtualLight = createVirtualLight( light, n );
  9241. virtualLight.originalCamera = camera;
  9242. var gyro = new THREE.Gyroscope();
  9243. gyro.position = light.shadowCascadeOffset;
  9244. gyro.add( virtualLight );
  9245. gyro.add( virtualLight.target );
  9246. camera.add( gyro );
  9247. light.shadowCascadeArray[ n ] = virtualLight;
  9248. console.log( "Created virtualLight", virtualLight );
  9249. } else {
  9250. virtualLight = light.shadowCascadeArray[ n ];
  9251. }
  9252. updateVirtualLight( light, n );
  9253. lights[ k ] = virtualLight;
  9254. k ++;
  9255. }
  9256. } else {
  9257. lights[ k ] = light;
  9258. k ++;
  9259. }
  9260. }
  9261. // render depth map
  9262. for ( i = 0, il = lights.length; i < il; i ++ ) {
  9263. light = lights[ i ];
  9264. if ( ! light.shadowMap ) {
  9265. var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
  9266. light.shadowMap = new THREE.WebGLRenderTarget( light.shadowMapWidth, light.shadowMapHeight, pars );
  9267. light.shadowMapSize = new THREE.Vector2( light.shadowMapWidth, light.shadowMapHeight );
  9268. light.shadowMatrix = new THREE.Matrix4();
  9269. }
  9270. if ( ! light.shadowCamera ) {
  9271. if ( light instanceof THREE.SpotLight ) {
  9272. light.shadowCamera = new THREE.PerspectiveCamera( light.shadowCameraFov, light.shadowMapWidth / light.shadowMapHeight, light.shadowCameraNear, light.shadowCameraFar );
  9273. } else if ( light instanceof THREE.DirectionalLight ) {
  9274. light.shadowCamera = new THREE.OrthographicCamera( light.shadowCameraLeft, light.shadowCameraRight, light.shadowCameraTop, light.shadowCameraBottom, light.shadowCameraNear, light.shadowCameraFar );
  9275. } else {
  9276. console.error( "Unsupported light type for shadow" );
  9277. continue;
  9278. }
  9279. scene.add( light.shadowCamera );
  9280. if ( _renderer.autoUpdateScene ) scene.updateMatrixWorld();
  9281. }
  9282. if ( light.shadowCameraVisible && ! light.cameraHelper ) {
  9283. light.cameraHelper = new THREE.CameraHelper( light.shadowCamera );
  9284. light.shadowCamera.add( light.cameraHelper );
  9285. }
  9286. if ( light.isVirtual && virtualLight.originalCamera == camera ) {
  9287. updateShadowCamera( camera, light );
  9288. }
  9289. shadowMap = light.shadowMap;
  9290. shadowMatrix = light.shadowMatrix;
  9291. shadowCamera = light.shadowCamera;
  9292. shadowCamera.position.copy( light.matrixWorld.getPosition() );
  9293. shadowCamera.lookAt( light.target.matrixWorld.getPosition() );
  9294. shadowCamera.updateMatrixWorld();
  9295. shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
  9296. if ( light.cameraHelper ) light.cameraHelper.lines.visible = light.shadowCameraVisible;
  9297. if ( light.shadowCameraVisible ) light.cameraHelper.update();
  9298. // compute shadow matrix
  9299. shadowMatrix.set( 0.5, 0.0, 0.0, 0.5,
  9300. 0.0, 0.5, 0.0, 0.5,
  9301. 0.0, 0.0, 0.5, 0.5,
  9302. 0.0, 0.0, 0.0, 1.0 );
  9303. shadowMatrix.multiplySelf( shadowCamera.projectionMatrix );
  9304. shadowMatrix.multiplySelf( shadowCamera.matrixWorldInverse );
  9305. // update camera matrices and frustum
  9306. if ( ! shadowCamera._viewMatrixArray ) shadowCamera._viewMatrixArray = new Float32Array( 16 );
  9307. if ( ! shadowCamera._projectionMatrixArray ) shadowCamera._projectionMatrixArray = new Float32Array( 16 );
  9308. shadowCamera.matrixWorldInverse.flattenToArray( shadowCamera._viewMatrixArray );
  9309. shadowCamera.projectionMatrix.flattenToArray( shadowCamera._projectionMatrixArray );
  9310. _projScreenMatrix.multiply( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
  9311. _frustum.setFromMatrix( _projScreenMatrix );
  9312. // render shadow map
  9313. _renderer.setRenderTarget( shadowMap );
  9314. _renderer.clear();
  9315. // set object matrices & frustum culling
  9316. renderList = scene.__webglObjects;
  9317. for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
  9318. webglObject = renderList[ j ];
  9319. object = webglObject.object;
  9320. webglObject.render = false;
  9321. if ( object.visible && object.castShadow ) {
  9322. if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
  9323. //object.matrixWorld.flattenToArray( object._objectMatrixArray );
  9324. object._modelViewMatrix.multiply( shadowCamera.matrixWorldInverse, object.matrixWorld);
  9325. webglObject.render = true;
  9326. }
  9327. }
  9328. }
  9329. // render regular objects
  9330. for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
  9331. webglObject = renderList[ j ];
  9332. if ( webglObject.render ) {
  9333. object = webglObject.object;
  9334. buffer = webglObject.buffer;
  9335. _renderer.setObjectFaces( object );
  9336. if ( object.customDepthMaterial ) {
  9337. material = object.customDepthMaterial;
  9338. } else if ( object.geometry.morphTargets.length ) {
  9339. material = _depthMaterialMorph;
  9340. } else {
  9341. material = _depthMaterial;
  9342. }
  9343. if ( buffer instanceof THREE.BufferGeometry ) {
  9344. _renderer.renderBufferDirect( shadowCamera, scene.__lights, fog, material, buffer, object );
  9345. } else {
  9346. _renderer.renderBuffer( shadowCamera, scene.__lights, fog, material, buffer, object );
  9347. }
  9348. }
  9349. }
  9350. // set matrices and render immediate objects
  9351. renderList = scene.__webglObjectsImmediate;
  9352. for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
  9353. webglObject = renderList[ j ];
  9354. object = webglObject.object;
  9355. if ( object.visible && object.castShadow ) {
  9356. if( object.matrixAutoUpdate ) {
  9357. //object.matrixWorld.flattenToArray( object._objectMatrixArray );
  9358. }
  9359. object._modelViewMatrix.multiply( shadowCamera.matrixWorldInverse, object.matrixWorld);
  9360. _renderer.renderImmediateObject( shadowCamera, scene.__lights, fog, _depthMaterial, object );
  9361. }
  9362. }
  9363. }
  9364. // restore GL state
  9365. var clearColor = _renderer.getClearColor(),
  9366. clearAlpha = _renderer.getClearAlpha();
  9367. _gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
  9368. _gl.enable( _gl.BLEND );
  9369. if ( _renderer.shadowMapCullFrontFaces ) _gl.cullFace( _gl.BACK );
  9370. };
  9371. function createVirtualLight( light, cascade ) {
  9372. var virtualLight = new THREE.DirectionalLight();
  9373. virtualLight.isVirtual = true;
  9374. virtualLight.onlyShadow = true;
  9375. virtualLight.castShadow = true;
  9376. virtualLight.shadowCameraNear = light.shadowCameraNear;
  9377. virtualLight.shadowCameraFar = light.shadowCameraFar;
  9378. virtualLight.shadowCameraLeft = light.shadowCameraLeft;
  9379. virtualLight.shadowCameraRight = light.shadowCameraRight;
  9380. virtualLight.shadowCameraBottom = light.shadowCameraBottom;
  9381. virtualLight.shadowCameraTop = light.shadowCameraTop;
  9382. virtualLight.shadowCameraVisible = light.shadowCameraVisible;
  9383. virtualLight.shadowDarkness = light.shadowDarkness;
  9384. virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];
  9385. virtualLight.shadowMapWidth = light.shadowCascadeWidth[ cascade ];
  9386. virtualLight.shadowMapHeight = light.shadowCascadeHeight[ cascade ];
  9387. virtualLight.pointsWorld = [];
  9388. virtualLight.pointsFrustum = [];
  9389. var pointsWorld = virtualLight.pointsWorld,
  9390. pointsFrustum = virtualLight.pointsFrustum;
  9391. for ( var i = 0; i < 8; i ++ ) {
  9392. pointsWorld[ i ] = new THREE.Vector3();
  9393. pointsFrustum[ i ] = new THREE.Vector3();
  9394. }
  9395. var nearZ = light.shadowCascadeNearZ[ cascade ];
  9396. var farZ = light.shadowCascadeFarZ[ cascade ];
  9397. pointsFrustum[ 0 ].set( -1, -1, nearZ );
  9398. pointsFrustum[ 1 ].set( 1, -1, nearZ );
  9399. pointsFrustum[ 2 ].set( -1, 1, nearZ );
  9400. pointsFrustum[ 3 ].set( 1, 1, nearZ );
  9401. pointsFrustum[ 4 ].set( -1, -1, farZ );
  9402. pointsFrustum[ 5 ].set( 1, -1, farZ );
  9403. pointsFrustum[ 6 ].set( -1, 1, farZ );
  9404. pointsFrustum[ 7 ].set( 1, 1, farZ );
  9405. return virtualLight;
  9406. }
  9407. // Synchronize virtual light with the original light
  9408. function updateVirtualLight( light, cascade ) {
  9409. var virtualLight = light.shadowCascadeArray[ cascade ];
  9410. virtualLight.position.copy( light.position );
  9411. virtualLight.target.position.copy( light.target.position );
  9412. virtualLight.lookAt( virtualLight.target );
  9413. virtualLight.shadowCameraVisible = light.shadowCameraVisible;
  9414. virtualLight.shadowDarkness = light.shadowDarkness;
  9415. virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];
  9416. var nearZ = light.shadowCascadeNearZ[ cascade ];
  9417. var farZ = light.shadowCascadeFarZ[ cascade ];
  9418. var pointsFrustum = virtualLight.pointsFrustum;
  9419. pointsFrustum[ 0 ].z = nearZ;
  9420. pointsFrustum[ 1 ].z = nearZ;
  9421. pointsFrustum[ 2 ].z = nearZ;
  9422. pointsFrustum[ 3 ].z = nearZ;
  9423. pointsFrustum[ 4 ].z = farZ;
  9424. pointsFrustum[ 5 ].z = farZ;
  9425. pointsFrustum[ 6 ].z = farZ;
  9426. pointsFrustum[ 7 ].z = farZ;
  9427. }
  9428. // Fit shadow camera's ortho frustum to camera frustum
  9429. function updateShadowCamera( camera, light ) {
  9430. var shadowCamera = light.shadowCamera,
  9431. pointsFrustum = light.pointsFrustum,
  9432. pointsWorld = light.pointsWorld;
  9433. _min.set( Infinity, Infinity, Infinity );
  9434. _max.set( -Infinity, -Infinity, -Infinity );
  9435. for ( var i = 0; i < 8; i ++ ) {
  9436. var p = pointsWorld[ i ];
  9437. p.copy( pointsFrustum[ i ] );
  9438. THREE.ShadowMapPlugin.__projector.unprojectVector( p, camera );
  9439. shadowCamera.matrixWorldInverse.multiplyVector3( p );
  9440. if ( p.x < _min.x ) _min.x = p.x;
  9441. if ( p.x > _max.x ) _max.x = p.x;
  9442. if ( p.y < _min.y ) _min.y = p.y;
  9443. if ( p.y > _max.y ) _max.y = p.y;
  9444. if ( p.z < _min.z ) _min.z = p.z;
  9445. if ( p.z > _max.z ) _max.z = p.z;
  9446. }
  9447. shadowCamera.left = _min.x;
  9448. shadowCamera.right = _max.x;
  9449. shadowCamera.top = _max.y;
  9450. shadowCamera.bottom = _min.y;
  9451. // can't really fit near/far
  9452. //shadowCamera.near = _min.z;
  9453. //shadowCamera.far = _max.z;
  9454. shadowCamera.updateProjectionMatrix();
  9455. }
  9456. };
  9457. THREE.ShadowMapPlugin.__projector = new THREE.Projector();
  9458. /**
  9459. * @author mikael emtinger / http://gomo.se/
  9460. * @author alteredq / http://alteredqualia.com/
  9461. */
  9462. THREE.SpritePlugin = function ( ) {
  9463. var _gl, _renderer, _sprite = {};
  9464. this.init = function ( renderer ) {
  9465. _gl = renderer.context;
  9466. _renderer = renderer;
  9467. _sprite.vertices = new Float32Array( 8 + 8 );
  9468. _sprite.faces = new Uint16Array( 6 );
  9469. var i = 0;
  9470. _sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = -1; // vertex 0
  9471. _sprite.vertices[ i++ ] = 0; _sprite.vertices[ i++ ] = 1; // uv 0
  9472. _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = -1; // vertex 1
  9473. _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = 1; // uv 1
  9474. _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = 1; // vertex 2
  9475. _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = 0; // uv 2
  9476. _sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = 1; // vertex 3
  9477. _sprite.vertices[ i++ ] = 0; _sprite.vertices[ i++ ] = 0; // uv 3
  9478. i = 0;
  9479. _sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 1; _sprite.faces[ i++ ] = 2;
  9480. _sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 2; _sprite.faces[ i++ ] = 3;
  9481. _sprite.vertexBuffer = _gl.createBuffer();
  9482. _sprite.elementBuffer = _gl.createBuffer();
  9483. _gl.bindBuffer( _gl.ARRAY_BUFFER, _sprite.vertexBuffer );
  9484. _gl.bufferData( _gl.ARRAY_BUFFER, _sprite.vertices, _gl.STATIC_DRAW );
  9485. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
  9486. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _sprite.faces, _gl.STATIC_DRAW );
  9487. _sprite.program = createProgram( THREE.ShaderSprite[ "sprite" ] );
  9488. _sprite.attributes = {};
  9489. _sprite.uniforms = {};
  9490. _sprite.attributes.position = _gl.getAttribLocation ( _sprite.program, "position" );
  9491. _sprite.attributes.uv = _gl.getAttribLocation ( _sprite.program, "uv" );
  9492. _sprite.uniforms.uvOffset = _gl.getUniformLocation( _sprite.program, "uvOffset" );
  9493. _sprite.uniforms.uvScale = _gl.getUniformLocation( _sprite.program, "uvScale" );
  9494. _sprite.uniforms.rotation = _gl.getUniformLocation( _sprite.program, "rotation" );
  9495. _sprite.uniforms.scale = _gl.getUniformLocation( _sprite.program, "scale" );
  9496. _sprite.uniforms.alignment = _gl.getUniformLocation( _sprite.program, "alignment" );
  9497. _sprite.uniforms.color = _gl.getUniformLocation( _sprite.program, "color" );
  9498. _sprite.uniforms.map = _gl.getUniformLocation( _sprite.program, "map" );
  9499. _sprite.uniforms.opacity = _gl.getUniformLocation( _sprite.program, "opacity" );
  9500. _sprite.uniforms.useScreenCoordinates = _gl.getUniformLocation( _sprite.program, "useScreenCoordinates" );
  9501. _sprite.uniforms.affectedByDistance = _gl.getUniformLocation( _sprite.program, "affectedByDistance" );
  9502. _sprite.uniforms.screenPosition = _gl.getUniformLocation( _sprite.program, "screenPosition" );
  9503. _sprite.uniforms.modelViewMatrix = _gl.getUniformLocation( _sprite.program, "modelViewMatrix" );
  9504. _sprite.uniforms.projectionMatrix = _gl.getUniformLocation( _sprite.program, "projectionMatrix" );
  9505. _sprite.attributesEnabled = false;
  9506. };
  9507. this.render = function ( scene, camera, viewportWidth, viewportHeight ) {
  9508. var sprites = scene.__webglSprites,
  9509. nSprites = sprites.length;
  9510. if ( ! nSprites ) return;
  9511. var attributes = _sprite.attributes,
  9512. uniforms = _sprite.uniforms;
  9513. var invAspect = viewportHeight / viewportWidth;
  9514. var halfViewportWidth = viewportWidth * 0.5,
  9515. halfViewportHeight = viewportHeight * 0.5;
  9516. var mergeWith3D = true;
  9517. // setup gl
  9518. _gl.useProgram( _sprite.program );
  9519. if ( ! _sprite.attributesEnabled ) {
  9520. _gl.enableVertexAttribArray( attributes.position );
  9521. _gl.enableVertexAttribArray( attributes.uv );
  9522. _sprite.attributesEnabled = true;
  9523. }
  9524. _gl.disable( _gl.CULL_FACE );
  9525. _gl.enable( _gl.BLEND );
  9526. _gl.depthMask( true );
  9527. _gl.bindBuffer( _gl.ARRAY_BUFFER, _sprite.vertexBuffer );
  9528. _gl.vertexAttribPointer( attributes.position, 2, _gl.FLOAT, false, 2 * 8, 0 );
  9529. _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );
  9530. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
  9531. _gl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera._projectionMatrixArray );
  9532. _gl.activeTexture( _gl.TEXTURE0 );
  9533. _gl.uniform1i( uniforms.map, 0 );
  9534. // update positions and sort
  9535. var i, sprite, screenPosition, size, scale = [];
  9536. for( i = 0; i < nSprites; i ++ ) {
  9537. sprite = sprites[ i ];
  9538. if ( ! sprite.visible || sprite.opacity === 0 ) continue;
  9539. if( ! sprite.useScreenCoordinates ) {
  9540. sprite._modelViewMatrix.multiply( camera.matrixWorldInverse, sprite.matrixWorld);
  9541. sprite.z = - sprite._modelViewMatrix.elements[14];
  9542. } else {
  9543. sprite.z = - sprite.position.z;
  9544. }
  9545. }
  9546. sprites.sort( painterSort );
  9547. // render all sprites
  9548. for( i = 0; i < nSprites; i ++ ) {
  9549. sprite = sprites[ i ];
  9550. if ( ! sprite.visible || sprite.opacity === 0 ) continue;
  9551. if ( sprite.map && sprite.map.image && sprite.map.image.width ) {
  9552. if ( sprite.useScreenCoordinates ) {
  9553. _gl.uniform1i( uniforms.useScreenCoordinates, 1 );
  9554. _gl.uniform3f( uniforms.screenPosition, ( sprite.position.x - halfViewportWidth ) / halfViewportWidth,
  9555. ( halfViewportHeight - sprite.position.y ) / halfViewportHeight,
  9556. Math.max( 0, Math.min( 1, sprite.position.z ) ) );
  9557. } else {
  9558. _gl.uniform1i( uniforms.useScreenCoordinates, 0 );
  9559. _gl.uniform1i( uniforms.affectedByDistance, sprite.affectedByDistance ? 1 : 0 );
  9560. _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite._modelViewMatrix.elements);
  9561. }
  9562. size = sprite.map.image.width / ( sprite.scaleByViewport ? viewportHeight : 1 );
  9563. scale[ 0 ] = size * invAspect * sprite.scale.x;
  9564. scale[ 1 ] = size * sprite.scale.y;
  9565. _gl.uniform2f( uniforms.uvScale, sprite.uvScale.x, sprite.uvScale.y );
  9566. _gl.uniform2f( uniforms.uvOffset, sprite.uvOffset.x, sprite.uvOffset.y );
  9567. _gl.uniform2f( uniforms.alignment, sprite.alignment.x, sprite.alignment.y );
  9568. _gl.uniform1f( uniforms.opacity, sprite.opacity );
  9569. _gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );
  9570. _gl.uniform1f( uniforms.rotation, sprite.rotation );
  9571. _gl.uniform2fv( uniforms.scale, scale );
  9572. if ( sprite.mergeWith3D && !mergeWith3D ) {
  9573. _gl.enable( _gl.DEPTH_TEST );
  9574. mergeWith3D = true;
  9575. } else if ( ! sprite.mergeWith3D && mergeWith3D ) {
  9576. _gl.disable( _gl.DEPTH_TEST );
  9577. mergeWith3D = false;
  9578. }
  9579. _renderer.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );
  9580. _renderer.setTexture( sprite.map, 0 );
  9581. _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
  9582. }
  9583. }
  9584. // restore gl
  9585. _gl.enable( _gl.CULL_FACE );
  9586. _gl.enable( _gl.DEPTH_TEST );
  9587. _gl.depthMask( true );
  9588. };
  9589. function createProgram ( shader ) {
  9590. var program = _gl.createProgram();
  9591. var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
  9592. var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
  9593. _gl.shaderSource( fragmentShader, shader.fragmentShader );
  9594. _gl.shaderSource( vertexShader, shader.vertexShader );
  9595. _gl.compileShader( fragmentShader );
  9596. _gl.compileShader( vertexShader );
  9597. _gl.attachShader( program, fragmentShader );
  9598. _gl.attachShader( program, vertexShader );
  9599. _gl.linkProgram( program );
  9600. return program;
  9601. };
  9602. function painterSort ( a, b ) {
  9603. return b.z - a.z;
  9604. };
  9605. };/**
  9606. * @author mikael emtinger / http://gomo.se/
  9607. *
  9608. */
  9609. THREE.ShaderFlares = {
  9610. 'lensFlareVertexTexture': {
  9611. vertexShader: [
  9612. "uniform vec3 screenPosition;",
  9613. "uniform vec2 scale;",
  9614. "uniform float rotation;",
  9615. "uniform int renderType;",
  9616. "uniform sampler2D occlusionMap;",
  9617. "attribute vec2 position;",
  9618. "attribute vec2 uv;",
  9619. "varying vec2 vUV;",
  9620. "varying float vVisibility;",
  9621. "void main() {",
  9622. "vUV = uv;",
  9623. "vec2 pos = position;",
  9624. "if( renderType == 2 ) {",
  9625. "vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) ) +",
  9626. "texture2D( occlusionMap, vec2( 0.5, 0.1 ) ) +",
  9627. "texture2D( occlusionMap, vec2( 0.9, 0.1 ) ) +",
  9628. "texture2D( occlusionMap, vec2( 0.9, 0.5 ) ) +",
  9629. "texture2D( occlusionMap, vec2( 0.9, 0.9 ) ) +",
  9630. "texture2D( occlusionMap, vec2( 0.5, 0.9 ) ) +",
  9631. "texture2D( occlusionMap, vec2( 0.1, 0.9 ) ) +",
  9632. "texture2D( occlusionMap, vec2( 0.1, 0.5 ) ) +",
  9633. "texture2D( occlusionMap, vec2( 0.5, 0.5 ) );",
  9634. "vVisibility = ( visibility.r / 9.0 ) *",
  9635. "( 1.0 - visibility.g / 9.0 ) *",
  9636. "( visibility.b / 9.0 ) *",
  9637. "( 1.0 - visibility.a / 9.0 );",
  9638. "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
  9639. "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
  9640. "}",
  9641. "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
  9642. "}"
  9643. ].join( "\n" ),
  9644. fragmentShader: [
  9645. "precision mediump float;",
  9646. "uniform sampler2D map;",
  9647. "uniform float opacity;",
  9648. "uniform int renderType;",
  9649. "uniform vec3 color;",
  9650. "varying vec2 vUV;",
  9651. "varying float vVisibility;",
  9652. "void main() {",
  9653. // pink square
  9654. "if( renderType == 0 ) {",
  9655. "gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );",
  9656. // restore
  9657. "} else if( renderType == 1 ) {",
  9658. "gl_FragColor = texture2D( map, vUV );",
  9659. // flare
  9660. "} else {",
  9661. "vec4 texture = texture2D( map, vUV );",
  9662. "texture.a *= opacity * vVisibility;",
  9663. "gl_FragColor = texture;",
  9664. "gl_FragColor.rgb *= color;",
  9665. "}",
  9666. "}"
  9667. ].join( "\n" )
  9668. },
  9669. 'lensFlare': {
  9670. vertexShader: [
  9671. "uniform vec3 screenPosition;",
  9672. "uniform vec2 scale;",
  9673. "uniform float rotation;",
  9674. "uniform int renderType;",
  9675. "attribute vec2 position;",
  9676. "attribute vec2 uv;",
  9677. "varying vec2 vUV;",
  9678. "void main() {",
  9679. "vUV = uv;",
  9680. "vec2 pos = position;",
  9681. "if( renderType == 2 ) {",
  9682. "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
  9683. "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
  9684. "}",
  9685. "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
  9686. "}"
  9687. ].join( "\n" ),
  9688. fragmentShader: [
  9689. "precision mediump float;",
  9690. "uniform sampler2D map;",
  9691. "uniform sampler2D occlusionMap;",
  9692. "uniform float opacity;",
  9693. "uniform int renderType;",
  9694. "uniform vec3 color;",
  9695. "varying vec2 vUV;",
  9696. "void main() {",
  9697. // pink square
  9698. "if( renderType == 0 ) {",
  9699. "gl_FragColor = vec4( texture2D( map, vUV ).rgb, 0.0 );",
  9700. // restore
  9701. "} else if( renderType == 1 ) {",
  9702. "gl_FragColor = texture2D( map, vUV );",
  9703. // flare
  9704. "} else {",
  9705. "float visibility = texture2D( occlusionMap, vec2( 0.5, 0.1 ) ).a +",
  9706. "texture2D( occlusionMap, vec2( 0.9, 0.5 ) ).a +",
  9707. "texture2D( occlusionMap, vec2( 0.5, 0.9 ) ).a +",
  9708. "texture2D( occlusionMap, vec2( 0.1, 0.5 ) ).a;",
  9709. "visibility = ( 1.0 - visibility / 4.0 );",
  9710. "vec4 texture = texture2D( map, vUV );",
  9711. "texture.a *= opacity * visibility;",
  9712. "gl_FragColor = texture;",
  9713. "gl_FragColor.rgb *= color;",
  9714. "}",
  9715. "}"
  9716. ].join( "\n" )
  9717. }
  9718. };
  9719. /**
  9720. * @author mikael emtinger / http://gomo.se/
  9721. *
  9722. */
  9723. THREE.ShaderSprite = {
  9724. 'sprite': {
  9725. vertexShader: [
  9726. "uniform int useScreenCoordinates;",
  9727. "uniform int affectedByDistance;",
  9728. "uniform vec3 screenPosition;",
  9729. "uniform mat4 modelViewMatrix;",
  9730. "uniform mat4 projectionMatrix;",
  9731. "uniform float rotation;",
  9732. "uniform vec2 scale;",
  9733. "uniform vec2 alignment;",
  9734. "uniform vec2 uvOffset;",
  9735. "uniform vec2 uvScale;",
  9736. "attribute vec2 position;",
  9737. "attribute vec2 uv;",
  9738. "varying vec2 vUV;",
  9739. "void main() {",
  9740. "vUV = uvOffset + uv * uvScale;",
  9741. "vec2 alignedPosition = position + alignment;",
  9742. "vec2 rotatedPosition;",
  9743. "rotatedPosition.x = ( cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y ) * scale.x;",
  9744. "rotatedPosition.y = ( sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y ) * scale.y;",
  9745. "vec4 finalPosition;",
  9746. "if( useScreenCoordinates != 0 ) {",
  9747. "finalPosition = vec4( screenPosition.xy + rotatedPosition, screenPosition.z, 1.0 );",
  9748. "} else {",
  9749. "finalPosition = projectionMatrix * modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );",
  9750. "finalPosition.xy += rotatedPosition * ( affectedByDistance == 1 ? 1.0 : finalPosition.z );",
  9751. "}",
  9752. "gl_Position = finalPosition;",
  9753. "}"
  9754. ].join( "\n" ),
  9755. fragmentShader: [
  9756. "precision mediump float;",
  9757. "uniform vec3 color;",
  9758. "uniform sampler2D map;",
  9759. "uniform float opacity;",
  9760. "varying vec2 vUV;",
  9761. "void main() {",
  9762. "vec4 texture = texture2D( map, vUV );",
  9763. "gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );",
  9764. "}"
  9765. ].join( "\n" )
  9766. }
  9767. };