2
0

ThreeWebGL.js 469 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007
  1. // ThreeWebGL.js - http://github.com/mrdoob/three.js
  2. /**
  3. * @author mr.doob / http://mrdoob.com/
  4. */
  5. var THREE = THREE || { REVISION: '50dev' };
  6. if ( ! self.console ) {
  7. self.console = {
  8. info: function () {},
  9. log: function () {},
  10. debug: function () {},
  11. warn: function () {},
  12. error: function () {}
  13. };
  14. }
  15. if ( ! self.Int32Array ) {
  16. self.Int32Array = Array;
  17. self.Float32Array = Array;
  18. }
  19. // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
  20. // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
  21. // requestAnimationFrame polyfill by Erik Möller
  22. // fixes from Paul Irish and Tino Zijdel
  23. ( function () {
  24. var lastTime = 0;
  25. var vendors = [ 'ms', 'moz', 'webkit', 'o' ];
  26. for ( var x = 0; x < vendors.length && !window.requestAnimationFrame; ++ x ) {
  27. window.requestAnimationFrame = window[ vendors[ x ] + 'RequestAnimationFrame' ];
  28. window.cancelAnimationFrame = window[ vendors[ x ] + 'CancelAnimationFrame' ] || window[ vendors[ x ] + 'CancelRequestAnimationFrame' ];
  29. }
  30. if ( !window.requestAnimationFrame ) {
  31. window.requestAnimationFrame = function ( callback, element ) {
  32. var currTime = Date.now(), timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
  33. var id = window.setTimeout( function() { callback( currTime + timeToCall ); }, timeToCall );
  34. lastTime = currTime + timeToCall;
  35. return id;
  36. };
  37. }
  38. if ( !window.cancelAnimationFrame ) {
  39. window.cancelAnimationFrame = function ( id ) { clearTimeout( id ); };
  40. }
  41. }() );
  42. // MATERIAL CONSTANTS
  43. // shading
  44. THREE.NoShading = 0;
  45. THREE.FlatShading = 1;
  46. THREE.SmoothShading = 2;
  47. // colors
  48. THREE.NoColors = 0;
  49. THREE.FaceColors = 1;
  50. THREE.VertexColors = 2;
  51. // blending modes
  52. THREE.NoBlending = 0;
  53. THREE.NormalBlending = 1;
  54. THREE.AdditiveBlending = 2;
  55. THREE.SubtractiveBlending = 3;
  56. THREE.MultiplyBlending = 4;
  57. THREE.CustomBlending = 5;
  58. // custom blending equations
  59. // (numbers start from 100 not to clash with other
  60. // mappings to OpenGL constants defined in Texture.js)
  61. THREE.AddEquation = 100;
  62. THREE.SubtractEquation = 101;
  63. THREE.ReverseSubtractEquation = 102;
  64. // custom blending destination factors
  65. THREE.ZeroFactor = 200;
  66. THREE.OneFactor = 201;
  67. THREE.SrcColorFactor = 202;
  68. THREE.OneMinusSrcColorFactor = 203;
  69. THREE.SrcAlphaFactor = 204;
  70. THREE.OneMinusSrcAlphaFactor = 205;
  71. THREE.DstAlphaFactor = 206;
  72. THREE.OneMinusDstAlphaFactor = 207;
  73. // custom blending source factors
  74. //THREE.ZeroFactor = 200;
  75. //THREE.OneFactor = 201;
  76. //THREE.SrcAlphaFactor = 204;
  77. //THREE.OneMinusSrcAlphaFactor = 205;
  78. //THREE.DstAlphaFactor = 206;
  79. //THREE.OneMinusDstAlphaFactor = 207;
  80. THREE.DstColorFactor = 208;
  81. THREE.OneMinusDstColorFactor = 209;
  82. THREE.SrcAlphaSaturateFactor = 210;
  83. // TEXTURE CONSTANTS
  84. THREE.MultiplyOperation = 0;
  85. THREE.MixOperation = 1;
  86. // Mapping modes
  87. THREE.UVMapping = function () {};
  88. THREE.CubeReflectionMapping = function () {};
  89. THREE.CubeRefractionMapping = function () {};
  90. THREE.SphericalReflectionMapping = function () {};
  91. THREE.SphericalRefractionMapping = function () {};
  92. // Wrapping modes
  93. THREE.RepeatWrapping = 1000;
  94. THREE.ClampToEdgeWrapping = 1001;
  95. THREE.MirroredRepeatWrapping = 1002;
  96. // Filters
  97. THREE.NearestFilter = 1003;
  98. THREE.NearestMipMapNearestFilter = 1004;
  99. THREE.NearestMipMapLinearFilter = 1005;
  100. THREE.LinearFilter = 1006;
  101. THREE.LinearMipMapNearestFilter = 1007;
  102. THREE.LinearMipMapLinearFilter = 1008;
  103. // Data types
  104. THREE.UnsignedByteType = 1009;
  105. THREE.ByteType = 1010;
  106. THREE.ShortType = 1011;
  107. THREE.UnsignedShortType = 1012;
  108. THREE.IntType = 1013;
  109. THREE.UnsignedIntType = 1014;
  110. THREE.FloatType = 1015;
  111. // Pixel types
  112. //THREE.UnsignedByteType = 1009;
  113. THREE.UnsignedShort4444Type = 1016;
  114. THREE.UnsignedShort5551Type = 1017;
  115. THREE.UnsignedShort565Type = 1018;
  116. // Pixel formats
  117. THREE.AlphaFormat = 1019;
  118. THREE.RGBFormat = 1020;
  119. THREE.RGBAFormat = 1021;
  120. THREE.LuminanceFormat = 1022;
  121. THREE.LuminanceAlphaFormat = 1023;
  122. /**
  123. * @author mr.doob / http://mrdoob.com/
  124. */
  125. THREE.Color = function ( hex ) {
  126. if ( hex !== undefined ) this.setHex( hex );
  127. return this;
  128. };
  129. THREE.Color.prototype = {
  130. constructor: THREE.Color,
  131. r: 1, g: 1, b: 1,
  132. copy: function ( color ) {
  133. this.r = color.r;
  134. this.g = color.g;
  135. this.b = color.b;
  136. return this;
  137. },
  138. copyGammaToLinear: function ( color ) {
  139. this.r = color.r * color.r;
  140. this.g = color.g * color.g;
  141. this.b = color.b * color.b;
  142. return this;
  143. },
  144. copyLinearToGamma: function ( color ) {
  145. this.r = Math.sqrt( color.r );
  146. this.g = Math.sqrt( color.g );
  147. this.b = Math.sqrt( color.b );
  148. return this;
  149. },
  150. convertGammaToLinear: function () {
  151. var r = this.r, g = this.g, b = this.b;
  152. this.r = r * r;
  153. this.g = g * g;
  154. this.b = b * b;
  155. return this;
  156. },
  157. convertLinearToGamma: function () {
  158. this.r = Math.sqrt( this.r );
  159. this.g = Math.sqrt( this.g );
  160. this.b = Math.sqrt( this.b );
  161. return this;
  162. },
  163. setRGB: function ( r, g, b ) {
  164. this.r = r;
  165. this.g = g;
  166. this.b = b;
  167. return this;
  168. },
  169. setHSV: function ( h, s, v ) {
  170. // based on MochiKit implementation by Bob Ippolito
  171. // h,s,v ranges are < 0.0 - 1.0 >
  172. var i, f, p, q, t;
  173. if ( v === 0 ) {
  174. this.r = this.g = this.b = 0;
  175. } else {
  176. i = Math.floor( h * 6 );
  177. f = ( h * 6 ) - i;
  178. p = v * ( 1 - s );
  179. q = v * ( 1 - ( s * f ) );
  180. t = v * ( 1 - ( s * ( 1 - f ) ) );
  181. if ( i === 0 ) {
  182. this.r = v;
  183. this.g = t;
  184. this.b = p;
  185. } else if ( i === 1 ) {
  186. this.r = q;
  187. this.g = v;
  188. this.b = p;
  189. } else if ( i === 2 ) {
  190. this.r = p;
  191. this.g = v;
  192. this.b = t;
  193. } else if ( i === 3 ) {
  194. this.r = p;
  195. this.g = q;
  196. this.b = v;
  197. } else if ( i === 4 ) {
  198. this.r = t;
  199. this.g = p;
  200. this.b = v;
  201. } else if ( i === 5 ) {
  202. this.r = v;
  203. this.g = p;
  204. this.b = q;
  205. }
  206. }
  207. return this;
  208. },
  209. setHex: function ( hex ) {
  210. hex = Math.floor( hex );
  211. this.r = ( hex >> 16 & 255 ) / 255;
  212. this.g = ( hex >> 8 & 255 ) / 255;
  213. this.b = ( hex & 255 ) / 255;
  214. return this;
  215. },
  216. lerpSelf: function ( color, alpha ) {
  217. this.r += ( color.r - this.r ) * alpha;
  218. this.g += ( color.g - this.g ) * alpha;
  219. this.b += ( color.b - this.b ) * alpha;
  220. return this;
  221. },
  222. getHex: function () {
  223. return Math.floor( this.r * 255 ) << 16 ^ Math.floor( this.g * 255 ) << 8 ^ Math.floor( this.b * 255 );
  224. },
  225. getContextStyle: function () {
  226. return 'rgb(' + Math.floor( this.r * 255 ) + ',' + Math.floor( this.g * 255 ) + ',' + Math.floor( this.b * 255 ) + ')';
  227. },
  228. clone: function () {
  229. return new THREE.Color().setRGB( this.r, this.g, this.b );
  230. }
  231. };
  232. /**
  233. * @author mr.doob / http://mrdoob.com/
  234. * @author philogb / http://blog.thejit.org/
  235. * @author egraether / http://egraether.com/
  236. * @author zz85 / http://www.lab4games.net/zz85/blog
  237. */
  238. THREE.Vector2 = function ( x, y ) {
  239. this.x = x || 0;
  240. this.y = y || 0;
  241. };
  242. THREE.Vector2.prototype = {
  243. constructor: THREE.Vector2,
  244. set: function ( x, y ) {
  245. this.x = x;
  246. this.y = y;
  247. return this;
  248. },
  249. copy: function ( v ) {
  250. this.x = v.x;
  251. this.y = v.y;
  252. return this;
  253. },
  254. add: function ( a, b ) {
  255. this.x = a.x + b.x;
  256. this.y = a.y + b.y;
  257. return this;
  258. },
  259. addSelf: function ( v ) {
  260. this.x += v.x;
  261. this.y += v.y;
  262. return this;
  263. },
  264. sub: function ( a, b ) {
  265. this.x = a.x - b.x;
  266. this.y = a.y - b.y;
  267. return this;
  268. },
  269. subSelf: function ( v ) {
  270. this.x -= v.x;
  271. this.y -= v.y;
  272. return this;
  273. },
  274. multiplyScalar: function ( s ) {
  275. this.x *= s;
  276. this.y *= s;
  277. return this;
  278. },
  279. divideScalar: function ( s ) {
  280. if ( s ) {
  281. this.x /= s;
  282. this.y /= s;
  283. } else {
  284. this.set( 0, 0 );
  285. }
  286. return this;
  287. },
  288. negate: function() {
  289. return this.multiplyScalar( - 1 );
  290. },
  291. dot: function ( v ) {
  292. return this.x * v.x + this.y * v.y;
  293. },
  294. lengthSq: function () {
  295. return this.x * this.x + this.y * this.y;
  296. },
  297. length: function () {
  298. return Math.sqrt( this.lengthSq() );
  299. },
  300. normalize: function () {
  301. return this.divideScalar( this.length() );
  302. },
  303. distanceTo: function ( v ) {
  304. return Math.sqrt( this.distanceToSquared( v ) );
  305. },
  306. distanceToSquared: function ( v ) {
  307. var dx = this.x - v.x, dy = this.y - v.y;
  308. return dx * dx + dy * dy;
  309. },
  310. setLength: function ( l ) {
  311. return this.normalize().multiplyScalar( l );
  312. },
  313. lerpSelf: function ( v, alpha ) {
  314. this.x += ( v.x - this.x ) * alpha;
  315. this.y += ( v.y - this.y ) * alpha;
  316. return this;
  317. },
  318. equals: function( v ) {
  319. return ( ( v.x === this.x ) && ( v.y === this.y ) );
  320. },
  321. isZero: function () {
  322. return ( this.lengthSq() < 0.0001 /* almostZero */ );
  323. },
  324. clone: function () {
  325. return new THREE.Vector2( this.x, this.y );
  326. }
  327. };
  328. /**
  329. * @author mr.doob / http://mrdoob.com/
  330. * @author kile / http://kile.stravaganza.org/
  331. * @author philogb / http://blog.thejit.org/
  332. * @author mikael emtinger / http://gomo.se/
  333. * @author egraether / http://egraether.com/
  334. * @author WestLangley / http://github.com/WestLangley
  335. */
  336. THREE.Vector3 = function ( x, y, z ) {
  337. this.x = x || 0;
  338. this.y = y || 0;
  339. this.z = z || 0;
  340. };
  341. THREE.Vector3.prototype = {
  342. constructor: THREE.Vector3,
  343. set: function ( x, y, z ) {
  344. this.x = x;
  345. this.y = y;
  346. this.z = z;
  347. return this;
  348. },
  349. setX: function ( x ) {
  350. this.x = x;
  351. return this;
  352. },
  353. setY: function ( y ) {
  354. this.y = y;
  355. return this;
  356. },
  357. setZ: function ( z ) {
  358. this.z = z;
  359. return this;
  360. },
  361. copy: function ( v ) {
  362. this.x = v.x;
  363. this.y = v.y;
  364. this.z = v.z;
  365. return this;
  366. },
  367. add: function ( a, b ) {
  368. this.x = a.x + b.x;
  369. this.y = a.y + b.y;
  370. this.z = a.z + b.z;
  371. return this;
  372. },
  373. addSelf: function ( v ) {
  374. this.x += v.x;
  375. this.y += v.y;
  376. this.z += v.z;
  377. return this;
  378. },
  379. addScalar: function ( s ) {
  380. this.x += s;
  381. this.y += s;
  382. this.z += s;
  383. return this;
  384. },
  385. sub: function ( a, b ) {
  386. this.x = a.x - b.x;
  387. this.y = a.y - b.y;
  388. this.z = a.z - b.z;
  389. return this;
  390. },
  391. subSelf: function ( v ) {
  392. this.x -= v.x;
  393. this.y -= v.y;
  394. this.z -= v.z;
  395. return this;
  396. },
  397. multiply: function ( a, b ) {
  398. this.x = a.x * b.x;
  399. this.y = a.y * b.y;
  400. this.z = a.z * b.z;
  401. return this;
  402. },
  403. multiplySelf: function ( v ) {
  404. this.x *= v.x;
  405. this.y *= v.y;
  406. this.z *= v.z;
  407. return this;
  408. },
  409. multiplyScalar: function ( s ) {
  410. this.x *= s;
  411. this.y *= s;
  412. this.z *= s;
  413. return this;
  414. },
  415. divideSelf: function ( v ) {
  416. this.x /= v.x;
  417. this.y /= v.y;
  418. this.z /= v.z;
  419. return this;
  420. },
  421. divideScalar: function ( s ) {
  422. if ( s ) {
  423. this.x /= s;
  424. this.y /= s;
  425. this.z /= s;
  426. } else {
  427. this.x = 0;
  428. this.y = 0;
  429. this.z = 0;
  430. }
  431. return this;
  432. },
  433. negate: function() {
  434. return this.multiplyScalar( - 1 );
  435. },
  436. dot: function ( v ) {
  437. return this.x * v.x + this.y * v.y + this.z * v.z;
  438. },
  439. lengthSq: function () {
  440. return this.x * this.x + this.y * this.y + this.z * this.z;
  441. },
  442. length: function () {
  443. return Math.sqrt( this.lengthSq() );
  444. },
  445. lengthManhattan: function () {
  446. return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
  447. },
  448. normalize: function () {
  449. return this.divideScalar( this.length() );
  450. },
  451. setLength: function ( l ) {
  452. return this.normalize().multiplyScalar( l );
  453. },
  454. lerpSelf: function ( v, alpha ) {
  455. this.x += ( v.x - this.x ) * alpha;
  456. this.y += ( v.y - this.y ) * alpha;
  457. this.z += ( v.z - this.z ) * alpha;
  458. return this;
  459. },
  460. cross: function ( a, b ) {
  461. this.x = a.y * b.z - a.z * b.y;
  462. this.y = a.z * b.x - a.x * b.z;
  463. this.z = a.x * b.y - a.y * b.x;
  464. return this;
  465. },
  466. crossSelf: function ( v ) {
  467. var x = this.x, y = this.y, z = this.z;
  468. this.x = y * v.z - z * v.y;
  469. this.y = z * v.x - x * v.z;
  470. this.z = x * v.y - y * v.x;
  471. return this;
  472. },
  473. distanceTo: function ( v ) {
  474. return Math.sqrt( this.distanceToSquared( v ) );
  475. },
  476. distanceToSquared: function ( v ) {
  477. return new THREE.Vector3().sub( this, v ).lengthSq();
  478. },
  479. getPositionFromMatrix: function ( m ) {
  480. this.x = m.elements[12];
  481. this.y = m.elements[13];
  482. this.z = m.elements[14];
  483. return this;
  484. },
  485. setEulerFromRotationMatrix: function ( m, order ) {
  486. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  487. // clamp, to handle numerical problems
  488. function clamp( x ) {
  489. return Math.min( Math.max( x, -1 ), 1 );
  490. }
  491. var te = m.elements;
  492. var m11 = te[0], m12 = te[4], m13 = te[8];
  493. var m21 = te[1], m22 = te[5], m23 = te[9];
  494. var m31 = te[2], m32 = te[6], m33 = te[10];
  495. if ( order === undefined || order === 'XYZ' ) {
  496. this.y = Math.asin( clamp( m13 ) );
  497. if ( Math.abs( m13 ) < 0.99999 ) {
  498. this.x = Math.atan2( - m23, m33 );
  499. this.z = Math.atan2( - m12, m11 );
  500. } else {
  501. this.x = Math.atan2( m21, m22 );
  502. this.z = 0;
  503. }
  504. } else if ( order === 'YXZ' ) {
  505. this.x = Math.asin( - clamp( m23 ) );
  506. if ( Math.abs( m23 ) < 0.99999 ) {
  507. this.y = Math.atan2( m13, m33 );
  508. this.z = Math.atan2( m21, m22 );
  509. } else {
  510. this.y = Math.atan2( - m31, m11 );
  511. this.z = 0;
  512. }
  513. } else if ( order === 'ZXY' ) {
  514. this.x = Math.asin( clamp( m32 ) );
  515. if ( Math.abs( m32 ) < 0.99999 ) {
  516. this.y = Math.atan2( - m31, m33 );
  517. this.z = Math.atan2( - m12, m22 );
  518. } else {
  519. this.y = 0;
  520. this.z = Math.atan2( m13, m11 );
  521. }
  522. } else if ( order === 'ZYX' ) {
  523. this.y = Math.asin( - clamp( m31 ) );
  524. if ( Math.abs( m31 ) < 0.99999 ) {
  525. this.x = Math.atan2( m32, m33 );
  526. this.z = Math.atan2( m21, m11 );
  527. } else {
  528. this.x = 0;
  529. this.z = Math.atan2( - m12, m22 );
  530. }
  531. } else if ( order === 'YZX' ) {
  532. this.z = Math.asin( clamp( m21 ) );
  533. if ( Math.abs( m21 ) < 0.99999 ) {
  534. this.x = Math.atan2( - m23, m22 );
  535. this.y = Math.atan2( - m31, m11 );
  536. } else {
  537. this.x = 0;
  538. this.y = Math.atan2( m31, m33 );
  539. }
  540. } else if ( order === 'XZY' ) {
  541. this.z = Math.asin( - clamp( m12 ) );
  542. if ( Math.abs( m12 ) < 0.99999 ) {
  543. this.x = Math.atan2( m32, m22 );
  544. this.y = Math.atan2( m13, m11 );
  545. } else {
  546. this.x = Math.atan2( - m13, m33 );
  547. this.y = 0;
  548. }
  549. }
  550. return this;
  551. },
  552. setEulerFromQuaternion: function ( q, order ) {
  553. // q is assumed to be normalized
  554. // clamp, to handle numerical problems
  555. function clamp( x ) {
  556. return Math.min( Math.max( x, -1 ), 1 );
  557. }
  558. // http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m
  559. var sqx = q.x * q.x;
  560. var sqy = q.y * q.y;
  561. var sqz = q.z * q.z;
  562. var sqw = q.w * q.w;
  563. if ( order === undefined || order === 'XYZ' ) {
  564. this.x = Math.atan2( 2 * ( q.x * q.w - q.y * q.z ), ( sqw - sqx - sqy + sqz ) );
  565. this.y = Math.asin( clamp( 2 * ( q.x * q.z + q.y * q.w ) ) );
  566. this.z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw + sqx - sqy - sqz ) );
  567. } else if ( order === 'YXZ' ) {
  568. this.x = Math.asin( clamp( 2 * ( q.x * q.w - q.y * q.z ) ) );
  569. this.y = Math.atan2( 2 * ( q.x * q.z + q.y * q.w ), ( sqw - sqx - sqy + sqz ) );
  570. this.z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw - sqx + sqy - sqz ) );
  571. } else if ( order === 'ZXY' ) {
  572. this.x = Math.asin( clamp( 2 * ( q.x * q.w + q.y * q.z ) ) );
  573. this.y = Math.atan2( 2 * ( q.y * q.w - q.z * q.x ), ( sqw - sqx - sqy + sqz ) );
  574. this.z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw - sqx + sqy - sqz ) );
  575. } else if ( order === 'ZYX' ) {
  576. this.x = Math.atan2( 2 * ( q.x * q.w + q.z * q.y ), ( sqw - sqx - sqy + sqz ) );
  577. this.y = Math.asin( clamp( 2 * ( q.y * q.w - q.x * q.z ) ) );
  578. this.z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw + sqx - sqy - sqz ) );
  579. } else if ( order === 'YZX' ) {
  580. this.x = Math.atan2( 2 * ( q.x * q.w - q.z * q.y ), ( sqw - sqx + sqy - sqz ) );
  581. this.y = Math.atan2( 2 * ( q.y * q.w - q.x * q.z ), ( sqw + sqx - sqy - sqz ) );
  582. this.z = Math.asin( clamp( 2 * ( q.x * q.y + q.z * q.w ) ) );
  583. } else if ( order === 'XZY' ) {
  584. this.x = Math.atan2( 2 * ( q.x * q.w + q.y * q.z ), ( sqw - sqx + sqy - sqz ) );
  585. this.y = Math.atan2( 2 * ( q.x * q.z + q.y * q.w ), ( sqw + sqx - sqy - sqz ) );
  586. this.z = Math.asin( clamp( 2 * ( q.z * q.w - q.x * q.y ) ) );
  587. }
  588. return this;
  589. },
  590. getScaleFromMatrix: function ( m ) {
  591. var sx = this.set( m.elements[0], m.elements[1], m.elements[2] ).length();
  592. var sy = this.set( m.elements[4], m.elements[5], m.elements[6] ).length();
  593. var sz = this.set( m.elements[8], m.elements[9], m.elements[10] ).length();
  594. this.x = sx;
  595. this.y = sy;
  596. this.z = sz;
  597. return this;
  598. },
  599. equals: function ( v ) {
  600. return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );
  601. },
  602. isZero: function () {
  603. return ( this.lengthSq() < 0.0001 /* almostZero */ );
  604. },
  605. clone: function () {
  606. return new THREE.Vector3( this.x, this.y, this.z );
  607. }
  608. };
  609. /**
  610. * @author supereggbert / http://www.paulbrunt.co.uk/
  611. * @author philogb / http://blog.thejit.org/
  612. * @author mikael emtinger / http://gomo.se/
  613. * @author egraether / http://egraether.com/
  614. * @author WestLangley / http://github.com/WestLangley
  615. */
  616. THREE.Vector4 = function ( x, y, z, w ) {
  617. this.x = x || 0;
  618. this.y = y || 0;
  619. this.z = z || 0;
  620. this.w = ( w !== undefined ) ? w : 1;
  621. };
  622. THREE.Vector4.prototype = {
  623. constructor: THREE.Vector4,
  624. set: function ( x, y, z, w ) {
  625. this.x = x;
  626. this.y = y;
  627. this.z = z;
  628. this.w = w;
  629. return this;
  630. },
  631. copy: function ( v ) {
  632. this.x = v.x;
  633. this.y = v.y;
  634. this.z = v.z;
  635. this.w = ( v.w !== undefined ) ? v.w : 1;
  636. return this;
  637. },
  638. add: function ( a, b ) {
  639. this.x = a.x + b.x;
  640. this.y = a.y + b.y;
  641. this.z = a.z + b.z;
  642. this.w = a.w + b.w;
  643. return this;
  644. },
  645. addSelf: function ( v ) {
  646. this.x += v.x;
  647. this.y += v.y;
  648. this.z += v.z;
  649. this.w += v.w;
  650. return this;
  651. },
  652. sub: function ( a, b ) {
  653. this.x = a.x - b.x;
  654. this.y = a.y - b.y;
  655. this.z = a.z - b.z;
  656. this.w = a.w - b.w;
  657. return this;
  658. },
  659. subSelf: function ( v ) {
  660. this.x -= v.x;
  661. this.y -= v.y;
  662. this.z -= v.z;
  663. this.w -= v.w;
  664. return this;
  665. },
  666. multiplyScalar: function ( s ) {
  667. this.x *= s;
  668. this.y *= s;
  669. this.z *= s;
  670. this.w *= s;
  671. return this;
  672. },
  673. divideScalar: function ( s ) {
  674. if ( s ) {
  675. this.x /= s;
  676. this.y /= s;
  677. this.z /= s;
  678. this.w /= s;
  679. } else {
  680. this.x = 0;
  681. this.y = 0;
  682. this.z = 0;
  683. this.w = 1;
  684. }
  685. return this;
  686. },
  687. negate: function() {
  688. return this.multiplyScalar( -1 );
  689. },
  690. dot: function ( v ) {
  691. return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
  692. },
  693. lengthSq: function () {
  694. return this.dot( this );
  695. },
  696. length: function () {
  697. return Math.sqrt( this.lengthSq() );
  698. },
  699. normalize: function () {
  700. return this.divideScalar( this.length() );
  701. },
  702. setLength: function ( l ) {
  703. return this.normalize().multiplyScalar( l );
  704. },
  705. lerpSelf: function ( v, alpha ) {
  706. this.x += ( v.x - this.x ) * alpha;
  707. this.y += ( v.y - this.y ) * alpha;
  708. this.z += ( v.z - this.z ) * alpha;
  709. this.w += ( v.w - this.w ) * alpha;
  710. return this;
  711. },
  712. clone: function () {
  713. return new THREE.Vector4( this.x, this.y, this.z, this.w );
  714. },
  715. setAxisAngleFromQuaternion: function ( q ) {
  716. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
  717. // q is assumed to be normalized
  718. this.w = 2 * Math.acos( q.w );
  719. var s = Math.sqrt( 1 - q.w * q.w );
  720. if ( s < 0.0001 ) {
  721. this.x = 1;
  722. this.y = 0;
  723. this.z = 0;
  724. } else {
  725. this.x = q.x / s;
  726. this.y = q.y / s;
  727. this.z = q.z / s;
  728. }
  729. return this;
  730. },
  731. setAxisAngleFromRotationMatrix: function ( m ) {
  732. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
  733. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  734. var angle, x, y, z, // variables for result
  735. epsilon = 0.01, // margin to allow for rounding errors
  736. epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees
  737. te = m.elements,
  738. m11 = te[0], m12 = te[4], m13 = te[8],
  739. m21 = te[1], m22 = te[5], m23 = te[9],
  740. m31 = te[2], m32 = te[6], m33 = te[10];
  741. if ( ( Math.abs( m12 - m21 ) < epsilon )
  742. && ( Math.abs( m13 - m31 ) < epsilon )
  743. && ( Math.abs( m23 - m32 ) < epsilon ) ) {
  744. // singularity found
  745. // first check for identity matrix which must have +1 for all terms
  746. // in leading diagonal and zero in other terms
  747. if ( ( Math.abs( m12 + m21 ) < epsilon2 )
  748. && ( Math.abs( m13 + m31 ) < epsilon2 )
  749. && ( Math.abs( m23 + m32 ) < epsilon2 )
  750. && ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {
  751. // this singularity is identity matrix so angle = 0
  752. this.set( 1, 0, 0, 0 );
  753. return this; // zero angle, arbitrary axis
  754. }
  755. // otherwise this singularity is angle = 180
  756. angle = Math.PI;
  757. var xx = ( m11 + 1 ) / 2;
  758. var yy = ( m22 + 1 ) / 2;
  759. var zz = ( m33 + 1 ) / 2;
  760. var xy = ( m12 + m21 ) / 4;
  761. var xz = ( m13 + m31 ) / 4;
  762. var yz = ( m23 + m32 ) / 4;
  763. if ( ( xx > yy ) && ( xx > zz ) ) { // m11 is the largest diagonal term
  764. if ( xx < epsilon ) {
  765. x = 0;
  766. y = 0.707106781;
  767. z = 0.707106781;
  768. } else {
  769. x = Math.sqrt( xx );
  770. y = xy / x;
  771. z = xz / x;
  772. }
  773. } else if ( yy > zz ) { // m22 is the largest diagonal term
  774. if ( yy < epsilon ) {
  775. x = 0.707106781;
  776. y = 0;
  777. z = 0.707106781;
  778. } else {
  779. y = Math.sqrt( yy );
  780. x = xy / y;
  781. z = yz / y;
  782. }
  783. } else { // m33 is the largest diagonal term so base result on this
  784. if ( zz < epsilon ) {
  785. x = 0.707106781;
  786. y = 0.707106781;
  787. z = 0;
  788. } else {
  789. z = Math.sqrt( zz );
  790. x = xz / z;
  791. y = yz / z;
  792. }
  793. }
  794. this.set( x, y, z, angle );
  795. return this; // return 180 deg rotation
  796. }
  797. // as we have reached here there are no singularities so we can handle normally
  798. var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 )
  799. + ( m13 - m31 ) * ( m13 - m31 )
  800. + ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize
  801. if ( Math.abs( s ) < 0.001 ) s = 1;
  802. // prevent divide by zero, should not happen if matrix is orthogonal and should be
  803. // caught by singularity test above, but I've left it in just in case
  804. this.x = ( m32 - m23 ) / s;
  805. this.y = ( m13 - m31 ) / s;
  806. this.z = ( m21 - m12 ) / s;
  807. this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );
  808. return this;
  809. }
  810. };
  811. /**
  812. * https://github.com/mrdoob/eventtarget.js/
  813. */
  814. THREE.EventTarget = function () {
  815. var listeners = {};
  816. this.addEventListener = function ( type, listener ) {
  817. if ( listeners[ type ] === undefined ) {
  818. listeners[ type ] = [];
  819. }
  820. if ( listeners[ type ].indexOf( listener ) === - 1 ) {
  821. listeners[ type ].push( listener );
  822. }
  823. };
  824. this.dispatchEvent = function ( event ) {
  825. for ( var listener in listeners[ event.type ] ) {
  826. listeners[ event.type ][ listener ]( event );
  827. }
  828. };
  829. this.removeEventListener = function ( type, listener ) {
  830. var index = listeners[ type ].indexOf( listener );
  831. if ( index !== - 1 ) {
  832. listeners[ type ].splice( index, 1 );
  833. }
  834. };
  835. };
  836. /**
  837. * @author mrdoob / http://mrdoob.com/
  838. * @author alteredq / http://alteredqualia.com/
  839. */
  840. THREE.Frustum = function ( ) {
  841. this.planes = [
  842. new THREE.Vector4(),
  843. new THREE.Vector4(),
  844. new THREE.Vector4(),
  845. new THREE.Vector4(),
  846. new THREE.Vector4(),
  847. new THREE.Vector4()
  848. ];
  849. };
  850. THREE.Frustum.prototype.setFromMatrix = function ( m ) {
  851. var plane;
  852. var planes = this.planes;
  853. var me = m.elements;
  854. var me0 = me[0], me1 = me[1], me2 = me[2], me3 = me[3];
  855. var me4 = me[4], me5 = me[5], me6 = me[6], me7 = me[7];
  856. var me8 = me[8], me9 = me[9], me10 = me[10], me11 = me[11];
  857. var me12 = me[12], me13 = me[13], me14 = me[14], me15 = me[15];
  858. planes[ 0 ].set( me3 - me0, me7 - me4, me11 - me8, me15 - me12 );
  859. planes[ 1 ].set( me3 + me0, me7 + me4, me11 + me8, me15 + me12 );
  860. planes[ 2 ].set( me3 + me1, me7 + me5, me11 + me9, me15 + me13 );
  861. planes[ 3 ].set( me3 - me1, me7 - me5, me11 - me9, me15 - me13 );
  862. planes[ 4 ].set( me3 - me2, me7 - me6, me11 - me10, me15 - me14 );
  863. planes[ 5 ].set( me3 + me2, me7 + me6, me11 + me10, me15 + me14 );
  864. for ( var i = 0; i < 6; i ++ ) {
  865. plane = planes[ i ];
  866. plane.divideScalar( Math.sqrt( plane.x * plane.x + plane.y * plane.y + plane.z * plane.z ) );
  867. }
  868. };
  869. THREE.Frustum.prototype.contains = function ( object ) {
  870. var distance = 0.0;
  871. var planes = this.planes;
  872. var matrix = object.matrixWorld;
  873. var me = matrix.elements;
  874. var radius = - object.geometry.boundingSphere.radius * matrix.getMaxScaleOnAxis();
  875. for ( var i = 0; i < 6; i ++ ) {
  876. distance = planes[ i ].x * me[12] + planes[ i ].y * me[13] + planes[ i ].z * me[14] + planes[ i ].w;
  877. if ( distance <= radius ) return false;
  878. }
  879. return true;
  880. };
  881. THREE.Frustum.__v1 = new THREE.Vector3();
  882. /**
  883. * @author mr.doob / http://mrdoob.com/
  884. */
  885. THREE.Ray = function ( origin, direction, near, far ) {
  886. this.origin = origin || new THREE.Vector3();
  887. this.direction = direction || new THREE.Vector3();
  888. this.near = near || 0;
  889. this.far = far || Infinity;
  890. //
  891. var a = new THREE.Vector3();
  892. var b = new THREE.Vector3();
  893. var c = new THREE.Vector3();
  894. var d = new THREE.Vector3();
  895. var originCopy = new THREE.Vector3();
  896. var directionCopy = new THREE.Vector3();
  897. var vector = new THREE.Vector3();
  898. var normal = new THREE.Vector3();
  899. var intersectPoint = new THREE.Vector3();
  900. var descSort = function ( a, b ) {
  901. return a.distance - b.distance;
  902. };
  903. //
  904. var v0 = new THREE.Vector3(), v1 = new THREE.Vector3(), v2 = new THREE.Vector3();
  905. var dot, intersect, distance;
  906. var distanceFromIntersection = function ( origin, direction, position ) {
  907. v0.sub( position, origin );
  908. dot = v0.dot( direction );
  909. intersect = v1.add( origin, v2.copy( direction ).multiplyScalar( dot ) );
  910. distance = position.distanceTo( intersect );
  911. return distance;
  912. }
  913. // http://www.blackpawn.com/texts/pointinpoly/default.html
  914. var dot00, dot01, dot02, dot11, dot12, invDenom, u, v;
  915. var pointInFace3 = function ( p, a, b, c ) {
  916. v0.sub( c, a );
  917. v1.sub( b, a );
  918. v2.sub( p, a );
  919. dot00 = v0.dot( v0 );
  920. dot01 = v0.dot( v1 );
  921. dot02 = v0.dot( v2 );
  922. dot11 = v1.dot( v1 );
  923. dot12 = v1.dot( v2 );
  924. invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 );
  925. u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
  926. v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
  927. return ( u >= 0 ) && ( v >= 0 ) && ( u + v < 1 );
  928. }
  929. //
  930. var precision = 0.0001;
  931. this.setPrecision = function ( value ) {
  932. precision = value;
  933. };
  934. this.intersectObject = function ( object, recursive ) {
  935. var intersect, intersects = [];
  936. if ( recursive === true ) {
  937. for ( var i = 0, l = object.children.length; i < l; i ++ ) {
  938. Array.prototype.push.apply( intersects, this.intersectObject( object.children[ i ], recursive ) );
  939. }
  940. }
  941. if ( object instanceof THREE.Particle ) {
  942. distance = distanceFromIntersection( this.origin, this.direction, object.matrixWorld.getPosition() );
  943. if ( distance > object.scale.x ) {
  944. return [];
  945. }
  946. intersect = {
  947. distance: distance,
  948. point: object.position,
  949. face: null,
  950. object: object
  951. };
  952. intersects.push( intersect );
  953. } else if ( object instanceof THREE.Mesh ) {
  954. // Checking boundingSphere
  955. var scale = THREE.Frustum.__v1.set( object.matrixWorld.getColumnX().length(), object.matrixWorld.getColumnY().length(), object.matrixWorld.getColumnZ().length() );
  956. var scaledRadius = object.geometry.boundingSphere.radius * Math.max( scale.x, Math.max( scale.y, scale.z ) );
  957. // Checking distance to ray
  958. distance = distanceFromIntersection( this.origin, this.direction, object.matrixWorld.getPosition() );
  959. if ( distance > scaledRadius) {
  960. return intersects;
  961. }
  962. // Checking faces
  963. var f, fl, face, dot, scalar,
  964. rangeSq = this.range * this.range,
  965. geometry = object.geometry,
  966. vertices = geometry.vertices,
  967. objMatrix;
  968. object.matrixRotationWorld.extractRotation( object.matrixWorld );
  969. for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
  970. face = geometry.faces[ f ];
  971. originCopy.copy( this.origin );
  972. directionCopy.copy( this.direction );
  973. objMatrix = object.matrixWorld;
  974. // determine if ray intersects the plane of the face
  975. // note: this works regardless of the direction of the face normal
  976. vector = objMatrix.multiplyVector3( vector.copy( face.centroid ) ).subSelf( originCopy );
  977. normal = object.matrixRotationWorld.multiplyVector3( normal.copy( face.normal ) );
  978. dot = directionCopy.dot( normal );
  979. // bail if ray and plane are parallel
  980. if ( Math.abs( dot ) < precision ) continue;
  981. // calc distance to plane
  982. scalar = normal.dot( vector ) / dot;
  983. // if negative distance, then plane is behind ray
  984. if ( scalar < 0 ) continue;
  985. if ( object.doubleSided || ( object.flipSided ? dot > 0 : dot < 0 ) ) {
  986. intersectPoint.add( originCopy, directionCopy.multiplyScalar( scalar ) );
  987. distance = originCopy.distanceTo( intersectPoint );
  988. if ( distance < this.near ) continue;
  989. if ( distance > this.far ) continue;
  990. if ( face instanceof THREE.Face3 ) {
  991. a = objMatrix.multiplyVector3( a.copy( vertices[ face.a ] ) );
  992. b = objMatrix.multiplyVector3( b.copy( vertices[ face.b ] ) );
  993. c = objMatrix.multiplyVector3( c.copy( vertices[ face.c ] ) );
  994. if ( pointInFace3( intersectPoint, a, b, c ) ) {
  995. intersect = {
  996. distance: distance,
  997. point: intersectPoint.clone(),
  998. face: face,
  999. object: object
  1000. };
  1001. intersects.push( intersect );
  1002. }
  1003. } else if ( face instanceof THREE.Face4 ) {
  1004. a = objMatrix.multiplyVector3( a.copy( vertices[ face.a ] ) );
  1005. b = objMatrix.multiplyVector3( b.copy( vertices[ face.b ] ) );
  1006. c = objMatrix.multiplyVector3( c.copy( vertices[ face.c ] ) );
  1007. d = objMatrix.multiplyVector3( d.copy( vertices[ face.d ] ) );
  1008. if ( pointInFace3( intersectPoint, a, b, d ) || pointInFace3( intersectPoint, b, c, d ) ) {
  1009. intersect = {
  1010. distance: distance,
  1011. point: intersectPoint.clone(),
  1012. face: face,
  1013. object: object
  1014. };
  1015. intersects.push( intersect );
  1016. }
  1017. }
  1018. }
  1019. }
  1020. }
  1021. intersects.sort( descSort );
  1022. return intersects;
  1023. };
  1024. this.intersectObjects = function ( objects, recursive ) {
  1025. var intersects = [];
  1026. for ( var i = 0, l = objects.length; i < l; i ++ ) {
  1027. Array.prototype.push.apply( intersects, this.intersectObject( objects[ i ], recursive ) );
  1028. }
  1029. intersects.sort( descSort );
  1030. return intersects;
  1031. };
  1032. };
  1033. /**
  1034. * @author mr.doob / http://mrdoob.com/
  1035. */
  1036. THREE.Rectangle = function () {
  1037. var _left = 0;
  1038. var _top = 0;
  1039. var _right = 0;
  1040. var _bottom = 0;
  1041. var _width = 0;
  1042. var _height = 0;
  1043. var _isEmpty = true;
  1044. function resize() {
  1045. _width = _right - _left;
  1046. _height = _bottom - _top;
  1047. }
  1048. this.getX = function () {
  1049. return _left;
  1050. };
  1051. this.getY = function () {
  1052. return _top;
  1053. };
  1054. this.getWidth = function () {
  1055. return _width;
  1056. };
  1057. this.getHeight = function () {
  1058. return _height;
  1059. };
  1060. this.getLeft = function() {
  1061. return _left;
  1062. };
  1063. this.getTop = function() {
  1064. return _top;
  1065. };
  1066. this.getRight = function() {
  1067. return _right;
  1068. };
  1069. this.getBottom = function() {
  1070. return _bottom;
  1071. };
  1072. this.set = function ( left, top, right, bottom ) {
  1073. _isEmpty = false;
  1074. _left = left; _top = top;
  1075. _right = right; _bottom = bottom;
  1076. resize();
  1077. };
  1078. this.addPoint = function ( x, y ) {
  1079. if ( _isEmpty === true ) {
  1080. _isEmpty = false;
  1081. _left = x; _top = y;
  1082. _right = x; _bottom = y;
  1083. resize();
  1084. } else {
  1085. _left = _left < x ? _left : x; // Math.min( _left, x );
  1086. _top = _top < y ? _top : y; // Math.min( _top, y );
  1087. _right = _right > x ? _right : x; // Math.max( _right, x );
  1088. _bottom = _bottom > y ? _bottom : y; // Math.max( _bottom, y );
  1089. resize();
  1090. }
  1091. };
  1092. this.add3Points = function ( x1, y1, x2, y2, x3, y3 ) {
  1093. if ( _isEmpty === true ) {
  1094. _isEmpty = false;
  1095. _left = x1 < x2 ? ( x1 < x3 ? x1 : x3 ) : ( x2 < x3 ? x2 : x3 );
  1096. _top = y1 < y2 ? ( y1 < y3 ? y1 : y3 ) : ( y2 < y3 ? y2 : y3 );
  1097. _right = x1 > x2 ? ( x1 > x3 ? x1 : x3 ) : ( x2 > x3 ? x2 : x3 );
  1098. _bottom = y1 > y2 ? ( y1 > y3 ? y1 : y3 ) : ( y2 > y3 ? y2 : y3 );
  1099. resize();
  1100. } else {
  1101. _left = x1 < x2 ? ( x1 < x3 ? ( x1 < _left ? x1 : _left ) : ( x3 < _left ? x3 : _left ) ) : ( x2 < x3 ? ( x2 < _left ? x2 : _left ) : ( x3 < _left ? x3 : _left ) );
  1102. _top = y1 < y2 ? ( y1 < y3 ? ( y1 < _top ? y1 : _top ) : ( y3 < _top ? y3 : _top ) ) : ( y2 < y3 ? ( y2 < _top ? y2 : _top ) : ( y3 < _top ? y3 : _top ) );
  1103. _right = x1 > x2 ? ( x1 > x3 ? ( x1 > _right ? x1 : _right ) : ( x3 > _right ? x3 : _right ) ) : ( x2 > x3 ? ( x2 > _right ? x2 : _right ) : ( x3 > _right ? x3 : _right ) );
  1104. _bottom = y1 > y2 ? ( y1 > y3 ? ( y1 > _bottom ? y1 : _bottom ) : ( y3 > _bottom ? y3 : _bottom ) ) : ( y2 > y3 ? ( y2 > _bottom ? y2 : _bottom ) : ( y3 > _bottom ? y3 : _bottom ) );
  1105. resize();
  1106. };
  1107. };
  1108. this.addRectangle = function ( r ) {
  1109. if ( _isEmpty === true ) {
  1110. _isEmpty = false;
  1111. _left = r.getLeft(); _top = r.getTop();
  1112. _right = r.getRight(); _bottom = r.getBottom();
  1113. resize();
  1114. } else {
  1115. _left = _left < r.getLeft() ? _left : r.getLeft(); // Math.min(_left, r.getLeft() );
  1116. _top = _top < r.getTop() ? _top : r.getTop(); // Math.min(_top, r.getTop() );
  1117. _right = _right > r.getRight() ? _right : r.getRight(); // Math.max(_right, r.getRight() );
  1118. _bottom = _bottom > r.getBottom() ? _bottom : r.getBottom(); // Math.max(_bottom, r.getBottom() );
  1119. resize();
  1120. }
  1121. };
  1122. this.inflate = function ( v ) {
  1123. _left -= v; _top -= v;
  1124. _right += v; _bottom += v;
  1125. resize();
  1126. };
  1127. this.minSelf = function ( r ) {
  1128. _left = _left > r.getLeft() ? _left : r.getLeft(); // Math.max( _left, r.getLeft() );
  1129. _top = _top > r.getTop() ? _top : r.getTop(); // Math.max( _top, r.getTop() );
  1130. _right = _right < r.getRight() ? _right : r.getRight(); // Math.min( _right, r.getRight() );
  1131. _bottom = _bottom < r.getBottom() ? _bottom : r.getBottom(); // Math.min( _bottom, r.getBottom() );
  1132. resize();
  1133. };
  1134. this.intersects = function ( r ) {
  1135. // http://gamemath.com/2011/09/detecting-whether-two-boxes-overlap/
  1136. if ( _right < r.getLeft() ) return false;
  1137. if ( _left > r.getRight() ) return false;
  1138. if ( _bottom < r.getTop() ) return false;
  1139. if ( _top > r.getBottom() ) return false;
  1140. return true;
  1141. };
  1142. this.empty = function () {
  1143. _isEmpty = true;
  1144. _left = 0; _top = 0;
  1145. _right = 0; _bottom = 0;
  1146. resize();
  1147. };
  1148. this.isEmpty = function () {
  1149. return _isEmpty;
  1150. };
  1151. };
  1152. /**
  1153. * @author alteredq / http://alteredqualia.com/
  1154. */
  1155. THREE.Math = {
  1156. // Clamp value to range <a, b>
  1157. clamp: function ( x, a, b ) {
  1158. return ( x < a ) ? a : ( ( x > b ) ? b : x );
  1159. },
  1160. // Clamp value to range <a, inf)
  1161. clampBottom: function ( x, a ) {
  1162. return x < a ? a : x;
  1163. },
  1164. // Linear mapping from range <a1, a2> to range <b1, b2>
  1165. mapLinear: function ( x, a1, a2, b1, b2 ) {
  1166. return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
  1167. },
  1168. // Random float from <0, 1> with 16 bits of randomness
  1169. // (standard Math.random() creates repetitive patterns when applied over larger space)
  1170. random16: function () {
  1171. return ( 65280 * Math.random() + 255 * Math.random() ) / 65535;
  1172. },
  1173. // Random integer from <low, high> interval
  1174. randInt: function ( low, high ) {
  1175. return low + Math.floor( Math.random() * ( high - low + 1 ) );
  1176. },
  1177. // Random float from <low, high> interval
  1178. randFloat: function ( low, high ) {
  1179. return low + Math.random() * ( high - low );
  1180. },
  1181. // Random float from <-range/2, range/2> interval
  1182. randFloatSpread: function ( range ) {
  1183. return range * ( 0.5 - Math.random() );
  1184. },
  1185. sign: function ( x ) {
  1186. return ( x < 0 ) ? -1 : ( ( x > 0 ) ? 1 : 0 );
  1187. }
  1188. };
  1189. /**
  1190. * @author alteredq / http://alteredqualia.com/
  1191. */
  1192. THREE.Matrix3 = function () {
  1193. this.elements = new Float32Array(9);
  1194. };
  1195. THREE.Matrix3.prototype = {
  1196. constructor: THREE.Matrix3,
  1197. getInverse: function ( matrix ) {
  1198. // input: THREE.Matrix4
  1199. // ( based on http://code.google.com/p/webgl-mjs/ )
  1200. var me = matrix.elements;
  1201. var a11 = me[10] * me[5] - me[6] * me[9];
  1202. var a21 = - me[10] * me[1] + me[2] * me[9];
  1203. var a31 = me[6] * me[1] - me[2] * me[5];
  1204. var a12 = - me[10] * me[4] + me[6] * me[8];
  1205. var a22 = me[10] * me[0] - me[2] * me[8];
  1206. var a32 = - me[6] * me[0] + me[2] * me[4];
  1207. var a13 = me[9] * me[4] - me[5] * me[8];
  1208. var a23 = - me[9] * me[0] + me[1] * me[8];
  1209. var a33 = me[5] * me[0] - me[1] * me[4];
  1210. var det = me[0] * a11 + me[1] * a12 + me[2] * a13;
  1211. // no inverse
  1212. if ( det === 0 ) {
  1213. console.warn( "Matrix3.getInverse(): determinant == 0" );
  1214. }
  1215. var idet = 1.0 / det;
  1216. var m = this.elements;
  1217. m[ 0 ] = idet * a11; m[ 1 ] = idet * a21; m[ 2 ] = idet * a31;
  1218. m[ 3 ] = idet * a12; m[ 4 ] = idet * a22; m[ 5 ] = idet * a32;
  1219. m[ 6 ] = idet * a13; m[ 7 ] = idet * a23; m[ 8 ] = idet * a33;
  1220. return this;
  1221. },
  1222. transpose: function () {
  1223. var tmp, m = this.elements;
  1224. tmp = m[1]; m[1] = m[3]; m[3] = tmp;
  1225. tmp = m[2]; m[2] = m[6]; m[6] = tmp;
  1226. tmp = m[5]; m[5] = m[7]; m[7] = tmp;
  1227. return this;
  1228. },
  1229. transposeIntoArray: function ( r ) {
  1230. var m = this.m;
  1231. r[ 0 ] = m[ 0 ];
  1232. r[ 1 ] = m[ 3 ];
  1233. r[ 2 ] = m[ 6 ];
  1234. r[ 3 ] = m[ 1 ];
  1235. r[ 4 ] = m[ 4 ];
  1236. r[ 5 ] = m[ 7 ];
  1237. r[ 6 ] = m[ 2 ];
  1238. r[ 7 ] = m[ 5 ];
  1239. r[ 8 ] = m[ 8 ];
  1240. return this;
  1241. }
  1242. };
  1243. /**
  1244. * @author mr.doob / http://mrdoob.com/
  1245. * @author supereggbert / http://www.paulbrunt.co.uk/
  1246. * @author philogb / http://blog.thejit.org/
  1247. * @author jordi_ros / http://plattsoft.com
  1248. * @author D1plo1d / http://github.com/D1plo1d
  1249. * @author alteredq / http://alteredqualia.com/
  1250. * @author mikael emtinger / http://gomo.se/
  1251. * @author timknip / http://www.floorplanner.com/
  1252. */
  1253. THREE.Matrix4 = function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
  1254. this.elements = new Float32Array( 16 );
  1255. this.set(
  1256. ( n11 !== undefined ) ? n11 : 1, n12 || 0, n13 || 0, n14 || 0,
  1257. n21 || 0, ( n22 !== undefined ) ? n22 : 1, n23 || 0, n24 || 0,
  1258. n31 || 0, n32 || 0, ( n33 !== undefined ) ? n33 : 1, n34 || 0,
  1259. n41 || 0, n42 || 0, n43 || 0, ( n44 !== undefined ) ? n44 : 1
  1260. );
  1261. };
  1262. THREE.Matrix4.prototype = {
  1263. constructor: THREE.Matrix4,
  1264. set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
  1265. var te = this.elements;
  1266. te[0] = n11; te[4] = n12; te[8] = n13; te[12] = n14;
  1267. te[1] = n21; te[5] = n22; te[9] = n23; te[13] = n24;
  1268. te[2] = n31; te[6] = n32; te[10] = n33; te[14] = n34;
  1269. te[3] = n41; te[7] = n42; te[11] = n43; te[15] = n44;
  1270. return this;
  1271. },
  1272. identity: function () {
  1273. this.set(
  1274. 1, 0, 0, 0,
  1275. 0, 1, 0, 0,
  1276. 0, 0, 1, 0,
  1277. 0, 0, 0, 1
  1278. );
  1279. return this;
  1280. },
  1281. copy: function ( m ) {
  1282. var me = m.elements;
  1283. this.set(
  1284. me[0], me[4], me[8], me[12],
  1285. me[1], me[5], me[9], me[13],
  1286. me[2], me[6], me[10], me[14],
  1287. me[3], me[7], me[11], me[15]
  1288. );
  1289. return this;
  1290. },
  1291. lookAt: function ( eye, target, up ) {
  1292. var te = this.elements;
  1293. var x = THREE.Matrix4.__v1;
  1294. var y = THREE.Matrix4.__v2;
  1295. var z = THREE.Matrix4.__v3;
  1296. z.sub( eye, target ).normalize();
  1297. if ( z.length() === 0 ) {
  1298. z.z = 1;
  1299. }
  1300. x.cross( up, z ).normalize();
  1301. if ( x.length() === 0 ) {
  1302. z.x += 0.0001;
  1303. x.cross( up, z ).normalize();
  1304. }
  1305. y.cross( z, x );
  1306. te[0] = x.x; te[4] = y.x; te[8] = z.x;
  1307. te[1] = x.y; te[5] = y.y; te[9] = z.y;
  1308. te[2] = x.z; te[6] = y.z; te[10] = z.z;
  1309. return this;
  1310. },
  1311. multiply: function ( a, b ) {
  1312. var ae = a.elements;
  1313. var be = b.elements;
  1314. var te = this.elements;
  1315. var a11 = ae[0], a12 = ae[4], a13 = ae[8], a14 = ae[12];
  1316. var a21 = ae[1], a22 = ae[5], a23 = ae[9], a24 = ae[13];
  1317. var a31 = ae[2], a32 = ae[6], a33 = ae[10], a34 = ae[14];
  1318. var a41 = ae[3], a42 = ae[7], a43 = ae[11], a44 = ae[15];
  1319. var b11 = be[0], b12 = be[4], b13 = be[8], b14 = be[12];
  1320. var b21 = be[1], b22 = be[5], b23 = be[9], b24 = be[13];
  1321. var b31 = be[2], b32 = be[6], b33 = be[10], b34 = be[14];
  1322. var b41 = be[3], b42 = be[7], b43 = be[11], b44 = be[15];
  1323. te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
  1324. te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
  1325. te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
  1326. te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
  1327. te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
  1328. te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
  1329. te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
  1330. te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
  1331. te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
  1332. te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
  1333. te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
  1334. te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
  1335. te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
  1336. te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
  1337. te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
  1338. te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
  1339. return this;
  1340. },
  1341. multiplySelf: function ( m ) {
  1342. return this.multiply( this, m );
  1343. },
  1344. multiplyToArray: function ( a, b, r ) {
  1345. var te = this.elements;
  1346. this.multiply( a, b );
  1347. r[ 0 ] = te[0]; r[ 1 ] = te[1]; r[ 2 ] = te[2]; r[ 3 ] = te[3];
  1348. r[ 4 ] = te[4]; r[ 5 ] = te[5]; r[ 6 ] = te[6]; r[ 7 ] = te[7];
  1349. r[ 8 ] = te[8]; r[ 9 ] = te[9]; r[ 10 ] = te[10]; r[ 11 ] = te[11];
  1350. r[ 12 ] = te[12]; r[ 13 ] = te[13]; r[ 14 ] = te[14]; r[ 15 ] = te[15];
  1351. return this;
  1352. },
  1353. multiplyScalar: function ( s ) {
  1354. var te = this.elements;
  1355. te[0] *= s; te[4] *= s; te[8] *= s; te[12] *= s;
  1356. te[1] *= s; te[5] *= s; te[9] *= s; te[13] *= s;
  1357. te[2] *= s; te[6] *= s; te[10] *= s; te[14] *= s;
  1358. te[3] *= s; te[7] *= s; te[11] *= s; te[15] *= s;
  1359. return this;
  1360. },
  1361. multiplyVector3: function ( v ) {
  1362. var te = this.elements;
  1363. var vx = v.x, vy = v.y, vz = v.z;
  1364. var d = 1 / ( te[3] * vx + te[7] * vy + te[11] * vz + te[15] );
  1365. v.x = ( te[0] * vx + te[4] * vy + te[8] * vz + te[12] ) * d;
  1366. v.y = ( te[1] * vx + te[5] * vy + te[9] * vz + te[13] ) * d;
  1367. v.z = ( te[2] * vx + te[6] * vy + te[10] * vz + te[14] ) * d;
  1368. return v;
  1369. },
  1370. multiplyVector4: function ( v ) {
  1371. var te = this.elements;
  1372. var vx = v.x, vy = v.y, vz = v.z, vw = v.w;
  1373. v.x = te[0] * vx + te[4] * vy + te[8] * vz + te[12] * vw;
  1374. v.y = te[1] * vx + te[5] * vy + te[9] * vz + te[13] * vw;
  1375. v.z = te[2] * vx + te[6] * vy + te[10] * vz + te[14] * vw;
  1376. v.w = te[3] * vx + te[7] * vy + te[11] * vz + te[15] * vw;
  1377. return v;
  1378. },
  1379. multiplyVector3Array: function ( a ) {
  1380. var tmp = THREE.Matrix4.__v1;
  1381. for ( var i = 0, il = a.length; i < il; i += 3 ) {
  1382. tmp.x = a[ i ];
  1383. tmp.y = a[ i + 1 ];
  1384. tmp.z = a[ i + 2 ];
  1385. this.multiplyVector3( tmp );
  1386. a[ i ] = tmp.x;
  1387. a[ i + 1 ] = tmp.y;
  1388. a[ i + 2 ] = tmp.z;
  1389. }
  1390. return a;
  1391. },
  1392. rotateAxis: function ( v ) {
  1393. var te = this.elements;
  1394. var vx = v.x, vy = v.y, vz = v.z;
  1395. v.x = vx * te[0] + vy * te[4] + vz * te[8];
  1396. v.y = vx * te[1] + vy * te[5] + vz * te[9];
  1397. v.z = vx * te[2] + vy * te[6] + vz * te[10];
  1398. v.normalize();
  1399. return v;
  1400. },
  1401. crossVector: function ( a ) {
  1402. var te = this.elements;
  1403. var v = new THREE.Vector4();
  1404. v.x = te[0] * a.x + te[4] * a.y + te[8] * a.z + te[12] * a.w;
  1405. v.y = te[1] * a.x + te[5] * a.y + te[9] * a.z + te[13] * a.w;
  1406. v.z = te[2] * a.x + te[6] * a.y + te[10] * a.z + te[14] * a.w;
  1407. v.w = ( a.w ) ? te[3] * a.x + te[7] * a.y + te[11] * a.z + te[15] * a.w : 1;
  1408. return v;
  1409. },
  1410. determinant: function () {
  1411. var te = this.elements;
  1412. var n11 = te[0], n12 = te[4], n13 = te[8], n14 = te[12];
  1413. var n21 = te[1], n22 = te[5], n23 = te[9], n24 = te[13];
  1414. var n31 = te[2], n32 = te[6], n33 = te[10], n34 = te[14];
  1415. var n41 = te[3], n42 = te[7], n43 = te[11], n44 = te[15];
  1416. //TODO: make this more efficient
  1417. //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
  1418. return (
  1419. n14 * n23 * n32 * n41-
  1420. n13 * n24 * n32 * n41-
  1421. n14 * n22 * n33 * n41+
  1422. n12 * n24 * n33 * n41+
  1423. n13 * n22 * n34 * n41-
  1424. n12 * n23 * n34 * n41-
  1425. n14 * n23 * n31 * n42+
  1426. n13 * n24 * n31 * n42+
  1427. n14 * n21 * n33 * n42-
  1428. n11 * n24 * n33 * n42-
  1429. n13 * n21 * n34 * n42+
  1430. n11 * n23 * n34 * n42+
  1431. n14 * n22 * n31 * n43-
  1432. n12 * n24 * n31 * n43-
  1433. n14 * n21 * n32 * n43+
  1434. n11 * n24 * n32 * n43+
  1435. n12 * n21 * n34 * n43-
  1436. n11 * n22 * n34 * n43-
  1437. n13 * n22 * n31 * n44+
  1438. n12 * n23 * n31 * n44+
  1439. n13 * n21 * n32 * n44-
  1440. n11 * n23 * n32 * n44-
  1441. n12 * n21 * n33 * n44+
  1442. n11 * n22 * n33 * n44
  1443. );
  1444. },
  1445. transpose: function () {
  1446. var te = this.elements;
  1447. var tmp;
  1448. tmp = te[1]; te[1] = te[4]; te[4] = tmp;
  1449. tmp = te[2]; te[2] = te[8]; te[8] = tmp;
  1450. tmp = te[6]; te[6] = te[9]; te[9] = tmp;
  1451. tmp = te[3]; te[3] = te[12]; te[12] = tmp;
  1452. tmp = te[7]; te[7] = te[13]; te[13] = tmp;
  1453. tmp = te[11]; te[11] = te[14]; te[14] = tmp;
  1454. return this;
  1455. },
  1456. flattenToArray: function ( flat ) {
  1457. var te = this.elements;
  1458. flat[ 0 ] = te[0]; flat[ 1 ] = te[1]; flat[ 2 ] = te[2]; flat[ 3 ] = te[3];
  1459. flat[ 4 ] = te[4]; flat[ 5 ] = te[5]; flat[ 6 ] = te[6]; flat[ 7 ] = te[7];
  1460. flat[ 8 ] = te[8]; flat[ 9 ] = te[9]; flat[ 10 ] = te[10]; flat[ 11 ] = te[11];
  1461. flat[ 12 ] = te[12]; flat[ 13 ] = te[13]; flat[ 14 ] = te[14]; flat[ 15 ] = te[15];
  1462. return flat;
  1463. },
  1464. flattenToArrayOffset: function( flat, offset ) {
  1465. var te = this.elements;
  1466. flat[ offset ] = te[0];
  1467. flat[ offset + 1 ] = te[1];
  1468. flat[ offset + 2 ] = te[2];
  1469. flat[ offset + 3 ] = te[3];
  1470. flat[ offset + 4 ] = te[4];
  1471. flat[ offset + 5 ] = te[5];
  1472. flat[ offset + 6 ] = te[6];
  1473. flat[ offset + 7 ] = te[7];
  1474. flat[ offset + 8 ] = te[8];
  1475. flat[ offset + 9 ] = te[9];
  1476. flat[ offset + 10 ] = te[10];
  1477. flat[ offset + 11 ] = te[11];
  1478. flat[ offset + 12 ] = te[12];
  1479. flat[ offset + 13 ] = te[13];
  1480. flat[ offset + 14 ] = te[14];
  1481. flat[ offset + 15 ] = te[15];
  1482. return flat;
  1483. },
  1484. getPosition: function () {
  1485. var te = this.elements;
  1486. return THREE.Matrix4.__v1.set( te[12], te[13], te[14] );
  1487. },
  1488. setPosition: function ( v ) {
  1489. var te = this.elements;
  1490. te[12] = v.x;
  1491. te[13] = v.y;
  1492. te[14] = v.z;
  1493. return this;
  1494. },
  1495. getColumnX: function () {
  1496. var te = this.elements;
  1497. return THREE.Matrix4.__v1.set( te[0], te[1], te[2] );
  1498. },
  1499. getColumnY: function () {
  1500. var te = this.elements;
  1501. return THREE.Matrix4.__v1.set( te[4], te[5], te[6] );
  1502. },
  1503. getColumnZ: function() {
  1504. var te = this.elements;
  1505. return THREE.Matrix4.__v1.set( te[8], te[9], te[10] );
  1506. },
  1507. getInverse: function ( m ) {
  1508. // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
  1509. var te = this.elements;
  1510. var me = m.elements;
  1511. var n11 = me[0], n12 = me[4], n13 = me[8], n14 = me[12];
  1512. var n21 = me[1], n22 = me[5], n23 = me[9], n24 = me[13];
  1513. var n31 = me[2], n32 = me[6], n33 = me[10], n34 = me[14];
  1514. var n41 = me[3], n42 = me[7], n43 = me[11], n44 = me[15];
  1515. te[0] = n23*n34*n42 - n24*n33*n42 + n24*n32*n43 - n22*n34*n43 - n23*n32*n44 + n22*n33*n44;
  1516. te[4] = n14*n33*n42 - n13*n34*n42 - n14*n32*n43 + n12*n34*n43 + n13*n32*n44 - n12*n33*n44;
  1517. te[8] = n13*n24*n42 - n14*n23*n42 + n14*n22*n43 - n12*n24*n43 - n13*n22*n44 + n12*n23*n44;
  1518. te[12] = n14*n23*n32 - n13*n24*n32 - n14*n22*n33 + n12*n24*n33 + n13*n22*n34 - n12*n23*n34;
  1519. te[1] = n24*n33*n41 - n23*n34*n41 - n24*n31*n43 + n21*n34*n43 + n23*n31*n44 - n21*n33*n44;
  1520. te[5] = n13*n34*n41 - n14*n33*n41 + n14*n31*n43 - n11*n34*n43 - n13*n31*n44 + n11*n33*n44;
  1521. te[9] = n14*n23*n41 - n13*n24*n41 - n14*n21*n43 + n11*n24*n43 + n13*n21*n44 - n11*n23*n44;
  1522. te[13] = n13*n24*n31 - n14*n23*n31 + n14*n21*n33 - n11*n24*n33 - n13*n21*n34 + n11*n23*n34;
  1523. te[2] = n22*n34*n41 - n24*n32*n41 + n24*n31*n42 - n21*n34*n42 - n22*n31*n44 + n21*n32*n44;
  1524. te[6] = n14*n32*n41 - n12*n34*n41 - n14*n31*n42 + n11*n34*n42 + n12*n31*n44 - n11*n32*n44;
  1525. te[10] = n12*n24*n41 - n14*n22*n41 + n14*n21*n42 - n11*n24*n42 - n12*n21*n44 + n11*n22*n44;
  1526. te[14] = n14*n22*n31 - n12*n24*n31 - n14*n21*n32 + n11*n24*n32 + n12*n21*n34 - n11*n22*n34;
  1527. te[3] = n23*n32*n41 - n22*n33*n41 - n23*n31*n42 + n21*n33*n42 + n22*n31*n43 - n21*n32*n43;
  1528. te[7] = n12*n33*n41 - n13*n32*n41 + n13*n31*n42 - n11*n33*n42 - n12*n31*n43 + n11*n32*n43;
  1529. te[11] = n13*n22*n41 - n12*n23*n41 - n13*n21*n42 + n11*n23*n42 + n12*n21*n43 - n11*n22*n43;
  1530. te[15] = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33;
  1531. this.multiplyScalar( 1 / m.determinant() );
  1532. return this;
  1533. },
  1534. setRotationFromEuler: function ( v, order ) {
  1535. var te = this.elements;
  1536. var x = v.x, y = v.y, z = v.z;
  1537. var a = Math.cos( x ), b = Math.sin( x );
  1538. var c = Math.cos( y ), d = Math.sin( y );
  1539. var e = Math.cos( z ), f = Math.sin( z );
  1540. if ( order === undefined || order === 'XYZ' ) {
  1541. var ae = a * e, af = a * f, be = b * e, bf = b * f;
  1542. te[0] = c * e;
  1543. te[4] = - c * f;
  1544. te[8] = d;
  1545. te[1] = af + be * d;
  1546. te[5] = ae - bf * d;
  1547. te[9] = - b * c;
  1548. te[2] = bf - ae * d;
  1549. te[6] = be + af * d;
  1550. te[10] = a * c;
  1551. } else if ( order === 'YXZ' ) {
  1552. var ce = c * e, cf = c * f, de = d * e, df = d * f;
  1553. te[0] = ce + df * b;
  1554. te[4] = de * b - cf;
  1555. te[8] = a * d;
  1556. te[1] = a * f;
  1557. te[5] = a * e;
  1558. te[9] = - b;
  1559. te[2] = cf * b - de;
  1560. te[6] = df + ce * b;
  1561. te[10] = a * c;
  1562. } else if ( order === 'ZXY' ) {
  1563. var ce = c * e, cf = c * f, de = d * e, df = d * f;
  1564. te[0] = ce - df * b;
  1565. te[4] = - a * f;
  1566. te[8] = de + cf * b;
  1567. te[1] = cf + de * b;
  1568. te[5] = a * e;
  1569. te[9] = df - ce * b;
  1570. te[2] = - a * d;
  1571. te[6] = b;
  1572. te[10] = a * c;
  1573. } else if ( order === 'ZYX' ) {
  1574. var ae = a * e, af = a * f, be = b * e, bf = b * f;
  1575. te[0] = c * e;
  1576. te[4] = be * d - af;
  1577. te[8] = ae * d + bf;
  1578. te[1] = c * f;
  1579. te[5] = bf * d + ae;
  1580. te[9] = af * d - be;
  1581. te[2] = - d;
  1582. te[6] = b * c;
  1583. te[10] = a * c;
  1584. } else if ( order === 'YZX' ) {
  1585. var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
  1586. te[0] = c * e;
  1587. te[4] = bd - ac * f;
  1588. te[8] = bc * f + ad;
  1589. te[1] = f;
  1590. te[5] = a * e;
  1591. te[9] = - b * e;
  1592. te[2] = - d * e;
  1593. te[6] = ad * f + bc;
  1594. te[10] = ac - bd * f;
  1595. } else if ( order === 'XZY' ) {
  1596. var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
  1597. te[0] = c * e;
  1598. te[4] = - f;
  1599. te[8] = d * e;
  1600. te[1] = ac * f + bd;
  1601. te[5] = a * e;
  1602. te[9] = ad * f - bc;
  1603. te[2] = bc * f - ad;
  1604. te[6] = b * e;
  1605. te[10] = bd * f + ac;
  1606. }
  1607. return this;
  1608. },
  1609. setRotationFromQuaternion: function ( q ) {
  1610. var te = this.elements;
  1611. var x = q.x, y = q.y, z = q.z, w = q.w;
  1612. var x2 = x + x, y2 = y + y, z2 = z + z;
  1613. var xx = x * x2, xy = x * y2, xz = x * z2;
  1614. var yy = y * y2, yz = y * z2, zz = z * z2;
  1615. var wx = w * x2, wy = w * y2, wz = w * z2;
  1616. te[0] = 1 - ( yy + zz );
  1617. te[4] = xy - wz;
  1618. te[8] = xz + wy;
  1619. te[1] = xy + wz;
  1620. te[5] = 1 - ( xx + zz );
  1621. te[9] = yz - wx;
  1622. te[2] = xz - wy;
  1623. te[6] = yz + wx;
  1624. te[10] = 1 - ( xx + yy );
  1625. return this;
  1626. },
  1627. compose: function ( translation, rotation, scale ) {
  1628. var te = this.elements;
  1629. var mRotation = THREE.Matrix4.__m1;
  1630. var mScale = THREE.Matrix4.__m2;
  1631. mRotation.identity();
  1632. mRotation.setRotationFromQuaternion( rotation );
  1633. mScale.makeScale( scale.x, scale.y, scale.z );
  1634. this.multiply( mRotation, mScale );
  1635. te[12] = translation.x;
  1636. te[13] = translation.y;
  1637. te[14] = translation.z;
  1638. return this;
  1639. },
  1640. decompose: function ( translation, rotation, scale ) {
  1641. var te = this.elements;
  1642. // grab the axis vectors
  1643. var x = THREE.Matrix4.__v1;
  1644. var y = THREE.Matrix4.__v2;
  1645. var z = THREE.Matrix4.__v3;
  1646. x.set( te[0], te[1], te[2] );
  1647. y.set( te[4], te[5], te[6] );
  1648. z.set( te[8], te[9], te[10] );
  1649. translation = ( translation instanceof THREE.Vector3 ) ? translation : new THREE.Vector3();
  1650. rotation = ( rotation instanceof THREE.Quaternion ) ? rotation : new THREE.Quaternion();
  1651. scale = ( scale instanceof THREE.Vector3 ) ? scale : new THREE.Vector3();
  1652. scale.x = x.length();
  1653. scale.y = y.length();
  1654. scale.z = z.length();
  1655. translation.x = te[12];
  1656. translation.y = te[13];
  1657. translation.z = te[14];
  1658. // scale the rotation part
  1659. var matrix = THREE.Matrix4.__m1;
  1660. matrix.copy( this );
  1661. matrix.elements[0] /= scale.x;
  1662. matrix.elements[1] /= scale.x;
  1663. matrix.elements[2] /= scale.x;
  1664. matrix.elements[4] /= scale.y;
  1665. matrix.elements[5] /= scale.y;
  1666. matrix.elements[6] /= scale.y;
  1667. matrix.elements[8] /= scale.z;
  1668. matrix.elements[9] /= scale.z;
  1669. matrix.elements[10] /= scale.z;
  1670. rotation.setFromRotationMatrix( matrix );
  1671. return [ translation, rotation, scale ];
  1672. },
  1673. extractPosition: function ( m ) {
  1674. var te = this.elements;
  1675. var me = m.elements;
  1676. te[12] = me[12];
  1677. te[13] = me[13];
  1678. te[14] = me[14];
  1679. return this;
  1680. },
  1681. extractRotation: function ( m ) {
  1682. var te = this.elements;
  1683. var me = m.elements;
  1684. var vector = THREE.Matrix4.__v1;
  1685. var scaleX = 1 / vector.set( me[0], me[1], me[2] ).length();
  1686. var scaleY = 1 / vector.set( me[4], me[5], me[6] ).length();
  1687. var scaleZ = 1 / vector.set( me[8], me[9], me[10] ).length();
  1688. te[0] = me[0] * scaleX;
  1689. te[1] = me[1] * scaleX;
  1690. te[2] = me[2] * scaleX;
  1691. te[4] = me[4] * scaleY;
  1692. te[5] = me[5] * scaleY;
  1693. te[6] = me[6] * scaleY;
  1694. te[8] = me[8] * scaleZ;
  1695. te[9] = me[9] * scaleZ;
  1696. te[10] = me[10] * scaleZ;
  1697. return this;
  1698. },
  1699. //
  1700. translate: function ( v ) {
  1701. var te = this.elements;
  1702. var x = v.x, y = v.y, z = v.z;
  1703. te[12] = te[0] * x + te[4] * y + te[8] * z + te[12];
  1704. te[13] = te[1] * x + te[5] * y + te[9] * z + te[13];
  1705. te[14] = te[2] * x + te[6] * y + te[10] * z + te[14];
  1706. te[15] = te[3] * x + te[7] * y + te[11] * z + te[15];
  1707. return this;
  1708. },
  1709. rotateX: function ( angle ) {
  1710. var te = this.elements;
  1711. var m12 = te[4];
  1712. var m22 = te[5];
  1713. var m32 = te[6];
  1714. var m42 = te[7];
  1715. var m13 = te[8];
  1716. var m23 = te[9];
  1717. var m33 = te[10];
  1718. var m43 = te[11];
  1719. var c = Math.cos( angle );
  1720. var s = Math.sin( angle );
  1721. te[4] = c * m12 + s * m13;
  1722. te[5] = c * m22 + s * m23;
  1723. te[6] = c * m32 + s * m33;
  1724. te[7] = c * m42 + s * m43;
  1725. te[8] = c * m13 - s * m12;
  1726. te[9] = c * m23 - s * m22;
  1727. te[10] = c * m33 - s * m32;
  1728. te[11] = c * m43 - s * m42;
  1729. return this;
  1730. },
  1731. rotateY: function ( angle ) {
  1732. var te = this.elements;
  1733. var m11 = te[0];
  1734. var m21 = te[1];
  1735. var m31 = te[2];
  1736. var m41 = te[3];
  1737. var m13 = te[8];
  1738. var m23 = te[9];
  1739. var m33 = te[10];
  1740. var m43 = te[11];
  1741. var c = Math.cos( angle );
  1742. var s = Math.sin( angle );
  1743. te[0] = c * m11 - s * m13;
  1744. te[1] = c * m21 - s * m23;
  1745. te[2] = c * m31 - s * m33;
  1746. te[3] = c * m41 - s * m43;
  1747. te[8] = c * m13 + s * m11;
  1748. te[9] = c * m23 + s * m21;
  1749. te[10] = c * m33 + s * m31;
  1750. te[11] = c * m43 + s * m41;
  1751. return this;
  1752. },
  1753. rotateZ: function ( angle ) {
  1754. var te = this.elements;
  1755. var m11 = te[0];
  1756. var m21 = te[1];
  1757. var m31 = te[2];
  1758. var m41 = te[3];
  1759. var m12 = te[4];
  1760. var m22 = te[5];
  1761. var m32 = te[6];
  1762. var m42 = te[7];
  1763. var c = Math.cos( angle );
  1764. var s = Math.sin( angle );
  1765. te[0] = c * m11 + s * m12;
  1766. te[1] = c * m21 + s * m22;
  1767. te[2] = c * m31 + s * m32;
  1768. te[3] = c * m41 + s * m42;
  1769. te[4] = c * m12 - s * m11;
  1770. te[5] = c * m22 - s * m21;
  1771. te[6] = c * m32 - s * m31;
  1772. te[7] = c * m42 - s * m41;
  1773. return this;
  1774. },
  1775. rotateByAxis: function ( axis, angle ) {
  1776. var te = this.elements;
  1777. // optimize by checking axis
  1778. if ( axis.x === 1 && axis.y === 0 && axis.z === 0 ) {
  1779. return this.rotateX( angle );
  1780. } else if ( axis.x === 0 && axis.y === 1 && axis.z === 0 ) {
  1781. return this.rotateY( angle );
  1782. } else if ( axis.x === 0 && axis.y === 0 && axis.z === 1 ) {
  1783. return this.rotateZ( angle );
  1784. }
  1785. var x = axis.x, y = axis.y, z = axis.z;
  1786. var n = Math.sqrt(x * x + y * y + z * z);
  1787. x /= n;
  1788. y /= n;
  1789. z /= n;
  1790. var xx = x * x, yy = y * y, zz = z * z;
  1791. var c = Math.cos( angle );
  1792. var s = Math.sin( angle );
  1793. var oneMinusCosine = 1 - c;
  1794. var xy = x * y * oneMinusCosine;
  1795. var xz = x * z * oneMinusCosine;
  1796. var yz = y * z * oneMinusCosine;
  1797. var xs = x * s;
  1798. var ys = y * s;
  1799. var zs = z * s;
  1800. var r11 = xx + (1 - xx) * c;
  1801. var r21 = xy + zs;
  1802. var r31 = xz - ys;
  1803. var r12 = xy - zs;
  1804. var r22 = yy + (1 - yy) * c;
  1805. var r32 = yz + xs;
  1806. var r13 = xz + ys;
  1807. var r23 = yz - xs;
  1808. var r33 = zz + (1 - zz) * c;
  1809. var m11 = te[0], m21 = te[1], m31 = te[2], m41 = te[3];
  1810. var m12 = te[4], m22 = te[5], m32 = te[6], m42 = te[7];
  1811. var m13 = te[8], m23 = te[9], m33 = te[10], m43 = te[11];
  1812. var m14 = te[12], m24 = te[13], m34 = te[14], m44 = te[15];
  1813. te[0] = r11 * m11 + r21 * m12 + r31 * m13;
  1814. te[1] = r11 * m21 + r21 * m22 + r31 * m23;
  1815. te[2] = r11 * m31 + r21 * m32 + r31 * m33;
  1816. te[3] = r11 * m41 + r21 * m42 + r31 * m43;
  1817. te[4] = r12 * m11 + r22 * m12 + r32 * m13;
  1818. te[5] = r12 * m21 + r22 * m22 + r32 * m23;
  1819. te[6] = r12 * m31 + r22 * m32 + r32 * m33;
  1820. te[7] = r12 * m41 + r22 * m42 + r32 * m43;
  1821. te[8] = r13 * m11 + r23 * m12 + r33 * m13;
  1822. te[9] = r13 * m21 + r23 * m22 + r33 * m23;
  1823. te[10] = r13 * m31 + r23 * m32 + r33 * m33;
  1824. te[11] = r13 * m41 + r23 * m42 + r33 * m43;
  1825. return this;
  1826. },
  1827. scale: function ( v ) {
  1828. var te = this.elements;
  1829. var x = v.x, y = v.y, z = v.z;
  1830. te[0] *= x; te[4] *= y; te[8] *= z;
  1831. te[1] *= x; te[5] *= y; te[9] *= z;
  1832. te[2] *= x; te[6] *= y; te[10] *= z;
  1833. te[3] *= x; te[7] *= y; te[11] *= z;
  1834. return this;
  1835. },
  1836. getMaxScaleOnAxis: function () {
  1837. var te = this.elements;
  1838. var scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2];
  1839. var scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6];
  1840. var scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10];
  1841. return Math.sqrt( Math.max( scaleXSq, Math.max( scaleYSq, scaleZSq ) ) );
  1842. },
  1843. //
  1844. makeTranslation: function ( x, y, z ) {
  1845. this.set(
  1846. 1, 0, 0, x,
  1847. 0, 1, 0, y,
  1848. 0, 0, 1, z,
  1849. 0, 0, 0, 1
  1850. );
  1851. return this;
  1852. },
  1853. makeRotationX: function ( theta ) {
  1854. var c = Math.cos( theta ), s = Math.sin( theta );
  1855. this.set(
  1856. 1, 0, 0, 0,
  1857. 0, c, -s, 0,
  1858. 0, s, c, 0,
  1859. 0, 0, 0, 1
  1860. );
  1861. return this;
  1862. },
  1863. makeRotationY: function ( theta ) {
  1864. var c = Math.cos( theta ), s = Math.sin( theta );
  1865. this.set(
  1866. c, 0, s, 0,
  1867. 0, 1, 0, 0,
  1868. -s, 0, c, 0,
  1869. 0, 0, 0, 1
  1870. );
  1871. return this;
  1872. },
  1873. makeRotationZ: function ( theta ) {
  1874. var c = Math.cos( theta ), s = Math.sin( theta );
  1875. this.set(
  1876. c, -s, 0, 0,
  1877. s, c, 0, 0,
  1878. 0, 0, 1, 0,
  1879. 0, 0, 0, 1
  1880. );
  1881. return this;
  1882. },
  1883. makeRotationAxis: function ( axis, angle ) {
  1884. // Based on http://www.gamedev.net/reference/articles/article1199.asp
  1885. var c = Math.cos( angle );
  1886. var s = Math.sin( angle );
  1887. var t = 1 - c;
  1888. var x = axis.x, y = axis.y, z = axis.z;
  1889. var tx = t * x, ty = t * y;
  1890. this.set(
  1891. tx * x + c, tx * y - s * z, tx * z + s * y, 0,
  1892. tx * y + s * z, ty * y + c, ty * z - s * x, 0,
  1893. tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
  1894. 0, 0, 0, 1
  1895. );
  1896. return this;
  1897. },
  1898. makeScale: function ( x, y, z ) {
  1899. this.set(
  1900. x, 0, 0, 0,
  1901. 0, y, 0, 0,
  1902. 0, 0, z, 0,
  1903. 0, 0, 0, 1
  1904. );
  1905. return this;
  1906. },
  1907. makeFrustum: function ( left, right, bottom, top, near, far ) {
  1908. var te = this.elements;
  1909. var x = 2 * near / ( right - left );
  1910. var y = 2 * near / ( top - bottom );
  1911. var a = ( right + left ) / ( right - left );
  1912. var b = ( top + bottom ) / ( top - bottom );
  1913. var c = - ( far + near ) / ( far - near );
  1914. var d = - 2 * far * near / ( far - near );
  1915. te[0] = x; te[4] = 0; te[8] = a; te[12] = 0;
  1916. te[1] = 0; te[5] = y; te[9] = b; te[13] = 0;
  1917. te[2] = 0; te[6] = 0; te[10] = c; te[14] = d;
  1918. te[3] = 0; te[7] = 0; te[11] = - 1; te[15] = 0;
  1919. return this;
  1920. },
  1921. makePerspective: function ( fov, aspect, near, far ) {
  1922. var ymax = near * Math.tan( fov * Math.PI / 360 );
  1923. var ymin = - ymax;
  1924. var xmin = ymin * aspect;
  1925. var xmax = ymax * aspect;
  1926. return this.makeFrustum( xmin, xmax, ymin, ymax, near, far );
  1927. },
  1928. makeOrthographic: function ( left, right, top, bottom, near, far ) {
  1929. var te = this.elements;
  1930. var w = right - left;
  1931. var h = top - bottom;
  1932. var p = far - near;
  1933. var x = ( right + left ) / w;
  1934. var y = ( top + bottom ) / h;
  1935. var z = ( far + near ) / p;
  1936. te[0] = 2 / w; te[4] = 0; te[8] = 0; te[12] = -x;
  1937. te[1] = 0; te[5] = 2 / h; te[9] = 0; te[13] = -y;
  1938. te[2] = 0; te[6] = 0; te[10] = -2 / p; te[14] = -z;
  1939. te[3] = 0; te[7] = 0; te[11] = 0; te[15] = 1;
  1940. return this;
  1941. },
  1942. clone: function () {
  1943. var te = this.elements;
  1944. return new THREE.Matrix4(
  1945. te[0], te[4], te[8], te[12],
  1946. te[1], te[5], te[9], te[13],
  1947. te[2], te[6], te[10], te[14],
  1948. te[3], te[7], te[11], te[15]
  1949. );
  1950. }
  1951. };
  1952. THREE.Matrix4.__v1 = new THREE.Vector3();
  1953. THREE.Matrix4.__v2 = new THREE.Vector3();
  1954. THREE.Matrix4.__v3 = new THREE.Vector3();
  1955. THREE.Matrix4.__m1 = new THREE.Matrix4();
  1956. THREE.Matrix4.__m2 = new THREE.Matrix4();
  1957. /**
  1958. * @author mr.doob / http://mrdoob.com/
  1959. * @author mikael emtinger / http://gomo.se/
  1960. * @author alteredq / http://alteredqualia.com/
  1961. */
  1962. THREE.Object3D = function () {
  1963. this.id = THREE.Object3DCount ++;
  1964. this.name = '';
  1965. this.parent = undefined;
  1966. this.children = [];
  1967. this.up = new THREE.Vector3( 0, 1, 0 );
  1968. this.position = new THREE.Vector3();
  1969. this.rotation = new THREE.Vector3();
  1970. this.eulerOrder = 'XYZ';
  1971. this.scale = new THREE.Vector3( 1, 1, 1 );
  1972. this.doubleSided = false;
  1973. this.flipSided = false;
  1974. this.renderDepth = null;
  1975. this.rotationAutoUpdate = true;
  1976. this.matrix = new THREE.Matrix4();
  1977. this.matrixWorld = new THREE.Matrix4();
  1978. this.matrixRotationWorld = new THREE.Matrix4();
  1979. this.matrixAutoUpdate = true;
  1980. this.matrixWorldNeedsUpdate = true;
  1981. this.quaternion = new THREE.Quaternion();
  1982. this.useQuaternion = false;
  1983. this.boundRadius = 0.0;
  1984. this.boundRadiusScale = 1.0;
  1985. this.visible = true;
  1986. this.castShadow = false;
  1987. this.receiveShadow = false;
  1988. this.frustumCulled = true;
  1989. this._vector = new THREE.Vector3();
  1990. };
  1991. THREE.Object3D.prototype = {
  1992. constructor: THREE.Object3D,
  1993. applyMatrix: function ( matrix ) {
  1994. this.matrix.multiply( matrix, this.matrix );
  1995. this.scale.getScaleFromMatrix( this.matrix );
  1996. var mat = new THREE.Matrix4().extractRotation( this.matrix );
  1997. this.rotation.setEulerFromRotationMatrix( mat, this.eulerOrder );
  1998. this.position.getPositionFromMatrix( this.matrix );
  1999. },
  2000. translate: function ( distance, axis ) {
  2001. this.matrix.rotateAxis( axis );
  2002. this.position.addSelf( axis.multiplyScalar( distance ) );
  2003. },
  2004. translateX: function ( distance ) {
  2005. this.translate( distance, this._vector.set( 1, 0, 0 ) );
  2006. },
  2007. translateY: function ( distance ) {
  2008. this.translate( distance, this._vector.set( 0, 1, 0 ) );
  2009. },
  2010. translateZ: function ( distance ) {
  2011. this.translate( distance, this._vector.set( 0, 0, 1 ) );
  2012. },
  2013. lookAt: function ( vector ) {
  2014. // TODO: Add hierarchy support.
  2015. this.matrix.lookAt( vector, this.position, this.up );
  2016. if ( this.rotationAutoUpdate ) {
  2017. this.rotation.setEulerFromRotationMatrix( this.matrix, this.eulerOrder );
  2018. }
  2019. },
  2020. add: function ( object ) {
  2021. if ( object === this ) {
  2022. console.warn( 'THREE.Object3D.add: An object can\'t be added as a child of itself.' );
  2023. return;
  2024. }
  2025. if ( object instanceof THREE.Object3D ) {
  2026. if ( object.parent !== undefined ) {
  2027. object.parent.remove( object );
  2028. }
  2029. object.parent = this;
  2030. this.children.push( object );
  2031. // add to scene
  2032. var scene = this;
  2033. while ( scene.parent !== undefined ) {
  2034. scene = scene.parent;
  2035. }
  2036. if ( scene !== undefined && scene instanceof THREE.Scene ) {
  2037. scene.__addObject( object );
  2038. }
  2039. }
  2040. },
  2041. remove: function ( object ) {
  2042. var index = this.children.indexOf( object );
  2043. if ( index !== - 1 ) {
  2044. object.parent = undefined;
  2045. this.children.splice( index, 1 );
  2046. // remove from scene
  2047. var scene = this;
  2048. while ( scene.parent !== undefined ) {
  2049. scene = scene.parent;
  2050. }
  2051. if ( scene !== undefined && scene instanceof THREE.Scene ) {
  2052. scene.__removeObject( object );
  2053. }
  2054. }
  2055. },
  2056. getChildByName: function ( name, recursive ) {
  2057. var c, cl, child;
  2058. for ( c = 0, cl = this.children.length; c < cl; c ++ ) {
  2059. child = this.children[ c ];
  2060. if ( child.name === name ) {
  2061. return child;
  2062. }
  2063. if ( recursive ) {
  2064. child = child.getChildByName( name, recursive );
  2065. if ( child !== undefined ) {
  2066. return child;
  2067. }
  2068. }
  2069. }
  2070. return undefined;
  2071. },
  2072. updateMatrix: function () {
  2073. this.matrix.setPosition( this.position );
  2074. if ( this.useQuaternion === true ) {
  2075. this.matrix.setRotationFromQuaternion( this.quaternion );
  2076. } else {
  2077. this.matrix.setRotationFromEuler( this.rotation, this.eulerOrder );
  2078. }
  2079. if ( this.scale.x !== 1 || this.scale.y !== 1 || this.scale.z !== 1 ) {
  2080. this.matrix.scale( this.scale );
  2081. this.boundRadiusScale = Math.max( this.scale.x, Math.max( this.scale.y, this.scale.z ) );
  2082. }
  2083. this.matrixWorldNeedsUpdate = true;
  2084. },
  2085. updateMatrixWorld: function ( force ) {
  2086. if ( this.matrixAutoUpdate === true ) this.updateMatrix();
  2087. if ( this.matrixWorldNeedsUpdate === true || force === true ) {
  2088. if ( this.parent !== undefined ) {
  2089. this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
  2090. } else {
  2091. this.matrixWorld.copy( this.matrix );
  2092. }
  2093. this.matrixWorldNeedsUpdate = false;
  2094. force = true;
  2095. }
  2096. // update children
  2097. for ( var i = 0, l = this.children.length; i < l; i ++ ) {
  2098. this.children[ i ].updateMatrixWorld( force );
  2099. }
  2100. },
  2101. worldToLocal: function ( vector ) {
  2102. return THREE.Object3D.__m1.getInverse( this.matrixWorld ).multiplyVector3( vector );
  2103. },
  2104. localToWorld: function ( vector ) {
  2105. return this.matrixWorld.multiplyVector3( vector );
  2106. }
  2107. };
  2108. THREE.Object3D.__m1 = new THREE.Matrix4();
  2109. THREE.Object3DCount = 0;
  2110. /**
  2111. * @author mr.doob / http://mrdoob.com/
  2112. * @author supereggbert / http://www.paulbrunt.co.uk/
  2113. * @author julianwa / https://github.com/julianwa
  2114. */
  2115. THREE.Projector = function() {
  2116. var _object, _objectCount, _objectPool = [],
  2117. _vertex, _vertexCount, _vertexPool = [],
  2118. _face, _face3Count, _face3Pool = [], _face4Count, _face4Pool = [],
  2119. _line, _lineCount, _linePool = [],
  2120. _particle, _particleCount, _particlePool = [],
  2121. _renderData = { objects: [], sprites: [], lights: [], elements: [] },
  2122. _vector3 = new THREE.Vector3(),
  2123. _vector4 = new THREE.Vector4(),
  2124. _projScreenMatrix = new THREE.Matrix4(),
  2125. _projScreenobjectMatrixWorld = new THREE.Matrix4(),
  2126. _frustum = new THREE.Frustum(),
  2127. _clippedVertex1PositionScreen = new THREE.Vector4(),
  2128. _clippedVertex2PositionScreen = new THREE.Vector4(),
  2129. _face3VertexNormals;
  2130. this.projectVector = function ( vector, camera ) {
  2131. camera.matrixWorldInverse.getInverse( camera.matrixWorld );
  2132. _projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
  2133. _projScreenMatrix.multiplyVector3( vector );
  2134. return vector;
  2135. };
  2136. this.unprojectVector = function ( vector, camera ) {
  2137. camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
  2138. _projScreenMatrix.multiply( camera.matrixWorld, camera.projectionMatrixInverse );
  2139. _projScreenMatrix.multiplyVector3( vector );
  2140. return vector;
  2141. };
  2142. this.pickingRay = function ( vector, camera ) {
  2143. var end, ray, t;
  2144. // set two vectors with opposing z values
  2145. vector.z = -1.0;
  2146. end = new THREE.Vector3( vector.x, vector.y, 1.0 );
  2147. this.unprojectVector( vector, camera );
  2148. this.unprojectVector( end, camera );
  2149. // find direction from vector to end
  2150. end.subSelf( vector ).normalize();
  2151. return new THREE.Ray( vector, end );
  2152. };
  2153. function projectGraph( root, sort ) {
  2154. _objectCount = 0;
  2155. _renderData.objects.length = 0;
  2156. _renderData.sprites.length = 0;
  2157. _renderData.lights.length = 0;
  2158. var projectObject = function ( object ) {
  2159. if ( object.visible === false ) return;
  2160. if ( ( object instanceof THREE.Mesh || object instanceof THREE.Line ) &&
  2161. ( object.frustumCulled === false || _frustum.contains( object ) === true ) ) {
  2162. _vector3.copy( object.matrixWorld.getPosition() );
  2163. _projScreenMatrix.multiplyVector3( _vector3 );
  2164. _object = getNextObjectInPool();
  2165. _object.object = object;
  2166. _object.z = _vector3.z;
  2167. _renderData.objects.push( _object );
  2168. } else if ( object instanceof THREE.Sprite || object instanceof THREE.Particle ) {
  2169. _vector3.copy( object.matrixWorld.getPosition() );
  2170. _projScreenMatrix.multiplyVector3( _vector3 );
  2171. _object = getNextObjectInPool();
  2172. _object.object = object;
  2173. _object.z = _vector3.z;
  2174. _renderData.sprites.push( _object );
  2175. } else if ( object instanceof THREE.Light ) {
  2176. _renderData.lights.push( object );
  2177. }
  2178. for ( var c = 0, cl = object.children.length; c < cl; c ++ ) {
  2179. projectObject( object.children[ c ] );
  2180. }
  2181. };
  2182. projectObject( root );
  2183. if ( sort === true ) _renderData.objects.sort( painterSort );
  2184. return _renderData;
  2185. };
  2186. this.projectScene = function ( scene, camera, sort ) {
  2187. var near = camera.near, far = camera.far, visible = false,
  2188. o, ol, v, vl, f, fl, n, nl, c, cl, u, ul, object,
  2189. objectMatrixWorld, objectMatrixWorldRotation,
  2190. geometry, geometryMaterials, vertices, vertex, vertexPositionScreen,
  2191. faces, face, faceVertexNormals, normal, faceVertexUvs, uvs,
  2192. v1, v2, v3, v4;
  2193. _face3Count = 0;
  2194. _face4Count = 0;
  2195. _lineCount = 0;
  2196. _particleCount = 0;
  2197. _renderData.elements.length = 0;
  2198. if ( camera.parent === undefined ) {
  2199. console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
  2200. scene.add( camera );
  2201. }
  2202. scene.updateMatrixWorld();
  2203. camera.matrixWorldInverse.getInverse( camera.matrixWorld );
  2204. _projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
  2205. _frustum.setFromMatrix( _projScreenMatrix );
  2206. _renderData = projectGraph( scene, false );
  2207. for ( o = 0, ol = _renderData.objects.length; o < ol; o++ ) {
  2208. object = _renderData.objects[ o ].object;
  2209. objectMatrixWorld = object.matrixWorld;
  2210. _vertexCount = 0;
  2211. if ( object instanceof THREE.Mesh ) {
  2212. geometry = object.geometry;
  2213. geometryMaterials = object.geometry.materials;
  2214. vertices = geometry.vertices;
  2215. faces = geometry.faces;
  2216. faceVertexUvs = geometry.faceVertexUvs;
  2217. objectMatrixWorldRotation = object.matrixRotationWorld.extractRotation( objectMatrixWorld );
  2218. for ( v = 0, vl = vertices.length; v < vl; v ++ ) {
  2219. _vertex = getNextVertexInPool();
  2220. _vertex.positionWorld.copy( vertices[ v ] );
  2221. objectMatrixWorld.multiplyVector3( _vertex.positionWorld );
  2222. _vertex.positionScreen.copy( _vertex.positionWorld );
  2223. _projScreenMatrix.multiplyVector4( _vertex.positionScreen );
  2224. _vertex.positionScreen.x /= _vertex.positionScreen.w;
  2225. _vertex.positionScreen.y /= _vertex.positionScreen.w;
  2226. _vertex.visible = _vertex.positionScreen.z > near && _vertex.positionScreen.z < far;
  2227. }
  2228. for ( f = 0, fl = faces.length; f < fl; f ++ ) {
  2229. face = faces[ f ];
  2230. if ( face instanceof THREE.Face3 ) {
  2231. v1 = _vertexPool[ face.a ];
  2232. v2 = _vertexPool[ face.b ];
  2233. v3 = _vertexPool[ face.c ];
  2234. if ( v1.visible === true && v2.visible === true && v3.visible === true ) {
  2235. visible = ( ( v3.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) -
  2236. ( v3.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) ) < 0;
  2237. if ( object.doubleSided === true || visible !== object.flipSided ) {
  2238. _face = getNextFace3InPool();
  2239. _face.v1.copy( v1 );
  2240. _face.v2.copy( v2 );
  2241. _face.v3.copy( v3 );
  2242. } else {
  2243. continue;
  2244. }
  2245. } else {
  2246. continue;
  2247. }
  2248. } else if ( face instanceof THREE.Face4 ) {
  2249. v1 = _vertexPool[ face.a ];
  2250. v2 = _vertexPool[ face.b ];
  2251. v3 = _vertexPool[ face.c ];
  2252. v4 = _vertexPool[ face.d ];
  2253. if ( v1.visible === true && v2.visible === true && v3.visible === true && v4.visible === true ) {
  2254. visible = ( v4.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) -
  2255. ( v4.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) < 0 ||
  2256. ( v2.positionScreen.x - v3.positionScreen.x ) * ( v4.positionScreen.y - v3.positionScreen.y ) -
  2257. ( v2.positionScreen.y - v3.positionScreen.y ) * ( v4.positionScreen.x - v3.positionScreen.x ) < 0;
  2258. if ( object.doubleSided === true || visible !== object.flipSided ) {
  2259. _face = getNextFace4InPool();
  2260. _face.v1.copy( v1 );
  2261. _face.v2.copy( v2 );
  2262. _face.v3.copy( v3 );
  2263. _face.v4.copy( v4 );
  2264. } else {
  2265. continue;
  2266. }
  2267. } else {
  2268. continue;
  2269. }
  2270. }
  2271. _face.normalWorld.copy( face.normal );
  2272. if ( visible === false && ( object.flipSided === true || object.doubleSided === true ) ) _face.normalWorld.negate();
  2273. objectMatrixWorldRotation.multiplyVector3( _face.normalWorld );
  2274. _face.centroidWorld.copy( face.centroid );
  2275. objectMatrixWorld.multiplyVector3( _face.centroidWorld );
  2276. _face.centroidScreen.copy( _face.centroidWorld );
  2277. _projScreenMatrix.multiplyVector3( _face.centroidScreen );
  2278. faceVertexNormals = face.vertexNormals;
  2279. for ( n = 0, nl = faceVertexNormals.length; n < nl; n ++ ) {
  2280. normal = _face.vertexNormalsWorld[ n ];
  2281. normal.copy( faceVertexNormals[ n ] );
  2282. if ( visible === false && ( object.flipSided === true || object.doubleSided === true ) ) normal.negate();
  2283. objectMatrixWorldRotation.multiplyVector3( normal );
  2284. }
  2285. for ( c = 0, cl = faceVertexUvs.length; c < cl; c ++ ) {
  2286. uvs = faceVertexUvs[ c ][ f ];
  2287. if ( uvs === undefined ) continue;
  2288. for ( u = 0, ul = uvs.length; u < ul; u ++ ) {
  2289. _face.uvs[ c ][ u ] = uvs[ u ];
  2290. }
  2291. }
  2292. _face.material = object.material;
  2293. _face.faceMaterial = face.materialIndex !== null ? geometryMaterials[ face.materialIndex ] : null;
  2294. _face.z = _face.centroidScreen.z;
  2295. _renderData.elements.push( _face );
  2296. }
  2297. } else if ( object instanceof THREE.Line ) {
  2298. _projScreenobjectMatrixWorld.multiply( _projScreenMatrix, objectMatrixWorld );
  2299. vertices = object.geometry.vertices;
  2300. v1 = getNextVertexInPool();
  2301. v1.positionScreen.copy( vertices[ 0 ] );
  2302. _projScreenobjectMatrixWorld.multiplyVector4( v1.positionScreen );
  2303. // Handle LineStrip and LinePieces
  2304. var step = object.type === THREE.LinePieces ? 2 : 1;
  2305. for ( v = 1, vl = vertices.length; v < vl; v ++ ) {
  2306. v1 = getNextVertexInPool();
  2307. v1.positionScreen.copy( vertices[ v ] );
  2308. _projScreenobjectMatrixWorld.multiplyVector4( v1.positionScreen );
  2309. if ( ( v + 1 ) % step > 0 ) continue;
  2310. v2 = _vertexPool[ _vertexCount - 2 ];
  2311. _clippedVertex1PositionScreen.copy( v1.positionScreen );
  2312. _clippedVertex2PositionScreen.copy( v2.positionScreen );
  2313. if ( clipLine( _clippedVertex1PositionScreen, _clippedVertex2PositionScreen ) === true ) {
  2314. // Perform the perspective divide
  2315. _clippedVertex1PositionScreen.multiplyScalar( 1 / _clippedVertex1PositionScreen.w );
  2316. _clippedVertex2PositionScreen.multiplyScalar( 1 / _clippedVertex2PositionScreen.w );
  2317. _line = getNextLineInPool();
  2318. _line.v1.positionScreen.copy( _clippedVertex1PositionScreen );
  2319. _line.v2.positionScreen.copy( _clippedVertex2PositionScreen );
  2320. _line.z = Math.max( _clippedVertex1PositionScreen.z, _clippedVertex2PositionScreen.z );
  2321. _line.material = object.material;
  2322. _renderData.elements.push( _line );
  2323. }
  2324. }
  2325. }
  2326. }
  2327. for ( o = 0, ol = _renderData.sprites.length; o < ol; o++ ) {
  2328. object = _renderData.sprites[ o ].object;
  2329. objectMatrixWorld = object.matrixWorld;
  2330. if ( object instanceof THREE.Particle ) {
  2331. _vector4.set( objectMatrixWorld.elements[12], objectMatrixWorld.elements[13], objectMatrixWorld.elements[14], 1 );
  2332. _projScreenMatrix.multiplyVector4( _vector4 );
  2333. _vector4.z /= _vector4.w;
  2334. if ( _vector4.z > 0 && _vector4.z < 1 ) {
  2335. _particle = getNextParticleInPool();
  2336. _particle.x = _vector4.x / _vector4.w;
  2337. _particle.y = _vector4.y / _vector4.w;
  2338. _particle.z = _vector4.z;
  2339. _particle.rotation = object.rotation.z;
  2340. _particle.scale.x = object.scale.x * Math.abs( _particle.x - ( _vector4.x + camera.projectionMatrix.elements[0] ) / ( _vector4.w + camera.projectionMatrix.elements[12] ) );
  2341. _particle.scale.y = object.scale.y * Math.abs( _particle.y - ( _vector4.y + camera.projectionMatrix.elements[5] ) / ( _vector4.w + camera.projectionMatrix.elements[13] ) );
  2342. _particle.material = object.material;
  2343. _renderData.elements.push( _particle );
  2344. }
  2345. }
  2346. }
  2347. sort && _renderData.elements.sort( painterSort );
  2348. return _renderData;
  2349. };
  2350. // Pools
  2351. function getNextObjectInPool() {
  2352. var object;
  2353. if ( _objectCount === _objectPool.length ) {
  2354. object = new THREE.RenderableObject();
  2355. _objectPool.push( object );
  2356. } else {
  2357. object = _objectPool[ _objectCount ];
  2358. }
  2359. _objectCount ++;
  2360. return object;
  2361. }
  2362. function getNextVertexInPool() {
  2363. var vertex;
  2364. if ( _vertexCount === _vertexPool.length ) {
  2365. vertex = new THREE.RenderableVertex();
  2366. _vertexPool.push( vertex );
  2367. } else {
  2368. vertex = _vertexPool[ _vertexCount ];
  2369. }
  2370. _vertexCount ++;
  2371. return vertex;
  2372. }
  2373. function getNextFace3InPool() {
  2374. var face;
  2375. if ( _face3Count === _face3Pool.length ) {
  2376. face = new THREE.RenderableFace3();
  2377. _face3Pool.push( face );
  2378. } else {
  2379. face = _face3Pool[ _face3Count ];
  2380. }
  2381. _face3Count ++;
  2382. return face;
  2383. }
  2384. function getNextFace4InPool() {
  2385. var face;
  2386. if ( _face4Count === _face4Pool.length ) {
  2387. face = new THREE.RenderableFace4();
  2388. _face4Pool.push( face );
  2389. } else {
  2390. face = _face4Pool[ _face4Count ];
  2391. }
  2392. _face4Count ++;
  2393. return face;
  2394. }
  2395. function getNextLineInPool() {
  2396. var line;
  2397. if ( _lineCount === _linePool.length ) {
  2398. line = new THREE.RenderableLine();
  2399. _linePool.push( line );
  2400. } else {
  2401. line = _linePool[ _lineCount ];
  2402. }
  2403. _lineCount ++;
  2404. return line;
  2405. }
  2406. function getNextParticleInPool() {
  2407. var particle;
  2408. if ( _particleCount === _particlePool.length ) {
  2409. particle = new THREE.RenderableParticle();
  2410. _particlePool.push( particle );
  2411. } else {
  2412. particle = _particlePool[ _particleCount ];
  2413. }
  2414. _particleCount ++;
  2415. return particle;
  2416. }
  2417. //
  2418. function painterSort( a, b ) {
  2419. return b.z - a.z;
  2420. }
  2421. function clipLine( s1, s2 ) {
  2422. var alpha1 = 0, alpha2 = 1,
  2423. // Calculate the boundary coordinate of each vertex for the near and far clip planes,
  2424. // Z = -1 and Z = +1, respectively.
  2425. bc1near = s1.z + s1.w,
  2426. bc2near = s2.z + s2.w,
  2427. bc1far = - s1.z + s1.w,
  2428. bc2far = - s2.z + s2.w;
  2429. if ( bc1near >= 0 && bc2near >= 0 && bc1far >= 0 && bc2far >= 0 ) {
  2430. // Both vertices lie entirely within all clip planes.
  2431. return true;
  2432. } else if ( ( bc1near < 0 && bc2near < 0) || (bc1far < 0 && bc2far < 0 ) ) {
  2433. // Both vertices lie entirely outside one of the clip planes.
  2434. return false;
  2435. } else {
  2436. // The line segment spans at least one clip plane.
  2437. if ( bc1near < 0 ) {
  2438. // v1 lies outside the near plane, v2 inside
  2439. alpha1 = Math.max( alpha1, bc1near / ( bc1near - bc2near ) );
  2440. } else if ( bc2near < 0 ) {
  2441. // v2 lies outside the near plane, v1 inside
  2442. alpha2 = Math.min( alpha2, bc1near / ( bc1near - bc2near ) );
  2443. }
  2444. if ( bc1far < 0 ) {
  2445. // v1 lies outside the far plane, v2 inside
  2446. alpha1 = Math.max( alpha1, bc1far / ( bc1far - bc2far ) );
  2447. } else if ( bc2far < 0 ) {
  2448. // v2 lies outside the far plane, v2 inside
  2449. alpha2 = Math.min( alpha2, bc1far / ( bc1far - bc2far ) );
  2450. }
  2451. if ( alpha2 < alpha1 ) {
  2452. // The line segment spans two boundaries, but is outside both of them.
  2453. // (This can't happen when we're only clipping against just near/far but good
  2454. // to leave the check here for future usage if other clip planes are added.)
  2455. return false;
  2456. } else {
  2457. // Update the s1 and s2 vertices to match the clipped line segment.
  2458. s1.lerpSelf( s2, alpha1 );
  2459. s2.lerpSelf( s1, 1 - alpha2 );
  2460. return true;
  2461. }
  2462. }
  2463. }
  2464. };
  2465. /**
  2466. * @author mikael emtinger / http://gomo.se/
  2467. * @author alteredq / http://alteredqualia.com/
  2468. * @author WestLangley / http://github.com/WestLangley
  2469. */
  2470. THREE.Quaternion = function( x, y, z, w ) {
  2471. this.x = x || 0;
  2472. this.y = y || 0;
  2473. this.z = z || 0;
  2474. this.w = ( w !== undefined ) ? w : 1;
  2475. };
  2476. THREE.Quaternion.prototype = {
  2477. constructor: THREE.Quaternion,
  2478. set: function ( x, y, z, w ) {
  2479. this.x = x;
  2480. this.y = y;
  2481. this.z = z;
  2482. this.w = w;
  2483. return this;
  2484. },
  2485. copy: function ( q ) {
  2486. this.x = q.x;
  2487. this.y = q.y;
  2488. this.z = q.z;
  2489. this.w = q.w;
  2490. return this;
  2491. },
  2492. setFromEuler: function ( v, order ) {
  2493. // http://www.mathworks.com/matlabcentral/fileexchange/
  2494. // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
  2495. // content/SpinCalc.m
  2496. var c1 = Math.cos( v.x / 2 );
  2497. var c2 = Math.cos( v.y / 2 );
  2498. var c3 = Math.cos( v.z / 2 );
  2499. var s1 = Math.sin( v.x / 2 );
  2500. var s2 = Math.sin( v.y / 2 );
  2501. var s3 = Math.sin( v.z / 2 );
  2502. if ( order === undefined || order === 'XYZ' ) {
  2503. this.x = s1 * c2 * c3 + c1 * s2 * s3;
  2504. this.y = c1 * s2 * c3 - s1 * c2 * s3;
  2505. this.z = c1 * c2 * s3 + s1 * s2 * c3;
  2506. this.w = c1 * c2 * c3 - s1 * s2 * s3;
  2507. } else if ( order === 'YXZ' ) {
  2508. this.x = s1 * c2 * c3 + c1 * s2 * s3;
  2509. this.y = c1 * s2 * c3 - s1 * c2 * s3;
  2510. this.z = c1 * c2 * s3 - s1 * s2 * c3;
  2511. this.w = c1 * c2 * c3 + s1 * s2 * s3;
  2512. } else if ( order === 'ZXY' ) {
  2513. this.x = s1 * c2 * c3 - c1 * s2 * s3;
  2514. this.y = c1 * s2 * c3 + s1 * c2 * s3;
  2515. this.z = c1 * c2 * s3 + s1 * s2 * c3;
  2516. this.w = c1 * c2 * c3 - s1 * s2 * s3;
  2517. } else if ( order === 'ZYX' ) {
  2518. this.x = s1 * c2 * c3 - c1 * s2 * s3;
  2519. this.y = c1 * s2 * c3 + s1 * c2 * s3;
  2520. this.z = c1 * c2 * s3 - s1 * s2 * c3;
  2521. this.w = c1 * c2 * c3 + s1 * s2 * s3;
  2522. } else if ( order === 'YZX' ) {
  2523. this.x = s1 * c2 * c3 + c1 * s2 * s3;
  2524. this.y = c1 * s2 * c3 + s1 * c2 * s3;
  2525. this.z = c1 * c2 * s3 - s1 * s2 * c3;
  2526. this.w = c1 * c2 * c3 - s1 * s2 * s3;
  2527. } else if ( order === 'XZY' ) {
  2528. this.x = s1 * c2 * c3 - c1 * s2 * s3;
  2529. this.y = c1 * s2 * c3 - s1 * c2 * s3;
  2530. this.z = c1 * c2 * s3 + s1 * s2 * c3;
  2531. this.w = c1 * c2 * c3 + s1 * s2 * s3;
  2532. }
  2533. return this;
  2534. },
  2535. setFromAxisAngle: function ( axis, angle ) {
  2536. // from http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
  2537. // axis have to be normalized
  2538. var halfAngle = angle / 2,
  2539. s = Math.sin( halfAngle );
  2540. this.x = axis.x * s;
  2541. this.y = axis.y * s;
  2542. this.z = axis.z * s;
  2543. this.w = Math.cos( halfAngle );
  2544. return this;
  2545. },
  2546. setFromRotationMatrix: function ( m ) {
  2547. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
  2548. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  2549. var te = m.elements,
  2550. m11 = te[0], m12 = te[4], m13 = te[8],
  2551. m21 = te[1], m22 = te[5], m23 = te[9],
  2552. m31 = te[2], m32 = te[6], m33 = te[10],
  2553. trace = m11 + m22 + m33,
  2554. s;
  2555. if( trace > 0 ) {
  2556. s = 0.5 / Math.sqrt( trace + 1.0 );
  2557. this.w = 0.25 / s;
  2558. this.x = ( m32 - m23 ) * s;
  2559. this.y = ( m13 - m31 ) * s;
  2560. this.z = ( m21 - m12 ) * s;
  2561. } else if ( m11 > m22 && m11 > m33 ) {
  2562. s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );
  2563. this.w = (m32 - m23 ) / s;
  2564. this.x = 0.25 * s;
  2565. this.y = (m12 + m21 ) / s;
  2566. this.z = (m13 + m31 ) / s;
  2567. } else if (m22 > m33) {
  2568. s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );
  2569. this.w = (m13 - m31 ) / s;
  2570. this.x = (m12 + m21 ) / s;
  2571. this.y = 0.25 * s;
  2572. this.z = (m23 + m32 ) / s;
  2573. } else {
  2574. s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );
  2575. this.w = ( m21 - m12 ) / s;
  2576. this.x = ( m13 + m31 ) / s;
  2577. this.y = ( m23 + m32 ) / s;
  2578. this.z = 0.25 * s;
  2579. }
  2580. return this;
  2581. },
  2582. calculateW : function () {
  2583. this.w = - Math.sqrt( Math.abs( 1.0 - this.x * this.x - this.y * this.y - this.z * this.z ) );
  2584. return this;
  2585. },
  2586. inverse: function () {
  2587. this.x *= -1;
  2588. this.y *= -1;
  2589. this.z *= -1;
  2590. return this;
  2591. },
  2592. length: function () {
  2593. return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
  2594. },
  2595. normalize: function () {
  2596. var l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
  2597. if ( l === 0 ) {
  2598. this.x = 0;
  2599. this.y = 0;
  2600. this.z = 0;
  2601. this.w = 0;
  2602. } else {
  2603. l = 1 / l;
  2604. this.x = this.x * l;
  2605. this.y = this.y * l;
  2606. this.z = this.z * l;
  2607. this.w = this.w * l;
  2608. }
  2609. return this;
  2610. },
  2611. multiply: function ( a, b ) {
  2612. // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
  2613. this.x = a.x * b.w + a.y * b.z - a.z * b.y + a.w * b.x;
  2614. this.y = -a.x * b.z + a.y * b.w + a.z * b.x + a.w * b.y;
  2615. this.z = a.x * b.y - a.y * b.x + a.z * b.w + a.w * b.z;
  2616. this.w = -a.x * b.x - a.y * b.y - a.z * b.z + a.w * b.w;
  2617. return this;
  2618. },
  2619. multiplySelf: function ( b ) {
  2620. var qax = this.x, qay = this.y, qaz = this.z, qaw = this.w,
  2621. qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w;
  2622. this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
  2623. this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
  2624. this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
  2625. this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
  2626. return this;
  2627. },
  2628. multiplyVector3: function ( vector, dest ) {
  2629. if ( !dest ) { dest = vector; }
  2630. var x = vector.x, y = vector.y, z = vector.z,
  2631. qx = this.x, qy = this.y, qz = this.z, qw = this.w;
  2632. // calculate quat * vector
  2633. var ix = qw * x + qy * z - qz * y,
  2634. iy = qw * y + qz * x - qx * z,
  2635. iz = qw * z + qx * y - qy * x,
  2636. iw = -qx * x - qy * y - qz * z;
  2637. // calculate result * inverse quat
  2638. dest.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
  2639. dest.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
  2640. dest.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
  2641. return dest;
  2642. },
  2643. slerpSelf: function ( qb, t ) {
  2644. var x = this.x, y = this.y, z = this.z, w = this.w;
  2645. // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
  2646. var cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z;
  2647. if ( cosHalfTheta < 0 ) {
  2648. this.w = -qb.w;
  2649. this.x = -qb.x;
  2650. this.y = -qb.y;
  2651. this.z = -qb.z;
  2652. cosHalfTheta = -cosHalfTheta;
  2653. } else {
  2654. this.copy( qb );
  2655. }
  2656. if ( cosHalfTheta >= 1.0 ) {
  2657. this.w = w;
  2658. this.x = x;
  2659. this.y = y;
  2660. this.z = z;
  2661. return this;
  2662. }
  2663. var halfTheta = Math.acos( cosHalfTheta );
  2664. var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
  2665. if ( Math.abs( sinHalfTheta ) < 0.001 ) {
  2666. this.w = 0.5 * ( w + this.w );
  2667. this.x = 0.5 * ( x + this.x );
  2668. this.y = 0.5 * ( y + this.y );
  2669. this.z = 0.5 * ( z + this.z );
  2670. return this;
  2671. }
  2672. var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
  2673. ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
  2674. this.w = ( w * ratioA + this.w * ratioB );
  2675. this.x = ( x * ratioA + this.x * ratioB );
  2676. this.y = ( y * ratioA + this.y * ratioB );
  2677. this.z = ( z * ratioA + this.z * ratioB );
  2678. return this;
  2679. },
  2680. clone: function () {
  2681. return new THREE.Quaternion( this.x, this.y, this.z, this.w );
  2682. }
  2683. }
  2684. THREE.Quaternion.slerp = function ( qa, qb, qm, t ) {
  2685. // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
  2686. var cosHalfTheta = qa.w * qb.w + qa.x * qb.x + qa.y * qb.y + qa.z * qb.z;
  2687. if ( cosHalfTheta < 0 ) {
  2688. qm.w = -qb.w;
  2689. qm.x = -qb.x;
  2690. qm.y = -qb.y;
  2691. qm.z = -qb.z;
  2692. cosHalfTheta = -cosHalfTheta;
  2693. } else {
  2694. qm.copy( qb );
  2695. }
  2696. if ( Math.abs( cosHalfTheta ) >= 1.0 ) {
  2697. qm.w = qa.w;
  2698. qm.x = qa.x;
  2699. qm.y = qa.y;
  2700. qm.z = qa.z;
  2701. return qm;
  2702. }
  2703. var halfTheta = Math.acos( cosHalfTheta );
  2704. var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
  2705. if ( Math.abs( sinHalfTheta ) < 0.001 ) {
  2706. qm.w = 0.5 * ( qa.w + qm.w );
  2707. qm.x = 0.5 * ( qa.x + qm.x );
  2708. qm.y = 0.5 * ( qa.y + qm.y );
  2709. qm.z = 0.5 * ( qa.z + qm.z );
  2710. return qm;
  2711. }
  2712. var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta;
  2713. var ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
  2714. qm.w = ( qa.w * ratioA + qm.w * ratioB );
  2715. qm.x = ( qa.x * ratioA + qm.x * ratioB );
  2716. qm.y = ( qa.y * ratioA + qm.y * ratioB );
  2717. qm.z = ( qa.z * ratioA + qm.z * ratioB );
  2718. return qm;
  2719. }
  2720. /**
  2721. * @author mr.doob / http://mrdoob.com/
  2722. */
  2723. THREE.Vertex = function () {
  2724. console.warn( 'THREE.Vertex has been DEPRECATED. Use THREE.Vector3 instead.')
  2725. };
  2726. /**
  2727. * @author mr.doob / http://mrdoob.com/
  2728. * @author alteredq / http://alteredqualia.com/
  2729. */
  2730. THREE.Face3 = function ( a, b, c, normal, color, materialIndex ) {
  2731. this.a = a;
  2732. this.b = b;
  2733. this.c = c;
  2734. this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
  2735. this.vertexNormals = normal instanceof Array ? normal : [ ];
  2736. this.color = color instanceof THREE.Color ? color : new THREE.Color();
  2737. this.vertexColors = color instanceof Array ? color : [];
  2738. this.vertexTangents = [];
  2739. this.materialIndex = materialIndex;
  2740. this.centroid = new THREE.Vector3();
  2741. };
  2742. THREE.Face3.prototype = {
  2743. constructor: THREE.Face3,
  2744. clone: function () {
  2745. var face = new THREE.Face3( this.a, this.b, this.c );
  2746. face.normal.copy( this.normal );
  2747. face.color.copy( this.color );
  2748. face.centroid.copy( this.centroid );
  2749. face.materialIndex = this.materialIndex;
  2750. var i, il;
  2751. for ( i = 0, il = this.vertexNormals.length; i < il; i ++ ) face.vertexNormals[ i ] = this.vertexNormals[ i ].clone();
  2752. for ( i = 0, il = this.vertexColors.length; i < il; i ++ ) face.vertexColors[ i ] = this.vertexColors[ i ].clone();
  2753. for ( i = 0, il = this.vertexTangents.length; i < il; i ++ ) face.vertexTangents[ i ] = this.vertexTangents[ i ].clone();
  2754. return face;
  2755. }
  2756. };
  2757. /**
  2758. * @author mr.doob / http://mrdoob.com/
  2759. * @author alteredq / http://alteredqualia.com/
  2760. */
  2761. THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) {
  2762. this.a = a;
  2763. this.b = b;
  2764. this.c = c;
  2765. this.d = d;
  2766. this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
  2767. this.vertexNormals = normal instanceof Array ? normal : [ ];
  2768. this.color = color instanceof THREE.Color ? color : new THREE.Color();
  2769. this.vertexColors = color instanceof Array ? color : [];
  2770. this.vertexTangents = [];
  2771. this.materialIndex = materialIndex;
  2772. this.centroid = new THREE.Vector3();
  2773. };
  2774. THREE.Face4.prototype = {
  2775. constructor: THREE.Face4,
  2776. clone: function () {
  2777. var face = new THREE.Face4( this.a, this.b, this.c, this.d );
  2778. face.normal.copy( this.normal );
  2779. face.color.copy( this.color );
  2780. face.centroid.copy( this.centroid );
  2781. face.materialIndex = this.materialIndex;
  2782. var i, il;
  2783. for ( i = 0, il = this.vertexNormals.length; i < il; i ++ ) face.vertexNormals[ i ] = this.vertexNormals[ i ].clone();
  2784. for ( i = 0, il = this.vertexColors.length; i < il; i ++ ) face.vertexColors[ i ] = this.vertexColors[ i ].clone();
  2785. for ( i = 0, il = this.vertexTangents.length; i < il; i ++ ) face.vertexTangents[ i ] = this.vertexTangents[ i ].clone();
  2786. return face;
  2787. }
  2788. };
  2789. /**
  2790. * @author mr.doob / http://mrdoob.com/
  2791. */
  2792. THREE.UV = function ( u, v ) {
  2793. this.u = u || 0;
  2794. this.v = v || 0;
  2795. };
  2796. THREE.UV.prototype = {
  2797. constructor: THREE.UV,
  2798. set: function ( u, v ) {
  2799. this.u = u;
  2800. this.v = v;
  2801. return this;
  2802. },
  2803. copy: function ( uv ) {
  2804. this.u = uv.u;
  2805. this.v = uv.v;
  2806. return this;
  2807. },
  2808. lerpSelf: function ( uv, alpha ) {
  2809. this.u += ( uv.u - this.u ) * alpha;
  2810. this.v += ( uv.v - this.v ) * alpha;
  2811. return this;
  2812. },
  2813. clone: function () {
  2814. return new THREE.UV( this.u, this.v );
  2815. }
  2816. };
  2817. /**
  2818. * @author mr.doob / http://mrdoob.com/
  2819. * @author kile / http://kile.stravaganza.org/
  2820. * @author alteredq / http://alteredqualia.com/
  2821. * @author mikael emtinger / http://gomo.se/
  2822. * @author zz85 / http://www.lab4games.net/zz85/blog
  2823. */
  2824. THREE.Geometry = function () {
  2825. this.id = THREE.GeometryCount ++;
  2826. this.name = '';
  2827. this.vertices = [];
  2828. this.colors = []; // one-to-one vertex colors, used in ParticleSystem, Line and Ribbon
  2829. this.materials = [];
  2830. this.faces = [];
  2831. this.faceUvs = [[]];
  2832. this.faceVertexUvs = [[]];
  2833. this.morphTargets = [];
  2834. this.morphColors = [];
  2835. this.morphNormals = [];
  2836. this.skinWeights = [];
  2837. this.skinIndices = [];
  2838. this.boundingBox = null;
  2839. this.boundingSphere = null;
  2840. this.hasTangents = false;
  2841. this.dynamic = false; // unless set to true the *Arrays will be deleted once sent to a buffer
  2842. };
  2843. THREE.Geometry.prototype = {
  2844. constructor : THREE.Geometry,
  2845. applyMatrix: function ( matrix ) {
  2846. var matrixRotation = new THREE.Matrix4();
  2847. matrixRotation.extractRotation( matrix );
  2848. for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
  2849. var vertex = this.vertices[ i ];
  2850. matrix.multiplyVector3( vertex );
  2851. }
  2852. for ( var i = 0, il = this.faces.length; i < il; i ++ ) {
  2853. var face = this.faces[ i ];
  2854. matrixRotation.multiplyVector3( face.normal );
  2855. for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
  2856. matrixRotation.multiplyVector3( face.vertexNormals[ j ] );
  2857. }
  2858. matrix.multiplyVector3( face.centroid );
  2859. }
  2860. },
  2861. computeCentroids: function () {
  2862. var f, fl, face;
  2863. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2864. face = this.faces[ f ];
  2865. face.centroid.set( 0, 0, 0 );
  2866. if ( face instanceof THREE.Face3 ) {
  2867. face.centroid.addSelf( this.vertices[ face.a ] );
  2868. face.centroid.addSelf( this.vertices[ face.b ] );
  2869. face.centroid.addSelf( this.vertices[ face.c ] );
  2870. face.centroid.divideScalar( 3 );
  2871. } else if ( face instanceof THREE.Face4 ) {
  2872. face.centroid.addSelf( this.vertices[ face.a ] );
  2873. face.centroid.addSelf( this.vertices[ face.b ] );
  2874. face.centroid.addSelf( this.vertices[ face.c ] );
  2875. face.centroid.addSelf( this.vertices[ face.d ] );
  2876. face.centroid.divideScalar( 4 );
  2877. }
  2878. }
  2879. },
  2880. computeFaceNormals: function () {
  2881. var n, nl, v, vl, vertex, f, fl, face, vA, vB, vC,
  2882. cb = new THREE.Vector3(), ab = new THREE.Vector3();
  2883. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2884. face = this.faces[ f ];
  2885. vA = this.vertices[ face.a ];
  2886. vB = this.vertices[ face.b ];
  2887. vC = this.vertices[ face.c ];
  2888. cb.sub( vC, vB );
  2889. ab.sub( vA, vB );
  2890. cb.crossSelf( ab );
  2891. if ( !cb.isZero() ) {
  2892. cb.normalize();
  2893. }
  2894. face.normal.copy( cb );
  2895. }
  2896. },
  2897. computeVertexNormals: function () {
  2898. var v, vl, f, fl, face, vertices;
  2899. // create internal buffers for reuse when calling this method repeatedly
  2900. // (otherwise memory allocation / deallocation every frame is big resource hog)
  2901. if ( this.__tmpVertices === undefined ) {
  2902. this.__tmpVertices = new Array( this.vertices.length );
  2903. vertices = this.__tmpVertices;
  2904. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  2905. vertices[ v ] = new THREE.Vector3();
  2906. }
  2907. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2908. face = this.faces[ f ];
  2909. if ( face instanceof THREE.Face3 ) {
  2910. face.vertexNormals = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
  2911. } else if ( face instanceof THREE.Face4 ) {
  2912. face.vertexNormals = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
  2913. }
  2914. }
  2915. } else {
  2916. vertices = this.__tmpVertices;
  2917. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  2918. vertices[ v ].set( 0, 0, 0 );
  2919. }
  2920. }
  2921. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2922. face = this.faces[ f ];
  2923. if ( face instanceof THREE.Face3 ) {
  2924. vertices[ face.a ].addSelf( face.normal );
  2925. vertices[ face.b ].addSelf( face.normal );
  2926. vertices[ face.c ].addSelf( face.normal );
  2927. } else if ( face instanceof THREE.Face4 ) {
  2928. vertices[ face.a ].addSelf( face.normal );
  2929. vertices[ face.b ].addSelf( face.normal );
  2930. vertices[ face.c ].addSelf( face.normal );
  2931. vertices[ face.d ].addSelf( face.normal );
  2932. }
  2933. }
  2934. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  2935. vertices[ v ].normalize();
  2936. }
  2937. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2938. face = this.faces[ f ];
  2939. if ( face instanceof THREE.Face3 ) {
  2940. face.vertexNormals[ 0 ].copy( vertices[ face.a ] );
  2941. face.vertexNormals[ 1 ].copy( vertices[ face.b ] );
  2942. face.vertexNormals[ 2 ].copy( vertices[ face.c ] );
  2943. } else if ( face instanceof THREE.Face4 ) {
  2944. face.vertexNormals[ 0 ].copy( vertices[ face.a ] );
  2945. face.vertexNormals[ 1 ].copy( vertices[ face.b ] );
  2946. face.vertexNormals[ 2 ].copy( vertices[ face.c ] );
  2947. face.vertexNormals[ 3 ].copy( vertices[ face.d ] );
  2948. }
  2949. }
  2950. },
  2951. computeMorphNormals: function () {
  2952. var i, il, f, fl, face;
  2953. // save original normals
  2954. // - create temp variables on first access
  2955. // otherwise just copy (for faster repeated calls)
  2956. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2957. face = this.faces[ f ];
  2958. if ( ! face.__originalFaceNormal ) {
  2959. face.__originalFaceNormal = face.normal.clone();
  2960. } else {
  2961. face.__originalFaceNormal.copy( face.normal );
  2962. }
  2963. if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];
  2964. for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {
  2965. if ( ! face.__originalVertexNormals[ i ] ) {
  2966. face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();
  2967. } else {
  2968. face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );
  2969. }
  2970. }
  2971. }
  2972. // use temp geometry to compute face and vertex normals for each morph
  2973. var tmpGeo = new THREE.Geometry();
  2974. tmpGeo.faces = this.faces;
  2975. for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {
  2976. // create on first access
  2977. if ( ! this.morphNormals[ i ] ) {
  2978. this.morphNormals[ i ] = {};
  2979. this.morphNormals[ i ].faceNormals = [];
  2980. this.morphNormals[ i ].vertexNormals = [];
  2981. var dstNormalsFace = this.morphNormals[ i ].faceNormals;
  2982. var dstNormalsVertex = this.morphNormals[ i ].vertexNormals;
  2983. var faceNormal, vertexNormals;
  2984. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  2985. face = this.faces[ f ];
  2986. faceNormal = new THREE.Vector3();
  2987. if ( face instanceof THREE.Face3 ) {
  2988. vertexNormals = { a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3() };
  2989. } else {
  2990. vertexNormals = { a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3(), d: new THREE.Vector3() };
  2991. }
  2992. dstNormalsFace.push( faceNormal );
  2993. dstNormalsVertex.push( vertexNormals );
  2994. }
  2995. }
  2996. var morphNormals = this.morphNormals[ i ];
  2997. // set vertices to morph target
  2998. tmpGeo.vertices = this.morphTargets[ i ].vertices;
  2999. // compute morph normals
  3000. tmpGeo.computeFaceNormals();
  3001. tmpGeo.computeVertexNormals();
  3002. // store morph normals
  3003. var faceNormal, vertexNormals;
  3004. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  3005. face = this.faces[ f ];
  3006. faceNormal = morphNormals.faceNormals[ f ];
  3007. vertexNormals = morphNormals.vertexNormals[ f ];
  3008. faceNormal.copy( face.normal );
  3009. if ( face instanceof THREE.Face3 ) {
  3010. vertexNormals.a.copy( face.vertexNormals[ 0 ] );
  3011. vertexNormals.b.copy( face.vertexNormals[ 1 ] );
  3012. vertexNormals.c.copy( face.vertexNormals[ 2 ] );
  3013. } else {
  3014. vertexNormals.a.copy( face.vertexNormals[ 0 ] );
  3015. vertexNormals.b.copy( face.vertexNormals[ 1 ] );
  3016. vertexNormals.c.copy( face.vertexNormals[ 2 ] );
  3017. vertexNormals.d.copy( face.vertexNormals[ 3 ] );
  3018. }
  3019. }
  3020. }
  3021. // restore original normals
  3022. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  3023. face = this.faces[ f ];
  3024. face.normal = face.__originalFaceNormal;
  3025. face.vertexNormals = face.__originalVertexNormals;
  3026. }
  3027. },
  3028. computeTangents: function () {
  3029. // based on http://www.terathon.com/code/tangent.html
  3030. // tangents go to vertices
  3031. var f, fl, v, vl, i, il, vertexIndex,
  3032. face, uv, vA, vB, vC, uvA, uvB, uvC,
  3033. x1, x2, y1, y2, z1, z2,
  3034. s1, s2, t1, t2, r, t, test,
  3035. tan1 = [], tan2 = [],
  3036. sdir = new THREE.Vector3(), tdir = new THREE.Vector3(),
  3037. tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(),
  3038. n = new THREE.Vector3(), w;
  3039. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  3040. tan1[ v ] = new THREE.Vector3();
  3041. tan2[ v ] = new THREE.Vector3();
  3042. }
  3043. function handleTriangle( context, a, b, c, ua, ub, uc ) {
  3044. vA = context.vertices[ a ];
  3045. vB = context.vertices[ b ];
  3046. vC = context.vertices[ c ];
  3047. uvA = uv[ ua ];
  3048. uvB = uv[ ub ];
  3049. uvC = uv[ uc ];
  3050. x1 = vB.x - vA.x;
  3051. x2 = vC.x - vA.x;
  3052. y1 = vB.y - vA.y;
  3053. y2 = vC.y - vA.y;
  3054. z1 = vB.z - vA.z;
  3055. z2 = vC.z - vA.z;
  3056. s1 = uvB.u - uvA.u;
  3057. s2 = uvC.u - uvA.u;
  3058. t1 = uvB.v - uvA.v;
  3059. t2 = uvC.v - uvA.v;
  3060. r = 1.0 / ( s1 * t2 - s2 * t1 );
  3061. sdir.set( ( t2 * x1 - t1 * x2 ) * r,
  3062. ( t2 * y1 - t1 * y2 ) * r,
  3063. ( t2 * z1 - t1 * z2 ) * r );
  3064. tdir.set( ( s1 * x2 - s2 * x1 ) * r,
  3065. ( s1 * y2 - s2 * y1 ) * r,
  3066. ( s1 * z2 - s2 * z1 ) * r );
  3067. tan1[ a ].addSelf( sdir );
  3068. tan1[ b ].addSelf( sdir );
  3069. tan1[ c ].addSelf( sdir );
  3070. tan2[ a ].addSelf( tdir );
  3071. tan2[ b ].addSelf( tdir );
  3072. tan2[ c ].addSelf( tdir );
  3073. }
  3074. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  3075. face = this.faces[ f ];
  3076. uv = this.faceVertexUvs[ 0 ][ f ]; // use UV layer 0 for tangents
  3077. if ( face instanceof THREE.Face3 ) {
  3078. handleTriangle( this, face.a, face.b, face.c, 0, 1, 2 );
  3079. } else if ( face instanceof THREE.Face4 ) {
  3080. handleTriangle( this, face.a, face.b, face.d, 0, 1, 3 );
  3081. handleTriangle( this, face.b, face.c, face.d, 1, 2, 3 );
  3082. }
  3083. }
  3084. var faceIndex = [ 'a', 'b', 'c', 'd' ];
  3085. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  3086. face = this.faces[ f ];
  3087. for ( i = 0; i < face.vertexNormals.length; i++ ) {
  3088. n.copy( face.vertexNormals[ i ] );
  3089. vertexIndex = face[ faceIndex[ i ] ];
  3090. t = tan1[ vertexIndex ];
  3091. // Gram-Schmidt orthogonalize
  3092. tmp.copy( t );
  3093. tmp.subSelf( n.multiplyScalar( n.dot( t ) ) ).normalize();
  3094. // Calculate handedness
  3095. tmp2.cross( face.vertexNormals[ i ], t );
  3096. test = tmp2.dot( tan2[ vertexIndex ] );
  3097. w = (test < 0.0) ? -1.0 : 1.0;
  3098. face.vertexTangents[ i ] = new THREE.Vector4( tmp.x, tmp.y, tmp.z, w );
  3099. }
  3100. }
  3101. this.hasTangents = true;
  3102. },
  3103. computeBoundingBox: function () {
  3104. if ( ! this.boundingBox ) {
  3105. this.boundingBox = { min: new THREE.Vector3(), max: new THREE.Vector3() };
  3106. }
  3107. if ( this.vertices.length > 0 ) {
  3108. var position, firstPosition = this.vertices[ 0 ];
  3109. this.boundingBox.min.copy( firstPosition );
  3110. this.boundingBox.max.copy( firstPosition );
  3111. var min = this.boundingBox.min,
  3112. max = this.boundingBox.max;
  3113. for ( var v = 1, vl = this.vertices.length; v < vl; v ++ ) {
  3114. position = this.vertices[ v ];
  3115. if ( position.x < min.x ) {
  3116. min.x = position.x;
  3117. } else if ( position.x > max.x ) {
  3118. max.x = position.x;
  3119. }
  3120. if ( position.y < min.y ) {
  3121. min.y = position.y;
  3122. } else if ( position.y > max.y ) {
  3123. max.y = position.y;
  3124. }
  3125. if ( position.z < min.z ) {
  3126. min.z = position.z;
  3127. } else if ( position.z > max.z ) {
  3128. max.z = position.z;
  3129. }
  3130. }
  3131. } else {
  3132. this.boundingBox.min.set( 0, 0, 0 );
  3133. this.boundingBox.max.set( 0, 0, 0 );
  3134. }
  3135. },
  3136. computeBoundingSphere: function () {
  3137. if ( ! this.boundingSphere ) this.boundingSphere = { radius: 0 };
  3138. var radius, maxRadius = 0;
  3139. for ( var v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  3140. radius = this.vertices[ v ].length();
  3141. if ( radius > maxRadius ) maxRadius = radius;
  3142. }
  3143. this.boundingSphere.radius = maxRadius;
  3144. },
  3145. /*
  3146. * Checks for duplicate vertices with hashmap.
  3147. * Duplicated vertices are removed
  3148. * and faces' vertices are updated.
  3149. */
  3150. mergeVertices: function() {
  3151. var verticesMap = {}; // Hashmap for looking up vertice by position coordinates (and making sure they are unique)
  3152. var unique = [], changes = [];
  3153. var v, key;
  3154. var precisionPoints = 4; // number of decimal points, eg. 4 for epsilon of 0.0001
  3155. var precision = Math.pow( 10, precisionPoints );
  3156. var i,il, face;
  3157. var abcd = 'abcd', o, k, j, jl, u;
  3158. for ( i = 0, il = this.vertices.length; i < il; i ++ ) {
  3159. v = this.vertices[ i ];
  3160. key = [ Math.round( v.x * precision ), Math.round( v.y * precision ), Math.round( v.z * precision ) ].join( '_' );
  3161. if ( verticesMap[ key ] === undefined ) {
  3162. verticesMap[ key ] = i;
  3163. unique.push( this.vertices[ i ] );
  3164. changes[ i ] = unique.length - 1;
  3165. } else {
  3166. //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
  3167. changes[ i ] = changes[ verticesMap[ key ] ];
  3168. }
  3169. };
  3170. // Start to patch face indices
  3171. for( i = 0, il = this.faces.length; i < il; i ++ ) {
  3172. face = this.faces[ i ];
  3173. if ( face instanceof THREE.Face3 ) {
  3174. face.a = changes[ face.a ];
  3175. face.b = changes[ face.b ];
  3176. face.c = changes[ face.c ];
  3177. } else if ( face instanceof THREE.Face4 ) {
  3178. face.a = changes[ face.a ];
  3179. face.b = changes[ face.b ];
  3180. face.c = changes[ face.c ];
  3181. face.d = changes[ face.d ];
  3182. // check dups in (a, b, c, d) and convert to -> face3
  3183. o = [ face.a, face.b, face.c, face.d ];
  3184. for ( k = 3; k > 0; k -- ) {
  3185. if ( o.indexOf( face[ abcd[ k ] ] ) !== k ) {
  3186. // console.log('faces', face.a, face.b, face.c, face.d, 'dup at', k);
  3187. o.splice( k, 1 );
  3188. this.faces[ i ] = new THREE.Face3( o[0], o[1], o[2], face.normal, face.color, face.materialIndex );
  3189. for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
  3190. u = this.faceVertexUvs[ j ][ i ];
  3191. if ( u ) u.splice( k, 1 );
  3192. }
  3193. this.faces[ i ].vertexColors = face.vertexColors;
  3194. break;
  3195. }
  3196. }
  3197. }
  3198. }
  3199. // Use unique set of vertices
  3200. var diff = this.vertices.length - unique.length;
  3201. this.vertices = unique;
  3202. return diff;
  3203. }
  3204. };
  3205. THREE.GeometryCount = 0;
  3206. /**
  3207. * Spline from Tween.js, slightly optimized (and trashed)
  3208. * http://sole.github.com/tween.js/examples/05_spline.html
  3209. *
  3210. * @author mrdoob / http://mrdoob.com/
  3211. * @author alteredq / http://alteredqualia.com/
  3212. */
  3213. THREE.Spline = function ( points ) {
  3214. this.points = points;
  3215. var c = [], v3 = { x: 0, y: 0, z: 0 },
  3216. point, intPoint, weight, w2, w3,
  3217. pa, pb, pc, pd;
  3218. this.initFromArray = function( a ) {
  3219. this.points = [];
  3220. for ( var i = 0; i < a.length; i++ ) {
  3221. this.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] };
  3222. }
  3223. };
  3224. this.getPoint = function ( k ) {
  3225. point = ( this.points.length - 1 ) * k;
  3226. intPoint = Math.floor( point );
  3227. weight = point - intPoint;
  3228. c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;
  3229. c[ 1 ] = intPoint;
  3230. c[ 2 ] = intPoint > this.points.length - 2 ? this.points.length - 1 : intPoint + 1;
  3231. c[ 3 ] = intPoint > this.points.length - 3 ? this.points.length - 1 : intPoint + 2;
  3232. pa = this.points[ c[ 0 ] ];
  3233. pb = this.points[ c[ 1 ] ];
  3234. pc = this.points[ c[ 2 ] ];
  3235. pd = this.points[ c[ 3 ] ];
  3236. w2 = weight * weight;
  3237. w3 = weight * w2;
  3238. v3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 );
  3239. v3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 );
  3240. v3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 );
  3241. return v3;
  3242. };
  3243. this.getControlPointsArray = function () {
  3244. var i, p, l = this.points.length,
  3245. coords = [];
  3246. for ( i = 0; i < l; i ++ ) {
  3247. p = this.points[ i ];
  3248. coords[ i ] = [ p.x, p.y, p.z ];
  3249. }
  3250. return coords;
  3251. };
  3252. // approximate length by summing linear segments
  3253. this.getLength = function ( nSubDivisions ) {
  3254. var i, index, nSamples, position,
  3255. point = 0, intPoint = 0, oldIntPoint = 0,
  3256. oldPosition = new THREE.Vector3(),
  3257. tmpVec = new THREE.Vector3(),
  3258. chunkLengths = [],
  3259. totalLength = 0;
  3260. // first point has 0 length
  3261. chunkLengths[ 0 ] = 0;
  3262. if ( !nSubDivisions ) nSubDivisions = 100;
  3263. nSamples = this.points.length * nSubDivisions;
  3264. oldPosition.copy( this.points[ 0 ] );
  3265. for ( i = 1; i < nSamples; i ++ ) {
  3266. index = i / nSamples;
  3267. position = this.getPoint( index );
  3268. tmpVec.copy( position );
  3269. totalLength += tmpVec.distanceTo( oldPosition );
  3270. oldPosition.copy( position );
  3271. point = ( this.points.length - 1 ) * index;
  3272. intPoint = Math.floor( point );
  3273. if ( intPoint != oldIntPoint ) {
  3274. chunkLengths[ intPoint ] = totalLength;
  3275. oldIntPoint = intPoint;
  3276. }
  3277. }
  3278. // last point ends with total length
  3279. chunkLengths[ chunkLengths.length ] = totalLength;
  3280. return { chunks: chunkLengths, total: totalLength };
  3281. };
  3282. this.reparametrizeByArcLength = function ( samplingCoef ) {
  3283. var i, j,
  3284. index, indexCurrent, indexNext,
  3285. linearDistance, realDistance,
  3286. sampling, position,
  3287. newpoints = [],
  3288. tmpVec = new THREE.Vector3(),
  3289. sl = this.getLength();
  3290. newpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() );
  3291. for ( i = 1; i < this.points.length; i++ ) {
  3292. //tmpVec.copy( this.points[ i - 1 ] );
  3293. //linearDistance = tmpVec.distanceTo( this.points[ i ] );
  3294. realDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ];
  3295. sampling = Math.ceil( samplingCoef * realDistance / sl.total );
  3296. indexCurrent = ( i - 1 ) / ( this.points.length - 1 );
  3297. indexNext = i / ( this.points.length - 1 );
  3298. for ( j = 1; j < sampling - 1; j++ ) {
  3299. index = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent );
  3300. position = this.getPoint( index );
  3301. newpoints.push( tmpVec.copy( position ).clone() );
  3302. }
  3303. newpoints.push( tmpVec.copy( this.points[ i ] ).clone() );
  3304. }
  3305. this.points = newpoints;
  3306. };
  3307. // Catmull-Rom
  3308. function interpolate( p0, p1, p2, p3, t, t2, t3 ) {
  3309. var v0 = ( p2 - p0 ) * 0.5,
  3310. v1 = ( p3 - p1 ) * 0.5;
  3311. return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;
  3312. };
  3313. };
  3314. /**
  3315. * @author mr.doob / http://mrdoob.com/
  3316. * @author mikael emtinger / http://gomo.se/
  3317. */
  3318. THREE.Camera = function () {
  3319. THREE.Object3D.call( this );
  3320. this.matrixWorldInverse = new THREE.Matrix4();
  3321. this.projectionMatrix = new THREE.Matrix4();
  3322. this.projectionMatrixInverse = new THREE.Matrix4();
  3323. };
  3324. THREE.Camera.prototype = Object.create( THREE.Object3D.prototype );
  3325. THREE.Camera.prototype.lookAt = function ( vector ) {
  3326. // TODO: Add hierarchy support.
  3327. this.matrix.lookAt( this.position, vector, this.up );
  3328. if ( this.rotationAutoUpdate === true ) {
  3329. this.rotation.setEulerFromRotationMatrix( this.matrix, this.eulerOrder );
  3330. }
  3331. };
  3332. /**
  3333. * @author alteredq / http://alteredqualia.com/
  3334. */
  3335. THREE.OrthographicCamera = function ( left, right, top, bottom, near, far ) {
  3336. THREE.Camera.call( this );
  3337. this.left = left;
  3338. this.right = right;
  3339. this.top = top;
  3340. this.bottom = bottom;
  3341. this.near = ( near !== undefined ) ? near : 0.1;
  3342. this.far = ( far !== undefined ) ? far : 2000;
  3343. this.updateProjectionMatrix();
  3344. };
  3345. THREE.OrthographicCamera.prototype = Object.create( THREE.Camera.prototype );
  3346. THREE.OrthographicCamera.prototype.updateProjectionMatrix = function () {
  3347. this.projectionMatrix.makeOrthographic( this.left, this.right, this.top, this.bottom, this.near, this.far );
  3348. };
  3349. /**
  3350. * @author mr.doob / http://mrdoob.com/
  3351. * @author greggman / http://games.greggman.com/
  3352. * @author zz85 / http://www.lab4games.net/zz85/blog
  3353. */
  3354. THREE.PerspectiveCamera = function ( fov, aspect, near, far ) {
  3355. THREE.Camera.call( this );
  3356. this.fov = fov !== undefined ? fov : 50;
  3357. this.aspect = aspect !== undefined ? aspect : 1;
  3358. this.near = near !== undefined ? near : 0.1;
  3359. this.far = far !== undefined ? far : 2000;
  3360. this.updateProjectionMatrix();
  3361. };
  3362. THREE.PerspectiveCamera.prototype = Object.create( THREE.Camera.prototype );
  3363. /**
  3364. * Uses Focal Length (in mm) to estimate and set FOV
  3365. * 35mm (fullframe) camera is used if frame size is not specified;
  3366. * Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html
  3367. */
  3368. THREE.PerspectiveCamera.prototype.setLens = function ( focalLength, frameHeight ) {
  3369. frameHeight = frameHeight !== undefined ? frameHeight : 24;
  3370. this.fov = 2 * Math.atan( frameHeight / ( focalLength * 2 ) ) * ( 180 / Math.PI );
  3371. this.updateProjectionMatrix();
  3372. }
  3373. /**
  3374. * Sets an offset in a larger frustum. This is useful for multi-window or
  3375. * multi-monitor/multi-machine setups.
  3376. *
  3377. * For example, if you have 3x2 monitors and each monitor is 1920x1080 and
  3378. * the monitors are in grid like this
  3379. *
  3380. * +---+---+---+
  3381. * | A | B | C |
  3382. * +---+---+---+
  3383. * | D | E | F |
  3384. * +---+---+---+
  3385. *
  3386. * then for each monitor you would call it like this
  3387. *
  3388. * var w = 1920;
  3389. * var h = 1080;
  3390. * var fullWidth = w * 3;
  3391. * var fullHeight = h * 2;
  3392. *
  3393. * --A--
  3394. * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
  3395. * --B--
  3396. * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
  3397. * --C--
  3398. * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
  3399. * --D--
  3400. * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
  3401. * --E--
  3402. * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
  3403. * --F--
  3404. * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
  3405. *
  3406. * Note there is no reason monitors have to be the same size or in a grid.
  3407. */
  3408. THREE.PerspectiveCamera.prototype.setViewOffset = function ( fullWidth, fullHeight, x, y, width, height ) {
  3409. this.fullWidth = fullWidth;
  3410. this.fullHeight = fullHeight;
  3411. this.x = x;
  3412. this.y = y;
  3413. this.width = width;
  3414. this.height = height;
  3415. this.updateProjectionMatrix();
  3416. };
  3417. THREE.PerspectiveCamera.prototype.updateProjectionMatrix = function () {
  3418. if ( this.fullWidth ) {
  3419. var aspect = this.fullWidth / this.fullHeight;
  3420. var top = Math.tan( this.fov * Math.PI / 360 ) * this.near;
  3421. var bottom = -top;
  3422. var left = aspect * bottom;
  3423. var right = aspect * top;
  3424. var width = Math.abs( right - left );
  3425. var height = Math.abs( top - bottom );
  3426. this.projectionMatrix.makeFrustum(
  3427. left + this.x * width / this.fullWidth,
  3428. left + ( this.x + this.width ) * width / this.fullWidth,
  3429. top - ( this.y + this.height ) * height / this.fullHeight,
  3430. top - this.y * height / this.fullHeight,
  3431. this.near,
  3432. this.far
  3433. );
  3434. } else {
  3435. this.projectionMatrix.makePerspective( this.fov, this.aspect, this.near, this.far );
  3436. }
  3437. };
  3438. /**
  3439. * @author mr.doob / http://mrdoob.com/
  3440. * @author alteredq / http://alteredqualia.com/
  3441. */
  3442. THREE.Light = function ( hex ) {
  3443. THREE.Object3D.call( this );
  3444. this.color = new THREE.Color( hex );
  3445. };
  3446. THREE.Light.prototype = Object.create( THREE.Object3D.prototype );
  3447. /**
  3448. * @author mr.doob / http://mrdoob.com/
  3449. */
  3450. THREE.AmbientLight = function ( hex ) {
  3451. THREE.Light.call( this, hex );
  3452. };
  3453. THREE.AmbientLight.prototype = Object.create( THREE.Light.prototype );
  3454. /**
  3455. * @author mr.doob / http://mrdoob.com/
  3456. * @author alteredq / http://alteredqualia.com/
  3457. */
  3458. THREE.DirectionalLight = function ( hex, intensity, distance ) {
  3459. THREE.Light.call( this, hex );
  3460. this.position = new THREE.Vector3( 0, 1, 0 );
  3461. this.target = new THREE.Object3D();
  3462. this.intensity = ( intensity !== undefined ) ? intensity : 1;
  3463. this.distance = ( distance !== undefined ) ? distance : 0;
  3464. this.castShadow = false;
  3465. this.onlyShadow = false;
  3466. //
  3467. this.shadowCameraNear = 50;
  3468. this.shadowCameraFar = 5000;
  3469. this.shadowCameraLeft = -500;
  3470. this.shadowCameraRight = 500;
  3471. this.shadowCameraTop = 500;
  3472. this.shadowCameraBottom = -500;
  3473. this.shadowCameraVisible = false;
  3474. this.shadowBias = 0;
  3475. this.shadowDarkness = 0.5;
  3476. this.shadowMapWidth = 512;
  3477. this.shadowMapHeight = 512;
  3478. //
  3479. this.shadowCascade = false;
  3480. this.shadowCascadeOffset = new THREE.Vector3( 0, 0, -1000 );
  3481. this.shadowCascadeCount = 2;
  3482. this.shadowCascadeBias = [ 0, 0, 0 ];
  3483. this.shadowCascadeWidth = [ 512, 512, 512 ];
  3484. this.shadowCascadeHeight = [ 512, 512, 512 ];
  3485. this.shadowCascadeNearZ = [ -1.000, 0.990, 0.998 ];
  3486. this.shadowCascadeFarZ = [ 0.990, 0.998, 1.000 ];
  3487. this.shadowCascadeArray = [];
  3488. //
  3489. this.shadowMap = null;
  3490. this.shadowMapSize = null;
  3491. this.shadowCamera = null;
  3492. this.shadowMatrix = null;
  3493. };
  3494. THREE.DirectionalLight.prototype = Object.create( THREE.Light.prototype );
  3495. /**
  3496. * @author mr.doob / http://mrdoob.com/
  3497. */
  3498. THREE.PointLight = function ( hex, intensity, distance ) {
  3499. THREE.Light.call( this, hex );
  3500. this.position = new THREE.Vector3( 0, 0, 0 );
  3501. this.intensity = ( intensity !== undefined ) ? intensity : 1;
  3502. this.distance = ( distance !== undefined ) ? distance : 0;
  3503. };
  3504. THREE.PointLight.prototype = Object.create( THREE.Light.prototype );
  3505. /**
  3506. * @author alteredq / http://alteredqualia.com/
  3507. */
  3508. THREE.SpotLight = function ( hex, intensity, distance, angle, exponent ) {
  3509. THREE.Light.call( this, hex );
  3510. this.position = new THREE.Vector3( 0, 1, 0 );
  3511. this.target = new THREE.Object3D();
  3512. this.intensity = ( intensity !== undefined ) ? intensity : 1;
  3513. this.distance = ( distance !== undefined ) ? distance : 0;
  3514. this.angle = ( angle !== undefined ) ? angle : Math.PI / 2;
  3515. this.exponent = ( exponent !== undefined ) ? exponent : 10;
  3516. this.castShadow = false;
  3517. this.onlyShadow = false;
  3518. //
  3519. this.shadowCameraNear = 50;
  3520. this.shadowCameraFar = 5000;
  3521. this.shadowCameraFov = 50;
  3522. this.shadowCameraVisible = false;
  3523. this.shadowBias = 0;
  3524. this.shadowDarkness = 0.5;
  3525. this.shadowMapWidth = 512;
  3526. this.shadowMapHeight = 512;
  3527. //
  3528. this.shadowMap = null;
  3529. this.shadowMapSize = null;
  3530. this.shadowCamera = null;
  3531. this.shadowMatrix = null;
  3532. };
  3533. THREE.SpotLight.prototype = Object.create( THREE.Light.prototype );
  3534. /**
  3535. * @author alteredq / http://alteredqualia.com/
  3536. */
  3537. THREE.Loader = function ( showStatus ) {
  3538. this.showStatus = showStatus;
  3539. this.statusDomElement = showStatus ? THREE.Loader.prototype.addStatusElement() : null;
  3540. this.onLoadStart = function () {};
  3541. this.onLoadProgress = function () {};
  3542. this.onLoadComplete = function () {};
  3543. };
  3544. THREE.Loader.prototype = {
  3545. constructor: THREE.Loader,
  3546. crossOrigin: 'anonymous',
  3547. addStatusElement: function () {
  3548. var e = document.createElement( "div" );
  3549. e.style.position = "absolute";
  3550. e.style.right = "0px";
  3551. e.style.top = "0px";
  3552. e.style.fontSize = "0.8em";
  3553. e.style.textAlign = "left";
  3554. e.style.background = "rgba(0,0,0,0.25)";
  3555. e.style.color = "#fff";
  3556. e.style.width = "120px";
  3557. e.style.padding = "0.5em 0.5em 0.5em 0.5em";
  3558. e.style.zIndex = 1000;
  3559. e.innerHTML = "Loading ...";
  3560. return e;
  3561. },
  3562. updateProgress: function ( progress ) {
  3563. var message = "Loaded ";
  3564. if ( progress.total ) {
  3565. message += ( 100 * progress.loaded / progress.total ).toFixed(0) + "%";
  3566. } else {
  3567. message += ( progress.loaded / 1000 ).toFixed(2) + " KB";
  3568. }
  3569. this.statusDomElement.innerHTML = message;
  3570. },
  3571. extractUrlBase: function ( url ) {
  3572. var parts = url.split( '/' );
  3573. parts.pop();
  3574. return ( parts.length < 1 ? '.' : parts.join( '/' ) ) + '/';
  3575. },
  3576. initMaterials: function ( scope, materials, texturePath ) {
  3577. scope.materials = [];
  3578. for ( var i = 0; i < materials.length; ++ i ) {
  3579. scope.materials[ i ] = THREE.Loader.prototype.createMaterial( materials[ i ], texturePath );
  3580. }
  3581. },
  3582. hasNormals: function ( scope ) {
  3583. var m, i, il = scope.materials.length;
  3584. for( i = 0; i < il; i ++ ) {
  3585. m = scope.materials[ i ];
  3586. if ( m instanceof THREE.ShaderMaterial ) return true;
  3587. }
  3588. return false;
  3589. },
  3590. createMaterial: function ( m, texturePath ) {
  3591. var _this = this;
  3592. function is_pow2( n ) {
  3593. var l = Math.log( n ) / Math.LN2;
  3594. return Math.floor( l ) == l;
  3595. }
  3596. function nearest_pow2( n ) {
  3597. var l = Math.log( n ) / Math.LN2;
  3598. return Math.pow( 2, Math.round( l ) );
  3599. }
  3600. function load_image( where, url ) {
  3601. var image = new Image();
  3602. image.onload = function () {
  3603. if ( !is_pow2( this.width ) || !is_pow2( this.height ) ) {
  3604. var width = nearest_pow2( this.width );
  3605. var height = nearest_pow2( this.height );
  3606. where.image.width = width;
  3607. where.image.height = height;
  3608. where.image.getContext( '2d' ).drawImage( this, 0, 0, width, height );
  3609. } else {
  3610. where.image = this;
  3611. }
  3612. where.needsUpdate = true;
  3613. };
  3614. image.crossOrigin = _this.crossOrigin;
  3615. image.src = url;
  3616. }
  3617. function create_texture( where, name, sourceFile, repeat, offset, wrap ) {
  3618. var texture = document.createElement( 'canvas' );
  3619. where[ name ] = new THREE.Texture( texture );
  3620. where[ name ].sourceFile = sourceFile;
  3621. if( repeat ) {
  3622. where[ name ].repeat.set( repeat[ 0 ], repeat[ 1 ] );
  3623. if ( repeat[ 0 ] != 1 ) where[ name ].wrapS = THREE.RepeatWrapping;
  3624. if ( repeat[ 1 ] != 1 ) where[ name ].wrapT = THREE.RepeatWrapping;
  3625. }
  3626. if ( offset ) {
  3627. where[ name ].offset.set( offset[ 0 ], offset[ 1 ] );
  3628. }
  3629. if ( wrap ) {
  3630. var wrapMap = {
  3631. "repeat": THREE.RepeatWrapping,
  3632. "mirror": THREE.MirroredRepeatWrapping
  3633. }
  3634. if ( wrapMap[ wrap[ 0 ] ] !== undefined ) where[ name ].wrapS = wrapMap[ wrap[ 0 ] ];
  3635. if ( wrapMap[ wrap[ 1 ] ] !== undefined ) where[ name ].wrapT = wrapMap[ wrap[ 1 ] ];
  3636. }
  3637. load_image( where[ name ], texturePath + "/" + sourceFile );
  3638. }
  3639. function rgb2hex( rgb ) {
  3640. return ( rgb[ 0 ] * 255 << 16 ) + ( rgb[ 1 ] * 255 << 8 ) + rgb[ 2 ] * 255;
  3641. }
  3642. // defaults
  3643. var mtype = "MeshLambertMaterial";
  3644. var mpars = { color: 0xeeeeee, opacity: 1.0, map: null, lightMap: null, normalMap: null, wireframe: m.wireframe };
  3645. // parameters from model file
  3646. if ( m.shading ) {
  3647. var shading = m.shading.toLowerCase();
  3648. if ( shading === "phong" ) mtype = "MeshPhongMaterial";
  3649. else if ( shading === "basic" ) mtype = "MeshBasicMaterial";
  3650. }
  3651. if ( m.blending !== undefined && THREE[ m.blending ] !== undefined ) {
  3652. mpars.blending = THREE[ m.blending ];
  3653. }
  3654. if ( m.transparent !== undefined || m.opacity < 1.0 ) {
  3655. mpars.transparent = m.transparent;
  3656. }
  3657. if ( m.depthTest !== undefined ) {
  3658. mpars.depthTest = m.depthTest;
  3659. }
  3660. if ( m.depthWrite !== undefined ) {
  3661. mpars.depthWrite = m.depthWrite;
  3662. }
  3663. if ( m.vertexColors !== undefined ) {
  3664. if ( m.vertexColors == "face" ) {
  3665. mpars.vertexColors = THREE.FaceColors;
  3666. } else if ( m.vertexColors ) {
  3667. mpars.vertexColors = THREE.VertexColors;
  3668. }
  3669. }
  3670. // colors
  3671. if ( m.colorDiffuse ) {
  3672. mpars.color = rgb2hex( m.colorDiffuse );
  3673. } else if ( m.DbgColor ) {
  3674. mpars.color = m.DbgColor;
  3675. }
  3676. if ( m.colorSpecular ) {
  3677. mpars.specular = rgb2hex( m.colorSpecular );
  3678. }
  3679. if ( m.colorAmbient ) {
  3680. mpars.ambient = rgb2hex( m.colorAmbient );
  3681. }
  3682. // modifiers
  3683. if ( m.transparency ) {
  3684. mpars.opacity = m.transparency;
  3685. }
  3686. if ( m.specularCoef ) {
  3687. mpars.shininess = m.specularCoef;
  3688. }
  3689. // textures
  3690. if ( m.mapDiffuse && texturePath ) {
  3691. create_texture( mpars, "map", m.mapDiffuse, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap );
  3692. }
  3693. if ( m.mapLight && texturePath ) {
  3694. create_texture( mpars, "lightMap", m.mapLight, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap );
  3695. }
  3696. if ( m.mapNormal && texturePath ) {
  3697. create_texture( mpars, "normalMap", m.mapNormal, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap );
  3698. }
  3699. if ( m.mapSpecular && texturePath ) {
  3700. create_texture( mpars, "specularMap", m.mapSpecular, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap );
  3701. }
  3702. // special case for normal mapped material
  3703. if ( m.mapNormal ) {
  3704. var shader = THREE.ShaderUtils.lib[ "normal" ];
  3705. var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
  3706. uniforms[ "tNormal" ].texture = mpars.normalMap;
  3707. if ( m.mapNormalFactor ) {
  3708. uniforms[ "uNormalScale" ].value = m.mapNormalFactor;
  3709. }
  3710. if ( mpars.map ) {
  3711. uniforms[ "tDiffuse" ].texture = mpars.map;
  3712. uniforms[ "enableDiffuse" ].value = true;
  3713. }
  3714. if ( mpars.specularMap ) {
  3715. uniforms[ "tSpecular" ].texture = mpars.specularMap;
  3716. uniforms[ "enableSpecular" ].value = true;
  3717. }
  3718. if ( mpars.lightMap ) {
  3719. uniforms[ "tAO" ].texture = mpars.lightMap;
  3720. uniforms[ "enableAO" ].value = true;
  3721. }
  3722. // for the moment don't handle displacement texture
  3723. uniforms[ "uDiffuseColor" ].value.setHex( mpars.color );
  3724. uniforms[ "uSpecularColor" ].value.setHex( mpars.specular );
  3725. uniforms[ "uAmbientColor" ].value.setHex( mpars.ambient );
  3726. uniforms[ "uShininess" ].value = mpars.shininess;
  3727. if ( mpars.opacity !== undefined ) {
  3728. uniforms[ "uOpacity" ].value = mpars.opacity;
  3729. }
  3730. var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: true };
  3731. var material = new THREE.ShaderMaterial( parameters );
  3732. } else {
  3733. var material = new THREE[ mtype ]( mpars );
  3734. }
  3735. if ( m.DbgName !== undefined ) material.name = m.DbgName;
  3736. return material;
  3737. }
  3738. };
  3739. /**
  3740. * @author alteredq / http://alteredqualia.com/
  3741. */
  3742. THREE.BinaryLoader = function ( showStatus ) {
  3743. THREE.Loader.call( this, showStatus );
  3744. };
  3745. THREE.BinaryLoader.prototype = Object.create( THREE.Loader.prototype );
  3746. // Load models generated by slim OBJ converter with BINARY option (converter_obj_three_slim.py -t binary)
  3747. // - binary models consist of two files: JS and BIN
  3748. // - parameters
  3749. // - url (required)
  3750. // - callback (required)
  3751. // - texturePath (optional: if not specified, textures will be assumed to be in the same folder as JS model file)
  3752. // - binaryPath (optional: if not specified, binary file will be assumed to be in the same folder as JS model file)
  3753. THREE.BinaryLoader.prototype.load = function( url, callback, texturePath, binaryPath ) {
  3754. texturePath = texturePath ? texturePath : this.extractUrlBase( url );
  3755. binaryPath = binaryPath ? binaryPath : this.extractUrlBase( url );
  3756. var callbackProgress = this.showProgress ? THREE.Loader.prototype.updateProgress : null;
  3757. this.onLoadStart();
  3758. // #1 load JS part via web worker
  3759. this.loadAjaxJSON( this, url, callback, texturePath, binaryPath, callbackProgress );
  3760. };
  3761. THREE.BinaryLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, binaryPath, callbackProgress ) {
  3762. var xhr = new XMLHttpRequest();
  3763. xhr.onreadystatechange = function () {
  3764. if ( xhr.readyState == 4 ) {
  3765. if ( xhr.status == 200 || xhr.status == 0 ) {
  3766. var json = JSON.parse( xhr.responseText );
  3767. context.loadAjaxBuffers( json, callback, binaryPath, texturePath, callbackProgress );
  3768. } else {
  3769. console.error( "THREE.BinaryLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
  3770. }
  3771. }
  3772. };
  3773. xhr.open( "GET", url, true );
  3774. if ( xhr.overrideMimeType ) xhr.overrideMimeType( "text/plain; charset=x-user-defined" );
  3775. xhr.setRequestHeader( "Content-Type", "text/plain" );
  3776. xhr.send( null );
  3777. };
  3778. THREE.BinaryLoader.prototype.loadAjaxBuffers = function ( json, callback, binaryPath, texturePath, callbackProgress ) {
  3779. var xhr = new XMLHttpRequest(),
  3780. url = binaryPath + "/" + json.buffers;
  3781. var length = 0;
  3782. xhr.onreadystatechange = function () {
  3783. if ( xhr.readyState == 4 ) {
  3784. if ( xhr.status == 200 || xhr.status == 0 ) {
  3785. THREE.BinaryLoader.prototype.createBinModel( xhr.response, callback, texturePath, json.materials );
  3786. } else {
  3787. console.error( "THREE.BinaryLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
  3788. }
  3789. } else if ( xhr.readyState == 3 ) {
  3790. if ( callbackProgress ) {
  3791. if ( length == 0 ) {
  3792. length = xhr.getResponseHeader( "Content-Length" );
  3793. }
  3794. callbackProgress( { total: length, loaded: xhr.responseText.length } );
  3795. }
  3796. } else if ( xhr.readyState == 2 ) {
  3797. length = xhr.getResponseHeader( "Content-Length" );
  3798. }
  3799. };
  3800. xhr.open( "GET", url, true );
  3801. xhr.responseType = "arraybuffer";
  3802. xhr.send( null );
  3803. };
  3804. // Binary AJAX parser
  3805. THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texturePath, materials ) {
  3806. var Model = function ( texturePath ) {
  3807. var scope = this,
  3808. currentOffset = 0,
  3809. md,
  3810. normals = [],
  3811. uvs = [],
  3812. start_tri_flat, start_tri_smooth, start_tri_flat_uv, start_tri_smooth_uv,
  3813. start_quad_flat, start_quad_smooth, start_quad_flat_uv, start_quad_smooth_uv,
  3814. tri_size, quad_size,
  3815. len_tri_flat, len_tri_smooth, len_tri_flat_uv, len_tri_smooth_uv,
  3816. len_quad_flat, len_quad_smooth, len_quad_flat_uv, len_quad_smooth_uv;
  3817. THREE.Geometry.call( this );
  3818. THREE.Loader.prototype.initMaterials( scope, materials, texturePath );
  3819. md = parseMetaData( data, currentOffset );
  3820. currentOffset += md.header_bytes;
  3821. /*
  3822. md.vertex_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
  3823. md.material_index_bytes = Uint16Array.BYTES_PER_ELEMENT;
  3824. md.normal_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
  3825. md.uv_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
  3826. */
  3827. // buffers sizes
  3828. tri_size = md.vertex_index_bytes * 3 + md.material_index_bytes;
  3829. quad_size = md.vertex_index_bytes * 4 + md.material_index_bytes;
  3830. len_tri_flat = md.ntri_flat * ( tri_size );
  3831. len_tri_smooth = md.ntri_smooth * ( tri_size + md.normal_index_bytes * 3 );
  3832. len_tri_flat_uv = md.ntri_flat_uv * ( tri_size + md.uv_index_bytes * 3 );
  3833. len_tri_smooth_uv = md.ntri_smooth_uv * ( tri_size + md.normal_index_bytes * 3 + md.uv_index_bytes * 3 );
  3834. len_quad_flat = md.nquad_flat * ( quad_size );
  3835. len_quad_smooth = md.nquad_smooth * ( quad_size + md.normal_index_bytes * 4 );
  3836. len_quad_flat_uv = md.nquad_flat_uv * ( quad_size + md.uv_index_bytes * 4 );
  3837. len_quad_smooth_uv = md.nquad_smooth_uv * ( quad_size + md.normal_index_bytes * 4 + md.uv_index_bytes * 4 );
  3838. // read buffers
  3839. currentOffset += init_vertices( currentOffset );
  3840. currentOffset += init_normals( currentOffset );
  3841. currentOffset += handlePadding( md.nnormals * 3 );
  3842. currentOffset += init_uvs( currentOffset );
  3843. start_tri_flat = currentOffset;
  3844. start_tri_smooth = start_tri_flat + len_tri_flat + handlePadding( md.ntri_flat * 2 );
  3845. start_tri_flat_uv = start_tri_smooth + len_tri_smooth + handlePadding( md.ntri_smooth * 2 );
  3846. start_tri_smooth_uv = start_tri_flat_uv + len_tri_flat_uv + handlePadding( md.ntri_flat_uv * 2 );
  3847. start_quad_flat = start_tri_smooth_uv + len_tri_smooth_uv + handlePadding( md.ntri_smooth_uv * 2 );
  3848. start_quad_smooth = start_quad_flat + len_quad_flat + handlePadding( md.nquad_flat * 2 );
  3849. start_quad_flat_uv = start_quad_smooth + len_quad_smooth + handlePadding( md.nquad_smooth * 2 );
  3850. start_quad_smooth_uv= start_quad_flat_uv + len_quad_flat_uv + handlePadding( md.nquad_flat_uv * 2 );
  3851. // have to first process faces with uvs
  3852. // so that face and uv indices match
  3853. init_triangles_flat_uv( start_tri_flat_uv );
  3854. init_triangles_smooth_uv( start_tri_smooth_uv );
  3855. init_quads_flat_uv( start_quad_flat_uv );
  3856. init_quads_smooth_uv( start_quad_smooth_uv );
  3857. // now we can process untextured faces
  3858. init_triangles_flat( start_tri_flat );
  3859. init_triangles_smooth( start_tri_smooth );
  3860. init_quads_flat( start_quad_flat );
  3861. init_quads_smooth( start_quad_smooth );
  3862. this.computeCentroids();
  3863. this.computeFaceNormals();
  3864. if ( THREE.Loader.prototype.hasNormals( this ) ) this.computeTangents();
  3865. function handlePadding( n ) {
  3866. return ( n % 4 ) ? ( 4 - n % 4 ) : 0;
  3867. };
  3868. function parseMetaData( data, offset ) {
  3869. var metaData = {
  3870. 'signature' :parseString( data, offset, 12 ),
  3871. 'header_bytes' :parseUChar8( data, offset + 12 ),
  3872. 'vertex_coordinate_bytes' :parseUChar8( data, offset + 13 ),
  3873. 'normal_coordinate_bytes' :parseUChar8( data, offset + 14 ),
  3874. 'uv_coordinate_bytes' :parseUChar8( data, offset + 15 ),
  3875. 'vertex_index_bytes' :parseUChar8( data, offset + 16 ),
  3876. 'normal_index_bytes' :parseUChar8( data, offset + 17 ),
  3877. 'uv_index_bytes' :parseUChar8( data, offset + 18 ),
  3878. 'material_index_bytes' :parseUChar8( data, offset + 19 ),
  3879. 'nvertices' :parseUInt32( data, offset + 20 ),
  3880. 'nnormals' :parseUInt32( data, offset + 20 + 4*1 ),
  3881. 'nuvs' :parseUInt32( data, offset + 20 + 4*2 ),
  3882. 'ntri_flat' :parseUInt32( data, offset + 20 + 4*3 ),
  3883. 'ntri_smooth' :parseUInt32( data, offset + 20 + 4*4 ),
  3884. 'ntri_flat_uv' :parseUInt32( data, offset + 20 + 4*5 ),
  3885. 'ntri_smooth_uv' :parseUInt32( data, offset + 20 + 4*6 ),
  3886. 'nquad_flat' :parseUInt32( data, offset + 20 + 4*7 ),
  3887. 'nquad_smooth' :parseUInt32( data, offset + 20 + 4*8 ),
  3888. 'nquad_flat_uv' :parseUInt32( data, offset + 20 + 4*9 ),
  3889. 'nquad_smooth_uv' :parseUInt32( data, offset + 20 + 4*10 )
  3890. };
  3891. /*
  3892. console.log( "signature: " + metaData.signature );
  3893. console.log( "header_bytes: " + metaData.header_bytes );
  3894. console.log( "vertex_coordinate_bytes: " + metaData.vertex_coordinate_bytes );
  3895. console.log( "normal_coordinate_bytes: " + metaData.normal_coordinate_bytes );
  3896. console.log( "uv_coordinate_bytes: " + metaData.uv_coordinate_bytes );
  3897. console.log( "vertex_index_bytes: " + metaData.vertex_index_bytes );
  3898. console.log( "normal_index_bytes: " + metaData.normal_index_bytes );
  3899. console.log( "uv_index_bytes: " + metaData.uv_index_bytes );
  3900. console.log( "material_index_bytes: " + metaData.material_index_bytes );
  3901. console.log( "nvertices: " + metaData.nvertices );
  3902. console.log( "nnormals: " + metaData.nnormals );
  3903. console.log( "nuvs: " + metaData.nuvs );
  3904. console.log( "ntri_flat: " + metaData.ntri_flat );
  3905. console.log( "ntri_smooth: " + metaData.ntri_smooth );
  3906. console.log( "ntri_flat_uv: " + metaData.ntri_flat_uv );
  3907. console.log( "ntri_smooth_uv: " + metaData.ntri_smooth_uv );
  3908. console.log( "nquad_flat: " + metaData.nquad_flat );
  3909. console.log( "nquad_smooth: " + metaData.nquad_smooth );
  3910. console.log( "nquad_flat_uv: " + metaData.nquad_flat_uv );
  3911. console.log( "nquad_smooth_uv: " + metaData.nquad_smooth_uv );
  3912. var total = metaData.header_bytes
  3913. + metaData.nvertices * metaData.vertex_coordinate_bytes * 3
  3914. + metaData.nnormals * metaData.normal_coordinate_bytes * 3
  3915. + metaData.nuvs * metaData.uv_coordinate_bytes * 2
  3916. + metaData.ntri_flat * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes )
  3917. + metaData.ntri_smooth * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 )
  3918. + metaData.ntri_flat_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.uv_index_bytes*3 )
  3919. + metaData.ntri_smooth_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 + metaData.uv_index_bytes*3 )
  3920. + metaData.nquad_flat * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes )
  3921. + metaData.nquad_smooth * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 )
  3922. + metaData.nquad_flat_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.uv_index_bytes*4 )
  3923. + metaData.nquad_smooth_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 + metaData.uv_index_bytes*4 );
  3924. console.log( "total bytes: " + total );
  3925. */
  3926. return metaData;
  3927. };
  3928. function parseString( data, offset, length ) {
  3929. var charArray = new Uint8Array( data, offset, length );
  3930. var text = "";
  3931. for ( var i = 0; i < length; i ++ ) {
  3932. text += String.fromCharCode( charArray[ offset + i ] );
  3933. }
  3934. return text;
  3935. };
  3936. function parseUChar8( data, offset ) {
  3937. var charArray = new Uint8Array( data, offset, 1 );
  3938. return charArray[ 0 ];
  3939. };
  3940. function parseUInt32( data, offset ) {
  3941. var intArray = new Uint32Array( data, offset, 1 );
  3942. return intArray[ 0 ];
  3943. };
  3944. function init_vertices( start ) {
  3945. var nElements = md.nvertices;
  3946. var coordArray = new Float32Array( data, start, nElements * 3 );
  3947. var i, x, y, z;
  3948. for( i = 0; i < nElements; i ++ ) {
  3949. x = coordArray[ i * 3 ];
  3950. y = coordArray[ i * 3 + 1 ];
  3951. z = coordArray[ i * 3 + 2 ];
  3952. vertex( scope, x, y, z );
  3953. }
  3954. return nElements * 3 * Float32Array.BYTES_PER_ELEMENT;
  3955. };
  3956. function init_normals( start ) {
  3957. var nElements = md.nnormals;
  3958. if ( nElements ) {
  3959. var normalArray = new Int8Array( data, start, nElements * 3 );
  3960. var i, x, y, z;
  3961. for( i = 0; i < nElements; i ++ ) {
  3962. x = normalArray[ i * 3 ];
  3963. y = normalArray[ i * 3 + 1 ];
  3964. z = normalArray[ i * 3 + 2 ];
  3965. normals.push( x/127, y/127, z/127 );
  3966. }
  3967. }
  3968. return nElements * 3 * Int8Array.BYTES_PER_ELEMENT;
  3969. };
  3970. function init_uvs( start ) {
  3971. var nElements = md.nuvs;
  3972. if ( nElements ) {
  3973. var uvArray = new Float32Array( data, start, nElements * 2 );
  3974. var i, u, v;
  3975. for( i = 0; i < nElements; i ++ ) {
  3976. u = uvArray[ i * 2 ];
  3977. v = uvArray[ i * 2 + 1 ];
  3978. uvs.push( u, v );
  3979. }
  3980. }
  3981. return nElements * 2 * Float32Array.BYTES_PER_ELEMENT;
  3982. };
  3983. function init_uvs3( nElements, offset ) {
  3984. var i, uva, uvb, uvc, u1, u2, u3, v1, v2, v3;
  3985. var uvIndexBuffer = new Uint32Array( data, offset, 3 * nElements );
  3986. for( i = 0; i < nElements; i ++ ) {
  3987. uva = uvIndexBuffer[ i * 3 ];
  3988. uvb = uvIndexBuffer[ i * 3 + 1 ];
  3989. uvc = uvIndexBuffer[ i * 3 + 2 ];
  3990. u1 = uvs[ uva*2 ];
  3991. v1 = uvs[ uva*2 + 1 ];
  3992. u2 = uvs[ uvb*2 ];
  3993. v2 = uvs[ uvb*2 + 1 ];
  3994. u3 = uvs[ uvc*2 ];
  3995. v3 = uvs[ uvc*2 + 1 ];
  3996. uv3( scope.faceVertexUvs[ 0 ], u1, v1, u2, v2, u3, v3 );
  3997. }
  3998. };
  3999. function init_uvs4( nElements, offset ) {
  4000. var i, uva, uvb, uvc, uvd, u1, u2, u3, u4, v1, v2, v3, v4;
  4001. var uvIndexBuffer = new Uint32Array( data, offset, 4 * nElements );
  4002. for( i = 0; i < nElements; i ++ ) {
  4003. uva = uvIndexBuffer[ i * 4 ];
  4004. uvb = uvIndexBuffer[ i * 4 + 1 ];
  4005. uvc = uvIndexBuffer[ i * 4 + 2 ];
  4006. uvd = uvIndexBuffer[ i * 4 + 3 ];
  4007. u1 = uvs[ uva*2 ];
  4008. v1 = uvs[ uva*2 + 1 ];
  4009. u2 = uvs[ uvb*2 ];
  4010. v2 = uvs[ uvb*2 + 1 ];
  4011. u3 = uvs[ uvc*2 ];
  4012. v3 = uvs[ uvc*2 + 1 ];
  4013. u4 = uvs[ uvd*2 ];
  4014. v4 = uvs[ uvd*2 + 1 ];
  4015. uv4( scope.faceVertexUvs[ 0 ], u1, v1, u2, v2, u3, v3, u4, v4 );
  4016. }
  4017. };
  4018. function init_faces3_flat( nElements, offsetVertices, offsetMaterials ) {
  4019. var i, a, b, c, m;
  4020. var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
  4021. var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
  4022. for( i = 0; i < nElements; i ++ ) {
  4023. a = vertexIndexBuffer[ i * 3 ];
  4024. b = vertexIndexBuffer[ i * 3 + 1 ];
  4025. c = vertexIndexBuffer[ i * 3 + 2 ];
  4026. m = materialIndexBuffer[ i ];
  4027. f3( scope, a, b, c, m );
  4028. }
  4029. };
  4030. function init_faces4_flat( nElements, offsetVertices, offsetMaterials ) {
  4031. var i, a, b, c, d, m;
  4032. var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
  4033. var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
  4034. for( i = 0; i < nElements; i ++ ) {
  4035. a = vertexIndexBuffer[ i * 4 ];
  4036. b = vertexIndexBuffer[ i * 4 + 1 ];
  4037. c = vertexIndexBuffer[ i * 4 + 2 ];
  4038. d = vertexIndexBuffer[ i * 4 + 3 ];
  4039. m = materialIndexBuffer[ i ];
  4040. f4( scope, a, b, c, d, m );
  4041. }
  4042. };
  4043. function init_faces3_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
  4044. var i, a, b, c, m;
  4045. var na, nb, nc;
  4046. var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
  4047. var normalIndexBuffer = new Uint32Array( data, offsetNormals, 3 * nElements );
  4048. var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
  4049. for( i = 0; i < nElements; i ++ ) {
  4050. a = vertexIndexBuffer[ i * 3 ];
  4051. b = vertexIndexBuffer[ i * 3 + 1 ];
  4052. c = vertexIndexBuffer[ i * 3 + 2 ];
  4053. na = normalIndexBuffer[ i * 3 ];
  4054. nb = normalIndexBuffer[ i * 3 + 1 ];
  4055. nc = normalIndexBuffer[ i * 3 + 2 ];
  4056. m = materialIndexBuffer[ i ];
  4057. f3n( scope, normals, a, b, c, m, na, nb, nc );
  4058. }
  4059. };
  4060. function init_faces4_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
  4061. var i, a, b, c, d, m;
  4062. var na, nb, nc, nd;
  4063. var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
  4064. var normalIndexBuffer = new Uint32Array( data, offsetNormals, 4 * nElements );
  4065. var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
  4066. for( i = 0; i < nElements; i ++ ) {
  4067. a = vertexIndexBuffer[ i * 4 ];
  4068. b = vertexIndexBuffer[ i * 4 + 1 ];
  4069. c = vertexIndexBuffer[ i * 4 + 2 ];
  4070. d = vertexIndexBuffer[ i * 4 + 3 ];
  4071. na = normalIndexBuffer[ i * 4 ];
  4072. nb = normalIndexBuffer[ i * 4 + 1 ];
  4073. nc = normalIndexBuffer[ i * 4 + 2 ];
  4074. nd = normalIndexBuffer[ i * 4 + 3 ];
  4075. m = materialIndexBuffer[ i ];
  4076. f4n( scope, normals, a, b, c, d, m, na, nb, nc, nd );
  4077. }
  4078. };
  4079. function init_triangles_flat( start ) {
  4080. var nElements = md.ntri_flat;
  4081. if ( nElements ) {
  4082. var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  4083. init_faces3_flat( nElements, start, offsetMaterials );
  4084. }
  4085. };
  4086. function init_triangles_flat_uv( start ) {
  4087. var nElements = md.ntri_flat_uv;
  4088. if ( nElements ) {
  4089. var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  4090. var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  4091. init_faces3_flat( nElements, start, offsetMaterials );
  4092. init_uvs3( nElements, offsetUvs );
  4093. }
  4094. };
  4095. function init_triangles_smooth( start ) {
  4096. var nElements = md.ntri_smooth;
  4097. if ( nElements ) {
  4098. var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  4099. var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  4100. init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
  4101. }
  4102. };
  4103. function init_triangles_smooth_uv( start ) {
  4104. var nElements = md.ntri_smooth_uv;
  4105. if ( nElements ) {
  4106. var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  4107. var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  4108. var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
  4109. init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
  4110. init_uvs3( nElements, offsetUvs );
  4111. }
  4112. };
  4113. function init_quads_flat( start ) {
  4114. var nElements = md.nquad_flat;
  4115. if ( nElements ) {
  4116. var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  4117. init_faces4_flat( nElements, start, offsetMaterials );
  4118. }
  4119. };
  4120. function init_quads_flat_uv( start ) {
  4121. var nElements = md.nquad_flat_uv;
  4122. if ( nElements ) {
  4123. var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  4124. var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  4125. init_faces4_flat( nElements, start, offsetMaterials );
  4126. init_uvs4( nElements, offsetUvs );
  4127. }
  4128. };
  4129. function init_quads_smooth( start ) {
  4130. var nElements = md.nquad_smooth;
  4131. if ( nElements ) {
  4132. var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  4133. var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  4134. init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
  4135. }
  4136. };
  4137. function init_quads_smooth_uv( start ) {
  4138. var nElements = md.nquad_smooth_uv;
  4139. if ( nElements ) {
  4140. var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  4141. var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  4142. var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
  4143. init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
  4144. init_uvs4( nElements, offsetUvs );
  4145. }
  4146. };
  4147. };
  4148. function vertex ( scope, x, y, z ) {
  4149. scope.vertices.push( new THREE.Vector3( x, y, z ) );
  4150. };
  4151. function f3 ( scope, a, b, c, mi ) {
  4152. scope.faces.push( new THREE.Face3( a, b, c, null, null, mi ) );
  4153. };
  4154. function f4 ( scope, a, b, c, d, mi ) {
  4155. scope.faces.push( new THREE.Face4( a, b, c, d, null, null, mi ) );
  4156. };
  4157. function f3n ( scope, normals, a, b, c, mi, na, nb, nc ) {
  4158. var nax = normals[ na*3 ],
  4159. nay = normals[ na*3 + 1 ],
  4160. naz = normals[ na*3 + 2 ],
  4161. nbx = normals[ nb*3 ],
  4162. nby = normals[ nb*3 + 1 ],
  4163. nbz = normals[ nb*3 + 2 ],
  4164. ncx = normals[ nc*3 ],
  4165. ncy = normals[ nc*3 + 1 ],
  4166. ncz = normals[ nc*3 + 2 ];
  4167. scope.faces.push( new THREE.Face3( a, b, c,
  4168. [new THREE.Vector3( nax, nay, naz ),
  4169. new THREE.Vector3( nbx, nby, nbz ),
  4170. new THREE.Vector3( ncx, ncy, ncz )],
  4171. null,
  4172. mi ) );
  4173. };
  4174. function f4n ( scope, normals, a, b, c, d, mi, na, nb, nc, nd ) {
  4175. var nax = normals[ na*3 ],
  4176. nay = normals[ na*3 + 1 ],
  4177. naz = normals[ na*3 + 2 ],
  4178. nbx = normals[ nb*3 ],
  4179. nby = normals[ nb*3 + 1 ],
  4180. nbz = normals[ nb*3 + 2 ],
  4181. ncx = normals[ nc*3 ],
  4182. ncy = normals[ nc*3 + 1 ],
  4183. ncz = normals[ nc*3 + 2 ],
  4184. ndx = normals[ nd*3 ],
  4185. ndy = normals[ nd*3 + 1 ],
  4186. ndz = normals[ nd*3 + 2 ];
  4187. scope.faces.push( new THREE.Face4( a, b, c, d,
  4188. [new THREE.Vector3( nax, nay, naz ),
  4189. new THREE.Vector3( nbx, nby, nbz ),
  4190. new THREE.Vector3( ncx, ncy, ncz ),
  4191. new THREE.Vector3( ndx, ndy, ndz )],
  4192. null,
  4193. mi ) );
  4194. };
  4195. function uv3 ( where, u1, v1, u2, v2, u3, v3 ) {
  4196. var uv = [];
  4197. uv.push( new THREE.UV( u1, v1 ) );
  4198. uv.push( new THREE.UV( u2, v2 ) );
  4199. uv.push( new THREE.UV( u3, v3 ) );
  4200. where.push( uv );
  4201. };
  4202. function uv4 ( where, u1, v1, u2, v2, u3, v3, u4, v4 ) {
  4203. var uv = [];
  4204. uv.push( new THREE.UV( u1, v1 ) );
  4205. uv.push( new THREE.UV( u2, v2 ) );
  4206. uv.push( new THREE.UV( u3, v3 ) );
  4207. uv.push( new THREE.UV( u4, v4 ) );
  4208. where.push( uv );
  4209. };
  4210. Model.prototype = Object.create( THREE.Geometry.prototype );
  4211. callback( new Model( texturePath ) );
  4212. };
  4213. /**
  4214. * @author mrdoob / http://mrdoob.com/
  4215. */
  4216. THREE.ImageLoader = function () {
  4217. THREE.EventTarget.call( this );
  4218. this.crossOrigin = null;
  4219. };
  4220. THREE.ImageLoader.prototype = {
  4221. constructor: THREE.ImageLoader,
  4222. load: function ( url ) {
  4223. var scope = this;
  4224. var image = new Image();
  4225. image.addEventListener( 'load', function () {
  4226. scope.dispatchEvent( { type: 'load', content: image } );
  4227. }, false );
  4228. image.addEventListener( 'error', function () {
  4229. scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
  4230. }, false );
  4231. if ( scope.crossOrigin ) image.crossOrigin = scope.crossOrigin;
  4232. image.src = url;
  4233. }
  4234. }
  4235. /**
  4236. * @author mrdoob / http://mrdoob.com/
  4237. * @author alteredq / http://alteredqualia.com/
  4238. */
  4239. THREE.JSONLoader = function ( showStatus ) {
  4240. THREE.Loader.call( this, showStatus );
  4241. };
  4242. THREE.JSONLoader.prototype = Object.create( THREE.Loader.prototype );
  4243. THREE.JSONLoader.prototype.load = function ( url, callback, texturePath ) {
  4244. var scope = this;
  4245. texturePath = texturePath ? texturePath : this.extractUrlBase( url );
  4246. this.onLoadStart();
  4247. this.loadAjaxJSON( this, url, callback, texturePath );
  4248. };
  4249. THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, callbackProgress ) {
  4250. var xhr = new XMLHttpRequest();
  4251. var length = 0;
  4252. xhr.onreadystatechange = function () {
  4253. if ( xhr.readyState === xhr.DONE ) {
  4254. if ( xhr.status === 200 || xhr.status === 0 ) {
  4255. if ( xhr.responseText ) {
  4256. var json = JSON.parse( xhr.responseText );
  4257. context.createModel( json, callback, texturePath );
  4258. } else {
  4259. console.warn( "THREE.JSONLoader: [" + url + "] seems to be unreachable or file there is empty" );
  4260. }
  4261. // in context of more complex asset initialization
  4262. // do not block on single failed file
  4263. // maybe should go even one more level up
  4264. context.onLoadComplete();
  4265. } else {
  4266. console.error( "THREE.JSONLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
  4267. }
  4268. } else if ( xhr.readyState === xhr.LOADING ) {
  4269. if ( callbackProgress ) {
  4270. if ( length === 0 ) {
  4271. length = xhr.getResponseHeader( "Content-Length" );
  4272. }
  4273. callbackProgress( { total: length, loaded: xhr.responseText.length } );
  4274. }
  4275. } else if ( xhr.readyState === xhr.HEADERS_RECEIVED ) {
  4276. length = xhr.getResponseHeader( "Content-Length" );
  4277. }
  4278. };
  4279. xhr.open( "GET", url, true );
  4280. if ( xhr.overrideMimeType ) xhr.overrideMimeType( "text/plain; charset=x-user-defined" );
  4281. xhr.setRequestHeader( "Content-Type", "text/plain" );
  4282. xhr.send( null );
  4283. };
  4284. THREE.JSONLoader.prototype.createModel = function ( json, callback, texturePath ) {
  4285. var scope = this,
  4286. geometry = new THREE.Geometry(),
  4287. scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;
  4288. this.initMaterials( geometry, json.materials, texturePath );
  4289. parseModel( scale );
  4290. parseSkin();
  4291. parseMorphing( scale );
  4292. geometry.computeCentroids();
  4293. geometry.computeFaceNormals();
  4294. if ( this.hasNormals( geometry ) ) geometry.computeTangents();
  4295. function parseModel( scale ) {
  4296. function isBitSet( value, position ) {
  4297. return value & ( 1 << position );
  4298. }
  4299. var i, j, fi,
  4300. offset, zLength, nVertices,
  4301. colorIndex, normalIndex, uvIndex, materialIndex,
  4302. type,
  4303. isQuad,
  4304. hasMaterial,
  4305. hasFaceUv, hasFaceVertexUv,
  4306. hasFaceNormal, hasFaceVertexNormal,
  4307. hasFaceColor, hasFaceVertexColor,
  4308. vertex, face, color, normal,
  4309. uvLayer, uvs, u, v,
  4310. faces = json.faces,
  4311. vertices = json.vertices,
  4312. normals = json.normals,
  4313. colors = json.colors,
  4314. nUvLayers = 0;
  4315. // disregard empty arrays
  4316. for ( i = 0; i < json.uvs.length; i++ ) {
  4317. if ( json.uvs[ i ].length ) nUvLayers ++;
  4318. }
  4319. for ( i = 0; i < nUvLayers; i++ ) {
  4320. geometry.faceUvs[ i ] = [];
  4321. geometry.faceVertexUvs[ i ] = [];
  4322. }
  4323. offset = 0;
  4324. zLength = vertices.length;
  4325. while ( offset < zLength ) {
  4326. vertex = new THREE.Vector3();
  4327. vertex.x = vertices[ offset ++ ] * scale;
  4328. vertex.y = vertices[ offset ++ ] * scale;
  4329. vertex.z = vertices[ offset ++ ] * scale;
  4330. geometry.vertices.push( vertex );
  4331. }
  4332. offset = 0;
  4333. zLength = faces.length;
  4334. while ( offset < zLength ) {
  4335. type = faces[ offset ++ ];
  4336. isQuad = isBitSet( type, 0 );
  4337. hasMaterial = isBitSet( type, 1 );
  4338. hasFaceUv = isBitSet( type, 2 );
  4339. hasFaceVertexUv = isBitSet( type, 3 );
  4340. hasFaceNormal = isBitSet( type, 4 );
  4341. hasFaceVertexNormal = isBitSet( type, 5 );
  4342. hasFaceColor = isBitSet( type, 6 );
  4343. hasFaceVertexColor = isBitSet( type, 7 );
  4344. //console.log("type", type, "bits", isQuad, hasMaterial, hasFaceUv, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
  4345. if ( isQuad ) {
  4346. face = new THREE.Face4();
  4347. face.a = faces[ offset ++ ];
  4348. face.b = faces[ offset ++ ];
  4349. face.c = faces[ offset ++ ];
  4350. face.d = faces[ offset ++ ];
  4351. nVertices = 4;
  4352. } else {
  4353. face = new THREE.Face3();
  4354. face.a = faces[ offset ++ ];
  4355. face.b = faces[ offset ++ ];
  4356. face.c = faces[ offset ++ ];
  4357. nVertices = 3;
  4358. }
  4359. if ( hasMaterial ) {
  4360. materialIndex = faces[ offset ++ ];
  4361. face.materialIndex = materialIndex;
  4362. }
  4363. // to get face <=> uv index correspondence
  4364. fi = geometry.faces.length;
  4365. if ( hasFaceUv ) {
  4366. for ( i = 0; i < nUvLayers; i++ ) {
  4367. uvLayer = json.uvs[ i ];
  4368. uvIndex = faces[ offset ++ ];
  4369. u = uvLayer[ uvIndex * 2 ];
  4370. v = uvLayer[ uvIndex * 2 + 1 ];
  4371. geometry.faceUvs[ i ][ fi ] = new THREE.UV( u, v );
  4372. }
  4373. }
  4374. if ( hasFaceVertexUv ) {
  4375. for ( i = 0; i < nUvLayers; i++ ) {
  4376. uvLayer = json.uvs[ i ];
  4377. uvs = [];
  4378. for ( j = 0; j < nVertices; j ++ ) {
  4379. uvIndex = faces[ offset ++ ];
  4380. u = uvLayer[ uvIndex * 2 ];
  4381. v = uvLayer[ uvIndex * 2 + 1 ];
  4382. uvs[ j ] = new THREE.UV( u, v );
  4383. }
  4384. geometry.faceVertexUvs[ i ][ fi ] = uvs;
  4385. }
  4386. }
  4387. if ( hasFaceNormal ) {
  4388. normalIndex = faces[ offset ++ ] * 3;
  4389. normal = new THREE.Vector3();
  4390. normal.x = normals[ normalIndex ++ ];
  4391. normal.y = normals[ normalIndex ++ ];
  4392. normal.z = normals[ normalIndex ];
  4393. face.normal = normal;
  4394. }
  4395. if ( hasFaceVertexNormal ) {
  4396. for ( i = 0; i < nVertices; i++ ) {
  4397. normalIndex = faces[ offset ++ ] * 3;
  4398. normal = new THREE.Vector3();
  4399. normal.x = normals[ normalIndex ++ ];
  4400. normal.y = normals[ normalIndex ++ ];
  4401. normal.z = normals[ normalIndex ];
  4402. face.vertexNormals.push( normal );
  4403. }
  4404. }
  4405. if ( hasFaceColor ) {
  4406. colorIndex = faces[ offset ++ ];
  4407. color = new THREE.Color( colors[ colorIndex ] );
  4408. face.color = color;
  4409. }
  4410. if ( hasFaceVertexColor ) {
  4411. for ( i = 0; i < nVertices; i++ ) {
  4412. colorIndex = faces[ offset ++ ];
  4413. color = new THREE.Color( colors[ colorIndex ] );
  4414. face.vertexColors.push( color );
  4415. }
  4416. }
  4417. geometry.faces.push( face );
  4418. }
  4419. };
  4420. function parseSkin() {
  4421. var i, l, x, y, z, w, a, b, c, d;
  4422. if ( json.skinWeights ) {
  4423. for ( i = 0, l = json.skinWeights.length; i < l; i += 2 ) {
  4424. x = json.skinWeights[ i ];
  4425. y = json.skinWeights[ i + 1 ];
  4426. z = 0;
  4427. w = 0;
  4428. geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );
  4429. }
  4430. }
  4431. if ( json.skinIndices ) {
  4432. for ( i = 0, l = json.skinIndices.length; i < l; i += 2 ) {
  4433. a = json.skinIndices[ i ];
  4434. b = json.skinIndices[ i + 1 ];
  4435. c = 0;
  4436. d = 0;
  4437. geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );
  4438. }
  4439. }
  4440. geometry.bones = json.bones;
  4441. geometry.animation = json.animation;
  4442. };
  4443. function parseMorphing( scale ) {
  4444. if ( json.morphTargets !== undefined ) {
  4445. var i, l, v, vl, dstVertices, srcVertices;
  4446. for ( i = 0, l = json.morphTargets.length; i < l; i ++ ) {
  4447. geometry.morphTargets[ i ] = {};
  4448. geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
  4449. geometry.morphTargets[ i ].vertices = [];
  4450. dstVertices = geometry.morphTargets[ i ].vertices;
  4451. srcVertices = json.morphTargets [ i ].vertices;
  4452. for( v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
  4453. var vertex = new THREE.Vector3();
  4454. vertex.x = srcVertices[ v ] * scale;
  4455. vertex.y = srcVertices[ v + 1 ] * scale;
  4456. vertex.z = srcVertices[ v + 2 ] * scale;
  4457. dstVertices.push( vertex );
  4458. }
  4459. }
  4460. }
  4461. if ( json.morphColors !== undefined ) {
  4462. var i, l, c, cl, dstColors, srcColors, color;
  4463. for ( i = 0, l = json.morphColors.length; i < l; i++ ) {
  4464. geometry.morphColors[ i ] = {};
  4465. geometry.morphColors[ i ].name = json.morphColors[ i ].name;
  4466. geometry.morphColors[ i ].colors = [];
  4467. dstColors = geometry.morphColors[ i ].colors;
  4468. srcColors = json.morphColors [ i ].colors;
  4469. for ( c = 0, cl = srcColors.length; c < cl; c += 3 ) {
  4470. color = new THREE.Color( 0xffaa00 );
  4471. color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
  4472. dstColors.push( color );
  4473. }
  4474. }
  4475. }
  4476. };
  4477. callback( geometry );
  4478. };
  4479. /**
  4480. * @author mrdoob / http://mrdoob.com/
  4481. * @author alteredq / http://alteredqualia.com/
  4482. */
  4483. THREE.GeometryLoader = function () {
  4484. THREE.EventTarget.call( this );
  4485. this.crossOrigin = null;
  4486. this.path = null;
  4487. };
  4488. THREE.GeometryLoader.prototype = {
  4489. constructor: THREE.GeometryLoader,
  4490. load: function ( url ) {
  4491. var scope = this;
  4492. var geometry = null;
  4493. if ( scope.path === null ) {
  4494. var parts = url.split( '/' ); parts.pop();
  4495. scope.path = ( parts.length < 1 ? '.' : parts.join( '/' ) );
  4496. }
  4497. //
  4498. var xhr = new XMLHttpRequest();
  4499. xhr.addEventListener( 'load', function ( event ) {
  4500. if ( event.target.responseText ) {
  4501. geometry = scope.parse( JSON.parse( event.target.responseText ), monitor );
  4502. } else {
  4503. scope.dispatchEvent( { type: 'error', message: 'Invalid file [' + url + ']' } );
  4504. }
  4505. }, false );
  4506. xhr.addEventListener( 'error', function () {
  4507. scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
  4508. }, false );
  4509. xhr.open( 'GET', url, true );
  4510. xhr.send( null );
  4511. //
  4512. var monitor = new THREE.LoadingMonitor();
  4513. monitor.addEventListener( 'load', function ( event ) {
  4514. scope.dispatchEvent( { type: 'load', content: geometry } );
  4515. } );
  4516. monitor.add( xhr );
  4517. },
  4518. parse: function ( data, monitor ) {
  4519. var scope = this;
  4520. var geometry = new THREE.Geometry();
  4521. var scale = ( data.scale !== undefined ) ? 1 / data.scale : 1;
  4522. // materials
  4523. if ( data.materials ) {
  4524. geometry.materials = [];
  4525. for ( var i = 0; i < data.materials.length; ++ i ) {
  4526. var m = data.materials[ i ];
  4527. function isPow2( n ) {
  4528. var l = Math.log( n ) / Math.LN2;
  4529. return Math.floor( l ) == l;
  4530. }
  4531. function nearestPow2( n ) {
  4532. var l = Math.log( n ) / Math.LN2;
  4533. return Math.pow( 2, Math.round( l ) );
  4534. }
  4535. function createTexture( where, name, sourceFile, repeat, offset, wrap ) {
  4536. where[ name ] = new THREE.Texture();
  4537. where[ name ].sourceFile = sourceFile;
  4538. if ( repeat ) {
  4539. where[ name ].repeat.set( repeat[ 0 ], repeat[ 1 ] );
  4540. if ( repeat[ 0 ] != 1 ) where[ name ].wrapS = THREE.RepeatWrapping;
  4541. if ( repeat[ 1 ] != 1 ) where[ name ].wrapT = THREE.RepeatWrapping;
  4542. }
  4543. if ( offset ) {
  4544. where[ name ].offset.set( offset[ 0 ], offset[ 1 ] );
  4545. }
  4546. if ( wrap ) {
  4547. var wrapMap = {
  4548. "repeat": THREE.RepeatWrapping,
  4549. "mirror": THREE.MirroredRepeatWrapping
  4550. }
  4551. if ( wrapMap[ wrap[ 0 ] ] !== undefined ) where[ name ].wrapS = wrapMap[ wrap[ 0 ] ];
  4552. if ( wrapMap[ wrap[ 1 ] ] !== undefined ) where[ name ].wrapT = wrapMap[ wrap[ 1 ] ];
  4553. }
  4554. // load image
  4555. var texture = where[ name ];
  4556. var loader = new THREE.ImageLoader();
  4557. loader.addEventListener( 'load', function ( event ) {
  4558. var image = event.content;
  4559. if ( !isPow2( image.width ) || !isPow2( image.height ) ) {
  4560. var width = nearestPow2( image.width );
  4561. var height = nearestPow2( image.height );
  4562. texture.image = document.createElement( 'canvas' );
  4563. texture.image.width = width;
  4564. texture.image.height = height;
  4565. texture.image.getContext( '2d' ).drawImage( image, 0, 0, width, height );
  4566. } else {
  4567. texture.image = image;
  4568. }
  4569. texture.needsUpdate = true;
  4570. } );
  4571. loader.crossOrigin = scope.crossOrigin;
  4572. loader.load( scope.path + '/' + sourceFile );
  4573. if ( monitor ) monitor.add( loader );
  4574. }
  4575. function rgb2hex( rgb ) {
  4576. return ( rgb[ 0 ] * 255 << 16 ) + ( rgb[ 1 ] * 255 << 8 ) + rgb[ 2 ] * 255;
  4577. }
  4578. // defaults
  4579. var mtype = "MeshLambertMaterial";
  4580. var mpars = { color: 0xeeeeee, opacity: 1.0, map: null, lightMap: null, normalMap: null, wireframe: m.wireframe };
  4581. // parameters from model file
  4582. if ( m.shading ) {
  4583. var shading = m.shading.toLowerCase();
  4584. if ( shading === "phong" ) mtype = "MeshPhongMaterial";
  4585. else if ( shading === "basic" ) mtype = "MeshBasicMaterial";
  4586. }
  4587. if ( m.blending !== undefined && THREE[ m.blending ] !== undefined ) {
  4588. mpars.blending = THREE[ m.blending ];
  4589. }
  4590. if ( m.transparent !== undefined || m.opacity < 1.0 ) {
  4591. mpars.transparent = m.transparent;
  4592. }
  4593. if ( m.depthTest !== undefined ) {
  4594. mpars.depthTest = m.depthTest;
  4595. }
  4596. if ( m.depthWrite !== undefined ) {
  4597. mpars.depthWrite = m.depthWrite;
  4598. }
  4599. if ( m.vertexColors !== undefined ) {
  4600. if ( m.vertexColors == "face" ) {
  4601. mpars.vertexColors = THREE.FaceColors;
  4602. } else if ( m.vertexColors ) {
  4603. mpars.vertexColors = THREE.VertexColors;
  4604. }
  4605. }
  4606. // colors
  4607. if ( m.colorDiffuse ) {
  4608. mpars.color = rgb2hex( m.colorDiffuse );
  4609. } else if ( m.DbgColor ) {
  4610. mpars.color = m.DbgColor;
  4611. }
  4612. if ( m.colorSpecular ) {
  4613. mpars.specular = rgb2hex( m.colorSpecular );
  4614. }
  4615. if ( m.colorAmbient ) {
  4616. mpars.ambient = rgb2hex( m.colorAmbient );
  4617. }
  4618. // modifiers
  4619. if ( m.transparency ) {
  4620. mpars.opacity = m.transparency;
  4621. }
  4622. if ( m.specularCoef ) {
  4623. mpars.shininess = m.specularCoef;
  4624. }
  4625. // textures
  4626. if ( m.mapDiffuse ) {
  4627. createTexture( mpars, "map", m.mapDiffuse, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap );
  4628. }
  4629. if ( m.mapLight ) {
  4630. createTexture( mpars, "lightMap", m.mapLight, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap );
  4631. }
  4632. if ( m.mapNormal ) {
  4633. createTexture( mpars, "normalMap", m.mapNormal, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap );
  4634. }
  4635. if ( m.mapSpecular ) {
  4636. createTexture( mpars, "specularMap", m.mapSpecular, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap );
  4637. }
  4638. // special case for normal mapped material
  4639. if ( m.mapNormal ) {
  4640. var shader = THREE.ShaderUtils.lib[ "normal" ];
  4641. var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
  4642. uniforms[ "tNormal" ].texture = mpars.normalMap;
  4643. if ( m.mapNormalFactor ) {
  4644. uniforms[ "uNormalScale" ].value = m.mapNormalFactor;
  4645. }
  4646. if ( mpars.map ) {
  4647. uniforms[ "tDiffuse" ].texture = mpars.map;
  4648. uniforms[ "enableDiffuse" ].value = true;
  4649. }
  4650. if ( mpars.specularMap ) {
  4651. uniforms[ "tSpecular" ].texture = mpars.specularMap;
  4652. uniforms[ "enableSpecular" ].value = true;
  4653. }
  4654. if ( mpars.lightMap ) {
  4655. uniforms[ "tAO" ].texture = mpars.lightMap;
  4656. uniforms[ "enableAO" ].value = true;
  4657. }
  4658. // for the moment don't handle displacement texture
  4659. uniforms[ "uDiffuseColor" ].value.setHex( mpars.color );
  4660. uniforms[ "uSpecularColor" ].value.setHex( mpars.specular );
  4661. uniforms[ "uAmbientColor" ].value.setHex( mpars.ambient );
  4662. uniforms[ "uShininess" ].value = mpars.shininess;
  4663. if ( mpars.opacity !== undefined ) {
  4664. uniforms[ "uOpacity" ].value = mpars.opacity;
  4665. }
  4666. var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: true };
  4667. var material = new THREE.ShaderMaterial( parameters );
  4668. } else {
  4669. var material = new THREE[ mtype ]( mpars );
  4670. }
  4671. if ( m.DbgName !== undefined ) material.name = m.DbgName;
  4672. geometry.materials[ i ] = material;
  4673. }
  4674. }
  4675. // geometry
  4676. function isBitSet( value, position ) {
  4677. return value & ( 1 << position );
  4678. }
  4679. var faces = data.faces;
  4680. var vertices = data.vertices;
  4681. var normals = data.normals;
  4682. var colors = data.colors;
  4683. var nUvLayers = 0;
  4684. // disregard empty arrays
  4685. if ( data.uvs ) {
  4686. for ( var i = 0; i < data.uvs.length; i ++ ) {
  4687. if ( data.uvs[ i ].length ) nUvLayers ++;
  4688. }
  4689. }
  4690. for ( var i = 0; i < nUvLayers; i ++ ) {
  4691. geometry.faceUvs[ i ] = [];
  4692. geometry.faceVertexUvs[ i ] = [];
  4693. }
  4694. var offset = 0;
  4695. var zLength = vertices.length;
  4696. while ( offset < zLength ) {
  4697. var vertex = new THREE.Vector3();
  4698. vertex.x = vertices[ offset ++ ] * scale;
  4699. vertex.y = vertices[ offset ++ ] * scale;
  4700. vertex.z = vertices[ offset ++ ] * scale;
  4701. geometry.vertices.push( vertex );
  4702. }
  4703. offset = 0;
  4704. zLength = faces.length;
  4705. while ( offset < zLength ) {
  4706. var type = faces[ offset ++ ];
  4707. var isQuad = isBitSet( type, 0 );
  4708. var hasMaterial = isBitSet( type, 1 );
  4709. var hasFaceUv = isBitSet( type, 2 );
  4710. var hasFaceVertexUv = isBitSet( type, 3 );
  4711. var hasFaceNormal = isBitSet( type, 4 );
  4712. var hasFaceVertexNormal = isBitSet( type, 5 );
  4713. var hasFaceColor = isBitSet( type, 6 );
  4714. var hasFaceVertexColor = isBitSet( type, 7 );
  4715. // console.log("type", type, "bits", isQuad, hasMaterial, hasFaceUv, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
  4716. if ( isQuad ) {
  4717. var face = new THREE.Face4();
  4718. face.a = faces[ offset ++ ];
  4719. face.b = faces[ offset ++ ];
  4720. face.c = faces[ offset ++ ];
  4721. face.d = faces[ offset ++ ];
  4722. var nVertices = 4;
  4723. } else {
  4724. var face = new THREE.Face3();
  4725. face.a = faces[ offset ++ ];
  4726. face.b = faces[ offset ++ ];
  4727. face.c = faces[ offset ++ ];
  4728. var nVertices = 3;
  4729. }
  4730. if ( hasMaterial ) {
  4731. var materialIndex = faces[ offset ++ ];
  4732. face.materialIndex = materialIndex;
  4733. }
  4734. // to get face <=> uv index correspondence
  4735. var fi = geometry.faces.length;
  4736. if ( hasFaceUv ) {
  4737. for ( var i = 0; i < nUvLayers; i ++ ) {
  4738. var uvLayer = data.uvs[ i ];
  4739. var uvIndex = faces[ offset ++ ];
  4740. var u = uvLayer[ uvIndex * 2 ];
  4741. var v = uvLayer[ uvIndex * 2 + 1 ];
  4742. geometry.faceUvs[ i ][ fi ] = new THREE.UV( u, v );
  4743. }
  4744. }
  4745. if ( hasFaceVertexUv ) {
  4746. for ( var i = 0; i < nUvLayers; i ++ ) {
  4747. var uvLayer = data.uvs[ i ];
  4748. var uvs = [];
  4749. for ( var j = 0; j < nVertices; j ++ ) {
  4750. var uvIndex = faces[ offset ++ ];
  4751. var u = uvLayer[ uvIndex * 2 ];
  4752. var v = uvLayer[ uvIndex * 2 + 1 ];
  4753. uvs[ j ] = new THREE.UV( u, v );
  4754. }
  4755. geometry.faceVertexUvs[ i ][ fi ] = uvs;
  4756. }
  4757. }
  4758. if ( hasFaceNormal ) {
  4759. var normalIndex = faces[ offset ++ ] * 3;
  4760. var normal = new THREE.Vector3();
  4761. normal.x = normals[ normalIndex ++ ];
  4762. normal.y = normals[ normalIndex ++ ];
  4763. normal.z = normals[ normalIndex ];
  4764. face.normal = normal;
  4765. }
  4766. if ( hasFaceVertexNormal ) {
  4767. for ( i = 0; i < nVertices; i ++ ) {
  4768. var normalIndex = faces[ offset ++ ] * 3;
  4769. var normal = new THREE.Vector3();
  4770. normal.x = normals[ normalIndex ++ ];
  4771. normal.y = normals[ normalIndex ++ ];
  4772. normal.z = normals[ normalIndex ];
  4773. face.vertexNormals.push( normal );
  4774. }
  4775. }
  4776. if ( hasFaceColor ) {
  4777. var colorIndex = faces[ offset ++ ];
  4778. face.color = new THREE.Color( colors[ colorIndex ] );
  4779. }
  4780. if ( hasFaceVertexColor ) {
  4781. for ( var i = 0; i < nVertices; i ++ ) {
  4782. var colorIndex = faces[ offset ++ ];
  4783. face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) );
  4784. }
  4785. }
  4786. geometry.faces.push( face );
  4787. }
  4788. // skin
  4789. if ( data.skinWeights ) {
  4790. for ( var i = 0, l = data.skinWeights.length; i < l; i += 2 ) {
  4791. var x = data.skinWeights[ i ];
  4792. var y = data.skinWeights[ i + 1 ];
  4793. var z = 0;
  4794. var w = 0;
  4795. geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );
  4796. }
  4797. }
  4798. if ( data.skinIndices ) {
  4799. for ( var i = 0, l = data.skinIndices.length; i < l; i += 2 ) {
  4800. var a = data.skinIndices[ i ];
  4801. var b = data.skinIndices[ i + 1 ];
  4802. var c = 0;
  4803. var d = 0;
  4804. geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );
  4805. }
  4806. }
  4807. geometry.bones = data.bones;
  4808. geometry.animation = data.animation;
  4809. // morphing
  4810. if ( data.morphTargets ) {
  4811. for ( var i = 0, l = data.morphTargets.length; i < l; i ++ ) {
  4812. geometry.morphTargets[ i ] = {};
  4813. geometry.morphTargets[ i ].name = data.morphTargets[ i ].name;
  4814. geometry.morphTargets[ i ].vertices = [];
  4815. var dstVertices = geometry.morphTargets[ i ].vertices;
  4816. var srcVertices = data.morphTargets [ i ].vertices;
  4817. for( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
  4818. var vertex = new THREE.Vector3();
  4819. vertex.x = srcVertices[ v ] * scale;
  4820. vertex.y = srcVertices[ v + 1 ] * scale;
  4821. vertex.z = srcVertices[ v + 2 ] * scale;
  4822. dstVertices.push( vertex );
  4823. }
  4824. }
  4825. }
  4826. if ( data.morphColors ) {
  4827. for ( var i = 0, l = data.morphColors.length; i < l; i++ ) {
  4828. geometry.morphColors[ i ] = {};
  4829. geometry.morphColors[ i ].name = data.morphColors[ i ].name;
  4830. geometry.morphColors[ i ].colors = [];
  4831. var dstColors = geometry.morphColors[ i ].colors;
  4832. var srcColors = data.morphColors [ i ].colors;
  4833. for ( var c = 0, cl = srcColors.length; c < cl; c += 3 ) {
  4834. var color = new THREE.Color( 0xffaa00 );
  4835. color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
  4836. dstColors.push( color );
  4837. }
  4838. }
  4839. }
  4840. geometry.computeCentroids();
  4841. geometry.computeFaceNormals();
  4842. return geometry;
  4843. }
  4844. };
  4845. /**
  4846. * @author alteredq / http://alteredqualia.com/
  4847. */
  4848. THREE.SceneLoader = function () {
  4849. this.onLoadStart = function () {};
  4850. this.onLoadProgress = function() {};
  4851. this.onLoadComplete = function () {};
  4852. this.callbackSync = function () {};
  4853. this.callbackProgress = function () {};
  4854. };
  4855. THREE.SceneLoader.prototype.constructor = THREE.SceneLoader;
  4856. THREE.SceneLoader.prototype.load = function( url, callbackFinished ) {
  4857. var context = this;
  4858. var xhr = new XMLHttpRequest();
  4859. xhr.onreadystatechange = function () {
  4860. if ( xhr.readyState === 4 ) {
  4861. if ( xhr.status === 200 || xhr.status === 0 ) {
  4862. var json = JSON.parse( xhr.responseText );
  4863. context.createScene( json, callbackFinished, url );
  4864. } else {
  4865. console.error( "THREE.SceneLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
  4866. }
  4867. }
  4868. };
  4869. xhr.open( "GET", url, true );
  4870. if ( xhr.overrideMimeType ) xhr.overrideMimeType( "text/plain; charset=x-user-defined" );
  4871. xhr.setRequestHeader( "Content-Type", "text/plain" );
  4872. xhr.send( null );
  4873. };
  4874. THREE.SceneLoader.prototype.createScene = function ( json, callbackFinished, url ) {
  4875. var scope = this;
  4876. var urlBase = THREE.Loader.prototype.extractUrlBase( url );
  4877. var dg, dm, dd, dl, dc, df, dt,
  4878. g, o, m, l, d, p, r, q, s, c, t, f, tt, pp, u,
  4879. geometry, material, camera, fog,
  4880. texture, images,
  4881. light,
  4882. data, binLoader, jsonLoader,
  4883. counter_models, counter_textures,
  4884. total_models, total_textures,
  4885. result;
  4886. data = json;
  4887. binLoader = new THREE.BinaryLoader();
  4888. jsonLoader = new THREE.JSONLoader();
  4889. counter_models = 0;
  4890. counter_textures = 0;
  4891. result = {
  4892. scene: new THREE.Scene(),
  4893. geometries: {},
  4894. materials: {},
  4895. textures: {},
  4896. objects: {},
  4897. cameras: {},
  4898. lights: {},
  4899. fogs: {},
  4900. empties: {}
  4901. };
  4902. if ( data.transform ) {
  4903. var position = data.transform.position,
  4904. rotation = data.transform.rotation,
  4905. scale = data.transform.scale;
  4906. if ( position )
  4907. result.scene.position.set( position[ 0 ], position[ 1 ], position [ 2 ] );
  4908. if ( rotation )
  4909. result.scene.rotation.set( rotation[ 0 ], rotation[ 1 ], rotation [ 2 ] );
  4910. if ( scale )
  4911. result.scene.scale.set( scale[ 0 ], scale[ 1 ], scale [ 2 ] );
  4912. if ( position || rotation || scale ) {
  4913. result.scene.updateMatrix();
  4914. result.scene.updateMatrixWorld();
  4915. }
  4916. }
  4917. function get_url( source_url, url_type ) {
  4918. if ( url_type == "relativeToHTML" ) {
  4919. return source_url;
  4920. } else {
  4921. return urlBase + "/" + source_url;
  4922. }
  4923. };
  4924. function handle_objects() {
  4925. var object;
  4926. for( dd in data.objects ) {
  4927. if ( !result.objects[ dd ] ) {
  4928. o = data.objects[ dd ];
  4929. if ( o.geometry !== undefined ) {
  4930. geometry = result.geometries[ o.geometry ];
  4931. // geometry already loaded
  4932. if ( geometry ) {
  4933. var hasNormals = false;
  4934. // not anymore support for multiple materials
  4935. // shouldn't really be array
  4936. material = result.materials[ o.materials[ 0 ] ];
  4937. hasNormals = material instanceof THREE.ShaderMaterial;
  4938. if ( hasNormals ) {
  4939. geometry.computeTangents();
  4940. }
  4941. p = o.position;
  4942. r = o.rotation;
  4943. q = o.quaternion;
  4944. s = o.scale;
  4945. m = o.matrix;
  4946. // turn off quaternions, for the moment
  4947. q = 0;
  4948. if ( o.materials.length == 0 ) {
  4949. material = new THREE.MeshFaceMaterial();
  4950. }
  4951. // dirty hack to handle meshes with multiple materials
  4952. // just use face materials defined in model
  4953. if ( o.materials.length > 1 ) {
  4954. material = new THREE.MeshFaceMaterial();
  4955. }
  4956. object = new THREE.Mesh( geometry, material );
  4957. object.name = dd;
  4958. if ( m ) {
  4959. object.matrixAutoUpdate = false;
  4960. object.matrix.set( m[0], m[1], m[2], m[3],
  4961. m[4], m[5], m[6], m[7],
  4962. m[8], m[9], m[10], m[11],
  4963. m[12], m[13], m[14], m[15]);
  4964. } else {
  4965. object.position.set( p[0], p[1], p[2] );
  4966. if ( q ) {
  4967. object.quaternion.set( q[0], q[1], q[2], q[3] );
  4968. object.useQuaternion = true;
  4969. } else {
  4970. object.rotation.set( r[0], r[1], r[2] );
  4971. }
  4972. object.scale.set( s[0], s[1], s[2] );
  4973. }
  4974. object.visible = o.visible;
  4975. object.doubleSided = o.doubleSided;
  4976. object.castShadow = o.castShadow;
  4977. object.receiveShadow = o.receiveShadow;
  4978. result.scene.add( object );
  4979. result.objects[ dd ] = object;
  4980. }
  4981. // pure Object3D
  4982. } else {
  4983. p = o.position;
  4984. r = o.rotation;
  4985. q = o.quaternion;
  4986. s = o.scale;
  4987. // turn off quaternions, for the moment
  4988. q = 0;
  4989. object = new THREE.Object3D();
  4990. object.name = dd;
  4991. object.position.set( p[0], p[1], p[2] );
  4992. if ( q ) {
  4993. object.quaternion.set( q[0], q[1], q[2], q[3] );
  4994. object.useQuaternion = true;
  4995. } else {
  4996. object.rotation.set( r[0], r[1], r[2] );
  4997. }
  4998. object.scale.set( s[0], s[1], s[2] );
  4999. object.visible = ( o.visible !== undefined ) ? o.visible : false;
  5000. result.scene.add( object );
  5001. result.objects[ dd ] = object;
  5002. result.empties[ dd ] = object;
  5003. }
  5004. }
  5005. }
  5006. };
  5007. function handle_mesh( geo, id ) {
  5008. result.geometries[ id ] = geo;
  5009. handle_objects();
  5010. };
  5011. function create_callback( id ) {
  5012. return function( geo ) {
  5013. handle_mesh( geo, id );
  5014. counter_models -= 1;
  5015. scope.onLoadComplete();
  5016. async_callback_gate();
  5017. }
  5018. };
  5019. function create_callback_embed( id ) {
  5020. return function( geo ) {
  5021. result.geometries[ id ] = geo;
  5022. }
  5023. };
  5024. function async_callback_gate() {
  5025. var progress = {
  5026. totalModels : total_models,
  5027. totalTextures : total_textures,
  5028. loadedModels : total_models - counter_models,
  5029. loadedTextures : total_textures - counter_textures
  5030. };
  5031. scope.callbackProgress( progress, result );
  5032. scope.onLoadProgress();
  5033. if( counter_models === 0 && counter_textures === 0 ) {
  5034. callbackFinished( result );
  5035. }
  5036. };
  5037. var callbackTexture = function ( count ) {
  5038. counter_textures -= count;
  5039. async_callback_gate();
  5040. scope.onLoadComplete();
  5041. };
  5042. // must use this instead of just directly calling callbackTexture
  5043. // because of closure in the calling context loop
  5044. var generateTextureCallback = function ( count ) {
  5045. return function() {
  5046. callbackTexture( count );
  5047. };
  5048. };
  5049. // first go synchronous elements
  5050. // cameras
  5051. for( dc in data.cameras ) {
  5052. c = data.cameras[ dc ];
  5053. if ( c.type === "perspective" ) {
  5054. camera = new THREE.PerspectiveCamera( c.fov, c.aspect, c.near, c.far );
  5055. } else if ( c.type === "ortho" ) {
  5056. camera = new THREE.OrthographicCamera( c.left, c.right, c.top, c.bottom, c.near, c.far );
  5057. }
  5058. p = c.position;
  5059. t = c.target;
  5060. u = c.up;
  5061. camera.position.set( p[0], p[1], p[2] );
  5062. camera.target = new THREE.Vector3( t[0], t[1], t[2] );
  5063. if ( u ) camera.up.set( u[0], u[1], u[2] );
  5064. result.cameras[ dc ] = camera;
  5065. }
  5066. // lights
  5067. var hex, intensity;
  5068. for ( dl in data.lights ) {
  5069. l = data.lights[ dl ];
  5070. hex = ( l.color !== undefined ) ? l.color : 0xffffff;
  5071. intensity = ( l.intensity !== undefined ) ? l.intensity : 1;
  5072. if ( l.type === "directional" ) {
  5073. p = l.direction;
  5074. light = new THREE.DirectionalLight( hex, intensity );
  5075. light.position.set( p[0], p[1], p[2] );
  5076. light.position.normalize();
  5077. } else if ( l.type === "point" ) {
  5078. p = l.position;
  5079. d = l.distance;
  5080. light = new THREE.PointLight( hex, intensity, d );
  5081. light.position.set( p[0], p[1], p[2] );
  5082. } else if ( l.type === "ambient" ) {
  5083. light = new THREE.AmbientLight( hex );
  5084. }
  5085. result.scene.add( light );
  5086. result.lights[ dl ] = light;
  5087. }
  5088. // fogs
  5089. for( df in data.fogs ) {
  5090. f = data.fogs[ df ];
  5091. if ( f.type === "linear" ) {
  5092. fog = new THREE.Fog( 0x000000, f.near, f.far );
  5093. } else if ( f.type === "exp2" ) {
  5094. fog = new THREE.FogExp2( 0x000000, f.density );
  5095. }
  5096. c = f.color;
  5097. fog.color.setRGB( c[0], c[1], c[2] );
  5098. result.fogs[ df ] = fog;
  5099. }
  5100. // defaults
  5101. if ( result.cameras && data.defaults.camera ) {
  5102. result.currentCamera = result.cameras[ data.defaults.camera ];
  5103. }
  5104. if ( result.fogs && data.defaults.fog ) {
  5105. result.scene.fog = result.fogs[ data.defaults.fog ];
  5106. }
  5107. c = data.defaults.bgcolor;
  5108. result.bgColor = new THREE.Color();
  5109. result.bgColor.setRGB( c[0], c[1], c[2] );
  5110. result.bgColorAlpha = data.defaults.bgalpha;
  5111. // now come potentially asynchronous elements
  5112. // geometries
  5113. // count how many models will be loaded asynchronously
  5114. for( dg in data.geometries ) {
  5115. g = data.geometries[ dg ];
  5116. if ( g.type == "bin_mesh" || g.type == "ascii_mesh" ) {
  5117. counter_models += 1;
  5118. scope.onLoadStart();
  5119. }
  5120. }
  5121. total_models = counter_models;
  5122. for ( dg in data.geometries ) {
  5123. g = data.geometries[ dg ];
  5124. if ( g.type === "cube" ) {
  5125. geometry = new THREE.CubeGeometry( g.width, g.height, g.depth, g.segmentsWidth, g.segmentsHeight, g.segmentsDepth, null, g.flipped, g.sides );
  5126. result.geometries[ dg ] = geometry;
  5127. } else if ( g.type === "plane" ) {
  5128. geometry = new THREE.PlaneGeometry( g.width, g.height, g.segmentsWidth, g.segmentsHeight );
  5129. result.geometries[ dg ] = geometry;
  5130. } else if ( g.type === "sphere" ) {
  5131. geometry = new THREE.SphereGeometry( g.radius, g.segmentsWidth, g.segmentsHeight );
  5132. result.geometries[ dg ] = geometry;
  5133. } else if ( g.type === "cylinder" ) {
  5134. geometry = new THREE.CylinderGeometry( g.topRad, g.botRad, g.height, g.radSegs, g.heightSegs );
  5135. result.geometries[ dg ] = geometry;
  5136. } else if ( g.type === "torus" ) {
  5137. geometry = new THREE.TorusGeometry( g.radius, g.tube, g.segmentsR, g.segmentsT );
  5138. result.geometries[ dg ] = geometry;
  5139. } else if ( g.type === "icosahedron" ) {
  5140. geometry = new THREE.IcosahedronGeometry( g.radius, g.subdivisions );
  5141. result.geometries[ dg ] = geometry;
  5142. } else if ( g.type === "bin_mesh" ) {
  5143. binLoader.load( get_url( g.url, data.urlBaseType ), create_callback( dg ) );
  5144. } else if ( g.type === "ascii_mesh" ) {
  5145. jsonLoader.load( get_url( g.url, data.urlBaseType ), create_callback( dg ) );
  5146. } else if ( g.type === "embedded_mesh" ) {
  5147. var modelJson = data.embeds[ g.id ],
  5148. texture_path = "";
  5149. // pass metadata along to jsonLoader so it knows the format version
  5150. modelJson.metadata = data.metadata;
  5151. if ( modelJson ) {
  5152. jsonLoader.createModel( modelJson, create_callback_embed( dg ), texture_path );
  5153. }
  5154. }
  5155. }
  5156. // textures
  5157. // count how many textures will be loaded asynchronously
  5158. for( dt in data.textures ) {
  5159. tt = data.textures[ dt ];
  5160. if( tt.url instanceof Array ) {
  5161. counter_textures += tt.url.length;
  5162. for( var n = 0; n < tt.url.length; n ++ ) {
  5163. scope.onLoadStart();
  5164. }
  5165. } else {
  5166. counter_textures += 1;
  5167. scope.onLoadStart();
  5168. }
  5169. }
  5170. total_textures = counter_textures;
  5171. for( dt in data.textures ) {
  5172. tt = data.textures[ dt ];
  5173. if ( tt.mapping !== undefined && THREE[ tt.mapping ] !== undefined ) {
  5174. tt.mapping = new THREE[ tt.mapping ]();
  5175. }
  5176. if( tt.url instanceof Array ) {
  5177. var count = tt.url.length;
  5178. var url_array = [];
  5179. for( var i = 0; i < count; i ++ ) {
  5180. url_array[ i ] = get_url( tt.url[ i ], data.urlBaseType );
  5181. }
  5182. texture = THREE.ImageUtils.loadTextureCube( url_array, tt.mapping, generateTextureCallback( count ) );
  5183. } else {
  5184. texture = THREE.ImageUtils.loadTexture( get_url( tt.url, data.urlBaseType ), tt.mapping, generateTextureCallback( 1 ) );
  5185. if ( THREE[ tt.minFilter ] !== undefined )
  5186. texture.minFilter = THREE[ tt.minFilter ];
  5187. if ( THREE[ tt.magFilter ] !== undefined )
  5188. texture.magFilter = THREE[ tt.magFilter ];
  5189. if ( tt.repeat ) {
  5190. texture.repeat.set( tt.repeat[ 0 ], tt.repeat[ 1 ] );
  5191. if ( tt.repeat[ 0 ] !== 1 ) texture.wrapS = THREE.RepeatWrapping;
  5192. if ( tt.repeat[ 1 ] !== 1 ) texture.wrapT = THREE.RepeatWrapping;
  5193. }
  5194. if ( tt.offset ) {
  5195. texture.offset.set( tt.offset[ 0 ], tt.offset[ 1 ] );
  5196. }
  5197. // handle wrap after repeat so that default repeat can be overriden
  5198. if ( tt.wrap ) {
  5199. var wrapMap = {
  5200. "repeat" : THREE.RepeatWrapping,
  5201. "mirror" : THREE.MirroredRepeatWrapping
  5202. }
  5203. if ( wrapMap[ tt.wrap[ 0 ] ] !== undefined ) texture.wrapS = wrapMap[ tt.wrap[ 0 ] ];
  5204. if ( wrapMap[ tt.wrap[ 1 ] ] !== undefined ) texture.wrapT = wrapMap[ tt.wrap[ 1 ] ];
  5205. }
  5206. }
  5207. result.textures[ dt ] = texture;
  5208. }
  5209. // materials
  5210. for ( dm in data.materials ) {
  5211. m = data.materials[ dm ];
  5212. for ( pp in m.parameters ) {
  5213. if ( pp === "envMap" || pp === "map" || pp === "lightMap" ) {
  5214. m.parameters[ pp ] = result.textures[ m.parameters[ pp ] ];
  5215. } else if ( pp === "shading" ) {
  5216. m.parameters[ pp ] = ( m.parameters[ pp ] == "flat" ) ? THREE.FlatShading : THREE.SmoothShading;
  5217. } else if ( pp === "blending" ) {
  5218. m.parameters[ pp ] = m.parameters[ pp ] in THREE ? THREE[ m.parameters[ pp ] ] : THREE.NormalBlending;
  5219. } else if ( pp === "combine" ) {
  5220. m.parameters[ pp ] = ( m.parameters[ pp ] == "MixOperation" ) ? THREE.MixOperation : THREE.MultiplyOperation;
  5221. } else if ( pp === "vertexColors" ) {
  5222. if ( m.parameters[ pp ] == "face" ) {
  5223. m.parameters[ pp ] = THREE.FaceColors;
  5224. // default to vertex colors if "vertexColors" is anything else face colors or 0 / null / false
  5225. } else if ( m.parameters[ pp ] ) {
  5226. m.parameters[ pp ] = THREE.VertexColors;
  5227. }
  5228. }
  5229. }
  5230. if ( m.parameters.opacity !== undefined && m.parameters.opacity < 1.0 ) {
  5231. m.parameters.transparent = true;
  5232. }
  5233. if ( m.parameters.normalMap ) {
  5234. var shader = THREE.ShaderUtils.lib[ "normal" ];
  5235. var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
  5236. var diffuse = m.parameters.color;
  5237. var specular = m.parameters.specular;
  5238. var ambient = m.parameters.ambient;
  5239. var shininess = m.parameters.shininess;
  5240. uniforms[ "tNormal" ].texture = result.textures[ m.parameters.normalMap ];
  5241. if ( m.parameters.normalMapFactor ) {
  5242. uniforms[ "uNormalScale" ].value = m.parameters.normalMapFactor;
  5243. }
  5244. if ( m.parameters.map ) {
  5245. uniforms[ "tDiffuse" ].texture = m.parameters.map;
  5246. uniforms[ "enableDiffuse" ].value = true;
  5247. }
  5248. if ( m.parameters.lightMap ) {
  5249. uniforms[ "tAO" ].texture = m.parameters.lightMap;
  5250. uniforms[ "enableAO" ].value = true;
  5251. }
  5252. if ( m.parameters.specularMap ) {
  5253. uniforms[ "tSpecular" ].texture = result.textures[ m.parameters.specularMap ];
  5254. uniforms[ "enableSpecular" ].value = true;
  5255. }
  5256. uniforms[ "uDiffuseColor" ].value.setHex( diffuse );
  5257. uniforms[ "uSpecularColor" ].value.setHex( specular );
  5258. uniforms[ "uAmbientColor" ].value.setHex( ambient );
  5259. uniforms[ "uShininess" ].value = shininess;
  5260. if ( m.parameters.opacity ) {
  5261. uniforms[ "uOpacity" ].value = m.parameters.opacity;
  5262. }
  5263. var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: true };
  5264. material = new THREE.ShaderMaterial( parameters );
  5265. } else {
  5266. material = new THREE[ m.type ]( m.parameters );
  5267. }
  5268. result.materials[ dm ] = material;
  5269. }
  5270. // objects ( synchronous init of procedural primitives )
  5271. handle_objects();
  5272. // synchronous callback
  5273. scope.callbackSync( result );
  5274. // just in case there are no async elements
  5275. async_callback_gate();
  5276. };
  5277. /**
  5278. * @author mrdoob / http://mrdoob.com/
  5279. */
  5280. THREE.TextureLoader = function () {
  5281. THREE.EventTarget.call( this );
  5282. this.crossOrigin = null;
  5283. };
  5284. THREE.TextureLoader.prototype = {
  5285. constructor: THREE.TextureLoader,
  5286. load: function ( url ) {
  5287. var scope = this;
  5288. var image = new Image();
  5289. image.addEventListener( 'load', function () {
  5290. var texture = new THREE.Texture( image );
  5291. texture.needsUpdate = true;
  5292. scope.dispatchEvent( { type: 'load', content: texture } );
  5293. }, false );
  5294. image.addEventListener( 'error', function () {
  5295. scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
  5296. }, false );
  5297. if ( scope.crossOrigin ) image.crossOrigin = scope.crossOrigin;
  5298. image.src = url;
  5299. }
  5300. }
  5301. /**
  5302. * @author mr.doob / http://mrdoob.com/
  5303. * @author alteredq / http://alteredqualia.com/
  5304. */
  5305. THREE.Material = function ( parameters ) {
  5306. parameters = parameters || {};
  5307. this.id = THREE.MaterialCount ++;
  5308. this.name = '';
  5309. this.opacity = parameters.opacity !== undefined ? parameters.opacity : 1;
  5310. this.transparent = parameters.transparent !== undefined ? parameters.transparent : false;
  5311. this.blending = parameters.blending !== undefined ? parameters.blending : THREE.NormalBlending;
  5312. this.blendSrc = parameters.blendSrc !== undefined ? parameters.blendSrc : THREE.SrcAlphaFactor;
  5313. this.blendDst = parameters.blendDst !== undefined ? parameters.blendDst : THREE.OneMinusSrcAlphaFactor;
  5314. this.blendEquation = parameters.blendEquation !== undefined ? parameters.blendEquation : THREE.AddEquation;
  5315. this.depthTest = parameters.depthTest !== undefined ? parameters.depthTest : true;
  5316. this.depthWrite = parameters.depthWrite !== undefined ? parameters.depthWrite : true;
  5317. this.polygonOffset = parameters.polygonOffset !== undefined ? parameters.polygonOffset : false;
  5318. this.polygonOffsetFactor = parameters.polygonOffsetFactor !== undefined ? parameters.polygonOffsetFactor : 0;
  5319. this.polygonOffsetUnits = parameters.polygonOffsetUnits !== undefined ? parameters.polygonOffsetUnits : 0;
  5320. this.alphaTest = parameters.alphaTest !== undefined ? parameters.alphaTest : 0;
  5321. this.overdraw = parameters.overdraw !== undefined ? parameters.overdraw : false; // Boolean for fixing antialiasing gaps in CanvasRenderer
  5322. this.visible = true;
  5323. this.needsUpdate = true;
  5324. }
  5325. THREE.MaterialCount = 0;
  5326. /**
  5327. * @author mr.doob / http://mrdoob.com/
  5328. * @author alteredq / http://alteredqualia.com/
  5329. *
  5330. * parameters = {
  5331. * color: <hex>,
  5332. * opacity: <float>,
  5333. *
  5334. * blending: THREE.NormalBlending,
  5335. * depthTest: <bool>,
  5336. *
  5337. * linewidth: <float>,
  5338. * linecap: "round",
  5339. * linejoin: "round",
  5340. *
  5341. * vertexColors: <bool>
  5342. *
  5343. * fog: <bool>
  5344. * }
  5345. */
  5346. THREE.LineBasicMaterial = function ( parameters ) {
  5347. THREE.Material.call( this, parameters );
  5348. parameters = parameters || {};
  5349. this.color = parameters.color !== undefined ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
  5350. this.linewidth = parameters.linewidth !== undefined ? parameters.linewidth : 1;
  5351. this.linecap = parameters.linecap !== undefined ? parameters.linecap : 'round';
  5352. this.linejoin = parameters.linejoin !== undefined ? parameters.linejoin : 'round';
  5353. this.vertexColors = parameters.vertexColors ? parameters.vertexColors : false;
  5354. this.fog = parameters.fog !== undefined ? parameters.fog : true;
  5355. };
  5356. THREE.LineBasicMaterial.prototype = Object.create( THREE.Material.prototype );
  5357. /**
  5358. * @author mr.doob / http://mrdoob.com/
  5359. * @author alteredq / http://alteredqualia.com/
  5360. *
  5361. * parameters = {
  5362. * color: <hex>,
  5363. * opacity: <float>,
  5364. * map: new THREE.Texture( <Image> ),
  5365. *
  5366. * lightMap: new THREE.Texture( <Image> ),
  5367. *
  5368. * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
  5369. * combine: THREE.Multiply,
  5370. * reflectivity: <float>,
  5371. * refractionRatio: <float>,
  5372. *
  5373. * shading: THREE.SmoothShading,
  5374. * blending: THREE.NormalBlending,
  5375. * depthTest: <bool>,
  5376. *
  5377. * wireframe: <boolean>,
  5378. * wireframeLinewidth: <float>,
  5379. *
  5380. * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
  5381. *
  5382. * skinning: <bool>,
  5383. * morphTargets: <bool>,
  5384. *
  5385. * fog: <bool>
  5386. * }
  5387. */
  5388. THREE.MeshBasicMaterial = function ( parameters ) {
  5389. THREE.Material.call( this, parameters );
  5390. parameters = parameters || {};
  5391. // color property represents emissive for MeshBasicMaterial
  5392. this.color = parameters.color !== undefined ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
  5393. this.map = parameters.map !== undefined ? parameters.map : null;
  5394. this.lightMap = parameters.lightMap !== undefined ? parameters.lightMap : null;
  5395. this.envMap = parameters.envMap !== undefined ? parameters.envMap : null;
  5396. this.combine = parameters.combine !== undefined ? parameters.combine : THREE.MultiplyOperation;
  5397. this.reflectivity = parameters.reflectivity !== undefined ? parameters.reflectivity : 1;
  5398. this.refractionRatio = parameters.refractionRatio !== undefined ? parameters.refractionRatio : 0.98;
  5399. this.fog = parameters.fog !== undefined ? parameters.fog : true;
  5400. this.shading = parameters.shading !== undefined ? parameters.shading : THREE.SmoothShading;
  5401. this.wireframe = parameters.wireframe !== undefined ? parameters.wireframe : false;
  5402. this.wireframeLinewidth = parameters.wireframeLinewidth !== undefined ? parameters.wireframeLinewidth : 1;
  5403. this.wireframeLinecap = parameters.wireframeLinecap !== undefined ? parameters.wireframeLinecap : 'round';
  5404. this.wireframeLinejoin = parameters.wireframeLinejoin !== undefined ? parameters.wireframeLinejoin : 'round';
  5405. this.vertexColors = parameters.vertexColors !== undefined ? parameters.vertexColors : THREE.NoColors;
  5406. this.skinning = parameters.skinning !== undefined ? parameters.skinning : false;
  5407. this.morphTargets = parameters.morphTargets !== undefined ? parameters.morphTargets : false;
  5408. };
  5409. THREE.MeshBasicMaterial.prototype = Object.create( THREE.Material.prototype );
  5410. /**
  5411. * @author mr.doob / http://mrdoob.com/
  5412. * @author alteredq / http://alteredqualia.com/
  5413. *
  5414. * parameters = {
  5415. * color: <hex>,
  5416. * ambient: <hex>,
  5417. * emissive: <hex>,
  5418. * opacity: <float>,
  5419. *
  5420. * map: new THREE.Texture( <Image> ),
  5421. *
  5422. * lightMap: new THREE.Texture( <Image> ),
  5423. *
  5424. * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
  5425. * combine: THREE.Multiply,
  5426. * reflectivity: <float>,
  5427. * refractionRatio: <float>,
  5428. *
  5429. * shading: THREE.SmoothShading,
  5430. * blending: THREE.NormalBlending,
  5431. * depthTest: <bool>,
  5432. *
  5433. * wireframe: <boolean>,
  5434. * wireframeLinewidth: <float>,
  5435. *
  5436. * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
  5437. *
  5438. * skinning: <bool>,
  5439. * morphTargets: <bool>,
  5440. * morphNormals: <bool>,
  5441. *
  5442. * fog: <bool>
  5443. * }
  5444. */
  5445. THREE.MeshLambertMaterial = function ( parameters ) {
  5446. THREE.Material.call( this, parameters );
  5447. parameters = parameters || {};
  5448. // color property represents diffuse for MeshLambertMaterial
  5449. this.color = parameters.color !== undefined ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
  5450. this.ambient = parameters.ambient !== undefined ? new THREE.Color( parameters.ambient ) : new THREE.Color( 0xffffff );
  5451. this.emissive = parameters.emissive !== undefined ? new THREE.Color( parameters.emissive ) : new THREE.Color( 0x000000 );
  5452. this.wrapAround = parameters.wrapAround !== undefined ? parameters.wrapAround: false;
  5453. this.wrapRGB = new THREE.Vector3( 1, 1, 1 );
  5454. this.map = parameters.map !== undefined ? parameters.map : null;
  5455. this.lightMap = parameters.lightMap !== undefined ? parameters.lightMap : null;
  5456. this.envMap = parameters.envMap !== undefined ? parameters.envMap : null;
  5457. this.combine = parameters.combine !== undefined ? parameters.combine : THREE.MultiplyOperation;
  5458. this.reflectivity = parameters.reflectivity !== undefined ? parameters.reflectivity : 1;
  5459. this.refractionRatio = parameters.refractionRatio !== undefined ? parameters.refractionRatio : 0.98;
  5460. this.fog = parameters.fog !== undefined ? parameters.fog : true;
  5461. this.shading = parameters.shading !== undefined ? parameters.shading : THREE.SmoothShading;
  5462. this.wireframe = parameters.wireframe !== undefined ? parameters.wireframe : false;
  5463. this.wireframeLinewidth = parameters.wireframeLinewidth !== undefined ? parameters.wireframeLinewidth : 1;
  5464. this.wireframeLinecap = parameters.wireframeLinecap !== undefined ? parameters.wireframeLinecap : 'round';
  5465. this.wireframeLinejoin = parameters.wireframeLinejoin !== undefined ? parameters.wireframeLinejoin : 'round';
  5466. this.vertexColors = parameters.vertexColors !== undefined ? parameters.vertexColors : THREE.NoColors;
  5467. this.skinning = parameters.skinning !== undefined ? parameters.skinning : false;
  5468. this.morphTargets = parameters.morphTargets !== undefined ? parameters.morphTargets : false;
  5469. this.morphNormals = parameters.morphNormals !== undefined ? parameters.morphNormals : false;
  5470. };
  5471. THREE.MeshLambertMaterial.prototype = Object.create( THREE.Material.prototype );
  5472. /**
  5473. * @author mr.doob / http://mrdoob.com/
  5474. * @author alteredq / http://alteredqualia.com/
  5475. *
  5476. * parameters = {
  5477. * color: <hex>,
  5478. * ambient: <hex>,
  5479. * emissive: <hex>,
  5480. * specular: <hex>,
  5481. * shininess: <float>,
  5482. * opacity: <float>,
  5483. *
  5484. * map: new THREE.Texture( <Image> ),
  5485. *
  5486. * lightMap: new THREE.Texture( <Image> ),
  5487. *
  5488. * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
  5489. * combine: THREE.Multiply,
  5490. * reflectivity: <float>,
  5491. * refractionRatio: <float>,
  5492. *
  5493. * shading: THREE.SmoothShading,
  5494. * blending: THREE.NormalBlending,
  5495. * depthTest: <bool>,
  5496. *
  5497. * wireframe: <boolean>,
  5498. * wireframeLinewidth: <float>,
  5499. *
  5500. * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
  5501. *
  5502. * skinning: <bool>,
  5503. * morphTargets: <bool>,
  5504. * morphNormals: <bool>,
  5505. *
  5506. * fog: <bool>
  5507. * }
  5508. */
  5509. THREE.MeshPhongMaterial = function ( parameters ) {
  5510. THREE.Material.call( this, parameters );
  5511. parameters = parameters || {};
  5512. // color property represents diffuse for MeshPhongMaterial
  5513. this.color = parameters.color !== undefined ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
  5514. this.ambient = parameters.ambient !== undefined ? new THREE.Color( parameters.ambient ) : new THREE.Color( 0xffffff );
  5515. this.emissive = parameters.emissive !== undefined ? new THREE.Color( parameters.emissive ) : new THREE.Color( 0x000000 );
  5516. this.specular = parameters.specular !== undefined ? new THREE.Color( parameters.specular ) : new THREE.Color( 0x111111 );
  5517. this.shininess = parameters.shininess !== undefined ? parameters.shininess : 30;
  5518. this.metal = parameters.metal !== undefined ? parameters.metal : false;
  5519. this.perPixel = parameters.perPixel !== undefined ? parameters.perPixel : false;
  5520. this.wrapAround = parameters.wrapAround !== undefined ? parameters.wrapAround: false;
  5521. this.wrapRGB = new THREE.Vector3( 1, 1, 1 );
  5522. this.map = parameters.map !== undefined ? parameters.map : null;
  5523. this.lightMap = parameters.lightMap !== undefined ? parameters.lightMap : null;
  5524. this.envMap = parameters.envMap !== undefined ? parameters.envMap : null;
  5525. this.combine = parameters.combine !== undefined ? parameters.combine : THREE.MultiplyOperation;
  5526. this.reflectivity = parameters.reflectivity !== undefined ? parameters.reflectivity : 1;
  5527. this.refractionRatio = parameters.refractionRatio !== undefined ? parameters.refractionRatio : 0.98;
  5528. this.fog = parameters.fog !== undefined ? parameters.fog : true;
  5529. this.shading = parameters.shading !== undefined ? parameters.shading : THREE.SmoothShading;
  5530. this.wireframe = parameters.wireframe !== undefined ? parameters.wireframe : false;
  5531. this.wireframeLinewidth = parameters.wireframeLinewidth !== undefined ? parameters.wireframeLinewidth : 1;
  5532. this.wireframeLinecap = parameters.wireframeLinecap !== undefined ? parameters.wireframeLinecap : 'round';
  5533. this.wireframeLinejoin = parameters.wireframeLinejoin !== undefined ? parameters.wireframeLinejoin : 'round';
  5534. this.vertexColors = parameters.vertexColors !== undefined ? parameters.vertexColors : THREE.NoColors;
  5535. this.skinning = parameters.skinning !== undefined ? parameters.skinning : false;
  5536. this.morphTargets = parameters.morphTargets !== undefined ? parameters.morphTargets : false;
  5537. this.morphNormals = parameters.morphNormals !== undefined ? parameters.morphNormals : false;
  5538. };
  5539. THREE.MeshPhongMaterial.prototype = Object.create( THREE.Material.prototype );
  5540. /**
  5541. * @author mr.doob / http://mrdoob.com/
  5542. * @author alteredq / http://alteredqualia.com/
  5543. *
  5544. * parameters = {
  5545. * opacity: <float>,
  5546. * blending: THREE.NormalBlending,
  5547. * depthTest: <bool>,
  5548. * wireframe: <boolean>,
  5549. * wireframeLinewidth: <float>
  5550. * }
  5551. */
  5552. THREE.MeshDepthMaterial = function ( parameters ) {
  5553. THREE.Material.call( this, parameters );
  5554. parameters = parameters || {};
  5555. this.shading = parameters.shading !== undefined ? parameters.shading : THREE.SmoothShading; // doesn't really apply here, normals are not used
  5556. this.wireframe = parameters.wireframe !== undefined ? parameters.wireframe : false;
  5557. this.wireframeLinewidth = parameters.wireframeLinewidth !== undefined ? parameters.wireframeLinewidth : 1;
  5558. };
  5559. THREE.MeshDepthMaterial.prototype = Object.create( THREE.Material.prototype );
  5560. /**
  5561. * @author mr.doob / http://mrdoob.com/
  5562. *
  5563. * parameters = {
  5564. * opacity: <float>,
  5565. * shading: THREE.FlatShading,
  5566. * blending: THREE.NormalBlending,
  5567. * depthTest: <bool>,
  5568. * wireframe: <boolean>,
  5569. * wireframeLinewidth: <float>
  5570. * }
  5571. */
  5572. THREE.MeshNormalMaterial = function ( parameters ) {
  5573. THREE.Material.call( this, parameters );
  5574. parameters = parameters || {};
  5575. this.shading = parameters.shading ? parameters.shading : THREE.FlatShading;
  5576. this.wireframe = parameters.wireframe ? parameters.wireframe : false;
  5577. this.wireframeLinewidth = parameters.wireframeLinewidth ? parameters.wireframeLinewidth : 1;
  5578. };
  5579. THREE.MeshNormalMaterial.prototype = Object.create( THREE.Material.prototype );
  5580. /**
  5581. * @author mr.doob / http://mrdoob.com/
  5582. */
  5583. THREE.MeshFaceMaterial = function () {};
  5584. /**
  5585. * @author mr.doob / http://mrdoob.com/
  5586. * @author alteredq / http://alteredqualia.com/
  5587. *
  5588. * parameters = {
  5589. * color: <hex>,
  5590. * opacity: <float>,
  5591. * map: new THREE.Texture( <Image> ),
  5592. *
  5593. * size: <float>,
  5594. *
  5595. * blending: THREE.NormalBlending,
  5596. * depthTest: <bool>,
  5597. *
  5598. * vertexColors: <bool>,
  5599. *
  5600. * fog: <bool>
  5601. * }
  5602. */
  5603. THREE.ParticleBasicMaterial = function ( parameters ) {
  5604. THREE.Material.call( this, parameters );
  5605. parameters = parameters || {};
  5606. this.color = parameters.color !== undefined ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
  5607. this.map = parameters.map !== undefined ? parameters.map : null;
  5608. this.size = parameters.size !== undefined ? parameters.size : 1;
  5609. this.sizeAttenuation = parameters.sizeAttenuation !== undefined ? parameters.sizeAttenuation : true;
  5610. this.vertexColors = parameters.vertexColors !== undefined ? parameters.vertexColors : false;
  5611. this.fog = parameters.fog !== undefined ? parameters.fog : true;
  5612. };
  5613. THREE.ParticleBasicMaterial.prototype = Object.create( THREE.Material.prototype );
  5614. /**
  5615. * @author alteredq / http://alteredqualia.com/
  5616. *
  5617. * parameters = {
  5618. * fragmentShader: <string>,
  5619. * vertexShader: <string>,
  5620. *
  5621. * uniforms: { "parameter1": { type: "f", value: 1.0 }, "parameter2": { type: "i" value2: 2 } },
  5622. *
  5623. * shading: THREE.SmoothShading,
  5624. * blending: THREE.NormalBlending,
  5625. * depthTest: <bool>,
  5626. *
  5627. * wireframe: <boolean>,
  5628. * wireframeLinewidth: <float>,
  5629. *
  5630. * lights: <bool>,
  5631. *
  5632. * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
  5633. *
  5634. * skinning: <bool>,
  5635. * morphTargets: <bool>,
  5636. * morphNormals: <bool>,
  5637. *
  5638. * fog: <bool>
  5639. * }
  5640. */
  5641. THREE.ShaderMaterial = function ( parameters ) {
  5642. THREE.Material.call( this, parameters );
  5643. parameters = parameters || {};
  5644. this.fragmentShader = parameters.fragmentShader !== undefined ? parameters.fragmentShader : "void main() {}";
  5645. this.vertexShader = parameters.vertexShader !== undefined ? parameters.vertexShader : "void main() {}";
  5646. this.uniforms = parameters.uniforms !== undefined ? parameters.uniforms : {};
  5647. this.attributes = parameters.attributes;
  5648. this.shading = parameters.shading !== undefined ? parameters.shading : THREE.SmoothShading;
  5649. this.wireframe = parameters.wireframe !== undefined ? parameters.wireframe : false;
  5650. this.wireframeLinewidth = parameters.wireframeLinewidth !== undefined ? parameters.wireframeLinewidth : 1;
  5651. this.fog = parameters.fog !== undefined ? parameters.fog : false; // set to use scene fog
  5652. this.lights = parameters.lights !== undefined ? parameters.lights : false; // set to use scene lights
  5653. this.vertexColors = parameters.vertexColors !== undefined ? parameters.vertexColors : THREE.NoColors; // set to use "color" attribute stream
  5654. this.skinning = parameters.skinning !== undefined ? parameters.skinning : false; // set to use skinning attribute streams
  5655. this.morphTargets = parameters.morphTargets !== undefined ? parameters.morphTargets : false; // set to use morph targets
  5656. this.morphNormals = parameters.morphNormals !== undefined ? parameters.morphNormals : false; // set to use morph normals
  5657. };
  5658. THREE.ShaderMaterial.prototype = Object.create( THREE.Material.prototype );
  5659. /**
  5660. * @author mr.doob / http://mrdoob.com/
  5661. * @author alteredq / http://alteredqualia.com/
  5662. * @author szimek / https://github.com/szimek/
  5663. */
  5664. THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
  5665. this.id = THREE.TextureCount ++;
  5666. this.image = image;
  5667. this.mapping = mapping !== undefined ? mapping : new THREE.UVMapping();
  5668. this.wrapS = wrapS !== undefined ? wrapS : THREE.ClampToEdgeWrapping;
  5669. this.wrapT = wrapT !== undefined ? wrapT : THREE.ClampToEdgeWrapping;
  5670. this.magFilter = magFilter !== undefined ? magFilter : THREE.LinearFilter;
  5671. this.minFilter = minFilter !== undefined ? minFilter : THREE.LinearMipMapLinearFilter;
  5672. this.anisotropy = anisotropy !== undefined ? anisotropy : 1;
  5673. this.format = format !== undefined ? format : THREE.RGBAFormat;
  5674. this.type = type !== undefined ? type : THREE.UnsignedByteType;
  5675. this.offset = new THREE.Vector2( 0, 0 );
  5676. this.repeat = new THREE.Vector2( 1, 1 );
  5677. this.generateMipmaps = true;
  5678. this.premultiplyAlpha = false;
  5679. this.flipY = true;
  5680. this.needsUpdate = false;
  5681. this.onUpdate = null;
  5682. };
  5683. THREE.Texture.prototype = {
  5684. constructor: THREE.Texture,
  5685. clone: function () {
  5686. var clonedTexture = new THREE.Texture( this.image, this.mapping, this.wrapS, this.wrapT, this.magFilter, this.minFilter, this.format, this.type );
  5687. clonedTexture.offset.copy( this.offset );
  5688. clonedTexture.repeat.copy( this.repeat );
  5689. return clonedTexture;
  5690. }
  5691. };
  5692. THREE.TextureCount = 0;
  5693. /**
  5694. * @author alteredq / http://alteredqualia.com/
  5695. */
  5696. THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter ) {
  5697. THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type );
  5698. this.image = { data: data, width: width, height: height };
  5699. };
  5700. THREE.DataTexture.prototype = Object.create( THREE.Texture.prototype );
  5701. THREE.DataTexture.prototype.clone = function () {
  5702. 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 );
  5703. clonedTexture.offset.copy( this.offset );
  5704. clonedTexture.repeat.copy( this.repeat );
  5705. return clonedTexture;
  5706. };
  5707. /**
  5708. * @author mr.doob / http://mrdoob.com/
  5709. */
  5710. THREE.Particle = function ( material ) {
  5711. THREE.Object3D.call( this );
  5712. this.material = material;
  5713. };
  5714. THREE.Particle.prototype = Object.create( THREE.Object3D.prototype );
  5715. /**
  5716. * @author alteredq / http://alteredqualia.com/
  5717. */
  5718. THREE.ParticleSystem = function ( geometry, material ) {
  5719. THREE.Object3D.call( this );
  5720. this.geometry = geometry;
  5721. this.material = ( material !== undefined ) ? material : new THREE.ParticleBasicMaterial( { color: Math.random() * 0xffffff } );
  5722. this.sortParticles = false;
  5723. if ( this.geometry ) {
  5724. // calc bound radius
  5725. if( !this.geometry.boundingSphere ) {
  5726. this.geometry.computeBoundingSphere();
  5727. }
  5728. this.boundRadius = geometry.boundingSphere.radius;
  5729. }
  5730. this.frustumCulled = false;
  5731. };
  5732. THREE.ParticleSystem.prototype = Object.create( THREE.Object3D.prototype );
  5733. /**
  5734. * @author mr.doob / http://mrdoob.com/
  5735. */
  5736. THREE.Line = function ( geometry, material, type ) {
  5737. THREE.Object3D.call( this );
  5738. this.geometry = geometry;
  5739. this.material = ( material !== undefined ) ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } );
  5740. this.type = ( type !== undefined ) ? type : THREE.LineStrip;
  5741. if ( this.geometry ) {
  5742. if ( ! this.geometry.boundingSphere ) {
  5743. this.geometry.computeBoundingSphere();
  5744. }
  5745. }
  5746. };
  5747. THREE.LineStrip = 0;
  5748. THREE.LinePieces = 1;
  5749. THREE.Line.prototype = Object.create( THREE.Object3D.prototype );
  5750. /**
  5751. * @author mr.doob / http://mrdoob.com/
  5752. * @author alteredq / http://alteredqualia.com/
  5753. * @author mikael emtinger / http://gomo.se/
  5754. */
  5755. THREE.Mesh = function ( geometry, material ) {
  5756. THREE.Object3D.call( this );
  5757. this.geometry = geometry;
  5758. this.material = ( material !== undefined ) ? material : new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, wireframe: true } );
  5759. if ( this.geometry ) {
  5760. // calc bound radius
  5761. if ( ! this.geometry.boundingSphere ) {
  5762. this.geometry.computeBoundingSphere();
  5763. }
  5764. this.boundRadius = geometry.boundingSphere.radius;
  5765. // setup morph targets
  5766. if( this.geometry.morphTargets.length ) {
  5767. this.morphTargetBase = -1;
  5768. this.morphTargetForcedOrder = [];
  5769. this.morphTargetInfluences = [];
  5770. this.morphTargetDictionary = {};
  5771. for( var m = 0; m < this.geometry.morphTargets.length; m ++ ) {
  5772. this.morphTargetInfluences.push( 0 );
  5773. this.morphTargetDictionary[ this.geometry.morphTargets[ m ].name ] = m;
  5774. }
  5775. }
  5776. }
  5777. }
  5778. THREE.Mesh.prototype = Object.create( THREE.Object3D.prototype );
  5779. /*
  5780. * Get Morph Target Index by Name
  5781. */
  5782. THREE.Mesh.prototype.getMorphTargetIndexByName = function( name ) {
  5783. if ( this.morphTargetDictionary[ name ] !== undefined ) {
  5784. return this.morphTargetDictionary[ name ];
  5785. }
  5786. console.log( "THREE.Mesh.getMorphTargetIndexByName: morph target " + name + " does not exist. Returning 0." );
  5787. return 0;
  5788. }
  5789. /**
  5790. * @author mikael emtinger / http://gomo.se/
  5791. * @author alteredq / http://alteredqualia.com/
  5792. */
  5793. THREE.Bone = function( belongsToSkin ) {
  5794. THREE.Object3D.call( this );
  5795. this.skin = belongsToSkin;
  5796. this.skinMatrix = new THREE.Matrix4();
  5797. };
  5798. THREE.Bone.prototype = Object.create( THREE.Object3D.prototype );
  5799. THREE.Bone.prototype.update = function( parentSkinMatrix, forceUpdate ) {
  5800. // update local
  5801. if ( this.matrixAutoUpdate ) {
  5802. forceUpdate |= this.updateMatrix();
  5803. }
  5804. // update skin matrix
  5805. if ( forceUpdate || this.matrixWorldNeedsUpdate ) {
  5806. if( parentSkinMatrix ) {
  5807. this.skinMatrix.multiply( parentSkinMatrix, this.matrix );
  5808. } else {
  5809. this.skinMatrix.copy( this.matrix );
  5810. }
  5811. this.matrixWorldNeedsUpdate = false;
  5812. forceUpdate = true;
  5813. }
  5814. // update children
  5815. var child, i, l = this.children.length;
  5816. for ( i = 0; i < l; i ++ ) {
  5817. this.children[ i ].update( this.skinMatrix, forceUpdate );
  5818. }
  5819. };
  5820. /**
  5821. * @author mikael emtinger / http://gomo.se/
  5822. * @author alteredq / http://alteredqualia.com/
  5823. */
  5824. THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) {
  5825. THREE.Mesh.call( this, geometry, material );
  5826. //
  5827. this.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;
  5828. // init bones
  5829. this.identityMatrix = new THREE.Matrix4();
  5830. this.bones = [];
  5831. this.boneMatrices = [];
  5832. var b, bone, gbone, p, q, s;
  5833. if ( this.geometry.bones !== undefined ) {
  5834. for ( b = 0; b < this.geometry.bones.length; b ++ ) {
  5835. gbone = this.geometry.bones[ b ];
  5836. p = gbone.pos;
  5837. q = gbone.rotq;
  5838. s = gbone.scl;
  5839. bone = this.addBone();
  5840. bone.name = gbone.name;
  5841. bone.position.set( p[0], p[1], p[2] );
  5842. bone.quaternion.set( q[0], q[1], q[2], q[3] );
  5843. bone.useQuaternion = true;
  5844. if ( s !== undefined ) {
  5845. bone.scale.set( s[0], s[1], s[2] );
  5846. } else {
  5847. bone.scale.set( 1, 1, 1 );
  5848. }
  5849. }
  5850. for ( b = 0; b < this.bones.length; b ++ ) {
  5851. gbone = this.geometry.bones[ b ];
  5852. bone = this.bones[ b ];
  5853. if ( gbone.parent === -1 ) {
  5854. this.add( bone );
  5855. } else {
  5856. this.bones[ gbone.parent ].add( bone );
  5857. }
  5858. }
  5859. //
  5860. var nBones = this.bones.length;
  5861. if ( this.useVertexTexture ) {
  5862. // layout (1 matrix = 4 pixels)
  5863. // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
  5864. // with 8x8 pixel texture max 16 bones (8 * 8 / 4)
  5865. // 16x16 pixel texture max 64 bones (16 * 16 / 4)
  5866. // 32x32 pixel texture max 256 bones (32 * 32 / 4)
  5867. // 64x64 pixel texture max 1024 bones (64 * 64 / 4)
  5868. var size;
  5869. if ( nBones > 256 )
  5870. size = 64;
  5871. else if ( nBones > 64 )
  5872. size = 32;
  5873. else if ( nBones > 16 )
  5874. size = 16;
  5875. else
  5876. size = 8;
  5877. this.boneTextureWidth = size;
  5878. this.boneTextureHeight = size;
  5879. this.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel
  5880. this.boneTexture = new THREE.DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, THREE.RGBAFormat, THREE.FloatType );
  5881. this.boneTexture.minFilter = THREE.NearestFilter;
  5882. this.boneTexture.magFilter = THREE.NearestFilter;
  5883. this.boneTexture.generateMipmaps = false;
  5884. this.boneTexture.flipY = false;
  5885. } else {
  5886. this.boneMatrices = new Float32Array( 16 * nBones );
  5887. }
  5888. this.pose();
  5889. }
  5890. };
  5891. THREE.SkinnedMesh.prototype = Object.create( THREE.Mesh.prototype );
  5892. THREE.SkinnedMesh.prototype.addBone = function( bone ) {
  5893. if ( bone === undefined ) {
  5894. bone = new THREE.Bone( this );
  5895. }
  5896. this.bones.push( bone );
  5897. return bone;
  5898. };
  5899. THREE.SkinnedMesh.prototype.updateMatrixWorld = function ( force ) {
  5900. this.matrixAutoUpdate && this.updateMatrix();
  5901. // update matrixWorld
  5902. if ( this.matrixWorldNeedsUpdate || force ) {
  5903. if ( this.parent ) {
  5904. this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
  5905. } else {
  5906. this.matrixWorld.copy( this.matrix );
  5907. }
  5908. this.matrixWorldNeedsUpdate = false;
  5909. force = true;
  5910. }
  5911. // update children
  5912. for ( var i = 0, l = this.children.length; i < l; i ++ ) {
  5913. var child = this.children[ i ];
  5914. if ( child instanceof THREE.Bone ) {
  5915. child.update( this.identityMatrix, false );
  5916. } else {
  5917. child.updateMatrixWorld( true );
  5918. }
  5919. }
  5920. // flatten bone matrices to array
  5921. var b, bl = this.bones.length,
  5922. ba = this.bones,
  5923. bm = this.boneMatrices;
  5924. for ( b = 0; b < bl; b ++ ) {
  5925. ba[ b ].skinMatrix.flattenToArrayOffset( bm, b * 16 );
  5926. }
  5927. if ( this.useVertexTexture ) {
  5928. this.boneTexture.needsUpdate = true;
  5929. }
  5930. };
  5931. /*
  5932. * Pose
  5933. */
  5934. THREE.SkinnedMesh.prototype.pose = function() {
  5935. this.updateMatrixWorld( true );
  5936. var bim, bone, boneInverses = [];
  5937. for ( var b = 0; b < this.bones.length; b ++ ) {
  5938. bone = this.bones[ b ];
  5939. var inverseMatrix = new THREE.Matrix4();
  5940. inverseMatrix.getInverse( bone.skinMatrix );
  5941. boneInverses.push( inverseMatrix );
  5942. bone.skinMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
  5943. }
  5944. // project vertices to local
  5945. if ( this.geometry.skinVerticesA === undefined ) {
  5946. this.geometry.skinVerticesA = [];
  5947. this.geometry.skinVerticesB = [];
  5948. var orgVertex, vertex;
  5949. for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) {
  5950. orgVertex = this.geometry.vertices[ i ];
  5951. var indexA = this.geometry.skinIndices[ i ].x;
  5952. var indexB = this.geometry.skinIndices[ i ].y;
  5953. vertex = new THREE.Vector3( orgVertex.x, orgVertex.y, orgVertex.z );
  5954. this.geometry.skinVerticesA.push( boneInverses[ indexA ].multiplyVector3( vertex ) );
  5955. vertex = new THREE.Vector3( orgVertex.x, orgVertex.y, orgVertex.z );
  5956. this.geometry.skinVerticesB.push( boneInverses[ indexB ].multiplyVector3( vertex ) );
  5957. // todo: add more influences
  5958. // normalize weights
  5959. if ( this.geometry.skinWeights[ i ].x + this.geometry.skinWeights[ i ].y !== 1 ) {
  5960. var len = ( 1.0 - ( this.geometry.skinWeights[ i ].x + this.geometry.skinWeights[ i ].y ) ) * 0.5;
  5961. this.geometry.skinWeights[ i ].x += len;
  5962. this.geometry.skinWeights[ i ].y += len;
  5963. }
  5964. }
  5965. }
  5966. };
  5967. /**
  5968. * @author alteredq / http://alteredqualia.com/
  5969. */
  5970. THREE.Ribbon = function ( geometry, material ) {
  5971. THREE.Object3D.call( this );
  5972. this.geometry = geometry;
  5973. this.material = material;
  5974. };
  5975. THREE.Ribbon.prototype = Object.create( THREE.Object3D.prototype );
  5976. /**
  5977. * @author mikael emtinger / http://gomo.se/
  5978. * @author alteredq / http://alteredqualia.com/
  5979. * @author mr.doob / http://mrdoob.com/
  5980. */
  5981. THREE.LOD = function () {
  5982. THREE.Object3D.call( this );
  5983. this.LODs = [];
  5984. };
  5985. THREE.LOD.prototype = Object.create( THREE.Object3D.prototype );
  5986. THREE.LOD.prototype.addLevel = function ( object3D, visibleAtDistance ) {
  5987. if ( visibleAtDistance === undefined ) {
  5988. visibleAtDistance = 0;
  5989. }
  5990. visibleAtDistance = Math.abs( visibleAtDistance );
  5991. for ( var l = 0; l < this.LODs.length; l ++ ) {
  5992. if ( visibleAtDistance < this.LODs[ l ].visibleAtDistance ) {
  5993. break;
  5994. }
  5995. }
  5996. this.LODs.splice( l, 0, { visibleAtDistance: visibleAtDistance, object3D: object3D } );
  5997. this.add( object3D );
  5998. };
  5999. THREE.LOD.prototype.update = function ( camera ) {
  6000. if ( this.LODs.length > 1 ) {
  6001. camera.matrixWorldInverse.getInverse( camera.matrixWorld );
  6002. var inverse = camera.matrixWorldInverse;
  6003. 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] );
  6004. this.LODs[ 0 ].object3D.visible = true;
  6005. for ( var l = 1; l < this.LODs.length; l ++ ) {
  6006. if( distance >= this.LODs[ l ].visibleAtDistance ) {
  6007. this.LODs[ l - 1 ].object3D.visible = false;
  6008. this.LODs[ l ].object3D.visible = true;
  6009. } else {
  6010. break;
  6011. }
  6012. }
  6013. for( ; l < this.LODs.length; l ++ ) {
  6014. this.LODs[ l ].object3D.visible = false;
  6015. }
  6016. }
  6017. };
  6018. /**
  6019. * @author mikael emtinger / http://gomo.se/
  6020. */
  6021. THREE.Sprite = function ( parameters ) {
  6022. THREE.Object3D.call( this );
  6023. this.color = ( parameters.color !== undefined ) ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
  6024. this.map = ( parameters.map !== undefined ) ? parameters.map : new THREE.Texture();
  6025. this.blending = ( parameters.blending !== undefined ) ? parameters.blending : THREE.NormalBlending;
  6026. this.blendSrc = parameters.blendSrc !== undefined ? parameters.blendSrc : THREE.SrcAlphaFactor;
  6027. this.blendDst = parameters.blendDst !== undefined ? parameters.blendDst : THREE.OneMinusSrcAlphaFactor;
  6028. this.blendEquation = parameters.blendEquation !== undefined ? parameters.blendEquation : THREE.AddEquation;
  6029. this.useScreenCoordinates = ( parameters.useScreenCoordinates !== undefined ) ? parameters.useScreenCoordinates : true;
  6030. this.mergeWith3D = ( parameters.mergeWith3D !== undefined ) ? parameters.mergeWith3D : !this.useScreenCoordinates;
  6031. this.affectedByDistance = ( parameters.affectedByDistance !== undefined ) ? parameters.affectedByDistance : !this.useScreenCoordinates;
  6032. this.scaleByViewport = ( parameters.scaleByViewport !== undefined ) ? parameters.scaleByViewport : !this.affectedByDistance;
  6033. this.alignment = ( parameters.alignment instanceof THREE.Vector2 ) ? parameters.alignment : THREE.SpriteAlignment.center;
  6034. this.rotation3d = this.rotation;
  6035. this.rotation = 0;
  6036. this.opacity = 1;
  6037. this.uvOffset = new THREE.Vector2( 0, 0 );
  6038. this.uvScale = new THREE.Vector2( 1, 1 );
  6039. };
  6040. THREE.Sprite.prototype = Object.create( THREE.Object3D.prototype );
  6041. /*
  6042. * Custom update matrix
  6043. */
  6044. THREE.Sprite.prototype.updateMatrix = function () {
  6045. this.matrix.setPosition( this.position );
  6046. this.rotation3d.set( 0, 0, this.rotation );
  6047. this.matrix.setRotationFromEuler( this.rotation3d );
  6048. if ( this.scale.x !== 1 || this.scale.y !== 1 ) {
  6049. this.matrix.scale( this.scale );
  6050. this.boundRadiusScale = Math.max( this.scale.x, this.scale.y );
  6051. }
  6052. this.matrixWorldNeedsUpdate = true;
  6053. };
  6054. /*
  6055. * Alignment
  6056. */
  6057. THREE.SpriteAlignment = {};
  6058. THREE.SpriteAlignment.topLeft = new THREE.Vector2( 1, -1 );
  6059. THREE.SpriteAlignment.topCenter = new THREE.Vector2( 0, -1 );
  6060. THREE.SpriteAlignment.topRight = new THREE.Vector2( -1, -1 );
  6061. THREE.SpriteAlignment.centerLeft = new THREE.Vector2( 1, 0 );
  6062. THREE.SpriteAlignment.center = new THREE.Vector2( 0, 0 );
  6063. THREE.SpriteAlignment.centerRight = new THREE.Vector2( -1, 0 );
  6064. THREE.SpriteAlignment.bottomLeft = new THREE.Vector2( 1, 1 );
  6065. THREE.SpriteAlignment.bottomCenter = new THREE.Vector2( 0, 1 );
  6066. THREE.SpriteAlignment.bottomRight = new THREE.Vector2( -1, 1 );
  6067. /**
  6068. * @author mr.doob / http://mrdoob.com/
  6069. */
  6070. THREE.Scene = function () {
  6071. THREE.Object3D.call( this );
  6072. this.fog = null;
  6073. this.overrideMaterial = null;
  6074. this.matrixAutoUpdate = false;
  6075. this.__objects = [];
  6076. this.__lights = [];
  6077. this.__objectsAdded = [];
  6078. this.__objectsRemoved = [];
  6079. };
  6080. THREE.Scene.prototype = Object.create( THREE.Object3D.prototype );
  6081. THREE.Scene.prototype.__addObject = function ( object ) {
  6082. if ( object instanceof THREE.Light ) {
  6083. if ( this.__lights.indexOf( object ) === - 1 ) {
  6084. this.__lights.push( object );
  6085. }
  6086. } else if ( !( object instanceof THREE.Camera || object instanceof THREE.Bone ) ) {
  6087. if ( this.__objects.indexOf( object ) === - 1 ) {
  6088. this.__objects.push( object );
  6089. this.__objectsAdded.push( object );
  6090. // check if previously removed
  6091. var i = this.__objectsRemoved.indexOf( object );
  6092. if ( i !== -1 ) {
  6093. this.__objectsRemoved.splice( i, 1 );
  6094. }
  6095. }
  6096. }
  6097. for ( var c = 0; c < object.children.length; c ++ ) {
  6098. this.__addObject( object.children[ c ] );
  6099. }
  6100. };
  6101. THREE.Scene.prototype.__removeObject = function ( object ) {
  6102. if ( object instanceof THREE.Light ) {
  6103. var i = this.__lights.indexOf( object );
  6104. if ( i !== -1 ) {
  6105. this.__lights.splice( i, 1 );
  6106. }
  6107. } else if ( !( object instanceof THREE.Camera ) ) {
  6108. var i = this.__objects.indexOf( object );
  6109. if( i !== -1 ) {
  6110. this.__objects.splice( i, 1 );
  6111. this.__objectsRemoved.push( object );
  6112. // check if previously added
  6113. var ai = this.__objectsAdded.indexOf( object );
  6114. if ( ai !== -1 ) {
  6115. this.__objectsAdded.splice( ai, 1 );
  6116. }
  6117. }
  6118. }
  6119. for ( var c = 0; c < object.children.length; c ++ ) {
  6120. this.__removeObject( object.children[ c ] );
  6121. }
  6122. };
  6123. /**
  6124. * @author mr.doob / http://mrdoob.com/
  6125. * @author alteredq / http://alteredqualia.com/
  6126. */
  6127. THREE.Fog = function ( hex, near, far ) {
  6128. this.color = new THREE.Color( hex );
  6129. this.near = ( near !== undefined ) ? near : 1;
  6130. this.far = ( far !== undefined ) ? far : 1000;
  6131. };
  6132. /**
  6133. * @author mr.doob / http://mrdoob.com/
  6134. * @author alteredq / http://alteredqualia.com/
  6135. */
  6136. THREE.FogExp2 = function ( hex, density ) {
  6137. this.color = new THREE.Color( hex );
  6138. this.density = ( density !== undefined ) ? density : 0.00025;
  6139. };
  6140. /**
  6141. * @author alteredq / http://alteredqualia.com/
  6142. * @author mrdoob / http://mrdoob.com/
  6143. * @author mikael emtinger / http://gomo.se/
  6144. */
  6145. THREE.ShaderChunk = {
  6146. // FOG
  6147. fog_pars_fragment: [
  6148. "#ifdef USE_FOG",
  6149. "uniform vec3 fogColor;",
  6150. "#ifdef FOG_EXP2",
  6151. "uniform float fogDensity;",
  6152. "#else",
  6153. "uniform float fogNear;",
  6154. "uniform float fogFar;",
  6155. "#endif",
  6156. "#endif"
  6157. ].join("\n"),
  6158. fog_fragment: [
  6159. "#ifdef USE_FOG",
  6160. "float depth = gl_FragCoord.z / gl_FragCoord.w;",
  6161. "#ifdef FOG_EXP2",
  6162. "const float LOG2 = 1.442695;",
  6163. "float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );",
  6164. "fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );",
  6165. "#else",
  6166. "float fogFactor = smoothstep( fogNear, fogFar, depth );",
  6167. "#endif",
  6168. "gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );",
  6169. "#endif"
  6170. ].join("\n"),
  6171. // ENVIRONMENT MAP
  6172. envmap_pars_fragment: [
  6173. "#ifdef USE_ENVMAP",
  6174. "varying vec3 vReflect;",
  6175. "uniform float reflectivity;",
  6176. "uniform samplerCube envMap;",
  6177. "uniform float flipEnvMap;",
  6178. "uniform int combine;",
  6179. "#endif"
  6180. ].join("\n"),
  6181. envmap_fragment: [
  6182. "#ifdef USE_ENVMAP",
  6183. "#ifdef DOUBLE_SIDED",
  6184. "float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );",
  6185. "vec4 cubeColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * vReflect.x, vReflect.yz ) );",
  6186. "#else",
  6187. "vec4 cubeColor = textureCube( envMap, vec3( flipEnvMap * vReflect.x, vReflect.yz ) );",
  6188. "#endif",
  6189. "#ifdef GAMMA_INPUT",
  6190. "cubeColor.xyz *= cubeColor.xyz;",
  6191. "#endif",
  6192. "if ( combine == 1 ) {",
  6193. "gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, reflectivity );",
  6194. "} else {",
  6195. "gl_FragColor.xyz = gl_FragColor.xyz * cubeColor.xyz;",
  6196. "}",
  6197. "#endif"
  6198. ].join("\n"),
  6199. envmap_pars_vertex: [
  6200. "#ifdef USE_ENVMAP",
  6201. "varying vec3 vReflect;",
  6202. "uniform float refractionRatio;",
  6203. "uniform bool useRefract;",
  6204. "#endif"
  6205. ].join("\n"),
  6206. envmap_vertex : [
  6207. "#ifdef USE_ENVMAP",
  6208. "vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
  6209. "vec3 nWorld = mat3( objectMatrix[ 0 ].xyz, objectMatrix[ 1 ].xyz, objectMatrix[ 2 ].xyz ) * normal;",
  6210. "if ( useRefract ) {",
  6211. "vReflect = refract( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ), refractionRatio );",
  6212. "} else {",
  6213. "vReflect = reflect( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ) );",
  6214. "}",
  6215. "#endif"
  6216. ].join("\n"),
  6217. // COLOR MAP (particles)
  6218. map_particle_pars_fragment: [
  6219. "#ifdef USE_MAP",
  6220. "uniform sampler2D map;",
  6221. "#endif"
  6222. ].join("\n"),
  6223. map_particle_fragment: [
  6224. "#ifdef USE_MAP",
  6225. "gl_FragColor = gl_FragColor * texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) );",
  6226. "#endif"
  6227. ].join("\n"),
  6228. // COLOR MAP (triangles)
  6229. map_pars_vertex: [
  6230. "#ifdef USE_MAP",
  6231. "varying vec2 vUv;",
  6232. "uniform vec4 offsetRepeat;",
  6233. "#endif"
  6234. ].join("\n"),
  6235. map_pars_fragment: [
  6236. "#ifdef USE_MAP",
  6237. "varying vec2 vUv;",
  6238. "uniform sampler2D map;",
  6239. "#endif"
  6240. ].join("\n"),
  6241. map_vertex: [
  6242. "#ifdef USE_MAP",
  6243. "vUv = uv * offsetRepeat.zw + offsetRepeat.xy;",
  6244. "#endif"
  6245. ].join("\n"),
  6246. map_fragment: [
  6247. "#ifdef USE_MAP",
  6248. "#ifdef GAMMA_INPUT",
  6249. "vec4 texelColor = texture2D( map, vUv );",
  6250. "texelColor.xyz *= texelColor.xyz;",
  6251. "gl_FragColor = gl_FragColor * texelColor;",
  6252. "#else",
  6253. "gl_FragColor = gl_FragColor * texture2D( map, vUv );",
  6254. "#endif",
  6255. "#endif"
  6256. ].join("\n"),
  6257. // LIGHT MAP
  6258. lightmap_pars_fragment: [
  6259. "#ifdef USE_LIGHTMAP",
  6260. "varying vec2 vUv2;",
  6261. "uniform sampler2D lightMap;",
  6262. "#endif"
  6263. ].join("\n"),
  6264. lightmap_pars_vertex: [
  6265. "#ifdef USE_LIGHTMAP",
  6266. "varying vec2 vUv2;",
  6267. "#endif"
  6268. ].join("\n"),
  6269. lightmap_fragment: [
  6270. "#ifdef USE_LIGHTMAP",
  6271. "gl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 );",
  6272. "#endif"
  6273. ].join("\n"),
  6274. lightmap_vertex: [
  6275. "#ifdef USE_LIGHTMAP",
  6276. "vUv2 = uv2;",
  6277. "#endif"
  6278. ].join("\n"),
  6279. // LIGHTS LAMBERT
  6280. lights_lambert_pars_vertex: [
  6281. "uniform vec3 ambient;",
  6282. "uniform vec3 diffuse;",
  6283. "uniform vec3 emissive;",
  6284. "uniform vec3 ambientLightColor;",
  6285. "#if MAX_DIR_LIGHTS > 0",
  6286. "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
  6287. "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
  6288. "#endif",
  6289. "#if MAX_POINT_LIGHTS > 0",
  6290. "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
  6291. "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
  6292. "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
  6293. "#endif",
  6294. "#if MAX_SPOT_LIGHTS > 0",
  6295. "uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];",
  6296. "uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
  6297. "uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];",
  6298. "uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
  6299. "uniform float spotLightAngle[ MAX_SPOT_LIGHTS ];",
  6300. "uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",
  6301. "#endif",
  6302. "#ifdef WRAP_AROUND",
  6303. "uniform vec3 wrapRGB;",
  6304. "#endif"
  6305. ].join("\n"),
  6306. lights_lambert_vertex: [
  6307. "vLightFront = vec3( 0.0 );",
  6308. "#ifdef DOUBLE_SIDED",
  6309. "vLightBack = vec3( 0.0 );",
  6310. "#endif",
  6311. "transformedNormal = normalize( transformedNormal );",
  6312. "#if MAX_DIR_LIGHTS > 0",
  6313. "for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
  6314. "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
  6315. "vec3 dirVector = normalize( lDirection.xyz );",
  6316. "float dotProduct = dot( transformedNormal, dirVector );",
  6317. "vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );",
  6318. "#ifdef DOUBLE_SIDED",
  6319. "vec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );",
  6320. "#ifdef WRAP_AROUND",
  6321. "vec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );",
  6322. "#endif",
  6323. "#endif",
  6324. "#ifdef WRAP_AROUND",
  6325. "vec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );",
  6326. "directionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );",
  6327. "#ifdef DOUBLE_SIDED",
  6328. "directionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );",
  6329. "#endif",
  6330. "#endif",
  6331. "vLightFront += directionalLightColor[ i ] * directionalLightWeighting;",
  6332. "#ifdef DOUBLE_SIDED",
  6333. "vLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;",
  6334. "#endif",
  6335. "}",
  6336. "#endif",
  6337. "#if MAX_POINT_LIGHTS > 0",
  6338. "for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
  6339. "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
  6340. "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
  6341. "float lDistance = 1.0;",
  6342. "if ( pointLightDistance[ i ] > 0.0 )",
  6343. "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
  6344. "lVector = normalize( lVector );",
  6345. "float dotProduct = dot( transformedNormal, lVector );",
  6346. "vec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );",
  6347. "#ifdef DOUBLE_SIDED",
  6348. "vec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );",
  6349. "#ifdef WRAP_AROUND",
  6350. "vec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );",
  6351. "#endif",
  6352. "#endif",
  6353. "#ifdef WRAP_AROUND",
  6354. "vec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );",
  6355. "pointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );",
  6356. "#ifdef DOUBLE_SIDED",
  6357. "pointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );",
  6358. "#endif",
  6359. "#endif",
  6360. "vLightFront += pointLightColor[ i ] * pointLightWeighting * lDistance;",
  6361. "#ifdef DOUBLE_SIDED",
  6362. "vLightBack += pointLightColor[ i ] * pointLightWeightingBack * lDistance;",
  6363. "#endif",
  6364. "}",
  6365. "#endif",
  6366. "#if MAX_SPOT_LIGHTS > 0",
  6367. "for( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
  6368. "vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
  6369. "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
  6370. "lVector = normalize( lVector );",
  6371. "float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - mPosition.xyz ) );",
  6372. "if ( spotEffect > spotLightAngle[ i ] ) {",
  6373. "spotEffect = pow( spotEffect, spotLightExponent[ i ] );",
  6374. "float lDistance = 1.0;",
  6375. "if ( spotLightDistance[ i ] > 0.0 )",
  6376. "lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",
  6377. "float dotProduct = dot( transformedNormal, lVector );",
  6378. "vec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );",
  6379. "#ifdef DOUBLE_SIDED",
  6380. "vec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );",
  6381. "#ifdef WRAP_AROUND",
  6382. "vec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );",
  6383. "#endif",
  6384. "#endif",
  6385. "#ifdef WRAP_AROUND",
  6386. "vec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );",
  6387. "spotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );",
  6388. "#ifdef DOUBLE_SIDED",
  6389. "spotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );",
  6390. "#endif",
  6391. "#endif",
  6392. "vLightFront += spotLightColor[ i ] * spotLightWeighting * lDistance * spotEffect;",
  6393. "#ifdef DOUBLE_SIDED",
  6394. "vLightBack += spotLightColor[ i ] * spotLightWeightingBack * lDistance * spotEffect;",
  6395. "#endif",
  6396. "}",
  6397. "}",
  6398. "#endif",
  6399. "vLightFront = vLightFront * diffuse + ambient * ambientLightColor + emissive;",
  6400. "#ifdef DOUBLE_SIDED",
  6401. "vLightBack = vLightBack * diffuse + ambient * ambientLightColor + emissive;",
  6402. "#endif"
  6403. ].join("\n"),
  6404. // LIGHTS PHONG
  6405. lights_phong_pars_vertex: [
  6406. "#ifndef PHONG_PER_PIXEL",
  6407. "#if MAX_POINT_LIGHTS > 0",
  6408. "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
  6409. "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
  6410. "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
  6411. "#endif",
  6412. "#if MAX_SPOT_LIGHTS > 0",
  6413. "uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
  6414. "uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
  6415. "varying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];",
  6416. "#endif",
  6417. "#endif",
  6418. "#if MAX_SPOT_LIGHTS > 0",
  6419. "varying vec3 vWorldPosition;",
  6420. "#endif"
  6421. ].join("\n"),
  6422. lights_phong_vertex: [
  6423. "#ifndef PHONG_PER_PIXEL",
  6424. "#if MAX_POINT_LIGHTS > 0",
  6425. "for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
  6426. "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
  6427. "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
  6428. "float lDistance = 1.0;",
  6429. "if ( pointLightDistance[ i ] > 0.0 )",
  6430. "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
  6431. "vPointLight[ i ] = vec4( lVector, lDistance );",
  6432. "}",
  6433. "#endif",
  6434. "#if MAX_SPOT_LIGHTS > 0",
  6435. "for( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
  6436. "vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
  6437. "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
  6438. "float lDistance = 1.0;",
  6439. "if ( spotLightDistance[ i ] > 0.0 )",
  6440. "lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",
  6441. "vSpotLight[ i ] = vec4( lVector, lDistance );",
  6442. "}",
  6443. "#endif",
  6444. "#endif",
  6445. "#if MAX_SPOT_LIGHTS > 0",
  6446. "vWorldPosition = mPosition.xyz;",
  6447. "#endif"
  6448. ].join("\n"),
  6449. lights_phong_pars_fragment: [
  6450. "uniform vec3 ambientLightColor;",
  6451. "#if MAX_DIR_LIGHTS > 0",
  6452. "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
  6453. "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
  6454. "#endif",
  6455. "#if MAX_POINT_LIGHTS > 0",
  6456. "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
  6457. "#ifdef PHONG_PER_PIXEL",
  6458. "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
  6459. "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
  6460. "#else",
  6461. "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
  6462. "#endif",
  6463. "#endif",
  6464. "#if MAX_SPOT_LIGHTS > 0",
  6465. "uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];",
  6466. "uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
  6467. "uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];",
  6468. "uniform float spotLightAngle[ MAX_SPOT_LIGHTS ];",
  6469. "uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",
  6470. "#ifdef PHONG_PER_PIXEL",
  6471. "uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
  6472. "#else",
  6473. "varying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];",
  6474. "#endif",
  6475. "varying vec3 vWorldPosition;",
  6476. "#endif",
  6477. "#ifdef WRAP_AROUND",
  6478. "uniform vec3 wrapRGB;",
  6479. "#endif",
  6480. "varying vec3 vViewPosition;",
  6481. "varying vec3 vNormal;"
  6482. ].join("\n"),
  6483. lights_phong_fragment: [
  6484. "vec3 normal = normalize( vNormal );",
  6485. "vec3 viewPosition = normalize( vViewPosition );",
  6486. "#ifdef DOUBLE_SIDED",
  6487. "normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );",
  6488. "#endif",
  6489. "#if MAX_POINT_LIGHTS > 0",
  6490. "vec3 pointDiffuse = vec3( 0.0 );",
  6491. "vec3 pointSpecular = vec3( 0.0 );",
  6492. "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
  6493. "#ifdef PHONG_PER_PIXEL",
  6494. "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
  6495. "vec3 lVector = lPosition.xyz + vViewPosition.xyz;",
  6496. "float lDistance = 1.0;",
  6497. "if ( pointLightDistance[ i ] > 0.0 )",
  6498. "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
  6499. "lVector = normalize( lVector );",
  6500. "#else",
  6501. "vec3 lVector = normalize( vPointLight[ i ].xyz );",
  6502. "float lDistance = vPointLight[ i ].w;",
  6503. "#endif",
  6504. // diffuse
  6505. "float dotProduct = dot( normal, lVector );",
  6506. "#ifdef WRAP_AROUND",
  6507. "float pointDiffuseWeightFull = max( dotProduct, 0.0 );",
  6508. "float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",
  6509. "vec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );",
  6510. "#else",
  6511. "float pointDiffuseWeight = max( dotProduct, 0.0 );",
  6512. "#endif",
  6513. "pointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;",
  6514. // specular
  6515. "vec3 pointHalfVector = normalize( lVector + viewPosition );",
  6516. "float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );",
  6517. "float pointSpecularWeight = max( pow( pointDotNormalHalf, shininess ), 0.0 );",
  6518. "#ifdef PHYSICALLY_BASED_SHADING",
  6519. // 2.0 => 2.0001 is hack to work around ANGLE bug
  6520. "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
  6521. "vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, pointHalfVector ), 5.0 );",
  6522. "pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;",
  6523. "#else",
  6524. "pointSpecular += specular * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance;",
  6525. "#endif",
  6526. "}",
  6527. "#endif",
  6528. "#if MAX_SPOT_LIGHTS > 0",
  6529. "vec3 spotDiffuse = vec3( 0.0 );",
  6530. "vec3 spotSpecular = vec3( 0.0 );",
  6531. "for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
  6532. "#ifdef PHONG_PER_PIXEL",
  6533. "vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
  6534. "vec3 lVector = lPosition.xyz + vViewPosition.xyz;",
  6535. "float lDistance = 1.0;",
  6536. "if ( spotLightDistance[ i ] > 0.0 )",
  6537. "lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",
  6538. "lVector = normalize( lVector );",
  6539. "#else",
  6540. "vec3 lVector = normalize( vSpotLight[ i ].xyz );",
  6541. "float lDistance = vSpotLight[ i ].w;",
  6542. "#endif",
  6543. "float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );",
  6544. "if ( spotEffect > spotLightAngle[ i ] ) {",
  6545. "spotEffect = pow( spotEffect, spotLightExponent[ i ] );",
  6546. // diffuse
  6547. "float dotProduct = dot( normal, lVector );",
  6548. "#ifdef WRAP_AROUND",
  6549. "float spotDiffuseWeightFull = max( dotProduct, 0.0 );",
  6550. "float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",
  6551. "vec3 spotDiffuseWeight = mix( vec3 ( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );",
  6552. "#else",
  6553. "float spotDiffuseWeight = max( dotProduct, 0.0 );",
  6554. "#endif",
  6555. "spotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect;",
  6556. // specular
  6557. "vec3 spotHalfVector = normalize( lVector + viewPosition );",
  6558. "float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );",
  6559. "float spotSpecularWeight = max( pow( spotDotNormalHalf, shininess ), 0.0 );",
  6560. "#ifdef PHYSICALLY_BASED_SHADING",
  6561. // 2.0 => 2.0001 is hack to work around ANGLE bug
  6562. "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
  6563. "vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, spotHalfVector ), 5.0 );",
  6564. "spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect;",
  6565. "#else",
  6566. "spotSpecular += specular * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * spotEffect;",
  6567. "#endif",
  6568. "}",
  6569. "}",
  6570. "#endif",
  6571. "#if MAX_DIR_LIGHTS > 0",
  6572. "vec3 dirDiffuse = vec3( 0.0 );",
  6573. "vec3 dirSpecular = vec3( 0.0 );" ,
  6574. "for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
  6575. "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
  6576. "vec3 dirVector = normalize( lDirection.xyz );",
  6577. // diffuse
  6578. "float dotProduct = dot( normal, dirVector );",
  6579. "#ifdef WRAP_AROUND",
  6580. "float dirDiffuseWeightFull = max( dotProduct, 0.0 );",
  6581. "float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",
  6582. "vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );",
  6583. "#else",
  6584. "float dirDiffuseWeight = max( dotProduct, 0.0 );",
  6585. "#endif",
  6586. "dirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;",
  6587. // specular
  6588. "vec3 dirHalfVector = normalize( dirVector + viewPosition );",
  6589. "float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
  6590. "float dirSpecularWeight = max( pow( dirDotNormalHalf, shininess ), 0.0 );",
  6591. "#ifdef PHYSICALLY_BASED_SHADING",
  6592. /*
  6593. // fresnel term from skin shader
  6594. "const float F0 = 0.128;",
  6595. "float base = 1.0 - dot( viewPosition, dirHalfVector );",
  6596. "float exponential = pow( base, 5.0 );",
  6597. "float fresnel = exponential + F0 * ( 1.0 - exponential );",
  6598. */
  6599. /*
  6600. // fresnel term from fresnel shader
  6601. "const float mFresnelBias = 0.08;",
  6602. "const float mFresnelScale = 0.3;",
  6603. "const float mFresnelPower = 5.0;",
  6604. "float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );",
  6605. */
  6606. // 2.0 => 2.0001 is hack to work around ANGLE bug
  6607. "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
  6608. //"dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;",
  6609. "vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );",
  6610. "dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;",
  6611. "#else",
  6612. "dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight;",
  6613. "#endif",
  6614. "}",
  6615. "#endif",
  6616. "vec3 totalDiffuse = vec3( 0.0 );",
  6617. "vec3 totalSpecular = vec3( 0.0 );",
  6618. "#if MAX_DIR_LIGHTS > 0",
  6619. "totalDiffuse += dirDiffuse;",
  6620. "totalSpecular += dirSpecular;",
  6621. "#endif",
  6622. "#if MAX_POINT_LIGHTS > 0",
  6623. "totalDiffuse += pointDiffuse;",
  6624. "totalSpecular += pointSpecular;",
  6625. "#endif",
  6626. "#if MAX_SPOT_LIGHTS > 0",
  6627. "totalDiffuse += spotDiffuse;",
  6628. "totalSpecular += spotSpecular;",
  6629. "#endif",
  6630. "#ifdef METAL",
  6631. "gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular );",
  6632. "#else",
  6633. "gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular;",
  6634. "#endif"
  6635. ].join("\n"),
  6636. // VERTEX COLORS
  6637. color_pars_fragment: [
  6638. "#ifdef USE_COLOR",
  6639. "varying vec3 vColor;",
  6640. "#endif"
  6641. ].join("\n"),
  6642. color_fragment: [
  6643. "#ifdef USE_COLOR",
  6644. "gl_FragColor = gl_FragColor * vec4( vColor, opacity );",
  6645. "#endif"
  6646. ].join("\n"),
  6647. color_pars_vertex: [
  6648. "#ifdef USE_COLOR",
  6649. "varying vec3 vColor;",
  6650. "#endif"
  6651. ].join("\n"),
  6652. color_vertex: [
  6653. "#ifdef USE_COLOR",
  6654. "#ifdef GAMMA_INPUT",
  6655. "vColor = color * color;",
  6656. "#else",
  6657. "vColor = color;",
  6658. "#endif",
  6659. "#endif"
  6660. ].join("\n"),
  6661. // SKINNING
  6662. skinning_pars_vertex: [
  6663. "#ifdef USE_SKINNING",
  6664. "#ifdef BONE_TEXTURE",
  6665. "uniform sampler2D boneTexture;",
  6666. "mat4 getBoneMatrix( const in float i ) {",
  6667. "float j = i * 4.0;",
  6668. "float x = mod( j, N_BONE_PIXEL_X );",
  6669. "float y = floor( j / N_BONE_PIXEL_X );",
  6670. "const float dx = 1.0 / N_BONE_PIXEL_X;",
  6671. "const float dy = 1.0 / N_BONE_PIXEL_Y;",
  6672. "y = dy * ( y + 0.5 );",
  6673. "vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );",
  6674. "vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );",
  6675. "vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );",
  6676. "vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );",
  6677. "mat4 bone = mat4( v1, v2, v3, v4 );",
  6678. "return bone;",
  6679. "}",
  6680. "#else",
  6681. "uniform mat4 boneGlobalMatrices[ MAX_BONES ];",
  6682. "mat4 getBoneMatrix( const in float i ) {",
  6683. "mat4 bone = boneGlobalMatrices[ int(i) ];",
  6684. "return bone;",
  6685. "}",
  6686. "#endif",
  6687. "#endif"
  6688. ].join("\n"),
  6689. skinbase_vertex: [
  6690. "#ifdef USE_SKINNING",
  6691. "mat4 boneMatX = getBoneMatrix( skinIndex.x );",
  6692. "mat4 boneMatY = getBoneMatrix( skinIndex.y );",
  6693. "#endif"
  6694. ].join("\n"),
  6695. skinning_vertex: [
  6696. "#ifdef USE_SKINNING",
  6697. "vec4 skinned = boneMatX * skinVertexA * skinWeight.x;",
  6698. "skinned += boneMatY * skinVertexB * skinWeight.y;",
  6699. "gl_Position = projectionMatrix * modelViewMatrix * skinned;",
  6700. "#endif"
  6701. ].join("\n"),
  6702. // MORPHING
  6703. morphtarget_pars_vertex: [
  6704. "#ifdef USE_MORPHTARGETS",
  6705. "#ifndef USE_MORPHNORMALS",
  6706. "uniform float morphTargetInfluences[ 8 ];",
  6707. "#else",
  6708. "uniform float morphTargetInfluences[ 4 ];",
  6709. "#endif",
  6710. "#endif"
  6711. ].join("\n"),
  6712. morphtarget_vertex: [
  6713. "#ifdef USE_MORPHTARGETS",
  6714. "vec3 morphed = vec3( 0.0 );",
  6715. "morphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];",
  6716. "morphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];",
  6717. "morphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];",
  6718. "morphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];",
  6719. "#ifndef USE_MORPHNORMALS",
  6720. "morphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];",
  6721. "morphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];",
  6722. "morphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];",
  6723. "morphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];",
  6724. "#endif",
  6725. "morphed += position;",
  6726. "gl_Position = projectionMatrix * modelViewMatrix * vec4( morphed, 1.0 );",
  6727. "#endif"
  6728. ].join("\n"),
  6729. default_vertex : [
  6730. "#ifndef USE_MORPHTARGETS",
  6731. "#ifndef USE_SKINNING",
  6732. "gl_Position = projectionMatrix * mvPosition;",
  6733. "#endif",
  6734. "#endif"
  6735. ].join("\n"),
  6736. morphnormal_vertex: [
  6737. "#ifdef USE_MORPHNORMALS",
  6738. "vec3 morphedNormal = vec3( 0.0 );",
  6739. "morphedNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];",
  6740. "morphedNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];",
  6741. "morphedNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];",
  6742. "morphedNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];",
  6743. "morphedNormal += normal;",
  6744. "vec3 transformedNormal = normalMatrix * morphedNormal;",
  6745. "#else",
  6746. "vec3 transformedNormal = normalMatrix * normal;",
  6747. "#endif"
  6748. ].join("\n"),
  6749. skinnormal_vertex: [
  6750. "#ifdef USE_SKINNING",
  6751. "mat4 skinMatrix = skinWeight.x * boneMatX;",
  6752. "skinMatrix += skinWeight.y * boneMatY;",
  6753. "vec4 skinnedNormal = skinMatrix * vec4( transformedNormal, 0.0 );",
  6754. "transformedNormal = skinnedNormal.xyz;",
  6755. "#endif"
  6756. ].join("\n"),
  6757. // SHADOW MAP
  6758. // based on SpiderGL shadow map and Fabien Sanglard's GLSL shadow mapping examples
  6759. // http://spidergl.org/example.php?id=6
  6760. // http://fabiensanglard.net/shadowmapping
  6761. shadowmap_pars_fragment: [
  6762. "#ifdef USE_SHADOWMAP",
  6763. "uniform sampler2D shadowMap[ MAX_SHADOWS ];",
  6764. "uniform vec2 shadowMapSize[ MAX_SHADOWS ];",
  6765. "uniform float shadowDarkness[ MAX_SHADOWS ];",
  6766. "uniform float shadowBias[ MAX_SHADOWS ];",
  6767. "varying vec4 vShadowCoord[ MAX_SHADOWS ];",
  6768. "float unpackDepth( const in vec4 rgba_depth ) {",
  6769. "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 );",
  6770. "float depth = dot( rgba_depth, bit_shift );",
  6771. "return depth;",
  6772. "}",
  6773. "#endif"
  6774. ].join("\n"),
  6775. shadowmap_fragment: [
  6776. "#ifdef USE_SHADOWMAP",
  6777. "#ifdef SHADOWMAP_DEBUG",
  6778. "vec3 frustumColors[3];",
  6779. "frustumColors[0] = vec3( 1.0, 0.5, 0.0 );",
  6780. "frustumColors[1] = vec3( 0.0, 1.0, 0.8 );",
  6781. "frustumColors[2] = vec3( 0.0, 0.5, 1.0 );",
  6782. "#endif",
  6783. "#ifdef SHADOWMAP_CASCADE",
  6784. "int inFrustumCount = 0;",
  6785. "#endif",
  6786. "float fDepth;",
  6787. "vec3 shadowColor = vec3( 1.0 );",
  6788. "for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
  6789. "vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;",
  6790. // "if ( something && something )" breaks ATI OpenGL shader compiler
  6791. // "if ( all( something, something ) )" using this instead
  6792. "bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );",
  6793. "bool inFrustum = all( inFrustumVec );",
  6794. // don't shadow pixels outside of light frustum
  6795. // use just first frustum (for cascades)
  6796. // don't shadow pixels behind far plane of light frustum
  6797. "#ifdef SHADOWMAP_CASCADE",
  6798. "inFrustumCount += int( inFrustum );",
  6799. "bvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );",
  6800. "#else",
  6801. "bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );",
  6802. "#endif",
  6803. "bool frustumTest = all( frustumTestVec );",
  6804. "if ( frustumTest ) {",
  6805. "shadowCoord.z += shadowBias[ i ];",
  6806. "#ifdef SHADOWMAP_SOFT",
  6807. // Percentage-close filtering
  6808. // (9 pixel kernel)
  6809. // http://fabiensanglard.net/shadowmappingPCF/
  6810. "float shadow = 0.0;",
  6811. /*
  6812. // nested loops breaks shader compiler / validator on some ATI cards when using OpenGL
  6813. // must enroll loop manually
  6814. "for ( float y = -1.25; y <= 1.25; y += 1.25 )",
  6815. "for ( float x = -1.25; x <= 1.25; x += 1.25 ) {",
  6816. "vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );",
  6817. // doesn't seem to produce any noticeable visual difference compared to simple "texture2D" lookup
  6818. //"vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );",
  6819. "float fDepth = unpackDepth( rgbaDepth );",
  6820. "if ( fDepth < shadowCoord.z )",
  6821. "shadow += 1.0;",
  6822. "}",
  6823. "shadow /= 9.0;",
  6824. */
  6825. "const float shadowDelta = 1.0 / 9.0;",
  6826. "float xPixelOffset = 1.0 / shadowMapSize[ i ].x;",
  6827. "float yPixelOffset = 1.0 / shadowMapSize[ i ].y;",
  6828. "float dx0 = -1.25 * xPixelOffset;",
  6829. "float dy0 = -1.25 * yPixelOffset;",
  6830. "float dx1 = 1.25 * xPixelOffset;",
  6831. "float dy1 = 1.25 * yPixelOffset;",
  6832. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );",
  6833. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  6834. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );",
  6835. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  6836. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );",
  6837. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  6838. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );",
  6839. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  6840. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );",
  6841. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  6842. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );",
  6843. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  6844. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );",
  6845. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  6846. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );",
  6847. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  6848. "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );",
  6849. "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
  6850. "shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );",
  6851. "#else",
  6852. "vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );",
  6853. "float fDepth = unpackDepth( rgbaDepth );",
  6854. "if ( fDepth < shadowCoord.z )",
  6855. // spot with multiple shadows is darker
  6856. "shadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );",
  6857. // spot with multiple shadows has the same color as single shadow spot
  6858. //"shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );",
  6859. "#endif",
  6860. "}",
  6861. "#ifdef SHADOWMAP_DEBUG",
  6862. "#ifdef SHADOWMAP_CASCADE",
  6863. "if ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];",
  6864. "#else",
  6865. "if ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];",
  6866. "#endif",
  6867. "#endif",
  6868. "}",
  6869. "#ifdef GAMMA_OUTPUT",
  6870. "shadowColor *= shadowColor;",
  6871. "#endif",
  6872. "gl_FragColor.xyz = gl_FragColor.xyz * shadowColor;",
  6873. "#endif"
  6874. ].join("\n"),
  6875. shadowmap_pars_vertex: [
  6876. "#ifdef USE_SHADOWMAP",
  6877. "varying vec4 vShadowCoord[ MAX_SHADOWS ];",
  6878. "uniform mat4 shadowMatrix[ MAX_SHADOWS ];",
  6879. "#endif"
  6880. ].join("\n"),
  6881. shadowmap_vertex: [
  6882. "#ifdef USE_SHADOWMAP",
  6883. "for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
  6884. "#ifdef USE_MORPHTARGETS",
  6885. "vShadowCoord[ i ] = shadowMatrix[ i ] * objectMatrix * vec4( morphed, 1.0 );",
  6886. "#else",
  6887. "#ifdef USE_SKINNING",
  6888. "vShadowCoord[ i ] = shadowMatrix[ i ] * objectMatrix * skinned;",
  6889. "#else",
  6890. "vShadowCoord[ i ] = shadowMatrix[ i ] * objectMatrix * vec4( position, 1.0 );",
  6891. "#endif",
  6892. "#endif",
  6893. "}",
  6894. "#endif"
  6895. ].join("\n"),
  6896. // ALPHATEST
  6897. alphatest_fragment: [
  6898. "#ifdef ALPHATEST",
  6899. "if ( gl_FragColor.a < ALPHATEST ) discard;",
  6900. "#endif"
  6901. ].join("\n"),
  6902. // LINEAR SPACE
  6903. linear_to_gamma_fragment: [
  6904. "#ifdef GAMMA_OUTPUT",
  6905. "gl_FragColor.xyz = sqrt( gl_FragColor.xyz );",
  6906. "#endif"
  6907. ].join("\n"),
  6908. };
  6909. THREE.UniformsUtils = {
  6910. merge: function ( uniforms ) {
  6911. var u, p, tmp, merged = {};
  6912. for ( u = 0; u < uniforms.length; u++ ) {
  6913. tmp = this.clone( uniforms[ u ] );
  6914. for ( p in tmp ) {
  6915. merged[ p ] = tmp[ p ];
  6916. }
  6917. }
  6918. return merged;
  6919. },
  6920. clone: function ( uniforms_src ) {
  6921. var u, p, parameter, parameter_src, uniforms_dst = {};
  6922. for ( u in uniforms_src ) {
  6923. uniforms_dst[ u ] = {};
  6924. for ( p in uniforms_src[ u ] ) {
  6925. parameter_src = uniforms_src[ u ][ p ];
  6926. if ( parameter_src instanceof THREE.Color ||
  6927. parameter_src instanceof THREE.Vector2 ||
  6928. parameter_src instanceof THREE.Vector3 ||
  6929. parameter_src instanceof THREE.Vector4 ||
  6930. parameter_src instanceof THREE.Matrix4 ||
  6931. parameter_src instanceof THREE.Texture ) {
  6932. uniforms_dst[ u ][ p ] = parameter_src.clone();
  6933. } else if ( parameter_src instanceof Array ) {
  6934. uniforms_dst[ u ][ p ] = parameter_src.slice();
  6935. } else {
  6936. uniforms_dst[ u ][ p ] = parameter_src;
  6937. }
  6938. }
  6939. }
  6940. return uniforms_dst;
  6941. }
  6942. };
  6943. THREE.UniformsLib = {
  6944. common: {
  6945. "diffuse" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
  6946. "opacity" : { type: "f", value: 1.0 },
  6947. "map" : { type: "t", value: 0, texture: null },
  6948. "offsetRepeat" : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) },
  6949. "lightMap" : { type: "t", value: 2, texture: null },
  6950. "envMap" : { type: "t", value: 1, texture: null },
  6951. "flipEnvMap" : { type: "f", value: -1 },
  6952. "useRefract" : { type: "i", value: 0 },
  6953. "reflectivity" : { type: "f", value: 1.0 },
  6954. "refractionRatio" : { type: "f", value: 0.98 },
  6955. "combine" : { type: "i", value: 0 },
  6956. "morphTargetInfluences" : { type: "f", value: 0 }
  6957. },
  6958. fog : {
  6959. "fogDensity" : { type: "f", value: 0.00025 },
  6960. "fogNear" : { type: "f", value: 1 },
  6961. "fogFar" : { type: "f", value: 2000 },
  6962. "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) }
  6963. },
  6964. lights: {
  6965. "ambientLightColor" : { type: "fv", value: [] },
  6966. "directionalLightDirection" : { type: "fv", value: [] },
  6967. "directionalLightColor" : { type: "fv", value: [] },
  6968. "pointLightColor" : { type: "fv", value: [] },
  6969. "pointLightPosition" : { type: "fv", value: [] },
  6970. "pointLightDistance" : { type: "fv1", value: [] },
  6971. "spotLightColor" : { type: "fv", value: [] },
  6972. "spotLightPosition" : { type: "fv", value: [] },
  6973. "spotLightDirection" : { type: "fv", value: [] },
  6974. "spotLightDistance" : { type: "fv1", value: [] },
  6975. "spotLightAngle" : { type: "fv1", value: [] },
  6976. "spotLightExponent" : { type: "fv1", value: [] }
  6977. },
  6978. particle: {
  6979. "psColor" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
  6980. "opacity" : { type: "f", value: 1.0 },
  6981. "size" : { type: "f", value: 1.0 },
  6982. "scale" : { type: "f", value: 1.0 },
  6983. "map" : { type: "t", value: 0, texture: null },
  6984. "fogDensity" : { type: "f", value: 0.00025 },
  6985. "fogNear" : { type: "f", value: 1 },
  6986. "fogFar" : { type: "f", value: 2000 },
  6987. "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) }
  6988. },
  6989. shadowmap: {
  6990. "shadowMap": { type: "tv", value: 6, texture: [] },
  6991. "shadowMapSize": { type: "v2v", value: [] },
  6992. "shadowBias" : { type: "fv1", value: [] },
  6993. "shadowDarkness": { type: "fv1", value: [] },
  6994. "shadowMatrix" : { type: "m4v", value: [] },
  6995. }
  6996. };
  6997. THREE.ShaderLib = {
  6998. 'depth': {
  6999. uniforms: {
  7000. "mNear": { type: "f", value: 1.0 },
  7001. "mFar" : { type: "f", value: 2000.0 },
  7002. "opacity" : { type: "f", value: 1.0 }
  7003. },
  7004. vertexShader: [
  7005. "void main() {",
  7006. "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
  7007. "}"
  7008. ].join("\n"),
  7009. fragmentShader: [
  7010. "uniform float mNear;",
  7011. "uniform float mFar;",
  7012. "uniform float opacity;",
  7013. "void main() {",
  7014. "float depth = gl_FragCoord.z / gl_FragCoord.w;",
  7015. "float color = 1.0 - smoothstep( mNear, mFar, depth );",
  7016. "gl_FragColor = vec4( vec3( color ), opacity );",
  7017. "}"
  7018. ].join("\n")
  7019. },
  7020. 'normal': {
  7021. uniforms: {
  7022. "opacity" : { type: "f", value: 1.0 }
  7023. },
  7024. vertexShader: [
  7025. "varying vec3 vNormal;",
  7026. "void main() {",
  7027. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  7028. "vNormal = normalMatrix * normal;",
  7029. "gl_Position = projectionMatrix * mvPosition;",
  7030. "}"
  7031. ].join("\n"),
  7032. fragmentShader: [
  7033. "uniform float opacity;",
  7034. "varying vec3 vNormal;",
  7035. "void main() {",
  7036. "gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",
  7037. "}"
  7038. ].join("\n")
  7039. },
  7040. 'basic': {
  7041. uniforms: THREE.UniformsUtils.merge( [
  7042. THREE.UniformsLib[ "common" ],
  7043. THREE.UniformsLib[ "fog" ],
  7044. THREE.UniformsLib[ "shadowmap" ]
  7045. ] ),
  7046. vertexShader: [
  7047. THREE.ShaderChunk[ "map_pars_vertex" ],
  7048. THREE.ShaderChunk[ "lightmap_pars_vertex" ],
  7049. THREE.ShaderChunk[ "envmap_pars_vertex" ],
  7050. THREE.ShaderChunk[ "color_pars_vertex" ],
  7051. THREE.ShaderChunk[ "skinning_pars_vertex" ],
  7052. THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
  7053. THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
  7054. "void main() {",
  7055. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  7056. THREE.ShaderChunk[ "map_vertex" ],
  7057. THREE.ShaderChunk[ "lightmap_vertex" ],
  7058. THREE.ShaderChunk[ "envmap_vertex" ],
  7059. THREE.ShaderChunk[ "color_vertex" ],
  7060. THREE.ShaderChunk[ "skinbase_vertex" ],
  7061. THREE.ShaderChunk[ "skinning_vertex" ],
  7062. THREE.ShaderChunk[ "morphtarget_vertex" ],
  7063. THREE.ShaderChunk[ "default_vertex" ],
  7064. THREE.ShaderChunk[ "shadowmap_vertex" ],
  7065. "}"
  7066. ].join("\n"),
  7067. fragmentShader: [
  7068. "uniform vec3 diffuse;",
  7069. "uniform float opacity;",
  7070. THREE.ShaderChunk[ "color_pars_fragment" ],
  7071. THREE.ShaderChunk[ "map_pars_fragment" ],
  7072. THREE.ShaderChunk[ "lightmap_pars_fragment" ],
  7073. THREE.ShaderChunk[ "envmap_pars_fragment" ],
  7074. THREE.ShaderChunk[ "fog_pars_fragment" ],
  7075. THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
  7076. "void main() {",
  7077. "gl_FragColor = vec4( diffuse, opacity );",
  7078. THREE.ShaderChunk[ "map_fragment" ],
  7079. THREE.ShaderChunk[ "alphatest_fragment" ],
  7080. THREE.ShaderChunk[ "lightmap_fragment" ],
  7081. THREE.ShaderChunk[ "color_fragment" ],
  7082. THREE.ShaderChunk[ "envmap_fragment" ],
  7083. THREE.ShaderChunk[ "shadowmap_fragment" ],
  7084. THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
  7085. THREE.ShaderChunk[ "fog_fragment" ],
  7086. "}"
  7087. ].join("\n")
  7088. },
  7089. 'lambert': {
  7090. uniforms: THREE.UniformsUtils.merge( [
  7091. THREE.UniformsLib[ "common" ],
  7092. THREE.UniformsLib[ "fog" ],
  7093. THREE.UniformsLib[ "lights" ],
  7094. THREE.UniformsLib[ "shadowmap" ],
  7095. {
  7096. "ambient" : { type: "c", value: new THREE.Color( 0xffffff ) },
  7097. "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
  7098. "wrapRGB" : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
  7099. }
  7100. ] ),
  7101. vertexShader: [
  7102. "varying vec3 vLightFront;",
  7103. "#ifdef DOUBLE_SIDED",
  7104. "varying vec3 vLightBack;",
  7105. "#endif",
  7106. THREE.ShaderChunk[ "map_pars_vertex" ],
  7107. THREE.ShaderChunk[ "lightmap_pars_vertex" ],
  7108. THREE.ShaderChunk[ "envmap_pars_vertex" ],
  7109. THREE.ShaderChunk[ "lights_lambert_pars_vertex" ],
  7110. THREE.ShaderChunk[ "color_pars_vertex" ],
  7111. THREE.ShaderChunk[ "skinning_pars_vertex" ],
  7112. THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
  7113. THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
  7114. "void main() {",
  7115. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  7116. THREE.ShaderChunk[ "map_vertex" ],
  7117. THREE.ShaderChunk[ "lightmap_vertex" ],
  7118. THREE.ShaderChunk[ "envmap_vertex" ],
  7119. THREE.ShaderChunk[ "color_vertex" ],
  7120. THREE.ShaderChunk[ "morphnormal_vertex" ],
  7121. THREE.ShaderChunk[ "skinbase_vertex" ],
  7122. THREE.ShaderChunk[ "skinnormal_vertex" ],
  7123. "#ifndef USE_ENVMAP",
  7124. "vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
  7125. "#endif",
  7126. THREE.ShaderChunk[ "lights_lambert_vertex" ],
  7127. THREE.ShaderChunk[ "skinning_vertex" ],
  7128. THREE.ShaderChunk[ "morphtarget_vertex" ],
  7129. THREE.ShaderChunk[ "default_vertex" ],
  7130. THREE.ShaderChunk[ "shadowmap_vertex" ],
  7131. "}"
  7132. ].join("\n"),
  7133. fragmentShader: [
  7134. "uniform float opacity;",
  7135. "varying vec3 vLightFront;",
  7136. "#ifdef DOUBLE_SIDED",
  7137. "varying vec3 vLightBack;",
  7138. "#endif",
  7139. THREE.ShaderChunk[ "color_pars_fragment" ],
  7140. THREE.ShaderChunk[ "map_pars_fragment" ],
  7141. THREE.ShaderChunk[ "lightmap_pars_fragment" ],
  7142. THREE.ShaderChunk[ "envmap_pars_fragment" ],
  7143. THREE.ShaderChunk[ "fog_pars_fragment" ],
  7144. THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
  7145. "void main() {",
  7146. "gl_FragColor = vec4( vec3 ( 1.0 ), opacity );",
  7147. THREE.ShaderChunk[ "map_fragment" ],
  7148. THREE.ShaderChunk[ "alphatest_fragment" ],
  7149. "#ifdef DOUBLE_SIDED",
  7150. //"float isFront = float( gl_FrontFacing );",
  7151. //"gl_FragColor.xyz *= isFront * vLightFront + ( 1.0 - isFront ) * vLightBack;",
  7152. "if ( gl_FrontFacing )",
  7153. "gl_FragColor.xyz *= vLightFront;",
  7154. "else",
  7155. "gl_FragColor.xyz *= vLightBack;",
  7156. "#else",
  7157. "gl_FragColor.xyz *= vLightFront;",
  7158. "#endif",
  7159. THREE.ShaderChunk[ "lightmap_fragment" ],
  7160. THREE.ShaderChunk[ "color_fragment" ],
  7161. THREE.ShaderChunk[ "envmap_fragment" ],
  7162. THREE.ShaderChunk[ "shadowmap_fragment" ],
  7163. THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
  7164. THREE.ShaderChunk[ "fog_fragment" ],
  7165. "}"
  7166. ].join("\n")
  7167. },
  7168. 'phong': {
  7169. uniforms: THREE.UniformsUtils.merge( [
  7170. THREE.UniformsLib[ "common" ],
  7171. THREE.UniformsLib[ "fog" ],
  7172. THREE.UniformsLib[ "lights" ],
  7173. THREE.UniformsLib[ "shadowmap" ],
  7174. {
  7175. "ambient" : { type: "c", value: new THREE.Color( 0xffffff ) },
  7176. "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
  7177. "specular" : { type: "c", value: new THREE.Color( 0x111111 ) },
  7178. "shininess": { type: "f", value: 30 },
  7179. "wrapRGB" : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
  7180. }
  7181. ] ),
  7182. vertexShader: [
  7183. "varying vec3 vViewPosition;",
  7184. "varying vec3 vNormal;",
  7185. THREE.ShaderChunk[ "map_pars_vertex" ],
  7186. THREE.ShaderChunk[ "lightmap_pars_vertex" ],
  7187. THREE.ShaderChunk[ "envmap_pars_vertex" ],
  7188. THREE.ShaderChunk[ "lights_phong_pars_vertex" ],
  7189. THREE.ShaderChunk[ "color_pars_vertex" ],
  7190. THREE.ShaderChunk[ "skinning_pars_vertex" ],
  7191. THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
  7192. THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
  7193. "void main() {",
  7194. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  7195. THREE.ShaderChunk[ "map_vertex" ],
  7196. THREE.ShaderChunk[ "lightmap_vertex" ],
  7197. THREE.ShaderChunk[ "envmap_vertex" ],
  7198. THREE.ShaderChunk[ "color_vertex" ],
  7199. "#ifndef USE_ENVMAP",
  7200. "vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
  7201. "#endif",
  7202. "vViewPosition = -mvPosition.xyz;",
  7203. THREE.ShaderChunk[ "morphnormal_vertex" ],
  7204. THREE.ShaderChunk[ "skinbase_vertex" ],
  7205. THREE.ShaderChunk[ "skinnormal_vertex" ],
  7206. "vNormal = transformedNormal;",
  7207. THREE.ShaderChunk[ "lights_phong_vertex" ],
  7208. THREE.ShaderChunk[ "skinning_vertex" ],
  7209. THREE.ShaderChunk[ "morphtarget_vertex" ],
  7210. THREE.ShaderChunk[ "default_vertex" ],
  7211. THREE.ShaderChunk[ "shadowmap_vertex" ],
  7212. "}"
  7213. ].join("\n"),
  7214. fragmentShader: [
  7215. "uniform vec3 diffuse;",
  7216. "uniform float opacity;",
  7217. "uniform vec3 ambient;",
  7218. "uniform vec3 emissive;",
  7219. "uniform vec3 specular;",
  7220. "uniform float shininess;",
  7221. THREE.ShaderChunk[ "color_pars_fragment" ],
  7222. THREE.ShaderChunk[ "map_pars_fragment" ],
  7223. THREE.ShaderChunk[ "lightmap_pars_fragment" ],
  7224. THREE.ShaderChunk[ "envmap_pars_fragment" ],
  7225. THREE.ShaderChunk[ "fog_pars_fragment" ],
  7226. THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
  7227. THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
  7228. "void main() {",
  7229. "gl_FragColor = vec4( vec3 ( 1.0 ), opacity );",
  7230. THREE.ShaderChunk[ "map_fragment" ],
  7231. THREE.ShaderChunk[ "alphatest_fragment" ],
  7232. THREE.ShaderChunk[ "lights_phong_fragment" ],
  7233. THREE.ShaderChunk[ "lightmap_fragment" ],
  7234. THREE.ShaderChunk[ "color_fragment" ],
  7235. THREE.ShaderChunk[ "envmap_fragment" ],
  7236. THREE.ShaderChunk[ "shadowmap_fragment" ],
  7237. THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
  7238. THREE.ShaderChunk[ "fog_fragment" ],
  7239. "}"
  7240. ].join("\n")
  7241. },
  7242. 'particle_basic': {
  7243. uniforms: THREE.UniformsUtils.merge( [
  7244. THREE.UniformsLib[ "particle" ],
  7245. THREE.UniformsLib[ "shadowmap" ]
  7246. ] ),
  7247. vertexShader: [
  7248. "uniform float size;",
  7249. "uniform float scale;",
  7250. THREE.ShaderChunk[ "color_pars_vertex" ],
  7251. THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
  7252. "void main() {",
  7253. THREE.ShaderChunk[ "color_vertex" ],
  7254. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  7255. "#ifdef USE_SIZEATTENUATION",
  7256. "gl_PointSize = size * ( scale / length( mvPosition.xyz ) );",
  7257. "#else",
  7258. "gl_PointSize = size;",
  7259. "#endif",
  7260. "gl_Position = projectionMatrix * mvPosition;",
  7261. THREE.ShaderChunk[ "shadowmap_vertex" ],
  7262. "}"
  7263. ].join("\n"),
  7264. fragmentShader: [
  7265. "uniform vec3 psColor;",
  7266. "uniform float opacity;",
  7267. THREE.ShaderChunk[ "color_pars_fragment" ],
  7268. THREE.ShaderChunk[ "map_particle_pars_fragment" ],
  7269. THREE.ShaderChunk[ "fog_pars_fragment" ],
  7270. THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
  7271. "void main() {",
  7272. "gl_FragColor = vec4( psColor, opacity );",
  7273. THREE.ShaderChunk[ "map_particle_fragment" ],
  7274. THREE.ShaderChunk[ "alphatest_fragment" ],
  7275. THREE.ShaderChunk[ "color_fragment" ],
  7276. THREE.ShaderChunk[ "shadowmap_fragment" ],
  7277. THREE.ShaderChunk[ "fog_fragment" ],
  7278. "}"
  7279. ].join("\n")
  7280. },
  7281. // Depth encoding into RGBA texture
  7282. // based on SpiderGL shadow map example
  7283. // http://spidergl.org/example.php?id=6
  7284. // originally from
  7285. // http://www.gamedev.net/topic/442138-packing-a-float-into-a-a8r8g8b8-texture-shader/page__whichpage__1%25EF%25BF%25BD
  7286. // see also here:
  7287. // http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/
  7288. 'depthRGBA': {
  7289. uniforms: {},
  7290. vertexShader: [
  7291. THREE.ShaderChunk[ "skinning_pars_vertex" ],
  7292. THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
  7293. "void main() {",
  7294. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  7295. THREE.ShaderChunk[ "skinbase_vertex" ],
  7296. THREE.ShaderChunk[ "skinning_vertex" ],
  7297. THREE.ShaderChunk[ "morphtarget_vertex" ],
  7298. THREE.ShaderChunk[ "default_vertex" ],
  7299. "}"
  7300. ].join("\n"),
  7301. fragmentShader: [
  7302. "vec4 pack_depth( const in float depth ) {",
  7303. "const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );",
  7304. "const vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );",
  7305. "vec4 res = fract( depth * bit_shift );",
  7306. "res -= res.xxyz * bit_mask;",
  7307. "return res;",
  7308. "}",
  7309. "void main() {",
  7310. "gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );",
  7311. //"gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z / gl_FragCoord.w );",
  7312. //"float z = ( ( gl_FragCoord.z / gl_FragCoord.w ) - 3.0 ) / ( 4000.0 - 3.0 );",
  7313. //"gl_FragData[ 0 ] = pack_depth( z );",
  7314. //"gl_FragData[ 0 ] = vec4( z, z, z, 1.0 );",
  7315. "}"
  7316. ].join("\n")
  7317. }
  7318. };/**
  7319. * @author supereggbert / http://www.paulbrunt.co.uk/
  7320. * @author mrdoob / http://mrdoob.com/
  7321. * @author alteredq / http://alteredqualia.com/
  7322. * @author szimek / https://github.com/szimek/
  7323. */
  7324. THREE.WebGLRenderer = function ( parameters ) {
  7325. console.log( 'THREE.WebGLRenderer', THREE.REVISION );
  7326. parameters = parameters || {};
  7327. var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ),
  7328. _precision = parameters.precision !== undefined ? parameters.precision : 'highp',
  7329. _alpha = parameters.alpha !== undefined ? parameters.alpha : true,
  7330. _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
  7331. _antialias = parameters.antialias !== undefined ? parameters.antialias : false,
  7332. _stencil = parameters.stencil !== undefined ? parameters.stencil : true,
  7333. _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
  7334. _clearColor = parameters.clearColor !== undefined ? new THREE.Color( parameters.clearColor ) : new THREE.Color( 0x000000 ),
  7335. _clearAlpha = parameters.clearAlpha !== undefined ? parameters.clearAlpha : 0,
  7336. _maxLights = parameters.maxLights !== undefined ? parameters.maxLights : 4;
  7337. // public properties
  7338. this.domElement = _canvas;
  7339. this.context = null;
  7340. // clearing
  7341. this.autoClear = true;
  7342. this.autoClearColor = true;
  7343. this.autoClearDepth = true;
  7344. this.autoClearStencil = true;
  7345. // scene graph
  7346. this.sortObjects = true;
  7347. this.autoUpdateObjects = true;
  7348. this.autoUpdateScene = true;
  7349. // physically based shading
  7350. this.gammaInput = false;
  7351. this.gammaOutput = false;
  7352. this.physicallyBasedShading = false;
  7353. // shadow map
  7354. this.shadowMapEnabled = false;
  7355. this.shadowMapAutoUpdate = true;
  7356. this.shadowMapSoft = true;
  7357. this.shadowMapCullFrontFaces = true;
  7358. this.shadowMapDebug = false;
  7359. this.shadowMapCascade = false;
  7360. // morphs
  7361. this.maxMorphTargets = 8;
  7362. this.maxMorphNormals = 4;
  7363. // flags
  7364. this.autoScaleCubemaps = true;
  7365. // custom render plugins
  7366. this.renderPluginsPre = [];
  7367. this.renderPluginsPost = [];
  7368. // info
  7369. this.info = {
  7370. memory: {
  7371. programs: 0,
  7372. geometries: 0,
  7373. textures: 0
  7374. },
  7375. render: {
  7376. calls: 0,
  7377. vertices: 0,
  7378. faces: 0,
  7379. points: 0
  7380. }
  7381. };
  7382. // internal properties
  7383. var _this = this,
  7384. _programs = [],
  7385. _programs_counter = 0,
  7386. // internal state cache
  7387. _currentProgram = null,
  7388. _currentFramebuffer = null,
  7389. _currentMaterialId = -1,
  7390. _currentGeometryGroupHash = null,
  7391. _currentCamera = null,
  7392. _geometryGroupCounter = 0,
  7393. // GL state cache
  7394. _oldDoubleSided = -1,
  7395. _oldFlipSided = -1,
  7396. _oldBlending = -1,
  7397. _oldBlendEquation = -1,
  7398. _oldBlendSrc = -1,
  7399. _oldBlendDst = -1,
  7400. _oldDepthTest = -1,
  7401. _oldDepthWrite = -1,
  7402. _oldPolygonOffset = null,
  7403. _oldPolygonOffsetFactor = null,
  7404. _oldPolygonOffsetUnits = null,
  7405. _oldLineWidth = null,
  7406. _viewportX = 0,
  7407. _viewportY = 0,
  7408. _viewportWidth = 0,
  7409. _viewportHeight = 0,
  7410. _currentWidth = 0,
  7411. _currentHeight = 0,
  7412. // frustum
  7413. _frustum = new THREE.Frustum(),
  7414. // camera matrices cache
  7415. _projScreenMatrix = new THREE.Matrix4(),
  7416. _projScreenMatrixPS = new THREE.Matrix4(),
  7417. _vector3 = new THREE.Vector4(),
  7418. // light arrays cache
  7419. _direction = new THREE.Vector3(),
  7420. _lightsNeedUpdate = true,
  7421. _lights = {
  7422. ambient: [ 0, 0, 0 ],
  7423. directional: { length: 0, colors: new Array(), positions: new Array() },
  7424. point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() },
  7425. spot: { length: 0, colors: new Array(), positions: new Array(), distances: new Array(), directions: new Array(), angles: new Array(), exponents: new Array() }
  7426. };
  7427. // initialize
  7428. var _gl;
  7429. var _glExtensionTextureFloat;
  7430. var _glExtensionStandardDerivatives;
  7431. var _glExtensionTextureFilterAnisotropic;
  7432. initGL();
  7433. setDefaultGLState();
  7434. this.context = _gl;
  7435. // GPU capabilities
  7436. var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ),
  7437. _maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE ),
  7438. _maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
  7439. var _maxAnisotropy = _glExtensionTextureFilterAnisotropic ? _gl.getParameter( _glExtensionTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT ) : 0;
  7440. var _supportsVertexTextures = ( _maxVertexTextures > 0 );
  7441. var _supportsBoneTextures = _supportsVertexTextures && _glExtensionTextureFloat;
  7442. // API
  7443. this.getContext = function () {
  7444. return _gl;
  7445. };
  7446. this.supportsVertexTextures = function () {
  7447. return _supportsVertexTextures;
  7448. };
  7449. this.getMaxAnisotropy = function () {
  7450. return _maxAnisotropy;
  7451. };
  7452. this.setSize = function ( width, height ) {
  7453. _canvas.width = width;
  7454. _canvas.height = height;
  7455. this.setViewport( 0, 0, _canvas.width, _canvas.height );
  7456. };
  7457. this.setViewport = function ( x, y, width, height ) {
  7458. _viewportX = x;
  7459. _viewportY = y;
  7460. _viewportWidth = width;
  7461. _viewportHeight = height;
  7462. _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
  7463. };
  7464. this.setScissor = function ( x, y, width, height ) {
  7465. _gl.scissor( x, y, width, height );
  7466. };
  7467. this.enableScissorTest = function ( enable ) {
  7468. enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
  7469. };
  7470. // Clearing
  7471. this.setClearColorHex = function ( hex, alpha ) {
  7472. _clearColor.setHex( hex );
  7473. _clearAlpha = alpha;
  7474. _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
  7475. };
  7476. this.setClearColor = function ( color, alpha ) {
  7477. _clearColor.copy( color );
  7478. _clearAlpha = alpha;
  7479. _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
  7480. };
  7481. this.getClearColor = function () {
  7482. return _clearColor;
  7483. };
  7484. this.getClearAlpha = function () {
  7485. return _clearAlpha;
  7486. };
  7487. this.clear = function ( color, depth, stencil ) {
  7488. var bits = 0;
  7489. if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;
  7490. if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;
  7491. if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;
  7492. _gl.clear( bits );
  7493. };
  7494. this.clearTarget = function ( renderTarget, color, depth, stencil ) {
  7495. this.setRenderTarget( renderTarget );
  7496. this.clear( color, depth, stencil );
  7497. };
  7498. // Plugins
  7499. this.addPostPlugin = function ( plugin ) {
  7500. plugin.init( this );
  7501. this.renderPluginsPost.push( plugin );
  7502. };
  7503. this.addPrePlugin = function ( plugin ) {
  7504. plugin.init( this );
  7505. this.renderPluginsPre.push( plugin );
  7506. };
  7507. // Deallocation
  7508. this.deallocateObject = function ( object ) {
  7509. if ( ! object.__webglInit ) return;
  7510. object.__webglInit = false;
  7511. delete object._modelViewMatrix;
  7512. delete object._normalMatrix;
  7513. delete object._normalMatrixArray;
  7514. delete object._modelViewMatrixArray;
  7515. delete object._objectMatrixArray;
  7516. if ( object instanceof THREE.Mesh ) {
  7517. for ( var g in object.geometry.geometryGroups ) {
  7518. deleteMeshBuffers( object.geometry.geometryGroups[ g ] );
  7519. }
  7520. } else if ( object instanceof THREE.Ribbon ) {
  7521. deleteRibbonBuffers( object.geometry );
  7522. } else if ( object instanceof THREE.Line ) {
  7523. deleteLineBuffers( object.geometry );
  7524. } else if ( object instanceof THREE.ParticleSystem ) {
  7525. deleteParticleBuffers( object.geometry );
  7526. }
  7527. };
  7528. this.deallocateTexture = function ( texture ) {
  7529. if ( ! texture.__webglInit ) return;
  7530. texture.__webglInit = false;
  7531. _gl.deleteTexture( texture.__webglTexture );
  7532. _this.info.memory.textures --;
  7533. };
  7534. this.deallocateRenderTarget = function ( renderTarget ) {
  7535. if ( !renderTarget || ! renderTarget.__webglTexture ) return;
  7536. _gl.deleteTexture( renderTarget.__webglTexture );
  7537. if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
  7538. for ( var i = 0; i < 6; i ++ ) {
  7539. _gl.deleteFramebuffer( renderTarget.__webglFramebuffer[ i ] );
  7540. _gl.deleteRenderbuffer( renderTarget.__webglRenderbuffer[ i ] );
  7541. }
  7542. } else {
  7543. _gl.deleteFramebuffer( renderTarget.__webglFramebuffer );
  7544. _gl.deleteRenderbuffer( renderTarget.__webglRenderbuffer );
  7545. }
  7546. };
  7547. this.deallocateMaterial = function ( material ) {
  7548. var program = material.program;
  7549. if ( ! program ) return;
  7550. material.program = undefined;
  7551. // only deallocate GL program if this was the last use of shared program
  7552. // assumed there is only single copy of any program in the _programs list
  7553. // (that's how it's constructed)
  7554. var i, il, programInfo;
  7555. var deleteProgram = false;
  7556. for ( i = 0, il = _programs.length; i < il; i ++ ) {
  7557. programInfo = _programs[ i ];
  7558. if ( programInfo.program === program ) {
  7559. programInfo.usedTimes --;
  7560. if ( programInfo.usedTimes === 0 ) {
  7561. deleteProgram = true;
  7562. }
  7563. break;
  7564. }
  7565. }
  7566. if ( deleteProgram ) {
  7567. // avoid using array.splice, this is costlier than creating new array from scratch
  7568. var newPrograms = [];
  7569. for ( i = 0, il = _programs.length; i < il; i ++ ) {
  7570. programInfo = _programs[ i ];
  7571. if ( programInfo.program !== program ) {
  7572. newPrograms.push( programInfo );
  7573. }
  7574. }
  7575. _programs = newPrograms;
  7576. _gl.deleteProgram( program );
  7577. _this.info.memory.programs --;
  7578. }
  7579. };
  7580. // Rendering
  7581. this.updateShadowMap = function ( scene, camera ) {
  7582. _currentProgram = null;
  7583. _oldBlending = -1;
  7584. _oldDepthTest = -1;
  7585. _oldDepthWrite = -1;
  7586. _currentGeometryGroupHash = -1;
  7587. _currentMaterialId = -1;
  7588. _lightsNeedUpdate = true;
  7589. _oldDoubleSided = -1;
  7590. _oldFlipSided = -1;
  7591. this.shadowMapPlugin.update( scene, camera );
  7592. };
  7593. // Internal functions
  7594. // Buffer allocation
  7595. function createParticleBuffers ( geometry ) {
  7596. geometry.__webglVertexBuffer = _gl.createBuffer();
  7597. geometry.__webglColorBuffer = _gl.createBuffer();
  7598. _this.info.geometries ++;
  7599. };
  7600. function createLineBuffers ( geometry ) {
  7601. geometry.__webglVertexBuffer = _gl.createBuffer();
  7602. geometry.__webglColorBuffer = _gl.createBuffer();
  7603. _this.info.memory.geometries ++;
  7604. };
  7605. function createRibbonBuffers ( geometry ) {
  7606. geometry.__webglVertexBuffer = _gl.createBuffer();
  7607. geometry.__webglColorBuffer = _gl.createBuffer();
  7608. _this.info.memory.geometries ++;
  7609. };
  7610. function createMeshBuffers ( geometryGroup ) {
  7611. geometryGroup.__webglVertexBuffer = _gl.createBuffer();
  7612. geometryGroup.__webglNormalBuffer = _gl.createBuffer();
  7613. geometryGroup.__webglTangentBuffer = _gl.createBuffer();
  7614. geometryGroup.__webglColorBuffer = _gl.createBuffer();
  7615. geometryGroup.__webglUVBuffer = _gl.createBuffer();
  7616. geometryGroup.__webglUV2Buffer = _gl.createBuffer();
  7617. geometryGroup.__webglSkinVertexABuffer = _gl.createBuffer();
  7618. geometryGroup.__webglSkinVertexBBuffer = _gl.createBuffer();
  7619. geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
  7620. geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
  7621. geometryGroup.__webglFaceBuffer = _gl.createBuffer();
  7622. geometryGroup.__webglLineBuffer = _gl.createBuffer();
  7623. var m, ml;
  7624. if ( geometryGroup.numMorphTargets ) {
  7625. geometryGroup.__webglMorphTargetsBuffers = [];
  7626. for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
  7627. geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
  7628. }
  7629. }
  7630. if ( geometryGroup.numMorphNormals ) {
  7631. geometryGroup.__webglMorphNormalsBuffers = [];
  7632. for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
  7633. geometryGroup.__webglMorphNormalsBuffers.push( _gl.createBuffer() );
  7634. }
  7635. }
  7636. _this.info.memory.geometries ++;
  7637. };
  7638. // Buffer deallocation
  7639. function deleteParticleBuffers ( geometry ) {
  7640. _gl.deleteBuffer( geometry.__webglVertexBuffer );
  7641. _gl.deleteBuffer( geometry.__webglColorBuffer );
  7642. _this.info.memory.geometries --;
  7643. };
  7644. function deleteLineBuffers ( geometry ) {
  7645. _gl.deleteBuffer( geometry.__webglVertexBuffer );
  7646. _gl.deleteBuffer( geometry.__webglColorBuffer );
  7647. _this.info.memory.geometries --;
  7648. };
  7649. function deleteRibbonBuffers ( geometry ) {
  7650. _gl.deleteBuffer( geometry.__webglVertexBuffer );
  7651. _gl.deleteBuffer( geometry.__webglColorBuffer );
  7652. _this.info.memory.geometries --;
  7653. };
  7654. function deleteMeshBuffers ( geometryGroup ) {
  7655. _gl.deleteBuffer( geometryGroup.__webglVertexBuffer );
  7656. _gl.deleteBuffer( geometryGroup.__webglNormalBuffer );
  7657. _gl.deleteBuffer( geometryGroup.__webglTangentBuffer );
  7658. _gl.deleteBuffer( geometryGroup.__webglColorBuffer );
  7659. _gl.deleteBuffer( geometryGroup.__webglUVBuffer );
  7660. _gl.deleteBuffer( geometryGroup.__webglUV2Buffer );
  7661. _gl.deleteBuffer( geometryGroup.__webglSkinVertexABuffer );
  7662. _gl.deleteBuffer( geometryGroup.__webglSkinVertexBBuffer );
  7663. _gl.deleteBuffer( geometryGroup.__webglSkinIndicesBuffer );
  7664. _gl.deleteBuffer( geometryGroup.__webglSkinWeightsBuffer );
  7665. _gl.deleteBuffer( geometryGroup.__webglFaceBuffer );
  7666. _gl.deleteBuffer( geometryGroup.__webglLineBuffer );
  7667. var m, ml;
  7668. if ( geometryGroup.numMorphTargets ) {
  7669. for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
  7670. _gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
  7671. }
  7672. }
  7673. if ( geometryGroup.numMorphNormals ) {
  7674. for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
  7675. _gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
  7676. }
  7677. }
  7678. if ( geometryGroup.__webglCustomAttributesList ) {
  7679. for ( var id in geometryGroup.__webglCustomAttributesList ) {
  7680. _gl.deleteBuffer( geometryGroup.__webglCustomAttributesList[ id ].buffer );
  7681. }
  7682. }
  7683. _this.info.memory.geometries --;
  7684. };
  7685. // Buffer initialization
  7686. function initCustomAttributes ( geometry, object ) {
  7687. var nvertices = geometry.vertices.length;
  7688. var material = object.material;
  7689. if ( material.attributes ) {
  7690. if ( geometry.__webglCustomAttributesList === undefined ) {
  7691. geometry.__webglCustomAttributesList = [];
  7692. }
  7693. for ( var a in material.attributes ) {
  7694. var attribute = material.attributes[ a ];
  7695. if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
  7696. attribute.__webglInitialized = true;
  7697. var size = 1; // "f" and "i"
  7698. if ( attribute.type === "v2" ) size = 2;
  7699. else if ( attribute.type === "v3" ) size = 3;
  7700. else if ( attribute.type === "v4" ) size = 4;
  7701. else if ( attribute.type === "c" ) size = 3;
  7702. attribute.size = size;
  7703. attribute.array = new Float32Array( nvertices * size );
  7704. attribute.buffer = _gl.createBuffer();
  7705. attribute.buffer.belongsToAttribute = a;
  7706. attribute.needsUpdate = true;
  7707. }
  7708. geometry.__webglCustomAttributesList.push( attribute );
  7709. }
  7710. }
  7711. };
  7712. function initParticleBuffers ( geometry, object ) {
  7713. var nvertices = geometry.vertices.length;
  7714. geometry.__vertexArray = new Float32Array( nvertices * 3 );
  7715. geometry.__colorArray = new Float32Array( nvertices * 3 );
  7716. geometry.__sortArray = [];
  7717. geometry.__webglParticleCount = nvertices;
  7718. initCustomAttributes ( geometry, object );
  7719. };
  7720. function initLineBuffers ( geometry, object ) {
  7721. var nvertices = geometry.vertices.length;
  7722. geometry.__vertexArray = new Float32Array( nvertices * 3 );
  7723. geometry.__colorArray = new Float32Array( nvertices * 3 );
  7724. geometry.__webglLineCount = nvertices;
  7725. initCustomAttributes ( geometry, object );
  7726. };
  7727. function initRibbonBuffers ( geometry ) {
  7728. var nvertices = geometry.vertices.length;
  7729. geometry.__vertexArray = new Float32Array( nvertices * 3 );
  7730. geometry.__colorArray = new Float32Array( nvertices * 3 );
  7731. geometry.__webglVertexCount = nvertices;
  7732. };
  7733. function initMeshBuffers ( geometryGroup, object ) {
  7734. var geometry = object.geometry,
  7735. faces3 = geometryGroup.faces3,
  7736. faces4 = geometryGroup.faces4,
  7737. nvertices = faces3.length * 3 + faces4.length * 4,
  7738. ntris = faces3.length * 1 + faces4.length * 2,
  7739. nlines = faces3.length * 3 + faces4.length * 4,
  7740. material = getBufferMaterial( object, geometryGroup ),
  7741. uvType = bufferGuessUVType( material ),
  7742. normalType = bufferGuessNormalType( material ),
  7743. vertexColorType = bufferGuessVertexColorType( material );
  7744. //console.log( "uvType", uvType, "normalType", normalType, "vertexColorType", vertexColorType, object, geometryGroup, material );
  7745. geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
  7746. if ( normalType ) {
  7747. geometryGroup.__normalArray = new Float32Array( nvertices * 3 );
  7748. }
  7749. if ( geometry.hasTangents ) {
  7750. geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
  7751. }
  7752. if ( vertexColorType ) {
  7753. geometryGroup.__colorArray = new Float32Array( nvertices * 3 );
  7754. }
  7755. if ( uvType ) {
  7756. if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
  7757. geometryGroup.__uvArray = new Float32Array( nvertices * 2 );
  7758. }
  7759. if ( geometry.faceUvs.length > 1 || geometry.faceVertexUvs.length > 1 ) {
  7760. geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );
  7761. }
  7762. }
  7763. if ( object.geometry.skinWeights.length && object.geometry.skinIndices.length ) {
  7764. geometryGroup.__skinVertexAArray = new Float32Array( nvertices * 4 );
  7765. geometryGroup.__skinVertexBArray = new Float32Array( nvertices * 4 );
  7766. geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 );
  7767. geometryGroup.__skinWeightArray = new Float32Array( nvertices * 4 );
  7768. }
  7769. geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
  7770. geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
  7771. var m, ml;
  7772. if ( geometryGroup.numMorphTargets ) {
  7773. geometryGroup.__morphTargetsArrays = [];
  7774. for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
  7775. geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );
  7776. }
  7777. }
  7778. if ( geometryGroup.numMorphNormals ) {
  7779. geometryGroup.__morphNormalsArrays = [];
  7780. for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
  7781. geometryGroup.__morphNormalsArrays.push( new Float32Array( nvertices * 3 ) );
  7782. }
  7783. }
  7784. geometryGroup.__webglFaceCount = ntris * 3;
  7785. geometryGroup.__webglLineCount = nlines * 2;
  7786. // custom attributes
  7787. if ( material.attributes ) {
  7788. if ( geometryGroup.__webglCustomAttributesList === undefined ) {
  7789. geometryGroup.__webglCustomAttributesList = [];
  7790. }
  7791. for ( var a in material.attributes ) {
  7792. // Do a shallow copy of the attribute object so different geometryGroup chunks use different
  7793. // attribute buffers which are correctly indexed in the setMeshBuffers function
  7794. var originalAttribute = material.attributes[ a ];
  7795. var attribute = {};
  7796. for ( var property in originalAttribute ) {
  7797. attribute[ property ] = originalAttribute[ property ];
  7798. }
  7799. if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
  7800. attribute.__webglInitialized = true;
  7801. var size = 1; // "f" and "i"
  7802. if( attribute.type === "v2" ) size = 2;
  7803. else if( attribute.type === "v3" ) size = 3;
  7804. else if( attribute.type === "v4" ) size = 4;
  7805. else if( attribute.type === "c" ) size = 3;
  7806. attribute.size = size;
  7807. attribute.array = new Float32Array( nvertices * size );
  7808. attribute.buffer = _gl.createBuffer();
  7809. attribute.buffer.belongsToAttribute = a;
  7810. originalAttribute.needsUpdate = true;
  7811. attribute.__original = originalAttribute;
  7812. }
  7813. geometryGroup.__webglCustomAttributesList.push( attribute );
  7814. }
  7815. }
  7816. geometryGroup.__inittedArrays = true;
  7817. };
  7818. function getBufferMaterial( object, geometryGroup ) {
  7819. if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
  7820. return object.material;
  7821. } else if ( geometryGroup.materialIndex >= 0 ) {
  7822. return object.geometry.materials[ geometryGroup.materialIndex ];
  7823. }
  7824. };
  7825. function materialNeedsSmoothNormals ( material ) {
  7826. return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
  7827. };
  7828. function bufferGuessNormalType ( material ) {
  7829. // only MeshBasicMaterial and MeshDepthMaterial don't need normals
  7830. if ( ( material instanceof THREE.MeshBasicMaterial && !material.envMap ) || material instanceof THREE.MeshDepthMaterial ) {
  7831. return false;
  7832. }
  7833. if ( materialNeedsSmoothNormals( material ) ) {
  7834. return THREE.SmoothShading;
  7835. } else {
  7836. return THREE.FlatShading;
  7837. }
  7838. };
  7839. function bufferGuessVertexColorType ( material ) {
  7840. if ( material.vertexColors ) {
  7841. return material.vertexColors;
  7842. }
  7843. return false;
  7844. };
  7845. function bufferGuessUVType ( material ) {
  7846. // material must use some texture to require uvs
  7847. if ( material.map || material.lightMap || material instanceof THREE.ShaderMaterial ) {
  7848. return true;
  7849. }
  7850. return false;
  7851. };
  7852. //
  7853. function initDirectBuffers( geometry ) {
  7854. var a, attribute, type;
  7855. for ( a in geometry.attributes ) {
  7856. if ( a === "index" ) {
  7857. type = _gl.ELEMENT_ARRAY_BUFFER;
  7858. } else {
  7859. type = _gl.ARRAY_BUFFER;
  7860. }
  7861. attribute = geometry.attributes[ a ];
  7862. attribute.buffer = _gl.createBuffer();
  7863. _gl.bindBuffer( type, attribute.buffer );
  7864. _gl.bufferData( type, attribute.array, _gl.STATIC_DRAW );
  7865. }
  7866. };
  7867. // Buffer setting
  7868. function setParticleBuffers ( geometry, hint, object ) {
  7869. var v, c, vertex, offset, index, color,
  7870. vertices = geometry.vertices,
  7871. vl = vertices.length,
  7872. colors = geometry.colors,
  7873. cl = colors.length,
  7874. vertexArray = geometry.__vertexArray,
  7875. colorArray = geometry.__colorArray,
  7876. sortArray = geometry.__sortArray,
  7877. dirtyVertices = geometry.verticesNeedUpdate,
  7878. dirtyElements = geometry.elementsNeedUpdate,
  7879. dirtyColors = geometry.colorsNeedUpdate,
  7880. customAttributes = geometry.__webglCustomAttributesList,
  7881. i, il,
  7882. a, ca, cal, value,
  7883. customAttribute;
  7884. if ( object.sortParticles ) {
  7885. _projScreenMatrixPS.copy( _projScreenMatrix );
  7886. _projScreenMatrixPS.multiplySelf( object.matrixWorld );
  7887. for ( v = 0; v < vl; v ++ ) {
  7888. vertex = vertices[ v ];
  7889. _vector3.copy( vertex );
  7890. _projScreenMatrixPS.multiplyVector3( _vector3 );
  7891. sortArray[ v ] = [ _vector3.z, v ];
  7892. }
  7893. sortArray.sort( function( a, b ) { return b[ 0 ] - a[ 0 ]; } );
  7894. for ( v = 0; v < vl; v ++ ) {
  7895. vertex = vertices[ sortArray[v][1] ];
  7896. offset = v * 3;
  7897. vertexArray[ offset ] = vertex.x;
  7898. vertexArray[ offset + 1 ] = vertex.y;
  7899. vertexArray[ offset + 2 ] = vertex.z;
  7900. }
  7901. for ( c = 0; c < cl; c ++ ) {
  7902. offset = c * 3;
  7903. color = colors[ sortArray[c][1] ];
  7904. colorArray[ offset ] = color.r;
  7905. colorArray[ offset + 1 ] = color.g;
  7906. colorArray[ offset + 2 ] = color.b;
  7907. }
  7908. if ( customAttributes ) {
  7909. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  7910. customAttribute = customAttributes[ i ];
  7911. if ( ! ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) ) continue;
  7912. offset = 0;
  7913. cal = customAttribute.value.length;
  7914. if ( customAttribute.size === 1 ) {
  7915. for ( ca = 0; ca < cal; ca ++ ) {
  7916. index = sortArray[ ca ][ 1 ];
  7917. customAttribute.array[ ca ] = customAttribute.value[ index ];
  7918. }
  7919. } else if ( customAttribute.size === 2 ) {
  7920. for ( ca = 0; ca < cal; ca ++ ) {
  7921. index = sortArray[ ca ][ 1 ];
  7922. value = customAttribute.value[ index ];
  7923. customAttribute.array[ offset ] = value.x;
  7924. customAttribute.array[ offset + 1 ] = value.y;
  7925. offset += 2;
  7926. }
  7927. } else if ( customAttribute.size === 3 ) {
  7928. if ( customAttribute.type === "c" ) {
  7929. for ( ca = 0; ca < cal; ca ++ ) {
  7930. index = sortArray[ ca ][ 1 ];
  7931. value = customAttribute.value[ index ];
  7932. customAttribute.array[ offset ] = value.r;
  7933. customAttribute.array[ offset + 1 ] = value.g;
  7934. customAttribute.array[ offset + 2 ] = value.b;
  7935. offset += 3;
  7936. }
  7937. } else {
  7938. for ( ca = 0; ca < cal; ca ++ ) {
  7939. index = sortArray[ ca ][ 1 ];
  7940. value = customAttribute.value[ index ];
  7941. customAttribute.array[ offset ] = value.x;
  7942. customAttribute.array[ offset + 1 ] = value.y;
  7943. customAttribute.array[ offset + 2 ] = value.z;
  7944. offset += 3;
  7945. }
  7946. }
  7947. } else if ( customAttribute.size === 4 ) {
  7948. for ( ca = 0; ca < cal; ca ++ ) {
  7949. index = sortArray[ ca ][ 1 ];
  7950. value = customAttribute.value[ index ];
  7951. customAttribute.array[ offset ] = value.x;
  7952. customAttribute.array[ offset + 1 ] = value.y;
  7953. customAttribute.array[ offset + 2 ] = value.z;
  7954. customAttribute.array[ offset + 3 ] = value.w;
  7955. offset += 4;
  7956. }
  7957. }
  7958. }
  7959. }
  7960. } else {
  7961. if ( dirtyVertices ) {
  7962. for ( v = 0; v < vl; v ++ ) {
  7963. vertex = vertices[ v ];
  7964. offset = v * 3;
  7965. vertexArray[ offset ] = vertex.x;
  7966. vertexArray[ offset + 1 ] = vertex.y;
  7967. vertexArray[ offset + 2 ] = vertex.z;
  7968. }
  7969. }
  7970. if ( dirtyColors ) {
  7971. for ( c = 0; c < cl; c ++ ) {
  7972. color = colors[ c ];
  7973. offset = c * 3;
  7974. colorArray[ offset ] = color.r;
  7975. colorArray[ offset + 1 ] = color.g;
  7976. colorArray[ offset + 2 ] = color.b;
  7977. }
  7978. }
  7979. if ( customAttributes ) {
  7980. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  7981. customAttribute = customAttributes[ i ];
  7982. if ( customAttribute.needsUpdate &&
  7983. ( customAttribute.boundTo === undefined ||
  7984. customAttribute.boundTo === "vertices") ) {
  7985. cal = customAttribute.value.length;
  7986. offset = 0;
  7987. if ( customAttribute.size === 1 ) {
  7988. for ( ca = 0; ca < cal; ca ++ ) {
  7989. customAttribute.array[ ca ] = customAttribute.value[ ca ];
  7990. }
  7991. } else if ( customAttribute.size === 2 ) {
  7992. for ( ca = 0; ca < cal; ca ++ ) {
  7993. value = customAttribute.value[ ca ];
  7994. customAttribute.array[ offset ] = value.x;
  7995. customAttribute.array[ offset + 1 ] = value.y;
  7996. offset += 2;
  7997. }
  7998. } else if ( customAttribute.size === 3 ) {
  7999. if ( customAttribute.type === "c" ) {
  8000. for ( ca = 0; ca < cal; ca ++ ) {
  8001. value = customAttribute.value[ ca ];
  8002. customAttribute.array[ offset ] = value.r;
  8003. customAttribute.array[ offset + 1 ] = value.g;
  8004. customAttribute.array[ offset + 2 ] = value.b;
  8005. offset += 3;
  8006. }
  8007. } else {
  8008. for ( ca = 0; ca < cal; ca ++ ) {
  8009. value = customAttribute.value[ ca ];
  8010. customAttribute.array[ offset ] = value.x;
  8011. customAttribute.array[ offset + 1 ] = value.y;
  8012. customAttribute.array[ offset + 2 ] = value.z;
  8013. offset += 3;
  8014. }
  8015. }
  8016. } else if ( customAttribute.size === 4 ) {
  8017. for ( ca = 0; ca < cal; ca ++ ) {
  8018. value = customAttribute.value[ ca ];
  8019. customAttribute.array[ offset ] = value.x;
  8020. customAttribute.array[ offset + 1 ] = value.y;
  8021. customAttribute.array[ offset + 2 ] = value.z;
  8022. customAttribute.array[ offset + 3 ] = value.w;
  8023. offset += 4;
  8024. }
  8025. }
  8026. }
  8027. }
  8028. }
  8029. }
  8030. if ( dirtyVertices || object.sortParticles ) {
  8031. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
  8032. _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
  8033. }
  8034. if ( dirtyColors || object.sortParticles ) {
  8035. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
  8036. _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
  8037. }
  8038. if ( customAttributes ) {
  8039. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  8040. customAttribute = customAttributes[ i ];
  8041. if ( customAttribute.needsUpdate || object.sortParticles ) {
  8042. _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
  8043. _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
  8044. }
  8045. }
  8046. }
  8047. };
  8048. function setLineBuffers ( geometry, hint ) {
  8049. var v, c, vertex, offset, color,
  8050. vertices = geometry.vertices,
  8051. colors = geometry.colors,
  8052. vl = vertices.length,
  8053. cl = colors.length,
  8054. vertexArray = geometry.__vertexArray,
  8055. colorArray = geometry.__colorArray,
  8056. dirtyVertices = geometry.verticesNeedUpdate,
  8057. dirtyColors = geometry.colorsNeedUpdate,
  8058. customAttributes = geometry.__webglCustomAttributesList,
  8059. i, il,
  8060. a, ca, cal, value,
  8061. customAttribute;
  8062. if ( dirtyVertices ) {
  8063. for ( v = 0; v < vl; v ++ ) {
  8064. vertex = vertices[ v ];
  8065. offset = v * 3;
  8066. vertexArray[ offset ] = vertex.x;
  8067. vertexArray[ offset + 1 ] = vertex.y;
  8068. vertexArray[ offset + 2 ] = vertex.z;
  8069. }
  8070. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
  8071. _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
  8072. }
  8073. if ( dirtyColors ) {
  8074. for ( c = 0; c < cl; c ++ ) {
  8075. color = colors[ c ];
  8076. offset = c * 3;
  8077. colorArray[ offset ] = color.r;
  8078. colorArray[ offset + 1 ] = color.g;
  8079. colorArray[ offset + 2 ] = color.b;
  8080. }
  8081. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
  8082. _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
  8083. }
  8084. if ( customAttributes ) {
  8085. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  8086. customAttribute = customAttributes[ i ];
  8087. if ( customAttribute.needsUpdate &&
  8088. ( customAttribute.boundTo === undefined ||
  8089. customAttribute.boundTo === "vertices" ) ) {
  8090. offset = 0;
  8091. cal = customAttribute.value.length;
  8092. if ( customAttribute.size === 1 ) {
  8093. for ( ca = 0; ca < cal; ca ++ ) {
  8094. customAttribute.array[ ca ] = customAttribute.value[ ca ];
  8095. }
  8096. } else if ( customAttribute.size === 2 ) {
  8097. for ( ca = 0; ca < cal; ca ++ ) {
  8098. value = customAttribute.value[ ca ];
  8099. customAttribute.array[ offset ] = value.x;
  8100. customAttribute.array[ offset + 1 ] = value.y;
  8101. offset += 2;
  8102. }
  8103. } else if ( customAttribute.size === 3 ) {
  8104. if ( customAttribute.type === "c" ) {
  8105. for ( ca = 0; ca < cal; ca ++ ) {
  8106. value = customAttribute.value[ ca ];
  8107. customAttribute.array[ offset ] = value.r;
  8108. customAttribute.array[ offset + 1 ] = value.g;
  8109. customAttribute.array[ offset + 2 ] = value.b;
  8110. offset += 3;
  8111. }
  8112. } else {
  8113. for ( ca = 0; ca < cal; ca ++ ) {
  8114. value = customAttribute.value[ ca ];
  8115. customAttribute.array[ offset ] = value.x;
  8116. customAttribute.array[ offset + 1 ] = value.y;
  8117. customAttribute.array[ offset + 2 ] = value.z;
  8118. offset += 3;
  8119. }
  8120. }
  8121. } else if ( customAttribute.size === 4 ) {
  8122. for ( ca = 0; ca < cal; ca ++ ) {
  8123. value = customAttribute.value[ ca ];
  8124. customAttribute.array[ offset ] = value.x;
  8125. customAttribute.array[ offset + 1 ] = value.y;
  8126. customAttribute.array[ offset + 2 ] = value.z;
  8127. customAttribute.array[ offset + 3 ] = value.w;
  8128. offset += 4;
  8129. }
  8130. }
  8131. _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
  8132. _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
  8133. }
  8134. }
  8135. }
  8136. };
  8137. function setRibbonBuffers ( geometry, hint ) {
  8138. var v, c, vertex, offset, color,
  8139. vertices = geometry.vertices,
  8140. colors = geometry.colors,
  8141. vl = vertices.length,
  8142. cl = colors.length,
  8143. vertexArray = geometry.__vertexArray,
  8144. colorArray = geometry.__colorArray,
  8145. dirtyVertices = geometry.verticesNeedUpdate,
  8146. dirtyColors = geometry.colorsNeedUpdate;
  8147. if ( dirtyVertices ) {
  8148. for ( v = 0; v < vl; v ++ ) {
  8149. vertex = vertices[ v ];
  8150. offset = v * 3;
  8151. vertexArray[ offset ] = vertex.x;
  8152. vertexArray[ offset + 1 ] = vertex.y;
  8153. vertexArray[ offset + 2 ] = vertex.z;
  8154. }
  8155. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
  8156. _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
  8157. }
  8158. if ( dirtyColors ) {
  8159. for ( c = 0; c < cl; c ++ ) {
  8160. color = colors[ c ];
  8161. offset = c * 3;
  8162. colorArray[ offset ] = color.r;
  8163. colorArray[ offset + 1 ] = color.g;
  8164. colorArray[ offset + 2 ] = color.b;
  8165. }
  8166. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
  8167. _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
  8168. }
  8169. };
  8170. function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
  8171. if ( ! geometryGroup.__inittedArrays ) {
  8172. // console.log( object );
  8173. return;
  8174. }
  8175. var normalType = bufferGuessNormalType( material ),
  8176. vertexColorType = bufferGuessVertexColorType( material ),
  8177. uvType = bufferGuessUVType( material ),
  8178. needsSmoothNormals = ( normalType === THREE.SmoothShading );
  8179. var f, fl, fi, face,
  8180. vertexNormals, faceNormal, normal,
  8181. vertexColors, faceColor,
  8182. vertexTangents,
  8183. uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4,
  8184. c1, c2, c3, c4,
  8185. sw1, sw2, sw3, sw4,
  8186. si1, si2, si3, si4,
  8187. sa1, sa2, sa3, sa4,
  8188. sb1, sb2, sb3, sb4,
  8189. m, ml, i, il,
  8190. vn, uvi, uv2i,
  8191. vk, vkl, vka,
  8192. nka, chf, faceVertexNormals,
  8193. a,
  8194. vertexIndex = 0,
  8195. offset = 0,
  8196. offset_uv = 0,
  8197. offset_uv2 = 0,
  8198. offset_face = 0,
  8199. offset_normal = 0,
  8200. offset_tangent = 0,
  8201. offset_line = 0,
  8202. offset_color = 0,
  8203. offset_skin = 0,
  8204. offset_morphTarget = 0,
  8205. offset_custom = 0,
  8206. offset_customSrc = 0,
  8207. value,
  8208. vertexArray = geometryGroup.__vertexArray,
  8209. uvArray = geometryGroup.__uvArray,
  8210. uv2Array = geometryGroup.__uv2Array,
  8211. normalArray = geometryGroup.__normalArray,
  8212. tangentArray = geometryGroup.__tangentArray,
  8213. colorArray = geometryGroup.__colorArray,
  8214. skinVertexAArray = geometryGroup.__skinVertexAArray,
  8215. skinVertexBArray = geometryGroup.__skinVertexBArray,
  8216. skinIndexArray = geometryGroup.__skinIndexArray,
  8217. skinWeightArray = geometryGroup.__skinWeightArray,
  8218. morphTargetsArrays = geometryGroup.__morphTargetsArrays,
  8219. morphNormalsArrays = geometryGroup.__morphNormalsArrays,
  8220. customAttributes = geometryGroup.__webglCustomAttributesList,
  8221. customAttribute,
  8222. faceArray = geometryGroup.__faceArray,
  8223. lineArray = geometryGroup.__lineArray,
  8224. geometry = object.geometry, // this is shared for all chunks
  8225. dirtyVertices = geometry.verticesNeedUpdate,
  8226. dirtyElements = geometry.elementsNeedUpdate,
  8227. dirtyUvs = geometry.uvsNeedUpdate,
  8228. dirtyNormals = geometry.normalsNeedUpdate,
  8229. dirtyTangents = geometry.tangentsNeedUpdate,
  8230. dirtyColors = geometry.colorsNeedUpdate,
  8231. dirtyMorphTargets = geometry.morphTargetsNeedUpdate,
  8232. vertices = geometry.vertices,
  8233. chunk_faces3 = geometryGroup.faces3,
  8234. chunk_faces4 = geometryGroup.faces4,
  8235. obj_faces = geometry.faces,
  8236. obj_uvs = geometry.faceVertexUvs[ 0 ],
  8237. obj_uvs2 = geometry.faceVertexUvs[ 1 ],
  8238. obj_colors = geometry.colors,
  8239. obj_skinVerticesA = geometry.skinVerticesA,
  8240. obj_skinVerticesB = geometry.skinVerticesB,
  8241. obj_skinIndices = geometry.skinIndices,
  8242. obj_skinWeights = geometry.skinWeights,
  8243. morphTargets = geometry.morphTargets,
  8244. morphNormals = geometry.morphNormals;
  8245. if ( dirtyVertices ) {
  8246. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8247. face = obj_faces[ chunk_faces3[ f ] ];
  8248. v1 = vertices[ face.a ];
  8249. v2 = vertices[ face.b ];
  8250. v3 = vertices[ face.c ];
  8251. vertexArray[ offset ] = v1.x;
  8252. vertexArray[ offset + 1 ] = v1.y;
  8253. vertexArray[ offset + 2 ] = v1.z;
  8254. vertexArray[ offset + 3 ] = v2.x;
  8255. vertexArray[ offset + 4 ] = v2.y;
  8256. vertexArray[ offset + 5 ] = v2.z;
  8257. vertexArray[ offset + 6 ] = v3.x;
  8258. vertexArray[ offset + 7 ] = v3.y;
  8259. vertexArray[ offset + 8 ] = v3.z;
  8260. offset += 9;
  8261. }
  8262. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8263. face = obj_faces[ chunk_faces4[ f ] ];
  8264. v1 = vertices[ face.a ];
  8265. v2 = vertices[ face.b ];
  8266. v3 = vertices[ face.c ];
  8267. v4 = vertices[ face.d ];
  8268. vertexArray[ offset ] = v1.x;
  8269. vertexArray[ offset + 1 ] = v1.y;
  8270. vertexArray[ offset + 2 ] = v1.z;
  8271. vertexArray[ offset + 3 ] = v2.x;
  8272. vertexArray[ offset + 4 ] = v2.y;
  8273. vertexArray[ offset + 5 ] = v2.z;
  8274. vertexArray[ offset + 6 ] = v3.x;
  8275. vertexArray[ offset + 7 ] = v3.y;
  8276. vertexArray[ offset + 8 ] = v3.z;
  8277. vertexArray[ offset + 9 ] = v4.x;
  8278. vertexArray[ offset + 10 ] = v4.y;
  8279. vertexArray[ offset + 11 ] = v4.z;
  8280. offset += 12;
  8281. }
  8282. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
  8283. _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
  8284. }
  8285. if ( dirtyMorphTargets ) {
  8286. for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
  8287. offset_morphTarget = 0;
  8288. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8289. chf = chunk_faces3[ f ];
  8290. face = obj_faces[ chf ];
  8291. // morph positions
  8292. v1 = morphTargets[ vk ].vertices[ face.a ];
  8293. v2 = morphTargets[ vk ].vertices[ face.b ];
  8294. v3 = morphTargets[ vk ].vertices[ face.c ];
  8295. vka = morphTargetsArrays[ vk ];
  8296. vka[ offset_morphTarget ] = v1.x;
  8297. vka[ offset_morphTarget + 1 ] = v1.y;
  8298. vka[ offset_morphTarget + 2 ] = v1.z;
  8299. vka[ offset_morphTarget + 3 ] = v2.x;
  8300. vka[ offset_morphTarget + 4 ] = v2.y;
  8301. vka[ offset_morphTarget + 5 ] = v2.z;
  8302. vka[ offset_morphTarget + 6 ] = v3.x;
  8303. vka[ offset_morphTarget + 7 ] = v3.y;
  8304. vka[ offset_morphTarget + 8 ] = v3.z;
  8305. // morph normals
  8306. if ( material.morphNormals ) {
  8307. if ( needsSmoothNormals ) {
  8308. faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ];
  8309. n1 = faceVertexNormals.a;
  8310. n2 = faceVertexNormals.b;
  8311. n3 = faceVertexNormals.c;
  8312. } else {
  8313. n1 = morphNormals[ vk ].faceNormals[ chf ];
  8314. n2 = n1;
  8315. n3 = n1;
  8316. }
  8317. nka = morphNormalsArrays[ vk ];
  8318. nka[ offset_morphTarget ] = n1.x;
  8319. nka[ offset_morphTarget + 1 ] = n1.y;
  8320. nka[ offset_morphTarget + 2 ] = n1.z;
  8321. nka[ offset_morphTarget + 3 ] = n2.x;
  8322. nka[ offset_morphTarget + 4 ] = n2.y;
  8323. nka[ offset_morphTarget + 5 ] = n2.z;
  8324. nka[ offset_morphTarget + 6 ] = n3.x;
  8325. nka[ offset_morphTarget + 7 ] = n3.y;
  8326. nka[ offset_morphTarget + 8 ] = n3.z;
  8327. }
  8328. //
  8329. offset_morphTarget += 9;
  8330. }
  8331. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8332. chf = chunk_faces4[ f ];
  8333. face = obj_faces[ chf ];
  8334. // morph positions
  8335. v1 = morphTargets[ vk ].vertices[ face.a ];
  8336. v2 = morphTargets[ vk ].vertices[ face.b ];
  8337. v3 = morphTargets[ vk ].vertices[ face.c ];
  8338. v4 = morphTargets[ vk ].vertices[ face.d ];
  8339. vka = morphTargetsArrays[ vk ];
  8340. vka[ offset_morphTarget ] = v1.x;
  8341. vka[ offset_morphTarget + 1 ] = v1.y;
  8342. vka[ offset_morphTarget + 2 ] = v1.z;
  8343. vka[ offset_morphTarget + 3 ] = v2.x;
  8344. vka[ offset_morphTarget + 4 ] = v2.y;
  8345. vka[ offset_morphTarget + 5 ] = v2.z;
  8346. vka[ offset_morphTarget + 6 ] = v3.x;
  8347. vka[ offset_morphTarget + 7 ] = v3.y;
  8348. vka[ offset_morphTarget + 8 ] = v3.z;
  8349. vka[ offset_morphTarget + 9 ] = v4.x;
  8350. vka[ offset_morphTarget + 10 ] = v4.y;
  8351. vka[ offset_morphTarget + 11 ] = v4.z;
  8352. // morph normals
  8353. if ( material.morphNormals ) {
  8354. if ( needsSmoothNormals ) {
  8355. faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ];
  8356. n1 = faceVertexNormals.a;
  8357. n2 = faceVertexNormals.b;
  8358. n3 = faceVertexNormals.c;
  8359. n4 = faceVertexNormals.d;
  8360. } else {
  8361. n1 = morphNormals[ vk ].faceNormals[ chf ];
  8362. n2 = n1;
  8363. n3 = n1;
  8364. n4 = n1;
  8365. }
  8366. nka = morphNormalsArrays[ vk ];
  8367. nka[ offset_morphTarget ] = n1.x;
  8368. nka[ offset_morphTarget + 1 ] = n1.y;
  8369. nka[ offset_morphTarget + 2 ] = n1.z;
  8370. nka[ offset_morphTarget + 3 ] = n2.x;
  8371. nka[ offset_morphTarget + 4 ] = n2.y;
  8372. nka[ offset_morphTarget + 5 ] = n2.z;
  8373. nka[ offset_morphTarget + 6 ] = n3.x;
  8374. nka[ offset_morphTarget + 7 ] = n3.y;
  8375. nka[ offset_morphTarget + 8 ] = n3.z;
  8376. nka[ offset_morphTarget + 9 ] = n4.x;
  8377. nka[ offset_morphTarget + 10 ] = n4.y;
  8378. nka[ offset_morphTarget + 11 ] = n4.z;
  8379. }
  8380. //
  8381. offset_morphTarget += 12;
  8382. }
  8383. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ vk ] );
  8384. _gl.bufferData( _gl.ARRAY_BUFFER, morphTargetsArrays[ vk ], hint );
  8385. if ( material.morphNormals ) {
  8386. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ vk ] );
  8387. _gl.bufferData( _gl.ARRAY_BUFFER, morphNormalsArrays[ vk ], hint );
  8388. }
  8389. }
  8390. }
  8391. if ( obj_skinWeights.length ) {
  8392. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8393. face = obj_faces[ chunk_faces3[ f ] ];
  8394. // weights
  8395. sw1 = obj_skinWeights[ face.a ];
  8396. sw2 = obj_skinWeights[ face.b ];
  8397. sw3 = obj_skinWeights[ face.c ];
  8398. skinWeightArray[ offset_skin ] = sw1.x;
  8399. skinWeightArray[ offset_skin + 1 ] = sw1.y;
  8400. skinWeightArray[ offset_skin + 2 ] = sw1.z;
  8401. skinWeightArray[ offset_skin + 3 ] = sw1.w;
  8402. skinWeightArray[ offset_skin + 4 ] = sw2.x;
  8403. skinWeightArray[ offset_skin + 5 ] = sw2.y;
  8404. skinWeightArray[ offset_skin + 6 ] = sw2.z;
  8405. skinWeightArray[ offset_skin + 7 ] = sw2.w;
  8406. skinWeightArray[ offset_skin + 8 ] = sw3.x;
  8407. skinWeightArray[ offset_skin + 9 ] = sw3.y;
  8408. skinWeightArray[ offset_skin + 10 ] = sw3.z;
  8409. skinWeightArray[ offset_skin + 11 ] = sw3.w;
  8410. // indices
  8411. si1 = obj_skinIndices[ face.a ];
  8412. si2 = obj_skinIndices[ face.b ];
  8413. si3 = obj_skinIndices[ face.c ];
  8414. skinIndexArray[ offset_skin ] = si1.x;
  8415. skinIndexArray[ offset_skin + 1 ] = si1.y;
  8416. skinIndexArray[ offset_skin + 2 ] = si1.z;
  8417. skinIndexArray[ offset_skin + 3 ] = si1.w;
  8418. skinIndexArray[ offset_skin + 4 ] = si2.x;
  8419. skinIndexArray[ offset_skin + 5 ] = si2.y;
  8420. skinIndexArray[ offset_skin + 6 ] = si2.z;
  8421. skinIndexArray[ offset_skin + 7 ] = si2.w;
  8422. skinIndexArray[ offset_skin + 8 ] = si3.x;
  8423. skinIndexArray[ offset_skin + 9 ] = si3.y;
  8424. skinIndexArray[ offset_skin + 10 ] = si3.z;
  8425. skinIndexArray[ offset_skin + 11 ] = si3.w;
  8426. // vertices A
  8427. sa1 = obj_skinVerticesA[ face.a ];
  8428. sa2 = obj_skinVerticesA[ face.b ];
  8429. sa3 = obj_skinVerticesA[ face.c ];
  8430. skinVertexAArray[ offset_skin ] = sa1.x;
  8431. skinVertexAArray[ offset_skin + 1 ] = sa1.y;
  8432. skinVertexAArray[ offset_skin + 2 ] = sa1.z;
  8433. skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
  8434. skinVertexAArray[ offset_skin + 4 ] = sa2.x;
  8435. skinVertexAArray[ offset_skin + 5 ] = sa2.y;
  8436. skinVertexAArray[ offset_skin + 6 ] = sa2.z;
  8437. skinVertexAArray[ offset_skin + 7 ] = 1;
  8438. skinVertexAArray[ offset_skin + 8 ] = sa3.x;
  8439. skinVertexAArray[ offset_skin + 9 ] = sa3.y;
  8440. skinVertexAArray[ offset_skin + 10 ] = sa3.z;
  8441. skinVertexAArray[ offset_skin + 11 ] = 1;
  8442. // vertices B
  8443. sb1 = obj_skinVerticesB[ face.a ];
  8444. sb2 = obj_skinVerticesB[ face.b ];
  8445. sb3 = obj_skinVerticesB[ face.c ];
  8446. skinVertexBArray[ offset_skin ] = sb1.x;
  8447. skinVertexBArray[ offset_skin + 1 ] = sb1.y;
  8448. skinVertexBArray[ offset_skin + 2 ] = sb1.z;
  8449. skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
  8450. skinVertexBArray[ offset_skin + 4 ] = sb2.x;
  8451. skinVertexBArray[ offset_skin + 5 ] = sb2.y;
  8452. skinVertexBArray[ offset_skin + 6 ] = sb2.z;
  8453. skinVertexBArray[ offset_skin + 7 ] = 1;
  8454. skinVertexBArray[ offset_skin + 8 ] = sb3.x;
  8455. skinVertexBArray[ offset_skin + 9 ] = sb3.y;
  8456. skinVertexBArray[ offset_skin + 10 ] = sb3.z;
  8457. skinVertexBArray[ offset_skin + 11 ] = 1;
  8458. offset_skin += 12;
  8459. }
  8460. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8461. face = obj_faces[ chunk_faces4[ f ] ];
  8462. // weights
  8463. sw1 = obj_skinWeights[ face.a ];
  8464. sw2 = obj_skinWeights[ face.b ];
  8465. sw3 = obj_skinWeights[ face.c ];
  8466. sw4 = obj_skinWeights[ face.d ];
  8467. skinWeightArray[ offset_skin ] = sw1.x;
  8468. skinWeightArray[ offset_skin + 1 ] = sw1.y;
  8469. skinWeightArray[ offset_skin + 2 ] = sw1.z;
  8470. skinWeightArray[ offset_skin + 3 ] = sw1.w;
  8471. skinWeightArray[ offset_skin + 4 ] = sw2.x;
  8472. skinWeightArray[ offset_skin + 5 ] = sw2.y;
  8473. skinWeightArray[ offset_skin + 6 ] = sw2.z;
  8474. skinWeightArray[ offset_skin + 7 ] = sw2.w;
  8475. skinWeightArray[ offset_skin + 8 ] = sw3.x;
  8476. skinWeightArray[ offset_skin + 9 ] = sw3.y;
  8477. skinWeightArray[ offset_skin + 10 ] = sw3.z;
  8478. skinWeightArray[ offset_skin + 11 ] = sw3.w;
  8479. skinWeightArray[ offset_skin + 12 ] = sw4.x;
  8480. skinWeightArray[ offset_skin + 13 ] = sw4.y;
  8481. skinWeightArray[ offset_skin + 14 ] = sw4.z;
  8482. skinWeightArray[ offset_skin + 15 ] = sw4.w;
  8483. // indices
  8484. si1 = obj_skinIndices[ face.a ];
  8485. si2 = obj_skinIndices[ face.b ];
  8486. si3 = obj_skinIndices[ face.c ];
  8487. si4 = obj_skinIndices[ face.d ];
  8488. skinIndexArray[ offset_skin ] = si1.x;
  8489. skinIndexArray[ offset_skin + 1 ] = si1.y;
  8490. skinIndexArray[ offset_skin + 2 ] = si1.z;
  8491. skinIndexArray[ offset_skin + 3 ] = si1.w;
  8492. skinIndexArray[ offset_skin + 4 ] = si2.x;
  8493. skinIndexArray[ offset_skin + 5 ] = si2.y;
  8494. skinIndexArray[ offset_skin + 6 ] = si2.z;
  8495. skinIndexArray[ offset_skin + 7 ] = si2.w;
  8496. skinIndexArray[ offset_skin + 8 ] = si3.x;
  8497. skinIndexArray[ offset_skin + 9 ] = si3.y;
  8498. skinIndexArray[ offset_skin + 10 ] = si3.z;
  8499. skinIndexArray[ offset_skin + 11 ] = si3.w;
  8500. skinIndexArray[ offset_skin + 12 ] = si4.x;
  8501. skinIndexArray[ offset_skin + 13 ] = si4.y;
  8502. skinIndexArray[ offset_skin + 14 ] = si4.z;
  8503. skinIndexArray[ offset_skin + 15 ] = si4.w;
  8504. // vertices A
  8505. sa1 = obj_skinVerticesA[ face.a ];
  8506. sa2 = obj_skinVerticesA[ face.b ];
  8507. sa3 = obj_skinVerticesA[ face.c ];
  8508. sa4 = obj_skinVerticesA[ face.d ];
  8509. skinVertexAArray[ offset_skin ] = sa1.x;
  8510. skinVertexAArray[ offset_skin + 1 ] = sa1.y;
  8511. skinVertexAArray[ offset_skin + 2 ] = sa1.z;
  8512. skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
  8513. skinVertexAArray[ offset_skin + 4 ] = sa2.x;
  8514. skinVertexAArray[ offset_skin + 5 ] = sa2.y;
  8515. skinVertexAArray[ offset_skin + 6 ] = sa2.z;
  8516. skinVertexAArray[ offset_skin + 7 ] = 1;
  8517. skinVertexAArray[ offset_skin + 8 ] = sa3.x;
  8518. skinVertexAArray[ offset_skin + 9 ] = sa3.y;
  8519. skinVertexAArray[ offset_skin + 10 ] = sa3.z;
  8520. skinVertexAArray[ offset_skin + 11 ] = 1;
  8521. skinVertexAArray[ offset_skin + 12 ] = sa4.x;
  8522. skinVertexAArray[ offset_skin + 13 ] = sa4.y;
  8523. skinVertexAArray[ offset_skin + 14 ] = sa4.z;
  8524. skinVertexAArray[ offset_skin + 15 ] = 1;
  8525. // vertices B
  8526. sb1 = obj_skinVerticesB[ face.a ];
  8527. sb2 = obj_skinVerticesB[ face.b ];
  8528. sb3 = obj_skinVerticesB[ face.c ];
  8529. sb4 = obj_skinVerticesB[ face.d ];
  8530. skinVertexBArray[ offset_skin ] = sb1.x;
  8531. skinVertexBArray[ offset_skin + 1 ] = sb1.y;
  8532. skinVertexBArray[ offset_skin + 2 ] = sb1.z;
  8533. skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
  8534. skinVertexBArray[ offset_skin + 4 ] = sb2.x;
  8535. skinVertexBArray[ offset_skin + 5 ] = sb2.y;
  8536. skinVertexBArray[ offset_skin + 6 ] = sb2.z;
  8537. skinVertexBArray[ offset_skin + 7 ] = 1;
  8538. skinVertexBArray[ offset_skin + 8 ] = sb3.x;
  8539. skinVertexBArray[ offset_skin + 9 ] = sb3.y;
  8540. skinVertexBArray[ offset_skin + 10 ] = sb3.z;
  8541. skinVertexBArray[ offset_skin + 11 ] = 1;
  8542. skinVertexBArray[ offset_skin + 12 ] = sb4.x;
  8543. skinVertexBArray[ offset_skin + 13 ] = sb4.y;
  8544. skinVertexBArray[ offset_skin + 14 ] = sb4.z;
  8545. skinVertexBArray[ offset_skin + 15 ] = 1;
  8546. offset_skin += 16;
  8547. }
  8548. if ( offset_skin > 0 ) {
  8549. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
  8550. _gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );
  8551. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
  8552. _gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );
  8553. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
  8554. _gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );
  8555. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
  8556. _gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
  8557. }
  8558. }
  8559. if ( dirtyColors && vertexColorType ) {
  8560. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8561. face = obj_faces[ chunk_faces3[ f ] ];
  8562. vertexColors = face.vertexColors;
  8563. faceColor = face.color;
  8564. if ( vertexColors.length === 3 && vertexColorType === THREE.VertexColors ) {
  8565. c1 = vertexColors[ 0 ];
  8566. c2 = vertexColors[ 1 ];
  8567. c3 = vertexColors[ 2 ];
  8568. } else {
  8569. c1 = faceColor;
  8570. c2 = faceColor;
  8571. c3 = faceColor;
  8572. }
  8573. colorArray[ offset_color ] = c1.r;
  8574. colorArray[ offset_color + 1 ] = c1.g;
  8575. colorArray[ offset_color + 2 ] = c1.b;
  8576. colorArray[ offset_color + 3 ] = c2.r;
  8577. colorArray[ offset_color + 4 ] = c2.g;
  8578. colorArray[ offset_color + 5 ] = c2.b;
  8579. colorArray[ offset_color + 6 ] = c3.r;
  8580. colorArray[ offset_color + 7 ] = c3.g;
  8581. colorArray[ offset_color + 8 ] = c3.b;
  8582. offset_color += 9;
  8583. }
  8584. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8585. face = obj_faces[ chunk_faces4[ f ] ];
  8586. vertexColors = face.vertexColors;
  8587. faceColor = face.color;
  8588. if ( vertexColors.length === 4 && vertexColorType === THREE.VertexColors ) {
  8589. c1 = vertexColors[ 0 ];
  8590. c2 = vertexColors[ 1 ];
  8591. c3 = vertexColors[ 2 ];
  8592. c4 = vertexColors[ 3 ];
  8593. } else {
  8594. c1 = faceColor;
  8595. c2 = faceColor;
  8596. c3 = faceColor;
  8597. c4 = faceColor;
  8598. }
  8599. colorArray[ offset_color ] = c1.r;
  8600. colorArray[ offset_color + 1 ] = c1.g;
  8601. colorArray[ offset_color + 2 ] = c1.b;
  8602. colorArray[ offset_color + 3 ] = c2.r;
  8603. colorArray[ offset_color + 4 ] = c2.g;
  8604. colorArray[ offset_color + 5 ] = c2.b;
  8605. colorArray[ offset_color + 6 ] = c3.r;
  8606. colorArray[ offset_color + 7 ] = c3.g;
  8607. colorArray[ offset_color + 8 ] = c3.b;
  8608. colorArray[ offset_color + 9 ] = c4.r;
  8609. colorArray[ offset_color + 10 ] = c4.g;
  8610. colorArray[ offset_color + 11 ] = c4.b;
  8611. offset_color += 12;
  8612. }
  8613. if ( offset_color > 0 ) {
  8614. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
  8615. _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
  8616. }
  8617. }
  8618. if ( dirtyTangents && geometry.hasTangents ) {
  8619. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8620. face = obj_faces[ chunk_faces3[ f ] ];
  8621. vertexTangents = face.vertexTangents;
  8622. t1 = vertexTangents[ 0 ];
  8623. t2 = vertexTangents[ 1 ];
  8624. t3 = vertexTangents[ 2 ];
  8625. tangentArray[ offset_tangent ] = t1.x;
  8626. tangentArray[ offset_tangent + 1 ] = t1.y;
  8627. tangentArray[ offset_tangent + 2 ] = t1.z;
  8628. tangentArray[ offset_tangent + 3 ] = t1.w;
  8629. tangentArray[ offset_tangent + 4 ] = t2.x;
  8630. tangentArray[ offset_tangent + 5 ] = t2.y;
  8631. tangentArray[ offset_tangent + 6 ] = t2.z;
  8632. tangentArray[ offset_tangent + 7 ] = t2.w;
  8633. tangentArray[ offset_tangent + 8 ] = t3.x;
  8634. tangentArray[ offset_tangent + 9 ] = t3.y;
  8635. tangentArray[ offset_tangent + 10 ] = t3.z;
  8636. tangentArray[ offset_tangent + 11 ] = t3.w;
  8637. offset_tangent += 12;
  8638. }
  8639. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8640. face = obj_faces[ chunk_faces4[ f ] ];
  8641. vertexTangents = face.vertexTangents;
  8642. t1 = vertexTangents[ 0 ];
  8643. t2 = vertexTangents[ 1 ];
  8644. t3 = vertexTangents[ 2 ];
  8645. t4 = vertexTangents[ 3 ];
  8646. tangentArray[ offset_tangent ] = t1.x;
  8647. tangentArray[ offset_tangent + 1 ] = t1.y;
  8648. tangentArray[ offset_tangent + 2 ] = t1.z;
  8649. tangentArray[ offset_tangent + 3 ] = t1.w;
  8650. tangentArray[ offset_tangent + 4 ] = t2.x;
  8651. tangentArray[ offset_tangent + 5 ] = t2.y;
  8652. tangentArray[ offset_tangent + 6 ] = t2.z;
  8653. tangentArray[ offset_tangent + 7 ] = t2.w;
  8654. tangentArray[ offset_tangent + 8 ] = t3.x;
  8655. tangentArray[ offset_tangent + 9 ] = t3.y;
  8656. tangentArray[ offset_tangent + 10 ] = t3.z;
  8657. tangentArray[ offset_tangent + 11 ] = t3.w;
  8658. tangentArray[ offset_tangent + 12 ] = t4.x;
  8659. tangentArray[ offset_tangent + 13 ] = t4.y;
  8660. tangentArray[ offset_tangent + 14 ] = t4.z;
  8661. tangentArray[ offset_tangent + 15 ] = t4.w;
  8662. offset_tangent += 16;
  8663. }
  8664. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
  8665. _gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
  8666. }
  8667. if ( dirtyNormals && normalType ) {
  8668. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8669. face = obj_faces[ chunk_faces3[ f ] ];
  8670. vertexNormals = face.vertexNormals;
  8671. faceNormal = face.normal;
  8672. if ( vertexNormals.length === 3 && needsSmoothNormals ) {
  8673. for ( i = 0; i < 3; i ++ ) {
  8674. vn = vertexNormals[ i ];
  8675. normalArray[ offset_normal ] = vn.x;
  8676. normalArray[ offset_normal + 1 ] = vn.y;
  8677. normalArray[ offset_normal + 2 ] = vn.z;
  8678. offset_normal += 3;
  8679. }
  8680. } else {
  8681. for ( i = 0; i < 3; i ++ ) {
  8682. normalArray[ offset_normal ] = faceNormal.x;
  8683. normalArray[ offset_normal + 1 ] = faceNormal.y;
  8684. normalArray[ offset_normal + 2 ] = faceNormal.z;
  8685. offset_normal += 3;
  8686. }
  8687. }
  8688. }
  8689. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8690. face = obj_faces[ chunk_faces4[ f ] ];
  8691. vertexNormals = face.vertexNormals;
  8692. faceNormal = face.normal;
  8693. if ( vertexNormals.length === 4 && needsSmoothNormals ) {
  8694. for ( i = 0; i < 4; i ++ ) {
  8695. vn = vertexNormals[ i ];
  8696. normalArray[ offset_normal ] = vn.x;
  8697. normalArray[ offset_normal + 1 ] = vn.y;
  8698. normalArray[ offset_normal + 2 ] = vn.z;
  8699. offset_normal += 3;
  8700. }
  8701. } else {
  8702. for ( i = 0; i < 4; i ++ ) {
  8703. normalArray[ offset_normal ] = faceNormal.x;
  8704. normalArray[ offset_normal + 1 ] = faceNormal.y;
  8705. normalArray[ offset_normal + 2 ] = faceNormal.z;
  8706. offset_normal += 3;
  8707. }
  8708. }
  8709. }
  8710. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
  8711. _gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
  8712. }
  8713. if ( dirtyUvs && obj_uvs && uvType ) {
  8714. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8715. fi = chunk_faces3[ f ];
  8716. face = obj_faces[ fi ];
  8717. uv = obj_uvs[ fi ];
  8718. if ( uv === undefined ) continue;
  8719. for ( i = 0; i < 3; i ++ ) {
  8720. uvi = uv[ i ];
  8721. uvArray[ offset_uv ] = uvi.u;
  8722. uvArray[ offset_uv + 1 ] = uvi.v;
  8723. offset_uv += 2;
  8724. }
  8725. }
  8726. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8727. fi = chunk_faces4[ f ];
  8728. face = obj_faces[ fi ];
  8729. uv = obj_uvs[ fi ];
  8730. if ( uv === undefined ) continue;
  8731. for ( i = 0; i < 4; i ++ ) {
  8732. uvi = uv[ i ];
  8733. uvArray[ offset_uv ] = uvi.u;
  8734. uvArray[ offset_uv + 1 ] = uvi.v;
  8735. offset_uv += 2;
  8736. }
  8737. }
  8738. if ( offset_uv > 0 ) {
  8739. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
  8740. _gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
  8741. }
  8742. }
  8743. if ( dirtyUvs && obj_uvs2 && uvType ) {
  8744. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8745. fi = chunk_faces3[ f ];
  8746. face = obj_faces[ fi ];
  8747. uv2 = obj_uvs2[ fi ];
  8748. if ( uv2 === undefined ) continue;
  8749. for ( i = 0; i < 3; i ++ ) {
  8750. uv2i = uv2[ i ];
  8751. uv2Array[ offset_uv2 ] = uv2i.u;
  8752. uv2Array[ offset_uv2 + 1 ] = uv2i.v;
  8753. offset_uv2 += 2;
  8754. }
  8755. }
  8756. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8757. fi = chunk_faces4[ f ];
  8758. face = obj_faces[ fi ];
  8759. uv2 = obj_uvs2[ fi ];
  8760. if ( uv2 === undefined ) continue;
  8761. for ( i = 0; i < 4; i ++ ) {
  8762. uv2i = uv2[ i ];
  8763. uv2Array[ offset_uv2 ] = uv2i.u;
  8764. uv2Array[ offset_uv2 + 1 ] = uv2i.v;
  8765. offset_uv2 += 2;
  8766. }
  8767. }
  8768. if ( offset_uv2 > 0 ) {
  8769. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
  8770. _gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
  8771. }
  8772. }
  8773. if ( dirtyElements ) {
  8774. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8775. face = obj_faces[ chunk_faces3[ f ] ];
  8776. faceArray[ offset_face ] = vertexIndex;
  8777. faceArray[ offset_face + 1 ] = vertexIndex + 1;
  8778. faceArray[ offset_face + 2 ] = vertexIndex + 2;
  8779. offset_face += 3;
  8780. lineArray[ offset_line ] = vertexIndex;
  8781. lineArray[ offset_line + 1 ] = vertexIndex + 1;
  8782. lineArray[ offset_line + 2 ] = vertexIndex;
  8783. lineArray[ offset_line + 3 ] = vertexIndex + 2;
  8784. lineArray[ offset_line + 4 ] = vertexIndex + 1;
  8785. lineArray[ offset_line + 5 ] = vertexIndex + 2;
  8786. offset_line += 6;
  8787. vertexIndex += 3;
  8788. }
  8789. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8790. face = obj_faces[ chunk_faces4[ f ] ];
  8791. faceArray[ offset_face ] = vertexIndex;
  8792. faceArray[ offset_face + 1 ] = vertexIndex + 1;
  8793. faceArray[ offset_face + 2 ] = vertexIndex + 3;
  8794. faceArray[ offset_face + 3 ] = vertexIndex + 1;
  8795. faceArray[ offset_face + 4 ] = vertexIndex + 2;
  8796. faceArray[ offset_face + 5 ] = vertexIndex + 3;
  8797. offset_face += 6;
  8798. lineArray[ offset_line ] = vertexIndex;
  8799. lineArray[ offset_line + 1 ] = vertexIndex + 1;
  8800. lineArray[ offset_line + 2 ] = vertexIndex;
  8801. lineArray[ offset_line + 3 ] = vertexIndex + 3;
  8802. lineArray[ offset_line + 4 ] = vertexIndex + 1;
  8803. lineArray[ offset_line + 5 ] = vertexIndex + 2;
  8804. lineArray[ offset_line + 6 ] = vertexIndex + 2;
  8805. lineArray[ offset_line + 7 ] = vertexIndex + 3;
  8806. offset_line += 8;
  8807. vertexIndex += 4;
  8808. }
  8809. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
  8810. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
  8811. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
  8812. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
  8813. }
  8814. if ( customAttributes ) {
  8815. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  8816. customAttribute = customAttributes[ i ];
  8817. if ( ! customAttribute.__original.needsUpdate ) continue;
  8818. offset_custom = 0;
  8819. offset_customSrc = 0;
  8820. if ( customAttribute.size === 1 ) {
  8821. if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
  8822. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8823. face = obj_faces[ chunk_faces3[ f ] ];
  8824. customAttribute.array[ offset_custom ] = customAttribute.value[ face.a ];
  8825. customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
  8826. customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
  8827. offset_custom += 3;
  8828. }
  8829. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8830. face = obj_faces[ chunk_faces4[ f ] ];
  8831. customAttribute.array[ offset_custom ] = customAttribute.value[ face.a ];
  8832. customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
  8833. customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
  8834. customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ face.d ];
  8835. offset_custom += 4;
  8836. }
  8837. } else if ( customAttribute.boundTo === "faces" ) {
  8838. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8839. value = customAttribute.value[ chunk_faces3[ f ] ];
  8840. customAttribute.array[ offset_custom ] = value;
  8841. customAttribute.array[ offset_custom + 1 ] = value;
  8842. customAttribute.array[ offset_custom + 2 ] = value;
  8843. offset_custom += 3;
  8844. }
  8845. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8846. value = customAttribute.value[ chunk_faces4[ f ] ];
  8847. customAttribute.array[ offset_custom ] = value;
  8848. customAttribute.array[ offset_custom + 1 ] = value;
  8849. customAttribute.array[ offset_custom + 2 ] = value;
  8850. customAttribute.array[ offset_custom + 3 ] = value;
  8851. offset_custom += 4;
  8852. }
  8853. }
  8854. } else if ( customAttribute.size === 2 ) {
  8855. if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
  8856. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8857. face = obj_faces[ chunk_faces3[ f ] ];
  8858. v1 = customAttribute.value[ face.a ];
  8859. v2 = customAttribute.value[ face.b ];
  8860. v3 = customAttribute.value[ face.c ];
  8861. customAttribute.array[ offset_custom ] = v1.x;
  8862. customAttribute.array[ offset_custom + 1 ] = v1.y;
  8863. customAttribute.array[ offset_custom + 2 ] = v2.x;
  8864. customAttribute.array[ offset_custom + 3 ] = v2.y;
  8865. customAttribute.array[ offset_custom + 4 ] = v3.x;
  8866. customAttribute.array[ offset_custom + 5 ] = v3.y;
  8867. offset_custom += 6;
  8868. }
  8869. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8870. face = obj_faces[ chunk_faces4[ f ] ];
  8871. v1 = customAttribute.value[ face.a ];
  8872. v2 = customAttribute.value[ face.b ];
  8873. v3 = customAttribute.value[ face.c ];
  8874. v4 = customAttribute.value[ face.d ];
  8875. customAttribute.array[ offset_custom ] = v1.x;
  8876. customAttribute.array[ offset_custom + 1 ] = v1.y;
  8877. customAttribute.array[ offset_custom + 2 ] = v2.x;
  8878. customAttribute.array[ offset_custom + 3 ] = v2.y;
  8879. customAttribute.array[ offset_custom + 4 ] = v3.x;
  8880. customAttribute.array[ offset_custom + 5 ] = v3.y;
  8881. customAttribute.array[ offset_custom + 6 ] = v4.x;
  8882. customAttribute.array[ offset_custom + 7 ] = v4.y;
  8883. offset_custom += 8;
  8884. }
  8885. } else if ( customAttribute.boundTo === "faces" ) {
  8886. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8887. value = customAttribute.value[ chunk_faces3[ f ] ];
  8888. v1 = value;
  8889. v2 = value;
  8890. v3 = value;
  8891. customAttribute.array[ offset_custom ] = v1.x;
  8892. customAttribute.array[ offset_custom + 1 ] = v1.y;
  8893. customAttribute.array[ offset_custom + 2 ] = v2.x;
  8894. customAttribute.array[ offset_custom + 3 ] = v2.y;
  8895. customAttribute.array[ offset_custom + 4 ] = v3.x;
  8896. customAttribute.array[ offset_custom + 5 ] = v3.y;
  8897. offset_custom += 6;
  8898. }
  8899. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8900. value = customAttribute.value[ chunk_faces4[ f ] ];
  8901. v1 = value;
  8902. v2 = value;
  8903. v3 = value;
  8904. v4 = value;
  8905. customAttribute.array[ offset_custom ] = v1.x;
  8906. customAttribute.array[ offset_custom + 1 ] = v1.y;
  8907. customAttribute.array[ offset_custom + 2 ] = v2.x;
  8908. customAttribute.array[ offset_custom + 3 ] = v2.y;
  8909. customAttribute.array[ offset_custom + 4 ] = v3.x;
  8910. customAttribute.array[ offset_custom + 5 ] = v3.y;
  8911. customAttribute.array[ offset_custom + 6 ] = v4.x;
  8912. customAttribute.array[ offset_custom + 7 ] = v4.y;
  8913. offset_custom += 8;
  8914. }
  8915. }
  8916. } else if ( customAttribute.size === 3 ) {
  8917. var pp;
  8918. if ( customAttribute.type === "c" ) {
  8919. pp = [ "r", "g", "b" ];
  8920. } else {
  8921. pp = [ "x", "y", "z" ];
  8922. }
  8923. if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
  8924. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8925. face = obj_faces[ chunk_faces3[ f ] ];
  8926. v1 = customAttribute.value[ face.a ];
  8927. v2 = customAttribute.value[ face.b ];
  8928. v3 = customAttribute.value[ face.c ];
  8929. customAttribute.array[ offset_custom ] = v1[ pp[ 0 ] ];
  8930. customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
  8931. customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
  8932. customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
  8933. customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
  8934. customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
  8935. customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
  8936. customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
  8937. customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
  8938. offset_custom += 9;
  8939. }
  8940. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8941. face = obj_faces[ chunk_faces4[ f ] ];
  8942. v1 = customAttribute.value[ face.a ];
  8943. v2 = customAttribute.value[ face.b ];
  8944. v3 = customAttribute.value[ face.c ];
  8945. v4 = customAttribute.value[ face.d ];
  8946. customAttribute.array[ offset_custom ] = v1[ pp[ 0 ] ];
  8947. customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
  8948. customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
  8949. customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
  8950. customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
  8951. customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
  8952. customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
  8953. customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
  8954. customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
  8955. customAttribute.array[ offset_custom + 9 ] = v4[ pp[ 0 ] ];
  8956. customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
  8957. customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
  8958. offset_custom += 12;
  8959. }
  8960. } else if ( customAttribute.boundTo === "faces" ) {
  8961. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  8962. value = customAttribute.value[ chunk_faces3[ f ] ];
  8963. v1 = value;
  8964. v2 = value;
  8965. v3 = value;
  8966. customAttribute.array[ offset_custom ] = v1[ pp[ 0 ] ];
  8967. customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
  8968. customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
  8969. customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
  8970. customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
  8971. customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
  8972. customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
  8973. customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
  8974. customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
  8975. offset_custom += 9;
  8976. }
  8977. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  8978. value = customAttribute.value[ chunk_faces4[ f ] ];
  8979. v1 = value;
  8980. v2 = value;
  8981. v3 = value;
  8982. v4 = value;
  8983. customAttribute.array[ offset_custom ] = v1[ pp[ 0 ] ];
  8984. customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
  8985. customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
  8986. customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
  8987. customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
  8988. customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
  8989. customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
  8990. customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
  8991. customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
  8992. customAttribute.array[ offset_custom + 9 ] = v4[ pp[ 0 ] ];
  8993. customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
  8994. customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
  8995. offset_custom += 12;
  8996. }
  8997. }
  8998. } else if ( customAttribute.size === 4 ) {
  8999. if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
  9000. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  9001. face = obj_faces[ chunk_faces3[ f ] ];
  9002. v1 = customAttribute.value[ face.a ];
  9003. v2 = customAttribute.value[ face.b ];
  9004. v3 = customAttribute.value[ face.c ];
  9005. customAttribute.array[ offset_custom ] = v1.x;
  9006. customAttribute.array[ offset_custom + 1 ] = v1.y;
  9007. customAttribute.array[ offset_custom + 2 ] = v1.z;
  9008. customAttribute.array[ offset_custom + 3 ] = v1.w;
  9009. customAttribute.array[ offset_custom + 4 ] = v2.x;
  9010. customAttribute.array[ offset_custom + 5 ] = v2.y;
  9011. customAttribute.array[ offset_custom + 6 ] = v2.z;
  9012. customAttribute.array[ offset_custom + 7 ] = v2.w;
  9013. customAttribute.array[ offset_custom + 8 ] = v3.x;
  9014. customAttribute.array[ offset_custom + 9 ] = v3.y;
  9015. customAttribute.array[ offset_custom + 10 ] = v3.z;
  9016. customAttribute.array[ offset_custom + 11 ] = v3.w;
  9017. offset_custom += 12;
  9018. }
  9019. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  9020. face = obj_faces[ chunk_faces4[ f ] ];
  9021. v1 = customAttribute.value[ face.a ];
  9022. v2 = customAttribute.value[ face.b ];
  9023. v3 = customAttribute.value[ face.c ];
  9024. v4 = customAttribute.value[ face.d ];
  9025. customAttribute.array[ offset_custom ] = v1.x;
  9026. customAttribute.array[ offset_custom + 1 ] = v1.y;
  9027. customAttribute.array[ offset_custom + 2 ] = v1.z;
  9028. customAttribute.array[ offset_custom + 3 ] = v1.w;
  9029. customAttribute.array[ offset_custom + 4 ] = v2.x;
  9030. customAttribute.array[ offset_custom + 5 ] = v2.y;
  9031. customAttribute.array[ offset_custom + 6 ] = v2.z;
  9032. customAttribute.array[ offset_custom + 7 ] = v2.w;
  9033. customAttribute.array[ offset_custom + 8 ] = v3.x;
  9034. customAttribute.array[ offset_custom + 9 ] = v3.y;
  9035. customAttribute.array[ offset_custom + 10 ] = v3.z;
  9036. customAttribute.array[ offset_custom + 11 ] = v3.w;
  9037. customAttribute.array[ offset_custom + 12 ] = v4.x;
  9038. customAttribute.array[ offset_custom + 13 ] = v4.y;
  9039. customAttribute.array[ offset_custom + 14 ] = v4.z;
  9040. customAttribute.array[ offset_custom + 15 ] = v4.w;
  9041. offset_custom += 16;
  9042. }
  9043. } else if ( customAttribute.boundTo === "faces" ) {
  9044. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  9045. value = customAttribute.value[ chunk_faces3[ f ] ];
  9046. v1 = value;
  9047. v2 = value;
  9048. v3 = value;
  9049. customAttribute.array[ offset_custom ] = v1.x;
  9050. customAttribute.array[ offset_custom + 1 ] = v1.y;
  9051. customAttribute.array[ offset_custom + 2 ] = v1.z;
  9052. customAttribute.array[ offset_custom + 3 ] = v1.w;
  9053. customAttribute.array[ offset_custom + 4 ] = v2.x;
  9054. customAttribute.array[ offset_custom + 5 ] = v2.y;
  9055. customAttribute.array[ offset_custom + 6 ] = v2.z;
  9056. customAttribute.array[ offset_custom + 7 ] = v2.w;
  9057. customAttribute.array[ offset_custom + 8 ] = v3.x;
  9058. customAttribute.array[ offset_custom + 9 ] = v3.y;
  9059. customAttribute.array[ offset_custom + 10 ] = v3.z;
  9060. customAttribute.array[ offset_custom + 11 ] = v3.w;
  9061. offset_custom += 12;
  9062. }
  9063. for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
  9064. value = customAttribute.value[ chunk_faces4[ f ] ];
  9065. v1 = value;
  9066. v2 = value;
  9067. v3 = value;
  9068. v4 = value;
  9069. customAttribute.array[ offset_custom ] = v1.x;
  9070. customAttribute.array[ offset_custom + 1 ] = v1.y;
  9071. customAttribute.array[ offset_custom + 2 ] = v1.z;
  9072. customAttribute.array[ offset_custom + 3 ] = v1.w;
  9073. customAttribute.array[ offset_custom + 4 ] = v2.x;
  9074. customAttribute.array[ offset_custom + 5 ] = v2.y;
  9075. customAttribute.array[ offset_custom + 6 ] = v2.z;
  9076. customAttribute.array[ offset_custom + 7 ] = v2.w;
  9077. customAttribute.array[ offset_custom + 8 ] = v3.x;
  9078. customAttribute.array[ offset_custom + 9 ] = v3.y;
  9079. customAttribute.array[ offset_custom + 10 ] = v3.z;
  9080. customAttribute.array[ offset_custom + 11 ] = v3.w;
  9081. customAttribute.array[ offset_custom + 12 ] = v4.x;
  9082. customAttribute.array[ offset_custom + 13 ] = v4.y;
  9083. customAttribute.array[ offset_custom + 14 ] = v4.z;
  9084. customAttribute.array[ offset_custom + 15 ] = v4.w;
  9085. offset_custom += 16;
  9086. }
  9087. }
  9088. }
  9089. _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
  9090. _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
  9091. }
  9092. }
  9093. if ( dispose ) {
  9094. delete geometryGroup.__inittedArrays;
  9095. delete geometryGroup.__colorArray;
  9096. delete geometryGroup.__normalArray;
  9097. delete geometryGroup.__tangentArray;
  9098. delete geometryGroup.__uvArray;
  9099. delete geometryGroup.__uv2Array;
  9100. delete geometryGroup.__faceArray;
  9101. delete geometryGroup.__vertexArray;
  9102. delete geometryGroup.__lineArray;
  9103. delete geometryGroup.__skinVertexAArray;
  9104. delete geometryGroup.__skinVertexBArray;
  9105. delete geometryGroup.__skinIndexArray;
  9106. delete geometryGroup.__skinWeightArray;
  9107. }
  9108. };
  9109. function setDirectBuffers ( geometry, hint, dispose ) {
  9110. var attributes = geometry.attributes;
  9111. var index = attributes[ "index" ];
  9112. var position = attributes[ "position" ];
  9113. var normal = attributes[ "normal" ];
  9114. var uv = attributes[ "uv" ];
  9115. var color = attributes[ "color" ];
  9116. var tangent = attributes[ "tangent" ];
  9117. if ( geometry.elementsNeedUpdate && index !== undefined ) {
  9118. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
  9119. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, index.array, hint );
  9120. }
  9121. if ( geometry.verticesNeedUpdate && position !== undefined ) {
  9122. _gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
  9123. _gl.bufferData( _gl.ARRAY_BUFFER, position.array, hint );
  9124. }
  9125. if ( geometry.normalsNeedUpdate && normal !== undefined ) {
  9126. _gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
  9127. _gl.bufferData( _gl.ARRAY_BUFFER, normal.array, hint );
  9128. }
  9129. if ( geometry.uvsNeedUpdate && uv !== undefined ) {
  9130. _gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
  9131. _gl.bufferData( _gl.ARRAY_BUFFER, uv.array, hint );
  9132. }
  9133. if ( geometry.colorsNeedUpdate && color !== undefined ) {
  9134. _gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
  9135. _gl.bufferData( _gl.ARRAY_BUFFER, color.array, hint );
  9136. }
  9137. if ( geometry.tangentsNeedUpdate && tangent !== undefined ) {
  9138. _gl.bindBuffer( _gl.ARRAY_BUFFER, tangent.buffer );
  9139. _gl.bufferData( _gl.ARRAY_BUFFER, tangent.array, hint );
  9140. }
  9141. if ( dispose ) {
  9142. for ( var i in geometry.attributes ) {
  9143. delete geometry.attributes[ i ].array;
  9144. }
  9145. }
  9146. };
  9147. // Buffer rendering
  9148. this.renderBufferImmediate = function ( object, program, material ) {
  9149. if ( object.hasPositions && ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
  9150. if ( object.hasNormals && ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
  9151. if ( object.hasUvs && ! object.__webglUvBuffer ) object.__webglUvBuffer = _gl.createBuffer();
  9152. if ( object.hasColors && ! object.__webglColorBuffer ) object.__webglColorBuffer = _gl.createBuffer();
  9153. if ( object.hasPositions ) {
  9154. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglVertexBuffer );
  9155. _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
  9156. _gl.enableVertexAttribArray( program.attributes.position );
  9157. _gl.vertexAttribPointer( program.attributes.position, 3, _gl.FLOAT, false, 0, 0 );
  9158. }
  9159. if ( object.hasNormals ) {
  9160. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
  9161. if ( material.shading === THREE.FlatShading ) {
  9162. var nx, ny, nz,
  9163. nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz,
  9164. normalArray,
  9165. i, il = object.count * 3;
  9166. for( i = 0; i < il; i += 9 ) {
  9167. normalArray = object.normalArray;
  9168. nax = normalArray[ i ];
  9169. nay = normalArray[ i + 1 ];
  9170. naz = normalArray[ i + 2 ];
  9171. nbx = normalArray[ i + 3 ];
  9172. nby = normalArray[ i + 4 ];
  9173. nbz = normalArray[ i + 5 ];
  9174. ncx = normalArray[ i + 6 ];
  9175. ncy = normalArray[ i + 7 ];
  9176. ncz = normalArray[ i + 8 ];
  9177. nx = ( nax + nbx + ncx ) / 3;
  9178. ny = ( nay + nby + ncy ) / 3;
  9179. nz = ( naz + nbz + ncz ) / 3;
  9180. normalArray[ i ] = nx;
  9181. normalArray[ i + 1 ] = ny;
  9182. normalArray[ i + 2 ] = nz;
  9183. normalArray[ i + 3 ] = nx;
  9184. normalArray[ i + 4 ] = ny;
  9185. normalArray[ i + 5 ] = nz;
  9186. normalArray[ i + 6 ] = nx;
  9187. normalArray[ i + 7 ] = ny;
  9188. normalArray[ i + 8 ] = nz;
  9189. }
  9190. }
  9191. _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
  9192. _gl.enableVertexAttribArray( program.attributes.normal );
  9193. _gl.vertexAttribPointer( program.attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
  9194. }
  9195. if ( object.hasUvs && material.map ) {
  9196. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglUvBuffer );
  9197. _gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
  9198. _gl.enableVertexAttribArray( program.attributes.uv );
  9199. _gl.vertexAttribPointer( program.attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
  9200. }
  9201. if ( object.hasColors && material.vertexColors !== THREE.NoColors ) {
  9202. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglColorBuffer );
  9203. _gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
  9204. _gl.enableVertexAttribArray( program.attributes.color );
  9205. _gl.vertexAttribPointer( program.attributes.color, 3, _gl.FLOAT, false, 0, 0 );
  9206. }
  9207. _gl.drawArrays( _gl.TRIANGLES, 0, object.count );
  9208. object.count = 0;
  9209. };
  9210. this.renderBufferDirect = function ( camera, lights, fog, material, geometry, object ) {
  9211. if ( material.visible === false ) return;
  9212. var program, attributes, linewidth, primitives, a, attribute;
  9213. program = setProgram( camera, lights, fog, material, object );
  9214. attributes = program.attributes;
  9215. var updateBuffers = false,
  9216. wireframeBit = material.wireframe ? 1 : 0,
  9217. geometryHash = ( geometry.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
  9218. if ( geometryHash !== _currentGeometryGroupHash ) {
  9219. _currentGeometryGroupHash = geometryHash;
  9220. updateBuffers = true;
  9221. }
  9222. // render mesh
  9223. if ( object instanceof THREE.Mesh ) {
  9224. var offsets = geometry.offsets;
  9225. // if there is more than 1 chunk
  9226. // must set attribute pointers to use new offsets for each chunk
  9227. // even if geometry and materials didn't change
  9228. if ( offsets.length > 1 ) updateBuffers = true;
  9229. for ( var i = 0, il = offsets.length; i < il; ++ i ) {
  9230. var startIndex = offsets[ i ].index;
  9231. if ( updateBuffers ) {
  9232. // vertices
  9233. var position = geometry.attributes[ "position" ];
  9234. var positionSize = position.itemSize;
  9235. _gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
  9236. _gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, startIndex * positionSize * 4 ); // 4 bytes per Float32
  9237. // normals
  9238. var normal = geometry.attributes[ "normal" ];
  9239. if ( attributes.normal >= 0 && normal ) {
  9240. var normalSize = normal.itemSize;
  9241. _gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
  9242. _gl.vertexAttribPointer( attributes.normal, normalSize, _gl.FLOAT, false, 0, startIndex * normalSize * 4 );
  9243. }
  9244. // uvs
  9245. var uv = geometry.attributes[ "uv" ];
  9246. if ( attributes.uv >= 0 && uv ) {
  9247. if ( uv.buffer ) {
  9248. var uvSize = uv.itemSize;
  9249. _gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
  9250. _gl.vertexAttribPointer( attributes.uv, uvSize, _gl.FLOAT, false, 0, startIndex * uvSize * 4 );
  9251. _gl.enableVertexAttribArray( attributes.uv );
  9252. } else {
  9253. _gl.disableVertexAttribArray( attributes.uv );
  9254. }
  9255. }
  9256. // colors
  9257. var color = geometry.attributes[ "color" ];
  9258. if ( attributes.color >= 0 && color ) {
  9259. var colorSize = color.itemSize;
  9260. _gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
  9261. _gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, startIndex * colorSize * 4 );
  9262. }
  9263. // tangents
  9264. var tangent = geometry.attributes[ "tangent" ];
  9265. if ( attributes.tangent >= 0 && tangent ) {
  9266. var tangentSize = tangent.itemSize;
  9267. _gl.bindBuffer( _gl.ARRAY_BUFFER, tangent.buffer );
  9268. _gl.vertexAttribPointer( attributes.tangent, tangentSize, _gl.FLOAT, false, 0, startIndex * tangentSize * 4 );
  9269. }
  9270. // indices
  9271. var index = geometry.attributes[ "index" ];
  9272. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
  9273. }
  9274. // render indexed triangles
  9275. _gl.drawElements( _gl.TRIANGLES, offsets[ i ].count, _gl.UNSIGNED_SHORT, offsets[ i ].start * 2 ); // 2 bytes per Uint16
  9276. _this.info.render.calls ++;
  9277. _this.info.render.vertices += offsets[ i ].count; // not really true, here vertices can be shared
  9278. _this.info.render.faces += offsets[ i ].count / 3;
  9279. }
  9280. }
  9281. };
  9282. this.renderBuffer = function ( camera, lights, fog, material, geometryGroup, object ) {
  9283. if ( material.visible === false ) return;
  9284. var program, attributes, linewidth, primitives, a, attribute, i, il;
  9285. program = setProgram( camera, lights, fog, material, object );
  9286. attributes = program.attributes;
  9287. var updateBuffers = false,
  9288. wireframeBit = material.wireframe ? 1 : 0,
  9289. geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
  9290. if ( geometryGroupHash !== _currentGeometryGroupHash ) {
  9291. _currentGeometryGroupHash = geometryGroupHash;
  9292. updateBuffers = true;
  9293. }
  9294. // vertices
  9295. if ( !material.morphTargets && attributes.position >= 0 ) {
  9296. if ( updateBuffers ) {
  9297. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
  9298. _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
  9299. }
  9300. } else {
  9301. if ( object.morphTargetBase ) {
  9302. setupMorphTargets( material, geometryGroup, object );
  9303. }
  9304. }
  9305. if ( updateBuffers ) {
  9306. // custom attributes
  9307. // Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
  9308. if ( geometryGroup.__webglCustomAttributesList ) {
  9309. for ( i = 0, il = geometryGroup.__webglCustomAttributesList.length; i < il; i ++ ) {
  9310. attribute = geometryGroup.__webglCustomAttributesList[ i ];
  9311. if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
  9312. _gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
  9313. _gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
  9314. }
  9315. }
  9316. }
  9317. // colors
  9318. if ( attributes.color >= 0 ) {
  9319. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
  9320. _gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
  9321. }
  9322. // normals
  9323. if ( attributes.normal >= 0 ) {
  9324. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
  9325. _gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
  9326. }
  9327. // tangents
  9328. if ( attributes.tangent >= 0 ) {
  9329. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
  9330. _gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
  9331. }
  9332. // uvs
  9333. if ( attributes.uv >= 0 ) {
  9334. if ( geometryGroup.__webglUVBuffer ) {
  9335. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
  9336. _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
  9337. _gl.enableVertexAttribArray( attributes.uv );
  9338. } else {
  9339. _gl.disableVertexAttribArray( attributes.uv );
  9340. }
  9341. }
  9342. if ( attributes.uv2 >= 0 ) {
  9343. if ( geometryGroup.__webglUV2Buffer ) {
  9344. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
  9345. _gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
  9346. _gl.enableVertexAttribArray( attributes.uv2 );
  9347. } else {
  9348. _gl.disableVertexAttribArray( attributes.uv2 );
  9349. }
  9350. }
  9351. if ( material.skinning &&
  9352. attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
  9353. attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
  9354. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
  9355. _gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
  9356. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
  9357. _gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
  9358. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
  9359. _gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
  9360. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
  9361. _gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
  9362. }
  9363. }
  9364. // render mesh
  9365. if ( object instanceof THREE.Mesh ) {
  9366. // wireframe
  9367. if ( material.wireframe ) {
  9368. setLineWidth( material.wireframeLinewidth );
  9369. if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
  9370. _gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
  9371. // triangles
  9372. } else {
  9373. if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
  9374. _gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
  9375. }
  9376. _this.info.render.calls ++;
  9377. _this.info.render.vertices += geometryGroup.__webglFaceCount;
  9378. _this.info.render.faces += geometryGroup.__webglFaceCount / 3;
  9379. // render lines
  9380. } else if ( object instanceof THREE.Line ) {
  9381. primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
  9382. setLineWidth( material.linewidth );
  9383. _gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
  9384. _this.info.render.calls ++;
  9385. // render particles
  9386. } else if ( object instanceof THREE.ParticleSystem ) {
  9387. _gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
  9388. _this.info.render.calls ++;
  9389. _this.info.render.points += geometryGroup.__webglParticleCount;
  9390. // render ribbon
  9391. } else if ( object instanceof THREE.Ribbon ) {
  9392. _gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
  9393. _this.info.render.calls ++;
  9394. }
  9395. };
  9396. function setupMorphTargets ( material, geometryGroup, object ) {
  9397. // set base
  9398. var attributes = material.program.attributes;
  9399. if ( object.morphTargetBase !== -1 ) {
  9400. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
  9401. _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
  9402. } else if ( attributes.position >= 0 ) {
  9403. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
  9404. _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
  9405. }
  9406. if ( object.morphTargetForcedOrder.length ) {
  9407. // set forced order
  9408. var m = 0;
  9409. var order = object.morphTargetForcedOrder;
  9410. var influences = object.morphTargetInfluences;
  9411. while ( m < material.numSupportedMorphTargets && m < order.length ) {
  9412. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
  9413. _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
  9414. if ( material.morphNormals ) {
  9415. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ order[ m ] ] );
  9416. _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
  9417. }
  9418. object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];
  9419. m ++;
  9420. }
  9421. } else {
  9422. // find the most influencing
  9423. var influence, activeInfluenceIndices = [];
  9424. var influences = object.morphTargetInfluences;
  9425. var i, il = influences.length;
  9426. for ( i = 0; i < il; i ++ ) {
  9427. influence = influences[ i ];
  9428. if ( influence > 0 ) {
  9429. activeInfluenceIndices.push( [ i, influence ] );
  9430. }
  9431. }
  9432. if ( activeInfluenceIndices.length > material.numSupportedMorphTargets ) {
  9433. activeInfluenceIndices.sort( numericalSort );
  9434. activeInfluenceIndices.length = material.numSupportedMorphTargets;
  9435. } else if ( activeInfluenceIndices.length > material.numSupportedMorphNormals ) {
  9436. activeInfluenceIndices.sort( numericalSort );
  9437. } else if ( activeInfluenceIndices.length === 0 ) {
  9438. activeInfluenceIndices.push( [ 0, 0 ] );
  9439. };
  9440. var influenceIndex, m = 0;
  9441. while ( m < material.numSupportedMorphTargets ) {
  9442. if ( activeInfluenceIndices[ m ] ) {
  9443. influenceIndex = activeInfluenceIndices[ m ][ 0 ];
  9444. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ influenceIndex ] );
  9445. _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
  9446. if ( material.morphNormals ) {
  9447. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ influenceIndex ] );
  9448. _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
  9449. }
  9450. object.__webglMorphTargetInfluences[ m ] = influences[ influenceIndex ];
  9451. } else {
  9452. _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
  9453. if ( material.morphNormals ) {
  9454. _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
  9455. }
  9456. object.__webglMorphTargetInfluences[ m ] = 0;
  9457. }
  9458. m ++;
  9459. }
  9460. }
  9461. // load updated influences uniform
  9462. if ( material.program.uniforms.morphTargetInfluences !== null ) {
  9463. _gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
  9464. }
  9465. };
  9466. // Sorting
  9467. function painterSort ( a, b ) {
  9468. return b.z - a.z;
  9469. };
  9470. function numericalSort ( a, b ) {
  9471. return b[ 1 ] - a[ 1 ];
  9472. };
  9473. // Rendering
  9474. this.render = function ( scene, camera, renderTarget, forceClear ) {
  9475. var i, il,
  9476. webglObject, object,
  9477. renderList,
  9478. lights = scene.__lights,
  9479. fog = scene.fog;
  9480. // reset caching for this frame
  9481. _currentMaterialId = -1;
  9482. _lightsNeedUpdate = true;
  9483. // update scene graph
  9484. if ( camera.parent === undefined ) {
  9485. console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
  9486. scene.add( camera );
  9487. }
  9488. if ( this.autoUpdateScene ) scene.updateMatrixWorld();
  9489. // update camera matrices and frustum
  9490. if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
  9491. if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
  9492. camera.matrixWorldInverse.getInverse( camera.matrixWorld );
  9493. camera.matrixWorldInverse.flattenToArray( camera._viewMatrixArray );
  9494. camera.projectionMatrix.flattenToArray( camera._projectionMatrixArray );
  9495. _projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
  9496. _frustum.setFromMatrix( _projScreenMatrix );
  9497. // update WebGL objects
  9498. if ( this.autoUpdateObjects ) this.initWebGLObjects( scene );
  9499. // custom render plugins (pre pass)
  9500. renderPlugins( this.renderPluginsPre, scene, camera );
  9501. //
  9502. _this.info.render.calls = 0;
  9503. _this.info.render.vertices = 0;
  9504. _this.info.render.faces = 0;
  9505. _this.info.render.points = 0;
  9506. this.setRenderTarget( renderTarget );
  9507. if ( this.autoClear || forceClear ) {
  9508. this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
  9509. }
  9510. // set matrices for regular objects (frustum culled)
  9511. renderList = scene.__webglObjects;
  9512. for ( i = 0, il = renderList.length; i < il; i ++ ) {
  9513. webglObject = renderList[ i ];
  9514. object = webglObject.object;
  9515. webglObject.render = false;
  9516. if ( object.visible ) {
  9517. if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
  9518. //object.matrixWorld.flattenToArray( object._objectMatrixArray );
  9519. setupMatrices( object, camera );
  9520. unrollBufferMaterial( webglObject );
  9521. webglObject.render = true;
  9522. if ( this.sortObjects ) {
  9523. if ( object.renderDepth ) {
  9524. webglObject.z = object.renderDepth;
  9525. } else {
  9526. _vector3.copy( object.matrixWorld.getPosition() );
  9527. _projScreenMatrix.multiplyVector3( _vector3 );
  9528. webglObject.z = _vector3.z;
  9529. }
  9530. }
  9531. }
  9532. }
  9533. }
  9534. if ( this.sortObjects ) {
  9535. renderList.sort( painterSort );
  9536. }
  9537. // set matrices for immediate objects
  9538. renderList = scene.__webglObjectsImmediate;
  9539. for ( i = 0, il = renderList.length; i < il; i ++ ) {
  9540. webglObject = renderList[ i ];
  9541. object = webglObject.object;
  9542. if ( object.visible ) {
  9543. /*
  9544. if ( object.matrixAutoUpdate ) {
  9545. object.matrixWorld.flattenToArray( object._objectMatrixArray );
  9546. }
  9547. */
  9548. setupMatrices( object, camera );
  9549. unrollImmediateBufferMaterial( webglObject );
  9550. }
  9551. }
  9552. if ( scene.overrideMaterial ) {
  9553. var material = scene.overrideMaterial;
  9554. this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
  9555. this.setDepthTest( material.depthTest );
  9556. this.setDepthWrite( material.depthWrite );
  9557. setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
  9558. renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, material );
  9559. renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, material );
  9560. } else {
  9561. // opaque pass (front-to-back order)
  9562. this.setBlending( THREE.NormalBlending );
  9563. renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
  9564. renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
  9565. // transparent pass (back-to-front order)
  9566. renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
  9567. renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
  9568. }
  9569. // custom render plugins (post pass)
  9570. renderPlugins( this.renderPluginsPost, scene, camera );
  9571. // Generate mipmap if we're using any kind of mipmap filtering
  9572. if ( renderTarget && renderTarget.generateMipmaps && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
  9573. updateRenderTargetMipmap( renderTarget );
  9574. }
  9575. // Ensure depth buffer writing is enabled so it can be cleared on next render
  9576. this.setDepthTest( true );
  9577. this.setDepthWrite( true );
  9578. // _gl.finish();
  9579. };
  9580. function renderPlugins( plugins, scene, camera ) {
  9581. if ( ! plugins.length ) return;
  9582. for ( var i = 0, il = plugins.length; i < il; i ++ ) {
  9583. // reset state for plugin (to start from clean slate)
  9584. _currentProgram = null;
  9585. _currentCamera = null;
  9586. _oldBlending = -1;
  9587. _oldDepthTest = -1;
  9588. _oldDepthWrite = -1;
  9589. _oldDoubleSided = -1;
  9590. _oldFlipSided = -1;
  9591. _currentGeometryGroupHash = -1;
  9592. _currentMaterialId = -1;
  9593. _lightsNeedUpdate = true;
  9594. plugins[ i ].render( scene, camera, _currentWidth, _currentHeight );
  9595. // reset state after plugin (anything could have changed)
  9596. _currentProgram = null;
  9597. _currentCamera = null;
  9598. _oldBlending = -1;
  9599. _oldDepthTest = -1;
  9600. _oldDepthWrite = -1;
  9601. _oldDoubleSided = -1;
  9602. _oldFlipSided = -1;
  9603. _currentGeometryGroupHash = -1;
  9604. _currentMaterialId = -1;
  9605. _lightsNeedUpdate = true;
  9606. }
  9607. };
  9608. function renderObjects ( renderList, reverse, materialType, camera, lights, fog, useBlending, overrideMaterial ) {
  9609. var webglObject, object, buffer, material, start, end, delta;
  9610. if ( reverse ) {
  9611. start = renderList.length - 1;
  9612. end = -1;
  9613. delta = -1;
  9614. } else {
  9615. start = 0;
  9616. end = renderList.length;
  9617. delta = 1;
  9618. }
  9619. for ( var i = start; i !== end; i += delta ) {
  9620. webglObject = renderList[ i ];
  9621. if ( webglObject.render ) {
  9622. object = webglObject.object;
  9623. buffer = webglObject.buffer;
  9624. if ( overrideMaterial ) {
  9625. material = overrideMaterial;
  9626. } else {
  9627. material = webglObject[ materialType ];
  9628. if ( ! material ) continue;
  9629. if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
  9630. _this.setDepthTest( material.depthTest );
  9631. _this.setDepthWrite( material.depthWrite );
  9632. setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
  9633. }
  9634. _this.setObjectFaces( object );
  9635. if ( buffer instanceof THREE.BufferGeometry ) {
  9636. _this.renderBufferDirect( camera, lights, fog, material, buffer, object );
  9637. } else {
  9638. _this.renderBuffer( camera, lights, fog, material, buffer, object );
  9639. }
  9640. }
  9641. }
  9642. };
  9643. function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, useBlending, overrideMaterial ) {
  9644. var webglObject, object, material, program;
  9645. for ( var i = 0, il = renderList.length; i < il; i ++ ) {
  9646. webglObject = renderList[ i ];
  9647. object = webglObject.object;
  9648. if ( object.visible ) {
  9649. if ( overrideMaterial ) {
  9650. material = overrideMaterial;
  9651. } else {
  9652. material = webglObject[ materialType ];
  9653. if ( ! material ) continue;
  9654. if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
  9655. _this.setDepthTest( material.depthTest );
  9656. _this.setDepthWrite( material.depthWrite );
  9657. setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
  9658. }
  9659. _this.renderImmediateObject( camera, lights, fog, material, object );
  9660. }
  9661. }
  9662. };
  9663. this.renderImmediateObject = function ( camera, lights, fog, material, object ) {
  9664. var program = setProgram( camera, lights, fog, material, object );
  9665. _currentGeometryGroupHash = -1;
  9666. _this.setObjectFaces( object );
  9667. if ( object.immediateRenderCallback ) {
  9668. object.immediateRenderCallback( program, _gl, _frustum );
  9669. } else {
  9670. object.render( function( object ) { _this.renderBufferImmediate( object, program, material ); } );
  9671. }
  9672. };
  9673. function unrollImmediateBufferMaterial ( globject ) {
  9674. var object = globject.object,
  9675. material = object.material;
  9676. if ( material.transparent ) {
  9677. globject.transparent = material;
  9678. globject.opaque = null;
  9679. } else {
  9680. globject.opaque = material;
  9681. globject.transparent = null;
  9682. }
  9683. };
  9684. function unrollBufferMaterial ( globject ) {
  9685. var object = globject.object,
  9686. buffer = globject.buffer,
  9687. material, materialIndex, meshMaterial;
  9688. meshMaterial = object.material;
  9689. if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
  9690. materialIndex = buffer.materialIndex;
  9691. if ( materialIndex >= 0 ) {
  9692. material = object.geometry.materials[ materialIndex ];
  9693. if ( material.transparent ) {
  9694. globject.transparent = material;
  9695. globject.opaque = null;
  9696. } else {
  9697. globject.opaque = material;
  9698. globject.transparent = null;
  9699. }
  9700. }
  9701. } else {
  9702. material = meshMaterial;
  9703. if ( material ) {
  9704. if ( material.transparent ) {
  9705. globject.transparent = material;
  9706. globject.opaque = null;
  9707. } else {
  9708. globject.opaque = material;
  9709. globject.transparent = null;
  9710. }
  9711. }
  9712. }
  9713. };
  9714. // Geometry splitting
  9715. function sortFacesByMaterial ( geometry ) {
  9716. var f, fl, face, materialIndex, vertices,
  9717. materialHash, groupHash,
  9718. hash_map = {};
  9719. var numMorphTargets = geometry.morphTargets.length;
  9720. var numMorphNormals = geometry.morphNormals.length;
  9721. geometry.geometryGroups = {};
  9722. for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
  9723. face = geometry.faces[ f ];
  9724. materialIndex = face.materialIndex;
  9725. materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
  9726. if ( hash_map[ materialHash ] === undefined ) {
  9727. hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
  9728. }
  9729. groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
  9730. if ( geometry.geometryGroups[ groupHash ] === undefined ) {
  9731. geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals };
  9732. }
  9733. vertices = face instanceof THREE.Face3 ? 3 : 4;
  9734. if ( geometry.geometryGroups[ groupHash ].vertices + vertices > 65535 ) {
  9735. hash_map[ materialHash ].counter += 1;
  9736. groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
  9737. if ( geometry.geometryGroups[ groupHash ] === undefined ) {
  9738. geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals };
  9739. }
  9740. }
  9741. if ( face instanceof THREE.Face3 ) {
  9742. geometry.geometryGroups[ groupHash ].faces3.push( f );
  9743. } else {
  9744. geometry.geometryGroups[ groupHash ].faces4.push( f );
  9745. }
  9746. geometry.geometryGroups[ groupHash ].vertices += vertices;
  9747. }
  9748. geometry.geometryGroupsList = [];
  9749. for ( var g in geometry.geometryGroups ) {
  9750. geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
  9751. geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
  9752. }
  9753. };
  9754. // Objects refresh
  9755. this.initWebGLObjects = function ( scene ) {
  9756. if ( !scene.__webglObjects ) {
  9757. scene.__webglObjects = [];
  9758. scene.__webglObjectsImmediate = [];
  9759. scene.__webglSprites = [];
  9760. scene.__webglFlares = [];
  9761. }
  9762. while ( scene.__objectsAdded.length ) {
  9763. addObject( scene.__objectsAdded[ 0 ], scene );
  9764. scene.__objectsAdded.splice( 0, 1 );
  9765. }
  9766. while ( scene.__objectsRemoved.length ) {
  9767. removeObject( scene.__objectsRemoved[ 0 ], scene );
  9768. scene.__objectsRemoved.splice( 0, 1 );
  9769. }
  9770. // update must be called after objects adding / removal
  9771. for ( var o = 0, ol = scene.__webglObjects.length; o < ol; o ++ ) {
  9772. updateObject( scene.__webglObjects[ o ].object );
  9773. }
  9774. };
  9775. // Objects adding
  9776. function addObject ( object, scene ) {
  9777. var g, geometry, geometryGroup;
  9778. if ( ! object.__webglInit ) {
  9779. object.__webglInit = true;
  9780. object._modelViewMatrix = new THREE.Matrix4();
  9781. object._normalMatrix = new THREE.Matrix3();
  9782. if ( object instanceof THREE.Mesh ) {
  9783. geometry = object.geometry;
  9784. if ( geometry instanceof THREE.Geometry ) {
  9785. if ( geometry.geometryGroups === undefined ) {
  9786. sortFacesByMaterial( geometry );
  9787. }
  9788. // create separate VBOs per geometry chunk
  9789. for ( g in geometry.geometryGroups ) {
  9790. geometryGroup = geometry.geometryGroups[ g ];
  9791. // initialise VBO on the first access
  9792. if ( ! geometryGroup.__webglVertexBuffer ) {
  9793. createMeshBuffers( geometryGroup );
  9794. initMeshBuffers( geometryGroup, object );
  9795. geometry.verticesNeedUpdate = true;
  9796. geometry.morphTargetsNeedUpdate = true;
  9797. geometry.elementsNeedUpdate = true;
  9798. geometry.uvsNeedUpdate = true;
  9799. geometry.normalsNeedUpdate = true;
  9800. geometry.tangentsNeedUpdate = true;
  9801. geometry.colorsNeedUpdate = true;
  9802. }
  9803. }
  9804. } else if ( geometry instanceof THREE.BufferGeometry ) {
  9805. initDirectBuffers( geometry );
  9806. }
  9807. } else if ( object instanceof THREE.Ribbon ) {
  9808. geometry = object.geometry;
  9809. if( ! geometry.__webglVertexBuffer ) {
  9810. createRibbonBuffers( geometry );
  9811. initRibbonBuffers( geometry );
  9812. geometry.verticesNeedUpdate = true;
  9813. geometry.colorsNeedUpdate = true;
  9814. }
  9815. } else if ( object instanceof THREE.Line ) {
  9816. geometry = object.geometry;
  9817. if( ! geometry.__webglVertexBuffer ) {
  9818. createLineBuffers( geometry );
  9819. initLineBuffers( geometry, object );
  9820. geometry.verticesNeedUpdate = true;
  9821. geometry.colorsNeedUpdate = true;
  9822. }
  9823. } else if ( object instanceof THREE.ParticleSystem ) {
  9824. geometry = object.geometry;
  9825. if ( ! geometry.__webglVertexBuffer ) {
  9826. createParticleBuffers( geometry );
  9827. initParticleBuffers( geometry, object );
  9828. geometry.verticesNeedUpdate = true;
  9829. geometry.colorsNeedUpdate = true;
  9830. }
  9831. }
  9832. }
  9833. if ( ! object.__webglActive ) {
  9834. if ( object instanceof THREE.Mesh ) {
  9835. geometry = object.geometry;
  9836. if ( geometry instanceof THREE.BufferGeometry ) {
  9837. addBuffer( scene.__webglObjects, geometry, object );
  9838. } else {
  9839. for ( g in geometry.geometryGroups ) {
  9840. geometryGroup = geometry.geometryGroups[ g ];
  9841. addBuffer( scene.__webglObjects, geometryGroup, object );
  9842. }
  9843. }
  9844. } else if ( object instanceof THREE.Ribbon ||
  9845. object instanceof THREE.Line ||
  9846. object instanceof THREE.ParticleSystem ) {
  9847. geometry = object.geometry;
  9848. addBuffer( scene.__webglObjects, geometry, object );
  9849. } else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
  9850. addBufferImmediate( scene.__webglObjectsImmediate, object );
  9851. } else if ( object instanceof THREE.Sprite ) {
  9852. scene.__webglSprites.push( object );
  9853. } else if ( object instanceof THREE.LensFlare ) {
  9854. scene.__webglFlares.push( object );
  9855. }
  9856. object.__webglActive = true;
  9857. }
  9858. };
  9859. function addBuffer ( objlist, buffer, object ) {
  9860. objlist.push(
  9861. {
  9862. buffer: buffer,
  9863. object: object,
  9864. opaque: null,
  9865. transparent: null
  9866. }
  9867. );
  9868. };
  9869. function addBufferImmediate ( objlist, object ) {
  9870. objlist.push(
  9871. {
  9872. object: object,
  9873. opaque: null,
  9874. transparent: null
  9875. }
  9876. );
  9877. };
  9878. // Objects updates
  9879. function updateObject ( object ) {
  9880. var geometry = object.geometry,
  9881. geometryGroup, customAttributesDirty, material;
  9882. if ( object instanceof THREE.Mesh ) {
  9883. if ( geometry instanceof THREE.BufferGeometry ) {
  9884. if ( geometry.verticesNeedUpdate || geometry.elementsNeedUpdate ||
  9885. geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
  9886. geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate ) {
  9887. setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
  9888. }
  9889. geometry.verticesNeedUpdate = false;
  9890. geometry.elementsNeedUpdate = false;
  9891. geometry.uvsNeedUpdate = false;
  9892. geometry.normalsNeedUpdate = false;
  9893. geometry.colorsNeedUpdate = false;
  9894. geometry.tangentsNeedUpdate = false;
  9895. } else {
  9896. // check all geometry groups
  9897. for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {
  9898. geometryGroup = geometry.geometryGroupsList[ i ];
  9899. material = getBufferMaterial( object, geometryGroup );
  9900. customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
  9901. if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate ||
  9902. geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
  9903. geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate || customAttributesDirty ) {
  9904. setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW, !geometry.dynamic, material );
  9905. }
  9906. }
  9907. geometry.verticesNeedUpdate = false;
  9908. geometry.morphTargetsNeedUpdate = false;
  9909. geometry.elementsNeedUpdate = false;
  9910. geometry.uvsNeedUpdate = false;
  9911. geometry.normalsNeedUpdate = false;
  9912. geometry.colorsNeedUpdate = false;
  9913. geometry.tangentsNeedUpdate = false;
  9914. material.attributes && clearCustomAttributes( material );
  9915. }
  9916. } else if ( object instanceof THREE.Ribbon ) {
  9917. if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
  9918. setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
  9919. }
  9920. geometry.verticesNeedUpdate = false;
  9921. geometry.colorsNeedUpdate = false;
  9922. } else if ( object instanceof THREE.Line ) {
  9923. material = getBufferMaterial( object, geometryGroup );
  9924. customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
  9925. if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || customAttributesDirty ) {
  9926. setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
  9927. }
  9928. geometry.verticesNeedUpdate = false;
  9929. geometry.colorsNeedUpdate = false;
  9930. material.attributes && clearCustomAttributes( material );
  9931. } else if ( object instanceof THREE.ParticleSystem ) {
  9932. material = getBufferMaterial( object, geometryGroup );
  9933. customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
  9934. if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || object.sortParticles || customAttributesDirty ) {
  9935. setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
  9936. }
  9937. geometry.verticesNeedUpdate = false;
  9938. geometry.colorsNeedUpdate = false;
  9939. material.attributes && clearCustomAttributes( material );
  9940. }
  9941. };
  9942. // Objects updates - custom attributes check
  9943. function areCustomAttributesDirty ( material ) {
  9944. for ( var a in material.attributes ) {
  9945. if ( material.attributes[ a ].needsUpdate ) return true;
  9946. }
  9947. return false;
  9948. };
  9949. function clearCustomAttributes ( material ) {
  9950. for ( var a in material.attributes ) {
  9951. material.attributes[ a ].needsUpdate = false;
  9952. }
  9953. };
  9954. // Objects removal
  9955. function removeObject ( object, scene ) {
  9956. if ( object instanceof THREE.Mesh ||
  9957. object instanceof THREE.ParticleSystem ||
  9958. object instanceof THREE.Ribbon ||
  9959. object instanceof THREE.Line ) {
  9960. removeInstances( scene.__webglObjects, object );
  9961. } else if ( object instanceof THREE.Sprite ) {
  9962. removeInstancesDirect( scene.__webglSprites, object );
  9963. } else if ( object instanceof THREE.LensFlare ) {
  9964. removeInstancesDirect( scene.__webglFlares, object );
  9965. } else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
  9966. removeInstances( scene.__webglObjectsImmediate, object );
  9967. }
  9968. object.__webglActive = false;
  9969. };
  9970. function removeInstances ( objlist, object ) {
  9971. for ( var o = objlist.length - 1; o >= 0; o -- ) {
  9972. if ( objlist[ o ].object === object ) {
  9973. objlist.splice( o, 1 );
  9974. }
  9975. }
  9976. };
  9977. function removeInstancesDirect ( objlist, object ) {
  9978. for ( var o = objlist.length - 1; o >= 0; o -- ) {
  9979. if ( objlist[ o ] === object ) {
  9980. objlist.splice( o, 1 );
  9981. }
  9982. }
  9983. };
  9984. // Materials
  9985. this.initMaterial = function ( material, lights, fog, object ) {
  9986. var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
  9987. if ( material instanceof THREE.MeshDepthMaterial ) {
  9988. shaderID = 'depth';
  9989. } else if ( material instanceof THREE.MeshNormalMaterial ) {
  9990. shaderID = 'normal';
  9991. } else if ( material instanceof THREE.MeshBasicMaterial ) {
  9992. shaderID = 'basic';
  9993. } else if ( material instanceof THREE.MeshLambertMaterial ) {
  9994. shaderID = 'lambert';
  9995. } else if ( material instanceof THREE.MeshPhongMaterial ) {
  9996. shaderID = 'phong';
  9997. } else if ( material instanceof THREE.LineBasicMaterial ) {
  9998. shaderID = 'basic';
  9999. } else if ( material instanceof THREE.ParticleBasicMaterial ) {
  10000. shaderID = 'particle_basic';
  10001. }
  10002. if ( shaderID ) {
  10003. setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
  10004. }
  10005. // heuristics to create shader parameters according to lights in the scene
  10006. // (not to blow over maxLights budget)
  10007. maxLightCount = allocateLights( lights );
  10008. maxShadows = allocateShadows( lights );
  10009. maxBones = allocateBones( object );
  10010. parameters = {
  10011. map: !!material.map,
  10012. envMap: !!material.envMap,
  10013. lightMap: !!material.lightMap,
  10014. vertexColors: material.vertexColors,
  10015. fog: fog,
  10016. useFog: material.fog,
  10017. sizeAttenuation: material.sizeAttenuation,
  10018. skinning: material.skinning,
  10019. maxBones: maxBones,
  10020. useVertexTexture: _supportsBoneTextures && object.useVertexTexture,
  10021. boneTextureWidth: object.boneTextureWidth,
  10022. boneTextureHeight: object.boneTextureHeight,
  10023. morphTargets: material.morphTargets,
  10024. morphNormals: material.morphNormals,
  10025. maxMorphTargets: this.maxMorphTargets,
  10026. maxMorphNormals: this.maxMorphNormals,
  10027. maxDirLights: maxLightCount.directional,
  10028. maxPointLights: maxLightCount.point,
  10029. maxSpotLights: maxLightCount.spot,
  10030. maxShadows: maxShadows,
  10031. shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
  10032. shadowMapSoft: this.shadowMapSoft,
  10033. shadowMapDebug: this.shadowMapDebug,
  10034. shadowMapCascade: this.shadowMapCascade,
  10035. alphaTest: material.alphaTest,
  10036. metal: material.metal,
  10037. perPixel: material.perPixel,
  10038. wrapAround: material.wrapAround,
  10039. doubleSided: object && object.doubleSided
  10040. };
  10041. material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
  10042. var attributes = material.program.attributes;
  10043. if ( attributes.position >= 0 ) _gl.enableVertexAttribArray( attributes.position );
  10044. if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
  10045. if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
  10046. if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
  10047. if ( material.skinning &&
  10048. attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
  10049. attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
  10050. _gl.enableVertexAttribArray( attributes.skinVertexA );
  10051. _gl.enableVertexAttribArray( attributes.skinVertexB );
  10052. _gl.enableVertexAttribArray( attributes.skinIndex );
  10053. _gl.enableVertexAttribArray( attributes.skinWeight );
  10054. }
  10055. if ( material.attributes ) {
  10056. for ( a in material.attributes ) {
  10057. if( attributes[ a ] !== undefined && attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] );
  10058. }
  10059. }
  10060. if ( material.morphTargets ) {
  10061. material.numSupportedMorphTargets = 0;
  10062. var id, base = "morphTarget";
  10063. for ( i = 0; i < this.maxMorphTargets; i ++ ) {
  10064. id = base + i;
  10065. if ( attributes[ id ] >= 0 ) {
  10066. _gl.enableVertexAttribArray( attributes[ id ] );
  10067. material.numSupportedMorphTargets ++;
  10068. }
  10069. }
  10070. }
  10071. if ( material.morphNormals ) {
  10072. material.numSupportedMorphNormals = 0;
  10073. var id, base = "morphNormal";
  10074. for ( i = 0; i < this.maxMorphNormals; i ++ ) {
  10075. id = base + i;
  10076. if ( attributes[ id ] >= 0 ) {
  10077. _gl.enableVertexAttribArray( attributes[ id ] );
  10078. material.numSupportedMorphNormals ++;
  10079. }
  10080. }
  10081. }
  10082. material.uniformsList = [];
  10083. for ( u in material.uniforms ) {
  10084. material.uniformsList.push( [ material.uniforms[ u ], u ] );
  10085. }
  10086. };
  10087. function setMaterialShaders( material, shaders ) {
  10088. material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
  10089. material.vertexShader = shaders.vertexShader;
  10090. material.fragmentShader = shaders.fragmentShader;
  10091. };
  10092. function setProgram( camera, lights, fog, material, object ) {
  10093. if ( material.needsUpdate ) {
  10094. if ( material.program ) _this.deallocateMaterial( material );
  10095. _this.initMaterial( material, lights, fog, object );
  10096. material.needsUpdate = false;
  10097. }
  10098. if ( material.morphTargets ) {
  10099. if ( ! object.__webglMorphTargetInfluences ) {
  10100. object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
  10101. }
  10102. }
  10103. var refreshMaterial = false;
  10104. var program = material.program,
  10105. p_uniforms = program.uniforms,
  10106. m_uniforms = material.uniforms;
  10107. if ( program !== _currentProgram ) {
  10108. _gl.useProgram( program );
  10109. _currentProgram = program;
  10110. refreshMaterial = true;
  10111. }
  10112. if ( material.id !== _currentMaterialId ) {
  10113. _currentMaterialId = material.id;
  10114. refreshMaterial = true;
  10115. }
  10116. if ( refreshMaterial || camera !== _currentCamera ) {
  10117. _gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera._projectionMatrixArray );
  10118. if ( camera !== _currentCamera ) _currentCamera = camera;
  10119. }
  10120. if ( refreshMaterial ) {
  10121. // refresh uniforms common to several materials
  10122. if ( fog && material.fog ) {
  10123. refreshUniformsFog( m_uniforms, fog );
  10124. }
  10125. if ( material instanceof THREE.MeshPhongMaterial ||
  10126. material instanceof THREE.MeshLambertMaterial ||
  10127. material.lights ) {
  10128. if ( _lightsNeedUpdate ) {
  10129. setupLights( program, lights );
  10130. _lightsNeedUpdate = false;
  10131. }
  10132. refreshUniformsLights( m_uniforms, _lights );
  10133. }
  10134. if ( material instanceof THREE.MeshBasicMaterial ||
  10135. material instanceof THREE.MeshLambertMaterial ||
  10136. material instanceof THREE.MeshPhongMaterial ) {
  10137. refreshUniformsCommon( m_uniforms, material );
  10138. }
  10139. // refresh single material specific uniforms
  10140. if ( material instanceof THREE.LineBasicMaterial ) {
  10141. refreshUniformsLine( m_uniforms, material );
  10142. } else if ( material instanceof THREE.ParticleBasicMaterial ) {
  10143. refreshUniformsParticle( m_uniforms, material );
  10144. } else if ( material instanceof THREE.MeshPhongMaterial ) {
  10145. refreshUniformsPhong( m_uniforms, material );
  10146. } else if ( material instanceof THREE.MeshLambertMaterial ) {
  10147. refreshUniformsLambert( m_uniforms, material );
  10148. } else if ( material instanceof THREE.MeshDepthMaterial ) {
  10149. m_uniforms.mNear.value = camera.near;
  10150. m_uniforms.mFar.value = camera.far;
  10151. m_uniforms.opacity.value = material.opacity;
  10152. } else if ( material instanceof THREE.MeshNormalMaterial ) {
  10153. m_uniforms.opacity.value = material.opacity;
  10154. }
  10155. if ( object.receiveShadow && ! material._shadowPass ) {
  10156. refreshUniformsShadow( m_uniforms, lights );
  10157. }
  10158. // load common uniforms
  10159. loadUniformsGeneric( program, material.uniformsList );
  10160. // load material specific uniforms
  10161. // (shader material also gets them for the sake of genericity)
  10162. if ( material instanceof THREE.ShaderMaterial ||
  10163. material instanceof THREE.MeshPhongMaterial ||
  10164. material.envMap ) {
  10165. if ( p_uniforms.cameraPosition !== null ) {
  10166. var position = camera.matrixWorld.getPosition();
  10167. _gl.uniform3f( p_uniforms.cameraPosition, position.x, position.y, position.z );
  10168. }
  10169. }
  10170. if ( material instanceof THREE.MeshPhongMaterial ||
  10171. material instanceof THREE.MeshLambertMaterial ||
  10172. material instanceof THREE.ShaderMaterial ||
  10173. material.skinning ) {
  10174. if ( p_uniforms.viewMatrix !== null ) {
  10175. _gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera._viewMatrixArray );
  10176. }
  10177. }
  10178. }
  10179. if ( material.skinning ) {
  10180. if ( _supportsBoneTextures && object.useVertexTexture ) {
  10181. if ( p_uniforms.boneTexture !== null ) {
  10182. // shadowMap texture array starts from 6
  10183. // texture unit 12 should leave space for 6 shadowmaps
  10184. var textureUnit = 12;
  10185. _gl.uniform1i( p_uniforms.boneTexture, textureUnit );
  10186. _this.setTexture( object.boneTexture, textureUnit );
  10187. }
  10188. } else {
  10189. if ( p_uniforms.boneGlobalMatrices !== null ) {
  10190. _gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );
  10191. }
  10192. }
  10193. }
  10194. loadUniformsMatrices( p_uniforms, object );
  10195. if ( p_uniforms.objectMatrix !== null ) {
  10196. _gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object.matrixWorld.elements );
  10197. }
  10198. return program;
  10199. };
  10200. // Uniforms (refresh uniforms objects)
  10201. function refreshUniformsCommon ( uniforms, material ) {
  10202. uniforms.opacity.value = material.opacity;
  10203. if ( _this.gammaInput ) {
  10204. uniforms.diffuse.value.copyGammaToLinear( material.color );
  10205. } else {
  10206. uniforms.diffuse.value = material.color;
  10207. }
  10208. uniforms.map.texture = material.map;
  10209. if ( material.map ) {
  10210. uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y );
  10211. }
  10212. uniforms.lightMap.texture = material.lightMap;
  10213. uniforms.envMap.texture = material.envMap;
  10214. uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
  10215. if ( _this.gammaInput ) {
  10216. //uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
  10217. uniforms.reflectivity.value = material.reflectivity;
  10218. } else {
  10219. uniforms.reflectivity.value = material.reflectivity;
  10220. }
  10221. uniforms.refractionRatio.value = material.refractionRatio;
  10222. uniforms.combine.value = material.combine;
  10223. uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
  10224. };
  10225. function refreshUniformsLine ( uniforms, material ) {
  10226. uniforms.diffuse.value = material.color;
  10227. uniforms.opacity.value = material.opacity;
  10228. };
  10229. function refreshUniformsParticle ( uniforms, material ) {
  10230. uniforms.psColor.value = material.color;
  10231. uniforms.opacity.value = material.opacity;
  10232. uniforms.size.value = material.size;
  10233. uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
  10234. uniforms.map.texture = material.map;
  10235. };
  10236. function refreshUniformsFog ( uniforms, fog ) {
  10237. uniforms.fogColor.value = fog.color;
  10238. if ( fog instanceof THREE.Fog ) {
  10239. uniforms.fogNear.value = fog.near;
  10240. uniforms.fogFar.value = fog.far;
  10241. } else if ( fog instanceof THREE.FogExp2 ) {
  10242. uniforms.fogDensity.value = fog.density;
  10243. }
  10244. };
  10245. function refreshUniformsPhong ( uniforms, material ) {
  10246. uniforms.shininess.value = material.shininess;
  10247. if ( _this.gammaInput ) {
  10248. uniforms.ambient.value.copyGammaToLinear( material.ambient );
  10249. uniforms.emissive.value.copyGammaToLinear( material.emissive );
  10250. uniforms.specular.value.copyGammaToLinear( material.specular );
  10251. } else {
  10252. uniforms.ambient.value = material.ambient;
  10253. uniforms.emissive.value = material.emissive;
  10254. uniforms.specular.value = material.specular;
  10255. }
  10256. if ( material.wrapAround ) {
  10257. uniforms.wrapRGB.value.copy( material.wrapRGB );
  10258. }
  10259. };
  10260. function refreshUniformsLambert ( uniforms, material ) {
  10261. if ( _this.gammaInput ) {
  10262. uniforms.ambient.value.copyGammaToLinear( material.ambient );
  10263. uniforms.emissive.value.copyGammaToLinear( material.emissive );
  10264. } else {
  10265. uniforms.ambient.value = material.ambient;
  10266. uniforms.emissive.value = material.emissive;
  10267. }
  10268. if ( material.wrapAround ) {
  10269. uniforms.wrapRGB.value.copy( material.wrapRGB );
  10270. }
  10271. };
  10272. function refreshUniformsLights ( uniforms, lights ) {
  10273. uniforms.ambientLightColor.value = lights.ambient;
  10274. uniforms.directionalLightColor.value = lights.directional.colors;
  10275. uniforms.directionalLightDirection.value = lights.directional.positions;
  10276. uniforms.pointLightColor.value = lights.point.colors;
  10277. uniforms.pointLightPosition.value = lights.point.positions;
  10278. uniforms.pointLightDistance.value = lights.point.distances;
  10279. uniforms.spotLightColor.value = lights.spot.colors;
  10280. uniforms.spotLightPosition.value = lights.spot.positions;
  10281. uniforms.spotLightDistance.value = lights.spot.distances;
  10282. uniforms.spotLightDirection.value = lights.spot.directions;
  10283. uniforms.spotLightAngle.value = lights.spot.angles;
  10284. uniforms.spotLightExponent.value = lights.spot.exponents;
  10285. };
  10286. function refreshUniformsShadow ( uniforms, lights ) {
  10287. if ( uniforms.shadowMatrix ) {
  10288. var j = 0;
  10289. for ( var i = 0, il = lights.length; i < il; i ++ ) {
  10290. var light = lights[ i ];
  10291. if ( ! light.castShadow ) continue;
  10292. if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) {
  10293. uniforms.shadowMap.texture[ j ] = light.shadowMap;
  10294. uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
  10295. uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;
  10296. uniforms.shadowDarkness.value[ j ] = light.shadowDarkness;
  10297. uniforms.shadowBias.value[ j ] = light.shadowBias;
  10298. j ++;
  10299. }
  10300. }
  10301. }
  10302. };
  10303. // Uniforms (load to GPU)
  10304. function loadUniformsMatrices ( uniforms, object ) {
  10305. _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrix.elements );
  10306. if ( uniforms.normalMatrix ) {
  10307. _gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrix.elements );
  10308. }
  10309. };
  10310. function loadUniformsGeneric ( program, uniforms ) {
  10311. var uniform, value, type, location, texture, i, il, j, jl, offset;
  10312. for ( j = 0, jl = uniforms.length; j < jl; j ++ ) {
  10313. location = program.uniforms[ uniforms[ j ][ 1 ] ];
  10314. if ( !location ) continue;
  10315. uniform = uniforms[ j ][ 0 ];
  10316. type = uniform.type;
  10317. value = uniform.value;
  10318. if ( type === "i" ) { // single integer
  10319. _gl.uniform1i( location, value );
  10320. } else if ( type === "f" ) { // single float
  10321. _gl.uniform1f( location, value );
  10322. } else if ( type === "v2" ) { // single THREE.Vector2
  10323. _gl.uniform2f( location, value.x, value.y );
  10324. } else if ( type === "v3" ) { // single THREE.Vector3
  10325. _gl.uniform3f( location, value.x, value.y, value.z );
  10326. } else if ( type === "v4" ) { // single THREE.Vector4
  10327. _gl.uniform4f( location, value.x, value.y, value.z, value.w );
  10328. } else if ( type === "c" ) { // single THREE.Color
  10329. _gl.uniform3f( location, value.r, value.g, value.b );
  10330. } else if ( type === "iv1" ) { // flat array of integers (JS or typed array)
  10331. _gl.uniform1iv( location, value );
  10332. } else if ( type === "iv" ) { // flat array of integers with 3 x N size (JS or typed array)
  10333. _gl.uniform3iv( location, value );
  10334. } else if ( type === "fv1" ) { // flat array of floats (JS or typed array)
  10335. _gl.uniform1fv( location, value );
  10336. } else if ( type === "fv" ) { // flat array of floats with 3 x N size (JS or typed array)
  10337. _gl.uniform3fv( location, value );
  10338. } else if ( type === "v2v" ) { // array of THREE.Vector2
  10339. if ( uniform._array === undefined ) {
  10340. uniform._array = new Float32Array( 2 * value.length );
  10341. }
  10342. for ( i = 0, il = value.length; i < il; i ++ ) {
  10343. offset = i * 2;
  10344. uniform._array[ offset ] = value[ i ].x;
  10345. uniform._array[ offset + 1 ] = value[ i ].y;
  10346. }
  10347. _gl.uniform2fv( location, uniform._array );
  10348. } else if ( type === "v3v" ) { // array of THREE.Vector3
  10349. if ( uniform._array === undefined ) {
  10350. uniform._array = new Float32Array( 3 * value.length );
  10351. }
  10352. for ( i = 0, il = value.length; i < il; i ++ ) {
  10353. offset = i * 3;
  10354. uniform._array[ offset ] = value[ i ].x;
  10355. uniform._array[ offset + 1 ] = value[ i ].y;
  10356. uniform._array[ offset + 2 ] = value[ i ].z;
  10357. }
  10358. _gl.uniform3fv( location, uniform._array );
  10359. } else if ( type === "v4v" ) { // array of THREE.Vector4
  10360. if ( uniform._array === undefined ) {
  10361. uniform._array = new Float32Array( 4 * value.length );
  10362. }
  10363. for ( i = 0, il = value.length; i < il; i ++ ) {
  10364. offset = i * 4;
  10365. uniform._array[ offset ] = value[ i ].x;
  10366. uniform._array[ offset + 1 ] = value[ i ].y;
  10367. uniform._array[ offset + 2 ] = value[ i ].z;
  10368. uniform._array[ offset + 3 ] = value[ i ].w;
  10369. }
  10370. _gl.uniform4fv( location, uniform._array );
  10371. } else if ( type === "m4") { // single THREE.Matrix4
  10372. if ( uniform._array === undefined ) {
  10373. uniform._array = new Float32Array( 16 );
  10374. }
  10375. value.flattenToArray( uniform._array );
  10376. _gl.uniformMatrix4fv( location, false, uniform._array );
  10377. } else if ( type === "m4v" ) { // array of THREE.Matrix4
  10378. if ( uniform._array === undefined ) {
  10379. uniform._array = new Float32Array( 16 * value.length );
  10380. }
  10381. for ( i = 0, il = value.length; i < il; i ++ ) {
  10382. value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
  10383. }
  10384. _gl.uniformMatrix4fv( location, false, uniform._array );
  10385. } else if ( type === "t" ) { // single THREE.Texture (2d or cube)
  10386. _gl.uniform1i( location, value );
  10387. texture = uniform.texture;
  10388. if ( !texture ) continue;
  10389. if ( texture.image instanceof Array && texture.image.length === 6 ) {
  10390. setCubeTexture( texture, value );
  10391. } else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
  10392. setCubeTextureDynamic( texture, value );
  10393. } else {
  10394. _this.setTexture( texture, value );
  10395. }
  10396. } else if ( type === "tv" ) { // array of THREE.Texture (2d)
  10397. if ( uniform._array === undefined ) {
  10398. uniform._array = [];
  10399. for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
  10400. uniform._array[ i ] = value + i;
  10401. }
  10402. }
  10403. _gl.uniform1iv( location, uniform._array );
  10404. for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
  10405. texture = uniform.texture[ i ];
  10406. if ( !texture ) continue;
  10407. _this.setTexture( texture, uniform._array[ i ] );
  10408. }
  10409. }
  10410. }
  10411. };
  10412. function setupMatrices ( object, camera ) {
  10413. object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld);
  10414. object._normalMatrix.getInverse( object._modelViewMatrix );
  10415. object._normalMatrix.transpose();
  10416. };
  10417. function setupLights ( program, lights ) {
  10418. var l, ll, light, n,
  10419. r = 0, g = 0, b = 0,
  10420. color, position, intensity, distance,
  10421. zlights = _lights,
  10422. dcolors = zlights.directional.colors,
  10423. dpositions = zlights.directional.positions,
  10424. pcolors = zlights.point.colors,
  10425. ppositions = zlights.point.positions,
  10426. pdistances = zlights.point.distances,
  10427. scolors = zlights.spot.colors,
  10428. spositions = zlights.spot.positions,
  10429. sdistances = zlights.spot.distances,
  10430. sdirections = zlights.spot.directions,
  10431. sangles = zlights.spot.angles,
  10432. sexponents = zlights.spot.exponents,
  10433. dlength = 0,
  10434. plength = 0,
  10435. slength = 0,
  10436. doffset = 0,
  10437. poffset = 0,
  10438. soffset = 0;
  10439. for ( l = 0, ll = lights.length; l < ll; l ++ ) {
  10440. light = lights[ l ];
  10441. if ( light.onlyShadow || ! light.visible ) continue;
  10442. color = light.color;
  10443. intensity = light.intensity;
  10444. distance = light.distance;
  10445. if ( light instanceof THREE.AmbientLight ) {
  10446. if ( _this.gammaInput ) {
  10447. r += color.r * color.r;
  10448. g += color.g * color.g;
  10449. b += color.b * color.b;
  10450. } else {
  10451. r += color.r;
  10452. g += color.g;
  10453. b += color.b;
  10454. }
  10455. } else if ( light instanceof THREE.DirectionalLight ) {
  10456. doffset = dlength * 3;
  10457. if ( _this.gammaInput ) {
  10458. dcolors[ doffset ] = color.r * color.r * intensity * intensity;
  10459. dcolors[ doffset + 1 ] = color.g * color.g * intensity * intensity;
  10460. dcolors[ doffset + 2 ] = color.b * color.b * intensity * intensity;
  10461. } else {
  10462. dcolors[ doffset ] = color.r * intensity;
  10463. dcolors[ doffset + 1 ] = color.g * intensity;
  10464. dcolors[ doffset + 2 ] = color.b * intensity;
  10465. }
  10466. _direction.copy( light.matrixWorld.getPosition() );
  10467. _direction.subSelf( light.target.matrixWorld.getPosition() );
  10468. _direction.normalize();
  10469. dpositions[ doffset ] = _direction.x;
  10470. dpositions[ doffset + 1 ] = _direction.y;
  10471. dpositions[ doffset + 2 ] = _direction.z;
  10472. dlength += 1;
  10473. } else if( light instanceof THREE.PointLight ) {
  10474. poffset = plength * 3;
  10475. if ( _this.gammaInput ) {
  10476. pcolors[ poffset ] = color.r * color.r * intensity * intensity;
  10477. pcolors[ poffset + 1 ] = color.g * color.g * intensity * intensity;
  10478. pcolors[ poffset + 2 ] = color.b * color.b * intensity * intensity;
  10479. } else {
  10480. pcolors[ poffset ] = color.r * intensity;
  10481. pcolors[ poffset + 1 ] = color.g * intensity;
  10482. pcolors[ poffset + 2 ] = color.b * intensity;
  10483. }
  10484. position = light.matrixWorld.getPosition();
  10485. ppositions[ poffset ] = position.x;
  10486. ppositions[ poffset + 1 ] = position.y;
  10487. ppositions[ poffset + 2 ] = position.z;
  10488. pdistances[ plength ] = distance;
  10489. plength += 1;
  10490. } else if( light instanceof THREE.SpotLight ) {
  10491. soffset = slength * 3;
  10492. if ( _this.gammaInput ) {
  10493. scolors[ soffset ] = color.r * color.r * intensity * intensity;
  10494. scolors[ soffset + 1 ] = color.g * color.g * intensity * intensity;
  10495. scolors[ soffset + 2 ] = color.b * color.b * intensity * intensity;
  10496. } else {
  10497. scolors[ soffset ] = color.r * intensity;
  10498. scolors[ soffset + 1 ] = color.g * intensity;
  10499. scolors[ soffset + 2 ] = color.b * intensity;
  10500. }
  10501. position = light.matrixWorld.getPosition();
  10502. spositions[ soffset ] = position.x;
  10503. spositions[ soffset + 1 ] = position.y;
  10504. spositions[ soffset + 2 ] = position.z;
  10505. sdistances[ slength ] = distance;
  10506. _direction.copy( position );
  10507. _direction.subSelf( light.target.matrixWorld.getPosition() );
  10508. _direction.normalize();
  10509. sdirections[ soffset ] = _direction.x;
  10510. sdirections[ soffset + 1 ] = _direction.y;
  10511. sdirections[ soffset + 2 ] = _direction.z;
  10512. sangles[ slength ] = Math.cos( light.angle );
  10513. sexponents[ slength ] = light.exponent;
  10514. slength += 1;
  10515. }
  10516. }
  10517. // null eventual remains from removed lights
  10518. // (this is to avoid if in shader)
  10519. for ( l = dlength * 3, ll = dcolors.length; l < ll; l ++ ) dcolors[ l ] = 0.0;
  10520. for ( l = plength * 3, ll = pcolors.length; l < ll; l ++ ) pcolors[ l ] = 0.0;
  10521. for ( l = slength * 3, ll = scolors.length; l < ll; l ++ ) scolors[ l ] = 0.0;
  10522. zlights.directional.length = dlength;
  10523. zlights.point.length = plength;
  10524. zlights.spot.length = slength;
  10525. zlights.ambient[ 0 ] = r;
  10526. zlights.ambient[ 1 ] = g;
  10527. zlights.ambient[ 2 ] = b;
  10528. };
  10529. // GL state setting
  10530. this.setFaceCulling = function ( cullFace, frontFace ) {
  10531. if ( cullFace ) {
  10532. if ( !frontFace || frontFace === "ccw" ) {
  10533. _gl.frontFace( _gl.CCW );
  10534. } else {
  10535. _gl.frontFace( _gl.CW );
  10536. }
  10537. if( cullFace === "back" ) {
  10538. _gl.cullFace( _gl.BACK );
  10539. } else if( cullFace === "front" ) {
  10540. _gl.cullFace( _gl.FRONT );
  10541. } else {
  10542. _gl.cullFace( _gl.FRONT_AND_BACK );
  10543. }
  10544. _gl.enable( _gl.CULL_FACE );
  10545. } else {
  10546. _gl.disable( _gl.CULL_FACE );
  10547. }
  10548. };
  10549. this.setObjectFaces = function ( object ) {
  10550. if ( _oldDoubleSided !== object.doubleSided ) {
  10551. if ( object.doubleSided ) {
  10552. _gl.disable( _gl.CULL_FACE );
  10553. } else {
  10554. _gl.enable( _gl.CULL_FACE );
  10555. }
  10556. _oldDoubleSided = object.doubleSided;
  10557. }
  10558. if ( _oldFlipSided !== object.flipSided ) {
  10559. if ( object.flipSided ) {
  10560. _gl.frontFace( _gl.CW );
  10561. } else {
  10562. _gl.frontFace( _gl.CCW );
  10563. }
  10564. _oldFlipSided = object.flipSided;
  10565. }
  10566. };
  10567. this.setDepthTest = function ( depthTest ) {
  10568. if ( _oldDepthTest !== depthTest ) {
  10569. if ( depthTest ) {
  10570. _gl.enable( _gl.DEPTH_TEST );
  10571. } else {
  10572. _gl.disable( _gl.DEPTH_TEST );
  10573. }
  10574. _oldDepthTest = depthTest;
  10575. }
  10576. };
  10577. this.setDepthWrite = function ( depthWrite ) {
  10578. if ( _oldDepthWrite !== depthWrite ) {
  10579. _gl.depthMask( depthWrite );
  10580. _oldDepthWrite = depthWrite;
  10581. }
  10582. };
  10583. function setLineWidth ( width ) {
  10584. if ( width !== _oldLineWidth ) {
  10585. _gl.lineWidth( width );
  10586. _oldLineWidth = width;
  10587. }
  10588. };
  10589. function setPolygonOffset ( polygonoffset, factor, units ) {
  10590. if ( _oldPolygonOffset !== polygonoffset ) {
  10591. if ( polygonoffset ) {
  10592. _gl.enable( _gl.POLYGON_OFFSET_FILL );
  10593. } else {
  10594. _gl.disable( _gl.POLYGON_OFFSET_FILL );
  10595. }
  10596. _oldPolygonOffset = polygonoffset;
  10597. }
  10598. if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
  10599. _gl.polygonOffset( factor, units );
  10600. _oldPolygonOffsetFactor = factor;
  10601. _oldPolygonOffsetUnits = units;
  10602. }
  10603. };
  10604. this.setBlending = function ( blending, blendEquation, blendSrc, blendDst ) {
  10605. if ( blending !== _oldBlending ) {
  10606. if ( blending === THREE.NoBlending ) {
  10607. _gl.disable( _gl.BLEND );
  10608. } else if ( blending === THREE.AdditiveBlending ) {
  10609. _gl.enable( _gl.BLEND );
  10610. _gl.blendEquation( _gl.FUNC_ADD );
  10611. _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
  10612. } else if ( blending === THREE.SubtractiveBlending ) {
  10613. // TODO: Find blendFuncSeparate() combination
  10614. _gl.enable( _gl.BLEND );
  10615. _gl.blendEquation( _gl.FUNC_ADD );
  10616. _gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
  10617. } else if ( blending === THREE.MultiplyBlending ) {
  10618. // TODO: Find blendFuncSeparate() combination
  10619. _gl.enable( _gl.BLEND );
  10620. _gl.blendEquation( _gl.FUNC_ADD );
  10621. _gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
  10622. } else if ( blending === THREE.CustomBlending ) {
  10623. _gl.enable( _gl.BLEND );
  10624. } else {
  10625. _gl.enable( _gl.BLEND );
  10626. _gl.blendEquationSeparate( _gl.FUNC_ADD, _gl.FUNC_ADD );
  10627. _gl.blendFuncSeparate( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
  10628. }
  10629. _oldBlending = blending;
  10630. }
  10631. if ( blending === THREE.CustomBlending ) {
  10632. if ( blendEquation !== _oldBlendEquation ) {
  10633. _gl.blendEquation( paramThreeToGL( blendEquation ) );
  10634. _oldBlendEquation = blendEquation;
  10635. }
  10636. if ( blendSrc !== _oldBlendSrc || blendDst !== _oldBlendDst ) {
  10637. _gl.blendFunc( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ) );
  10638. _oldBlendSrc = blendSrc;
  10639. _oldBlendDst = blendDst;
  10640. }
  10641. } else {
  10642. _oldBlendEquation = null;
  10643. _oldBlendSrc = null;
  10644. _oldBlendDst = null;
  10645. }
  10646. };
  10647. // Shaders
  10648. function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
  10649. var p, pl, program, code;
  10650. var chunks = [];
  10651. // Generate code
  10652. if ( shaderID ) {
  10653. chunks.push( shaderID );
  10654. } else {
  10655. chunks.push( fragmentShader );
  10656. chunks.push( vertexShader );
  10657. }
  10658. for ( p in parameters ) {
  10659. chunks.push( p );
  10660. chunks.push( parameters[ p ] );
  10661. }
  10662. code = chunks.join();
  10663. // Check if code has been already compiled
  10664. for ( p = 0, pl = _programs.length; p < pl; p ++ ) {
  10665. var programInfo = _programs[ p ];
  10666. if ( programInfo.code === code ) {
  10667. // console.log( "Code already compiled." /*: \n\n" + code*/ );
  10668. programInfo.usedTimes ++;
  10669. return programInfo.program;
  10670. }
  10671. }
  10672. //console.log( "building new program " );
  10673. //
  10674. program = _gl.createProgram();
  10675. var prefix_vertex = [
  10676. "precision " + _precision + " float;",
  10677. _supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
  10678. _this.gammaInput ? "#define GAMMA_INPUT" : "",
  10679. _this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
  10680. _this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",
  10681. "#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
  10682. "#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
  10683. "#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
  10684. "#define MAX_SHADOWS " + parameters.maxShadows,
  10685. "#define MAX_BONES " + parameters.maxBones,
  10686. parameters.map ? "#define USE_MAP" : "",
  10687. parameters.envMap ? "#define USE_ENVMAP" : "",
  10688. parameters.lightMap ? "#define USE_LIGHTMAP" : "",
  10689. parameters.vertexColors ? "#define USE_COLOR" : "",
  10690. parameters.skinning ? "#define USE_SKINNING" : "",
  10691. parameters.useVertexTexture ? "#define BONE_TEXTURE" : "",
  10692. parameters.boneTextureWidth ? "#define N_BONE_PIXEL_X " + parameters.boneTextureWidth.toFixed( 1 ) : "",
  10693. parameters.boneTextureHeight ? "#define N_BONE_PIXEL_Y " + parameters.boneTextureHeight.toFixed( 1 ) : "",
  10694. parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
  10695. parameters.morphNormals ? "#define USE_MORPHNORMALS" : "",
  10696. parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
  10697. parameters.wrapAround ? "#define WRAP_AROUND" : "",
  10698. parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
  10699. parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
  10700. parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
  10701. parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
  10702. parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
  10703. parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",
  10704. "uniform mat4 objectMatrix;",
  10705. "uniform mat4 modelViewMatrix;",
  10706. "uniform mat4 projectionMatrix;",
  10707. "uniform mat4 viewMatrix;",
  10708. "uniform mat3 normalMatrix;",
  10709. "uniform vec3 cameraPosition;",
  10710. "attribute vec3 position;",
  10711. "attribute vec3 normal;",
  10712. "attribute vec2 uv;",
  10713. "attribute vec2 uv2;",
  10714. "#ifdef USE_COLOR",
  10715. "attribute vec3 color;",
  10716. "#endif",
  10717. "#ifdef USE_MORPHTARGETS",
  10718. "attribute vec3 morphTarget0;",
  10719. "attribute vec3 morphTarget1;",
  10720. "attribute vec3 morphTarget2;",
  10721. "attribute vec3 morphTarget3;",
  10722. "#ifdef USE_MORPHNORMALS",
  10723. "attribute vec3 morphNormal0;",
  10724. "attribute vec3 morphNormal1;",
  10725. "attribute vec3 morphNormal2;",
  10726. "attribute vec3 morphNormal3;",
  10727. "#else",
  10728. "attribute vec3 morphTarget4;",
  10729. "attribute vec3 morphTarget5;",
  10730. "attribute vec3 morphTarget6;",
  10731. "attribute vec3 morphTarget7;",
  10732. "#endif",
  10733. "#endif",
  10734. "#ifdef USE_SKINNING",
  10735. "attribute vec4 skinVertexA;",
  10736. "attribute vec4 skinVertexB;",
  10737. "attribute vec4 skinIndex;",
  10738. "attribute vec4 skinWeight;",
  10739. "#endif",
  10740. ""
  10741. ].join("\n");
  10742. var prefix_fragment = [
  10743. "precision " + _precision + " float;",
  10744. "#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
  10745. "#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
  10746. "#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
  10747. "#define MAX_SHADOWS " + parameters.maxShadows,
  10748. parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",
  10749. _this.gammaInput ? "#define GAMMA_INPUT" : "",
  10750. _this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
  10751. _this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",
  10752. ( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
  10753. ( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
  10754. parameters.map ? "#define USE_MAP" : "",
  10755. parameters.envMap ? "#define USE_ENVMAP" : "",
  10756. parameters.lightMap ? "#define USE_LIGHTMAP" : "",
  10757. parameters.vertexColors ? "#define USE_COLOR" : "",
  10758. parameters.metal ? "#define METAL" : "",
  10759. parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
  10760. parameters.wrapAround ? "#define WRAP_AROUND" : "",
  10761. parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
  10762. parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
  10763. parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
  10764. parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
  10765. parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
  10766. "uniform mat4 viewMatrix;",
  10767. "uniform vec3 cameraPosition;",
  10768. ""
  10769. ].join("\n");
  10770. var glFragmentShader = getShader( "fragment", prefix_fragment + fragmentShader );
  10771. var glVertexShader = getShader( "vertex", prefix_vertex + vertexShader );
  10772. _gl.attachShader( program, glVertexShader );
  10773. _gl.attachShader( program, glFragmentShader );
  10774. _gl.linkProgram( program );
  10775. if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
  10776. console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
  10777. }
  10778. // clean up
  10779. _gl.deleteShader( glFragmentShader );
  10780. _gl.deleteShader( glVertexShader );
  10781. //console.log( prefix_fragment + fragmentShader );
  10782. //console.log( prefix_vertex + vertexShader );
  10783. program.uniforms = {};
  10784. program.attributes = {};
  10785. var identifiers, u, a, i;
  10786. // cache uniform locations
  10787. identifiers = [
  10788. 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
  10789. 'morphTargetInfluences'
  10790. ];
  10791. if ( parameters.useVertexTexture ) {
  10792. identifiers.push( 'boneTexture' );
  10793. } else {
  10794. identifiers.push( 'boneGlobalMatrices' );
  10795. }
  10796. for ( u in uniforms ) {
  10797. identifiers.push( u );
  10798. }
  10799. cacheUniformLocations( program, identifiers );
  10800. // cache attributes locations
  10801. identifiers = [
  10802. "position", "normal", "uv", "uv2", "tangent", "color",
  10803. "skinVertexA", "skinVertexB", "skinIndex", "skinWeight"
  10804. ];
  10805. for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
  10806. identifiers.push( "morphTarget" + i );
  10807. }
  10808. for ( i = 0; i < parameters.maxMorphNormals; i ++ ) {
  10809. identifiers.push( "morphNormal" + i );
  10810. }
  10811. for ( a in attributes ) {
  10812. identifiers.push( a );
  10813. }
  10814. cacheAttributeLocations( program, identifiers );
  10815. program.id = _programs_counter ++;
  10816. _programs.push( { program: program, code: code, usedTimes: 1 } );
  10817. _this.info.memory.programs = _programs.length;
  10818. return program;
  10819. };
  10820. // Shader parameters cache
  10821. function cacheUniformLocations ( program, identifiers ) {
  10822. var i, l, id;
  10823. for( i = 0, l = identifiers.length; i < l; i ++ ) {
  10824. id = identifiers[ i ];
  10825. program.uniforms[ id ] = _gl.getUniformLocation( program, id );
  10826. }
  10827. };
  10828. function cacheAttributeLocations ( program, identifiers ) {
  10829. var i, l, id;
  10830. for( i = 0, l = identifiers.length; i < l; i ++ ) {
  10831. id = identifiers[ i ];
  10832. program.attributes[ id ] = _gl.getAttribLocation( program, id );
  10833. }
  10834. };
  10835. function getShader ( type, string ) {
  10836. var shader;
  10837. if ( type === "fragment" ) {
  10838. shader = _gl.createShader( _gl.FRAGMENT_SHADER );
  10839. } else if ( type === "vertex" ) {
  10840. shader = _gl.createShader( _gl.VERTEX_SHADER );
  10841. }
  10842. _gl.shaderSource( shader, string );
  10843. _gl.compileShader( shader );
  10844. if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
  10845. console.error( _gl.getShaderInfoLog( shader ) );
  10846. console.error( string );
  10847. return null;
  10848. }
  10849. return shader;
  10850. };
  10851. // Textures
  10852. function isPowerOfTwo ( value ) {
  10853. return ( value & ( value - 1 ) ) === 0;
  10854. };
  10855. function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
  10856. if ( isImagePowerOfTwo ) {
  10857. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
  10858. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
  10859. _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
  10860. _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
  10861. } else {
  10862. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
  10863. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
  10864. _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
  10865. _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
  10866. }
  10867. if ( _glExtensionTextureFilterAnisotropic ) {
  10868. _gl.texParameterf( textureType, _glExtensionTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, texture.anisotropy );
  10869. }
  10870. };
  10871. this.setTexture = function ( texture, slot ) {
  10872. if ( texture.needsUpdate ) {
  10873. if ( ! texture.__webglInit ) {
  10874. texture.__webglInit = true;
  10875. texture.__webglTexture = _gl.createTexture();
  10876. _this.info.memory.textures ++;
  10877. }
  10878. _gl.activeTexture( _gl.TEXTURE0 + slot );
  10879. _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
  10880. _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
  10881. _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
  10882. var image = texture.image,
  10883. isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
  10884. glFormat = paramThreeToGL( texture.format ),
  10885. glType = paramThreeToGL( texture.type );
  10886. setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );
  10887. if ( texture instanceof THREE.DataTexture ) {
  10888. _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
  10889. } else {
  10890. _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
  10891. }
  10892. if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
  10893. texture.needsUpdate = false;
  10894. if ( texture.onUpdate ) texture.onUpdate();
  10895. } else {
  10896. _gl.activeTexture( _gl.TEXTURE0 + slot );
  10897. _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
  10898. }
  10899. };
  10900. function clampToMaxSize ( image, maxSize ) {
  10901. if ( image.width <= maxSize && image.height <= maxSize ) {
  10902. return image;
  10903. }
  10904. // Warning: Scaling through the canvas will only work with images that use
  10905. // premultiplied alpha.
  10906. var maxDimension = Math.max( image.width, image.height );
  10907. var newWidth = Math.floor( image.width * maxSize / maxDimension );
  10908. var newHeight = Math.floor( image.height * maxSize / maxDimension );
  10909. var canvas = document.createElement( 'canvas' );
  10910. canvas.width = newWidth;
  10911. canvas.height = newHeight;
  10912. var ctx = canvas.getContext( "2d" );
  10913. ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight );
  10914. return canvas;
  10915. }
  10916. function setCubeTexture ( texture, slot ) {
  10917. if ( texture.image.length === 6 ) {
  10918. if ( texture.needsUpdate ) {
  10919. if ( ! texture.image.__webglTextureCube ) {
  10920. texture.image.__webglTextureCube = _gl.createTexture();
  10921. }
  10922. _gl.activeTexture( _gl.TEXTURE0 + slot );
  10923. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
  10924. _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
  10925. var cubeImage = [];
  10926. for ( var i = 0; i < 6; i ++ ) {
  10927. if ( _this.autoScaleCubemaps ) {
  10928. cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );
  10929. } else {
  10930. cubeImage[ i ] = texture.image[ i ];
  10931. }
  10932. }
  10933. var image = cubeImage[ 0 ],
  10934. isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
  10935. glFormat = paramThreeToGL( texture.format ),
  10936. glType = paramThreeToGL( texture.type );
  10937. setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );
  10938. for ( var i = 0; i < 6; i ++ ) {
  10939. _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
  10940. }
  10941. if ( texture.generateMipmaps && isImagePowerOfTwo ) {
  10942. _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
  10943. }
  10944. texture.needsUpdate = false;
  10945. if ( texture.onUpdate ) texture.onUpdate();
  10946. } else {
  10947. _gl.activeTexture( _gl.TEXTURE0 + slot );
  10948. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
  10949. }
  10950. }
  10951. };
  10952. function setCubeTextureDynamic ( texture, slot ) {
  10953. _gl.activeTexture( _gl.TEXTURE0 + slot );
  10954. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
  10955. };
  10956. // Render targets
  10957. function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
  10958. _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
  10959. _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
  10960. };
  10961. function setupRenderBuffer ( renderbuffer, renderTarget ) {
  10962. _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
  10963. if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
  10964. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
  10965. _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
  10966. /* For some reason this is not working. Defaulting to RGBA4.
  10967. } else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
  10968. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTarget.width, renderTarget.height );
  10969. _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
  10970. */
  10971. } else if( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
  10972. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
  10973. _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
  10974. } else {
  10975. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
  10976. }
  10977. };
  10978. this.setRenderTarget = function ( renderTarget ) {
  10979. var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
  10980. if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
  10981. if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
  10982. if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
  10983. renderTarget.__webglTexture = _gl.createTexture();
  10984. // Setup texture, create render and frame buffers
  10985. var isTargetPowerOfTwo = isPowerOfTwo( renderTarget.width ) && isPowerOfTwo( renderTarget.height ),
  10986. glFormat = paramThreeToGL( renderTarget.format ),
  10987. glType = paramThreeToGL( renderTarget.type );
  10988. if ( isCube ) {
  10989. renderTarget.__webglFramebuffer = [];
  10990. renderTarget.__webglRenderbuffer = [];
  10991. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
  10992. setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
  10993. for ( var i = 0; i < 6; i ++ ) {
  10994. renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
  10995. renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
  10996. _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
  10997. setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
  10998. setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
  10999. }
  11000. if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
  11001. } else {
  11002. renderTarget.__webglFramebuffer = _gl.createFramebuffer();
  11003. renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
  11004. _gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
  11005. setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
  11006. _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
  11007. setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
  11008. setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
  11009. if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
  11010. }
  11011. // Release everything
  11012. if ( isCube ) {
  11013. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
  11014. } else {
  11015. _gl.bindTexture( _gl.TEXTURE_2D, null );
  11016. }
  11017. _gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
  11018. _gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
  11019. }
  11020. var framebuffer, width, height, vx, vy;
  11021. if ( renderTarget ) {
  11022. if ( isCube ) {
  11023. framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
  11024. } else {
  11025. framebuffer = renderTarget.__webglFramebuffer;
  11026. }
  11027. width = renderTarget.width;
  11028. height = renderTarget.height;
  11029. vx = 0;
  11030. vy = 0;
  11031. } else {
  11032. framebuffer = null;
  11033. width = _viewportWidth;
  11034. height = _viewportHeight;
  11035. vx = _viewportX;
  11036. vy = _viewportY;
  11037. }
  11038. if ( framebuffer !== _currentFramebuffer ) {
  11039. _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
  11040. _gl.viewport( vx, vy, width, height );
  11041. _currentFramebuffer = framebuffer;
  11042. }
  11043. _currentWidth = width;
  11044. _currentHeight = height;
  11045. };
  11046. function updateRenderTargetMipmap ( renderTarget ) {
  11047. if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
  11048. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
  11049. _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
  11050. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
  11051. } else {
  11052. _gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
  11053. _gl.generateMipmap( _gl.TEXTURE_2D );
  11054. _gl.bindTexture( _gl.TEXTURE_2D, null );
  11055. }
  11056. };
  11057. // Fallback filters for non-power-of-2 textures
  11058. function filterFallback ( f ) {
  11059. if ( f === THREE.NearestFilter || f === THREE.NearestMipMapNearestFilter || f === THREE.NearestMipMapLinearFilter ) {
  11060. return _gl.NEAREST;
  11061. }
  11062. return _gl.LINEAR;
  11063. };
  11064. // Map three.js constants to WebGL constants
  11065. function paramThreeToGL ( p ) {
  11066. if ( p === THREE.RepeatWrapping ) return _gl.REPEAT;
  11067. if ( p === THREE.ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
  11068. if ( p === THREE.MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;
  11069. if ( p === THREE.NearestFilter ) return _gl.NEAREST;
  11070. if ( p === THREE.NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;
  11071. if ( p === THREE.NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;
  11072. if ( p === THREE.LinearFilter ) return _gl.LINEAR;
  11073. if ( p === THREE.LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;
  11074. if ( p === THREE.LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;
  11075. if ( p === THREE.UnsignedByteType ) return _gl.UNSIGNED_BYTE;
  11076. if ( p === THREE.UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;
  11077. if ( p === THREE.UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;
  11078. if ( p === THREE.UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;
  11079. if ( p === THREE.ByteType ) return _gl.BYTE;
  11080. if ( p === THREE.ShortType ) return _gl.SHORT;
  11081. if ( p === THREE.UnsignedShortType ) return _gl.UNSIGNED_SHORT;
  11082. if ( p === THREE.IntType ) return _gl.INT;
  11083. if ( p === THREE.UnsignedIntType ) return _gl.UNSIGNED_INT;
  11084. if ( p === THREE.FloatType ) return _gl.FLOAT;
  11085. if ( p === THREE.AlphaFormat ) return _gl.ALPHA;
  11086. if ( p === THREE.RGBFormat ) return _gl.RGB;
  11087. if ( p === THREE.RGBAFormat ) return _gl.RGBA;
  11088. if ( p === THREE.LuminanceFormat ) return _gl.LUMINANCE;
  11089. if ( p === THREE.LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;
  11090. if ( p === THREE.AddEquation ) return _gl.FUNC_ADD;
  11091. if ( p === THREE.SubtractEquation ) return _gl.FUNC_SUBTRACT;
  11092. if ( p === THREE.ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;
  11093. if ( p === THREE.ZeroFactor ) return _gl.ZERO;
  11094. if ( p === THREE.OneFactor ) return _gl.ONE;
  11095. if ( p === THREE.SrcColorFactor ) return _gl.SRC_COLOR;
  11096. if ( p === THREE.OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;
  11097. if ( p === THREE.SrcAlphaFactor ) return _gl.SRC_ALPHA;
  11098. if ( p === THREE.OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;
  11099. if ( p === THREE.DstAlphaFactor ) return _gl.DST_ALPHA;
  11100. if ( p === THREE.OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;
  11101. if ( p === THREE.DstColorFactor ) return _gl.DST_COLOR;
  11102. if ( p === THREE.OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;
  11103. if ( p === THREE.SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;
  11104. return 0;
  11105. };
  11106. // Allocations
  11107. function allocateBones ( object ) {
  11108. if ( _supportsBoneTextures && object.useVertexTexture ) {
  11109. return 1024;
  11110. } else {
  11111. // default for when object is not specified
  11112. // ( for example when prebuilding shader
  11113. // to be used with multiple objects )
  11114. //
  11115. // - leave some extra space for other uniforms
  11116. // - limit here is ANGLE's 254 max uniform vectors
  11117. // (up to 54 should be safe)
  11118. var nVertexUniforms = _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS );
  11119. var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
  11120. var maxBones = nVertexMatrices;
  11121. if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
  11122. maxBones = Math.min( object.bones.length, maxBones );
  11123. if ( maxBones < object.bones.length ) {
  11124. console.warn( "WebGLRenderer: too many bones - " + object.bones.length + ", this GPU supports just " + maxBones + " (try OpenGL instead of ANGLE)" );
  11125. }
  11126. }
  11127. return maxBones;
  11128. }
  11129. };
  11130. function allocateLights ( lights ) {
  11131. var l, ll, light, dirLights, pointLights, spotLights, maxDirLights, maxPointLights, maxSpotLights;
  11132. dirLights = pointLights = spotLights = maxDirLights = maxPointLights = maxSpotLights = 0;
  11133. for ( l = 0, ll = lights.length; l < ll; l ++ ) {
  11134. light = lights[ l ];
  11135. if ( light.onlyShadow ) continue;
  11136. if ( light instanceof THREE.DirectionalLight ) dirLights ++;
  11137. if ( light instanceof THREE.PointLight ) pointLights ++;
  11138. if ( light instanceof THREE.SpotLight ) spotLights ++;
  11139. }
  11140. if ( ( pointLights + spotLights + dirLights ) <= _maxLights ) {
  11141. maxDirLights = dirLights;
  11142. maxPointLights = pointLights;
  11143. maxSpotLights = spotLights;
  11144. } else {
  11145. maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
  11146. maxPointLights = _maxLights - maxDirLights;
  11147. maxSpotLights = maxPointLights; // this is not really correct
  11148. }
  11149. return { 'directional' : maxDirLights, 'point' : maxPointLights, 'spot': maxSpotLights };
  11150. };
  11151. function allocateShadows ( lights ) {
  11152. var l, ll, light, maxShadows = 0;
  11153. for ( l = 0, ll = lights.length; l < ll; l++ ) {
  11154. light = lights[ l ];
  11155. if ( ! light.castShadow ) continue;
  11156. if ( light instanceof THREE.SpotLight ) maxShadows ++;
  11157. if ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) maxShadows ++;
  11158. }
  11159. return maxShadows;
  11160. };
  11161. // Initialization
  11162. function initGL () {
  11163. try {
  11164. if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { alpha: _alpha, premultipliedAlpha: _premultipliedAlpha, antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {
  11165. throw 'Error creating WebGL context.';
  11166. }
  11167. } catch ( error ) {
  11168. console.error( error );
  11169. }
  11170. _glExtensionTextureFloat = _gl.getExtension( 'OES_texture_float' );
  11171. _glExtensionStandardDerivatives = _gl.getExtension( 'OES_standard_derivatives' );
  11172. _glExtensionTextureFilterAnisotropic = _gl.getExtension( 'EXT_texture_filter_anisotropic' ) ||
  11173. _gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) ||
  11174. _gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );
  11175. if ( ! _glExtensionTextureFloat ) {
  11176. console.log( 'THREE.WebGLRenderer: Float textures not supported.' );
  11177. }
  11178. if ( ! _glExtensionStandardDerivatives ) {
  11179. console.log( 'THREE.WebGLRenderer: Standard derivatives not supported.' );
  11180. }
  11181. if ( ! _glExtensionTextureFilterAnisotropic ) {
  11182. console.log( 'THREE.WebGLRenderer: Anisotropic texture filtering not supported.' );
  11183. }
  11184. };
  11185. function setDefaultGLState () {
  11186. _gl.clearColor( 0, 0, 0, 1 );
  11187. _gl.clearDepth( 1 );
  11188. _gl.clearStencil( 0 );
  11189. _gl.enable( _gl.DEPTH_TEST );
  11190. _gl.depthFunc( _gl.LEQUAL );
  11191. _gl.frontFace( _gl.CCW );
  11192. _gl.cullFace( _gl.BACK );
  11193. _gl.enable( _gl.CULL_FACE );
  11194. _gl.enable( _gl.BLEND );
  11195. _gl.blendEquation( _gl.FUNC_ADD );
  11196. _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );
  11197. _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
  11198. };
  11199. // default plugins (order is important)
  11200. this.shadowMapPlugin = new THREE.ShadowMapPlugin();
  11201. this.addPrePlugin( this.shadowMapPlugin );
  11202. this.addPostPlugin( new THREE.SpritePlugin() );
  11203. this.addPostPlugin( new THREE.LensFlarePlugin() );
  11204. };
  11205. /**
  11206. * @author szimek / https://github.com/szimek/
  11207. */
  11208. THREE.WebGLRenderTarget = function ( width, height, options ) {
  11209. this.width = width;
  11210. this.height = height;
  11211. options = options || {};
  11212. this.wrapS = options.wrapS !== undefined ? options.wrapS : THREE.ClampToEdgeWrapping;
  11213. this.wrapT = options.wrapT !== undefined ? options.wrapT : THREE.ClampToEdgeWrapping;
  11214. this.magFilter = options.magFilter !== undefined ? options.magFilter : THREE.LinearFilter;
  11215. this.minFilter = options.minFilter !== undefined ? options.minFilter : THREE.LinearMipMapLinearFilter;
  11216. this.offset = new THREE.Vector2( 0, 0 );
  11217. this.repeat = new THREE.Vector2( 1, 1 );
  11218. this.format = options.format !== undefined ? options.format : THREE.RGBAFormat;
  11219. this.type = options.type !== undefined ? options.type : THREE.UnsignedByteType;
  11220. this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
  11221. this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;
  11222. this.generateMipmaps = true;
  11223. };
  11224. THREE.WebGLRenderTarget.prototype.clone = function() {
  11225. var tmp = new THREE.WebGLRenderTarget( this.width, this.height );
  11226. tmp.wrapS = this.wrapS;
  11227. tmp.wrapT = this.wrapT;
  11228. tmp.magFilter = this.magFilter;
  11229. tmp.minFilter = this.minFilter;
  11230. tmp.offset.copy( this.offset );
  11231. tmp.repeat.copy( this.repeat );
  11232. tmp.format = this.format;
  11233. tmp.type = this.type;
  11234. tmp.depthBuffer = this.depthBuffer;
  11235. tmp.stencilBuffer = this.stencilBuffer;
  11236. return tmp;
  11237. };
  11238. /**
  11239. * @author alteredq / http://alteredqualia.com
  11240. */
  11241. THREE.WebGLRenderTargetCube = function ( width, height, options ) {
  11242. THREE.WebGLRenderTarget.call( this, width, height, options );
  11243. this.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5
  11244. };
  11245. THREE.WebGLRenderTargetCube.prototype = Object.create( THREE.WebGLRenderTarget.prototype );
  11246. /**
  11247. * @author mr.doob / http://mrdoob.com/
  11248. */
  11249. THREE.RenderableVertex = function () {
  11250. this.positionWorld = new THREE.Vector3();
  11251. this.positionScreen = new THREE.Vector4();
  11252. this.visible = true;
  11253. };
  11254. THREE.RenderableVertex.prototype.copy = function ( vertex ) {
  11255. this.positionWorld.copy( vertex.positionWorld );
  11256. this.positionScreen.copy( vertex.positionScreen );
  11257. }
  11258. /**
  11259. * @author mr.doob / http://mrdoob.com/
  11260. */
  11261. THREE.RenderableFace3 = function () {
  11262. this.v1 = new THREE.RenderableVertex();
  11263. this.v2 = new THREE.RenderableVertex();
  11264. this.v3 = new THREE.RenderableVertex();
  11265. this.centroidWorld = new THREE.Vector3();
  11266. this.centroidScreen = new THREE.Vector3();
  11267. this.normalWorld = new THREE.Vector3();
  11268. this.vertexNormalsWorld = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
  11269. this.material = null;
  11270. this.faceMaterial = null;
  11271. this.uvs = [[]];
  11272. this.z = null;
  11273. };
  11274. /**
  11275. * @author mr.doob / http://mrdoob.com/
  11276. */
  11277. THREE.RenderableFace4 = function () {
  11278. this.v1 = new THREE.RenderableVertex();
  11279. this.v2 = new THREE.RenderableVertex();
  11280. this.v3 = new THREE.RenderableVertex();
  11281. this.v4 = new THREE.RenderableVertex();
  11282. this.centroidWorld = new THREE.Vector3();
  11283. this.centroidScreen = new THREE.Vector3();
  11284. this.normalWorld = new THREE.Vector3();
  11285. this.vertexNormalsWorld = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
  11286. this.material = null;
  11287. this.faceMaterial = null;
  11288. this.uvs = [[]];
  11289. this.z = null;
  11290. };
  11291. /**
  11292. * @author mr.doob / http://mrdoob.com/
  11293. */
  11294. THREE.RenderableObject = function () {
  11295. this.object = null;
  11296. this.z = null;
  11297. };
  11298. /**
  11299. * @author mr.doob / http://mrdoob.com/
  11300. */
  11301. THREE.RenderableParticle = function () {
  11302. this.x = null;
  11303. this.y = null;
  11304. this.z = null;
  11305. this.rotation = null;
  11306. this.scale = new THREE.Vector2();
  11307. this.material = null;
  11308. };
  11309. /**
  11310. * @author mr.doob / http://mrdoob.com/
  11311. */
  11312. THREE.RenderableLine = function () {
  11313. this.z = null;
  11314. this.v1 = new THREE.RenderableVertex();
  11315. this.v2 = new THREE.RenderableVertex();
  11316. this.material = null;
  11317. };
  11318. /**
  11319. * @author alteredq / http://alteredqualia.com/
  11320. */
  11321. THREE.BufferGeometry = function () {
  11322. this.id = THREE.GeometryCount ++;
  11323. // attributes
  11324. this.attributes = {};
  11325. // attributes typed arrays are kept only if dynamic flag is set
  11326. this.dynamic = false;
  11327. // boundings
  11328. this.boundingBox = null;
  11329. this.boundingSphere = null;
  11330. this.hasTangents = false;
  11331. // for compatibility
  11332. this.morphTargets = [];
  11333. };
  11334. THREE.BufferGeometry.prototype = {
  11335. constructor : THREE.BufferGeometry,
  11336. applyMatrix: function ( matrix ) {
  11337. var positionArray;
  11338. var normalArray;
  11339. if ( this.attributes[ "position" ] ) positionArray = this.attributes[ "position" ].array;
  11340. if ( this.attributes[ "normal" ] ) normalArray = this.attributes[ "normal" ].array;
  11341. if ( positionArray !== undefined ) {
  11342. matrix.multiplyVector3Array( positionArray );
  11343. this.verticesNeedUpdate = true;
  11344. }
  11345. if ( normalArray !== undefined ) {
  11346. var matrixRotation = new THREE.Matrix4();
  11347. matrixRotation.extractRotation( matrix );
  11348. matrixRotation.multiplyVector3Array( normalArray );
  11349. this.normalsNeedUpdate = true;
  11350. }
  11351. },
  11352. computeBoundingBox: function () {
  11353. if ( ! this.boundingBox ) {
  11354. this.boundingBox = {
  11355. min: new THREE.Vector3( Infinity, Infinity, Infinity ),
  11356. max: new THREE.Vector3( -Infinity, -Infinity, -Infinity )
  11357. };
  11358. }
  11359. var positions = this.attributes[ "position" ].array;
  11360. if ( positions ) {
  11361. var bb = this.boundingBox;
  11362. var x, y, z;
  11363. for ( var i = 0, il = positions.length; i < il; i += 3 ) {
  11364. x = positions[ i ];
  11365. y = positions[ i + 1 ];
  11366. z = positions[ i + 2 ];
  11367. // bounding box
  11368. if ( x < bb.min.x ) {
  11369. bb.min.x = x;
  11370. } else if ( x > bb.max.x ) {
  11371. bb.max.x = x;
  11372. }
  11373. if ( y < bb.min.y ) {
  11374. bb.min.y = y;
  11375. } else if ( y > bb.max.y ) {
  11376. bb.max.y = y;
  11377. }
  11378. if ( z < bb.min.z ) {
  11379. bb.min.z = z;
  11380. } else if ( z > bb.max.z ) {
  11381. bb.max.z = z;
  11382. }
  11383. }
  11384. }
  11385. if ( positions === undefined || positions.length === 0 ) {
  11386. this.boundingBox.min.set( 0, 0, 0 );
  11387. this.boundingBox.max.set( 0, 0, 0 );
  11388. }
  11389. },
  11390. computeBoundingSphere: function () {
  11391. if ( ! this.boundingSphere ) this.boundingSphere = { radius: 0 };
  11392. var positions = this.attributes[ "position" ].array;
  11393. if ( positions ) {
  11394. var radius, maxRadius = 0;
  11395. var x, y, z;
  11396. for ( var i = 0, il = positions.length; i < il; i += 3 ) {
  11397. x = positions[ i ];
  11398. y = positions[ i + 1 ];
  11399. z = positions[ i + 2 ];
  11400. radius = Math.sqrt( x * x + y * y + z * z );
  11401. if ( radius > maxRadius ) maxRadius = radius;
  11402. }
  11403. this.boundingSphere.radius = maxRadius;
  11404. }
  11405. },
  11406. computeVertexNormals: function () {
  11407. if ( this.attributes[ "position" ] && this.attributes[ "index" ] ) {
  11408. var i, il;
  11409. var j, jl;
  11410. var nVertexElements = this.attributes[ "position" ].array.length;
  11411. if ( this.attributes[ "normal" ] === undefined ) {
  11412. this.attributes[ "normal" ] = {
  11413. itemSize: 3,
  11414. array: new Float32Array( nVertexElements ),
  11415. numItems: nVertexElements
  11416. };
  11417. } else {
  11418. // reset existing normals to zero
  11419. for ( i = 0, il = this.attributes[ "normal" ].array.length; i < il; i ++ ) {
  11420. this.attributes[ "normal" ].array[ i ] = 0;
  11421. }
  11422. }
  11423. var offsets = this.offsets;
  11424. var indices = this.attributes[ "index" ].array;
  11425. var positions = this.attributes[ "position" ].array;
  11426. var normals = this.attributes[ "normal" ].array;
  11427. var vA, vB, vC, x, y, z,
  11428. pA = new THREE.Vector3(),
  11429. pB = new THREE.Vector3(),
  11430. pC = new THREE.Vector3(),
  11431. cb = new THREE.Vector3(),
  11432. ab = new THREE.Vector3();
  11433. for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
  11434. var start = offsets[ j ].start;
  11435. var count = offsets[ j ].count;
  11436. var index = offsets[ j ].index;
  11437. for ( i = start, il = start + count; i < il; i += 3 ) {
  11438. vA = index + indices[ i ];
  11439. vB = index + indices[ i + 1 ];
  11440. vC = index + indices[ i + 2 ];
  11441. x = positions[ vA * 3 ];
  11442. y = positions[ vA * 3 + 1 ];
  11443. z = positions[ vA * 3 + 2 ];
  11444. pA.set( x, y, z );
  11445. x = positions[ vB * 3 ];
  11446. y = positions[ vB * 3 + 1 ];
  11447. z = positions[ vB * 3 + 2 ];
  11448. pB.set( x, y, z );
  11449. x = positions[ vC * 3 ];
  11450. y = positions[ vC * 3 + 1 ];
  11451. z = positions[ vC * 3 + 2 ];
  11452. pC.set( x, y, z );
  11453. cb.sub( pC, pB );
  11454. ab.sub( pA, pB );
  11455. cb.crossSelf( ab );
  11456. normals[ vA * 3 ] += cb.x;
  11457. normals[ vA * 3 + 1 ] += cb.y;
  11458. normals[ vA * 3 + 2 ] += cb.z;
  11459. normals[ vB * 3 ] += cb.x;
  11460. normals[ vB * 3 + 1 ] += cb.y;
  11461. normals[ vB * 3 + 2 ] += cb.z;
  11462. normals[ vC * 3 ] += cb.x;
  11463. normals[ vC * 3 + 1 ] += cb.y;
  11464. normals[ vC * 3 + 2 ] += cb.z;
  11465. }
  11466. }
  11467. // normalize normals
  11468. for ( i = 0, il = normals.length; i < il; i += 3 ) {
  11469. x = normals[ i ];
  11470. y = normals[ i + 1 ];
  11471. z = normals[ i + 2 ];
  11472. var n = 1.0 / Math.sqrt( x * x + y * y + z * z );
  11473. normals[ i ] *= n;
  11474. normals[ i + 1 ] *= n;
  11475. normals[ i + 2 ] *= n;
  11476. }
  11477. this.normalsNeedUpdate = true;
  11478. }
  11479. },
  11480. computeTangents: function () {
  11481. // based on http://www.terathon.com/code/tangent.html
  11482. // (per vertex tangents)
  11483. if ( this.attributes[ "index" ] === undefined ||
  11484. this.attributes[ "position" ] === undefined ||
  11485. this.attributes[ "normal" ] === undefined ||
  11486. this.attributes[ "uv" ] === undefined ) {
  11487. console.warn( "Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()" );
  11488. return;
  11489. }
  11490. var indices = this.attributes[ "index" ].array;
  11491. var positions = this.attributes[ "position" ].array;
  11492. var normals = this.attributes[ "normal" ].array;
  11493. var uvs = this.attributes[ "uv" ].array;
  11494. var nVertices = positions.length / 3;
  11495. if ( this.attributes[ "tangent" ] === undefined ) {
  11496. var nTangentElements = 4 * nVertices;
  11497. this.attributes[ "tangent" ] = {
  11498. itemSize: 4,
  11499. array: new Float32Array( nTangentElements ),
  11500. numItems: nTangentElements
  11501. };
  11502. }
  11503. var tangents = this.attributes[ "tangent" ].array;
  11504. var tan1 = [], tan2 = [];
  11505. for ( var k = 0; k < nVertices; k ++ ) {
  11506. tan1[ k ] = new THREE.Vector3();
  11507. tan2[ k ] = new THREE.Vector3();
  11508. }
  11509. var xA, yA, zA,
  11510. xB, yB, zB,
  11511. xC, yC, zC,
  11512. uA, vA,
  11513. uB, vB,
  11514. uC, vC,
  11515. x1, x2, y1, y2, z1, z2,
  11516. s1, s2, t1, t2, r;
  11517. var sdir = new THREE.Vector3(), tdir = new THREE.Vector3();
  11518. function handleTriangle( a, b, c ) {
  11519. xA = positions[ a * 3 ];
  11520. yA = positions[ a * 3 + 1 ];
  11521. zA = positions[ a * 3 + 2 ];
  11522. xB = positions[ b * 3 ];
  11523. yB = positions[ b * 3 + 1 ];
  11524. zB = positions[ b * 3 + 2 ];
  11525. xC = positions[ c * 3 ];
  11526. yC = positions[ c * 3 + 1 ];
  11527. zC = positions[ c * 3 + 2 ];
  11528. uA = uvs[ a * 2 ];
  11529. vA = uvs[ a * 2 + 1 ];
  11530. uB = uvs[ b * 2 ];
  11531. vB = uvs[ b * 2 + 1 ];
  11532. uC = uvs[ c * 2 ];
  11533. vC = uvs[ c * 2 + 1 ];
  11534. x1 = xB - xA;
  11535. x2 = xC - xA;
  11536. y1 = yB - yA;
  11537. y2 = yC - yA;
  11538. z1 = zB - zA;
  11539. z2 = zC - zA;
  11540. s1 = uB - uA;
  11541. s2 = uC - uA;
  11542. t1 = vB - vA;
  11543. t2 = vC - vA;
  11544. r = 1.0 / ( s1 * t2 - s2 * t1 );
  11545. sdir.set( ( t2 * x1 - t1 * x2 ) * r,
  11546. ( t2 * y1 - t1 * y2 ) * r,
  11547. ( t2 * z1 - t1 * z2 ) * r );
  11548. tdir.set( ( s1 * x2 - s2 * x1 ) * r,
  11549. ( s1 * y2 - s2 * y1 ) * r,
  11550. ( s1 * z2 - s2 * z1 ) * r );
  11551. tan1[ a ].addSelf( sdir );
  11552. tan1[ b ].addSelf( sdir );
  11553. tan1[ c ].addSelf( sdir );
  11554. tan2[ a ].addSelf( tdir );
  11555. tan2[ b ].addSelf( tdir );
  11556. tan2[ c ].addSelf( tdir );
  11557. }
  11558. var i, il;
  11559. var j, jl;
  11560. var iA, iB, iC;
  11561. var offsets = this.offsets;
  11562. for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
  11563. var start = offsets[ j ].start;
  11564. var count = offsets[ j ].count;
  11565. var index = offsets[ j ].index;
  11566. for ( i = start, il = start + count; i < il; i += 3 ) {
  11567. iA = index + indices[ i ];
  11568. iB = index + indices[ i + 1 ];
  11569. iC = index + indices[ i + 2 ];
  11570. handleTriangle( iA, iB, iC );
  11571. }
  11572. }
  11573. var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3();
  11574. var n = new THREE.Vector3(), n2 = new THREE.Vector3();
  11575. var w, t, test;
  11576. var nx, ny, nz;
  11577. function handleVertex( v ) {
  11578. n.x = normals[ v * 3 ];
  11579. n.y = normals[ v * 3 + 1 ];
  11580. n.z = normals[ v * 3 + 2 ];
  11581. n2.copy( n );
  11582. t = tan1[ v ];
  11583. // Gram-Schmidt orthogonalize
  11584. tmp.copy( t );
  11585. tmp.subSelf( n.multiplyScalar( n.dot( t ) ) ).normalize();
  11586. // Calculate handedness
  11587. tmp2.cross( n2, t );
  11588. test = tmp2.dot( tan2[ v ] );
  11589. w = ( test < 0.0 ) ? -1.0 : 1.0;
  11590. tangents[ v * 4 ] = tmp.x;
  11591. tangents[ v * 4 + 1 ] = tmp.y;
  11592. tangents[ v * 4 + 2 ] = tmp.z;
  11593. tangents[ v * 4 + 3 ] = w;
  11594. }
  11595. for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
  11596. var start = offsets[ j ].start;
  11597. var count = offsets[ j ].count;
  11598. var index = offsets[ j ].index;
  11599. for ( i = start, il = start + count; i < il; i += 3 ) {
  11600. iA = index + indices[ i ];
  11601. iB = index + indices[ i + 1 ];
  11602. iC = index + indices[ i + 2 ];
  11603. handleVertex( iA );
  11604. handleVertex( iB );
  11605. handleVertex( iC );
  11606. }
  11607. }
  11608. this.hasTangents = true;
  11609. this.tangentsNeedUpdate = true;
  11610. }
  11611. };
  11612. /**
  11613. * @author alteredq / http://alteredqualia.com/
  11614. */
  11615. THREE.Gyroscope = function () {
  11616. THREE.Object3D.call( this );
  11617. };
  11618. THREE.Gyroscope.prototype = Object.create( THREE.Object3D.prototype );
  11619. THREE.Gyroscope.prototype.updateMatrixWorld = function ( force ) {
  11620. this.matrixAutoUpdate && this.updateMatrix();
  11621. // update matrixWorld
  11622. if ( this.matrixWorldNeedsUpdate || force ) {
  11623. if ( this.parent ) {
  11624. this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
  11625. this.matrixWorld.decompose( this.translationWorld, this.rotationWorld, this.scaleWorld );
  11626. this.matrix.decompose( this.translationObject, this.rotationObject, this.scaleObject );
  11627. this.matrixWorld.compose( this.translationWorld, this.rotationObject, this.scaleWorld );
  11628. } else {
  11629. this.matrixWorld.copy( this.matrix );
  11630. }
  11631. this.matrixWorldNeedsUpdate = false;
  11632. force = true;
  11633. }
  11634. // update children
  11635. for ( var i = 0, l = this.children.length; i < l; i ++ ) {
  11636. this.children[ i ].updateMatrixWorld( force );
  11637. }
  11638. };
  11639. THREE.Gyroscope.prototype.translationWorld = new THREE.Vector3();
  11640. THREE.Gyroscope.prototype.translationObject = new THREE.Vector3();
  11641. THREE.Gyroscope.prototype.rotationWorld = new THREE.Quaternion();
  11642. THREE.Gyroscope.prototype.rotationObject = new THREE.Quaternion();
  11643. THREE.Gyroscope.prototype.scaleWorld = new THREE.Vector3();
  11644. THREE.Gyroscope.prototype.scaleObject = new THREE.Vector3();
  11645. /**
  11646. * @author alteredq / http://alteredqualia.com/
  11647. *
  11648. * - shows frustum, line of sight and up of the camera
  11649. * - suitable for fast updates
  11650. * - based on frustum visualization in lightgl.js shadowmap example
  11651. * http://evanw.github.com/lightgl.js/tests/shadowmap.html
  11652. */
  11653. THREE.CameraHelper = function ( camera ) {
  11654. THREE.Object3D.call( this );
  11655. var _this = this;
  11656. this.lineGeometry = new THREE.Geometry();
  11657. this.lineMaterial = new THREE.LineBasicMaterial( { color: 0xffffff, vertexColors: THREE.FaceColors } );
  11658. this.pointMap = {};
  11659. // colors
  11660. var hexFrustum = 0xffaa00,
  11661. hexCone = 0xff0000,
  11662. hexUp = 0x00aaff,
  11663. hexTarget = 0xffffff,
  11664. hexCross = 0x333333;
  11665. // near
  11666. addLine( "n1", "n2", hexFrustum );
  11667. addLine( "n2", "n4", hexFrustum );
  11668. addLine( "n4", "n3", hexFrustum );
  11669. addLine( "n3", "n1", hexFrustum );
  11670. // far
  11671. addLine( "f1", "f2", hexFrustum );
  11672. addLine( "f2", "f4", hexFrustum );
  11673. addLine( "f4", "f3", hexFrustum );
  11674. addLine( "f3", "f1", hexFrustum );
  11675. // sides
  11676. addLine( "n1", "f1", hexFrustum );
  11677. addLine( "n2", "f2", hexFrustum );
  11678. addLine( "n3", "f3", hexFrustum );
  11679. addLine( "n4", "f4", hexFrustum );
  11680. // cone
  11681. addLine( "p", "n1", hexCone );
  11682. addLine( "p", "n2", hexCone );
  11683. addLine( "p", "n3", hexCone );
  11684. addLine( "p", "n4", hexCone );
  11685. // up
  11686. addLine( "u1", "u2", hexUp );
  11687. addLine( "u2", "u3", hexUp );
  11688. addLine( "u3", "u1", hexUp );
  11689. // target
  11690. addLine( "c", "t", hexTarget );
  11691. addLine( "p", "c", hexCross );
  11692. // cross
  11693. addLine( "cn1", "cn2", hexCross );
  11694. addLine( "cn3", "cn4", hexCross );
  11695. addLine( "cf1", "cf2", hexCross );
  11696. addLine( "cf3", "cf4", hexCross );
  11697. this.camera = camera;
  11698. function addLine( a, b, hex ) {
  11699. addPoint( a, hex );
  11700. addPoint( b, hex );
  11701. }
  11702. function addPoint( id, hex ) {
  11703. _this.lineGeometry.vertices.push( new THREE.Vector3() );
  11704. _this.lineGeometry.colors.push( new THREE.Color( hex ) );
  11705. if ( _this.pointMap[ id ] === undefined ) _this.pointMap[ id ] = [];
  11706. _this.pointMap[ id ].push( _this.lineGeometry.vertices.length - 1 );
  11707. }
  11708. this.update( camera );
  11709. this.lines = new THREE.Line( this.lineGeometry, this.lineMaterial, THREE.LinePieces );
  11710. this.add( this.lines );
  11711. };
  11712. THREE.CameraHelper.prototype = Object.create( THREE.Object3D.prototype );
  11713. THREE.CameraHelper.prototype.update = function () {
  11714. var camera = this.camera;
  11715. var w = 1;
  11716. var h = 1;
  11717. var _this = this;
  11718. // we need just camera projection matrix
  11719. // world matrix must be identity
  11720. THREE.CameraHelper.__c.projectionMatrix.copy( camera.projectionMatrix );
  11721. // center / target
  11722. setPoint( "c", 0, 0, -1 );
  11723. setPoint( "t", 0, 0, 1 );
  11724. // near
  11725. setPoint( "n1", -w, -h, -1 );
  11726. setPoint( "n2", w, -h, -1 );
  11727. setPoint( "n3", -w, h, -1 );
  11728. setPoint( "n4", w, h, -1 );
  11729. // far
  11730. setPoint( "f1", -w, -h, 1 );
  11731. setPoint( "f2", w, -h, 1 );
  11732. setPoint( "f3", -w, h, 1 );
  11733. setPoint( "f4", w, h, 1 );
  11734. // up
  11735. setPoint( "u1", w * 0.7, h * 1.1, -1 );
  11736. setPoint( "u2", -w * 0.7, h * 1.1, -1 );
  11737. setPoint( "u3", 0, h * 2, -1 );
  11738. // cross
  11739. setPoint( "cf1", -w, 0, 1 );
  11740. setPoint( "cf2", w, 0, 1 );
  11741. setPoint( "cf3", 0, -h, 1 );
  11742. setPoint( "cf4", 0, h, 1 );
  11743. setPoint( "cn1", -w, 0, -1 );
  11744. setPoint( "cn2", w, 0, -1 );
  11745. setPoint( "cn3", 0, -h, -1 );
  11746. setPoint( "cn4", 0, h, -1 );
  11747. function setPoint( point, x, y, z ) {
  11748. THREE.CameraHelper.__v.set( x, y, z );
  11749. THREE.CameraHelper.__projector.unprojectVector( THREE.CameraHelper.__v, THREE.CameraHelper.__c );
  11750. var points = _this.pointMap[ point ];
  11751. if ( points !== undefined ) {
  11752. for ( var i = 0, il = points.length; i < il; i ++ ) {
  11753. var j = points[ i ];
  11754. _this.lineGeometry.vertices[ j ].copy( THREE.CameraHelper.__v );
  11755. }
  11756. }
  11757. }
  11758. this.lineGeometry.verticesNeedUpdate = true;
  11759. };
  11760. THREE.CameraHelper.__projector = new THREE.Projector();
  11761. THREE.CameraHelper.__v = new THREE.Vector3();
  11762. THREE.CameraHelper.__c = new THREE.Camera();
  11763. /**
  11764. * @author mikael emtinger / http://gomo.se/
  11765. * @author alteredq / http://alteredqualia.com/
  11766. */
  11767. THREE.LensFlare = function ( texture, size, distance, blending, color ) {
  11768. THREE.Object3D.call( this );
  11769. this.lensFlares = [];
  11770. this.positionScreen = new THREE.Vector3();
  11771. this.customUpdateCallback = undefined;
  11772. if( texture !== undefined ) {
  11773. this.add( texture, size, distance, blending, color );
  11774. }
  11775. };
  11776. THREE.LensFlare.prototype = Object.create( THREE.Object3D.prototype );
  11777. /*
  11778. * Add: adds another flare
  11779. */
  11780. THREE.LensFlare.prototype.add = function ( texture, size, distance, blending, color, opacity ) {
  11781. if( size === undefined ) size = -1;
  11782. if( distance === undefined ) distance = 0;
  11783. if( opacity === undefined ) opacity = 1;
  11784. if( color === undefined ) color = new THREE.Color( 0xffffff );
  11785. if( blending === undefined ) blending = THREE.NormalBlending;
  11786. distance = Math.min( distance, Math.max( 0, distance ) );
  11787. this.lensFlares.push( { texture: texture, // THREE.Texture
  11788. size: size, // size in pixels (-1 = use texture.width)
  11789. distance: distance, // distance (0-1) from light source (0=at light source)
  11790. x: 0, y: 0, z: 0, // screen position (-1 => 1) z = 0 is ontop z = 1 is back
  11791. scale: 1, // scale
  11792. rotation: 1, // rotation
  11793. opacity: opacity, // opacity
  11794. color: color, // color
  11795. blending: blending } ); // blending
  11796. };
  11797. /*
  11798. * Update lens flares update positions on all flares based on the screen position
  11799. * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.
  11800. */
  11801. THREE.LensFlare.prototype.updateLensFlares = function () {
  11802. var f, fl = this.lensFlares.length;
  11803. var flare;
  11804. var vecX = -this.positionScreen.x * 2;
  11805. var vecY = -this.positionScreen.y * 2;
  11806. for( f = 0; f < fl; f ++ ) {
  11807. flare = this.lensFlares[ f ];
  11808. flare.x = this.positionScreen.x + vecX * flare.distance;
  11809. flare.y = this.positionScreen.y + vecY * flare.distance;
  11810. flare.wantedRotation = flare.x * Math.PI * 0.25;
  11811. flare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;
  11812. }
  11813. };
  11814. /**
  11815. * @author alteredq / http://alteredqualia.com/
  11816. */
  11817. THREE.ImmediateRenderObject = function ( ) {
  11818. THREE.Object3D.call( this );
  11819. this.render = function ( renderCallback ) { };
  11820. };
  11821. THREE.ImmediateRenderObject.prototype = Object.create( THREE.Object3D.prototype );
  11822. /**
  11823. * @author mikael emtinger / http://gomo.se/
  11824. * @author alteredq / http://alteredqualia.com/
  11825. */
  11826. THREE.LensFlarePlugin = function ( ) {
  11827. var _gl, _renderer, _lensFlare = {};
  11828. this.init = function ( renderer ) {
  11829. _gl = renderer.context;
  11830. _renderer = renderer;
  11831. _lensFlare.vertices = new Float32Array( 8 + 8 );
  11832. _lensFlare.faces = new Uint16Array( 6 );
  11833. var i = 0;
  11834. _lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = -1; // vertex
  11835. _lensFlare.vertices[ i++ ] = 0; _lensFlare.vertices[ i++ ] = 0; // uv... etc.
  11836. _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = -1;
  11837. _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 0;
  11838. _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 1;
  11839. _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 1;
  11840. _lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = 1;
  11841. _lensFlare.vertices[ i++ ] = 0; _lensFlare.vertices[ i++ ] = 1;
  11842. i = 0;
  11843. _lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 1; _lensFlare.faces[ i++ ] = 2;
  11844. _lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 2; _lensFlare.faces[ i++ ] = 3;
  11845. // buffers
  11846. _lensFlare.vertexBuffer = _gl.createBuffer();
  11847. _lensFlare.elementBuffer = _gl.createBuffer();
  11848. _gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
  11849. _gl.bufferData( _gl.ARRAY_BUFFER, _lensFlare.vertices, _gl.STATIC_DRAW );
  11850. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
  11851. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.faces, _gl.STATIC_DRAW );
  11852. // textures
  11853. _lensFlare.tempTexture = _gl.createTexture();
  11854. _lensFlare.occlusionTexture = _gl.createTexture();
  11855. _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
  11856. _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, 16, 16, 0, _gl.RGB, _gl.UNSIGNED_BYTE, null );
  11857. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
  11858. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
  11859. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
  11860. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
  11861. _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
  11862. _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, 16, 16, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, null );
  11863. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
  11864. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
  11865. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
  11866. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
  11867. if ( _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ) <= 0 ) {
  11868. _lensFlare.hasVertexTexture = false;
  11869. _lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlare" ] );
  11870. } else {
  11871. _lensFlare.hasVertexTexture = true;
  11872. _lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlareVertexTexture" ] );
  11873. }
  11874. _lensFlare.attributes = {};
  11875. _lensFlare.uniforms = {};
  11876. _lensFlare.attributes.vertex = _gl.getAttribLocation ( _lensFlare.program, "position" );
  11877. _lensFlare.attributes.uv = _gl.getAttribLocation ( _lensFlare.program, "uv" );
  11878. _lensFlare.uniforms.renderType = _gl.getUniformLocation( _lensFlare.program, "renderType" );
  11879. _lensFlare.uniforms.map = _gl.getUniformLocation( _lensFlare.program, "map" );
  11880. _lensFlare.uniforms.occlusionMap = _gl.getUniformLocation( _lensFlare.program, "occlusionMap" );
  11881. _lensFlare.uniforms.opacity = _gl.getUniformLocation( _lensFlare.program, "opacity" );
  11882. _lensFlare.uniforms.color = _gl.getUniformLocation( _lensFlare.program, "color" );
  11883. _lensFlare.uniforms.scale = _gl.getUniformLocation( _lensFlare.program, "scale" );
  11884. _lensFlare.uniforms.rotation = _gl.getUniformLocation( _lensFlare.program, "rotation" );
  11885. _lensFlare.uniforms.screenPosition = _gl.getUniformLocation( _lensFlare.program, "screenPosition" );
  11886. _lensFlare.attributesEnabled = false;
  11887. };
  11888. /*
  11889. * Render lens flares
  11890. * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,
  11891. * reads these back and calculates occlusion.
  11892. * Then _lensFlare.update_lensFlares() is called to re-position and
  11893. * update transparency of flares. Then they are rendered.
  11894. *
  11895. */
  11896. this.render = function ( scene, camera, viewportWidth, viewportHeight ) {
  11897. var flares = scene.__webglFlares,
  11898. nFlares = flares.length;
  11899. if ( ! nFlares ) return;
  11900. var tempPosition = new THREE.Vector3();
  11901. var invAspect = viewportHeight / viewportWidth,
  11902. halfViewportWidth = viewportWidth * 0.5,
  11903. halfViewportHeight = viewportHeight * 0.5;
  11904. var size = 16 / viewportHeight,
  11905. scale = new THREE.Vector2( size * invAspect, size );
  11906. var screenPosition = new THREE.Vector3( 1, 1, 0 ),
  11907. screenPositionPixels = new THREE.Vector2( 1, 1 );
  11908. var uniforms = _lensFlare.uniforms,
  11909. attributes = _lensFlare.attributes;
  11910. // set _lensFlare program and reset blending
  11911. _gl.useProgram( _lensFlare.program );
  11912. if ( ! _lensFlare.attributesEnabled ) {
  11913. _gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
  11914. _gl.enableVertexAttribArray( _lensFlare.attributes.uv );
  11915. _lensFlare.attributesEnabled = true;
  11916. }
  11917. // loop through all lens flares to update their occlusion and positions
  11918. // setup gl and common used attribs/unforms
  11919. _gl.uniform1i( uniforms.occlusionMap, 0 );
  11920. _gl.uniform1i( uniforms.map, 1 );
  11921. _gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
  11922. _gl.vertexAttribPointer( attributes.vertex, 2, _gl.FLOAT, false, 2 * 8, 0 );
  11923. _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );
  11924. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
  11925. _gl.disable( _gl.CULL_FACE );
  11926. _gl.depthMask( false );
  11927. var i, j, jl, flare, sprite;
  11928. for ( i = 0; i < nFlares; i ++ ) {
  11929. size = 16 / viewportHeight;
  11930. scale.set( size * invAspect, size );
  11931. // calc object screen position
  11932. flare = flares[ i ];
  11933. tempPosition.set( flare.matrixWorld.elements[12], flare.matrixWorld.elements[13], flare.matrixWorld.elements[14] );
  11934. camera.matrixWorldInverse.multiplyVector3( tempPosition );
  11935. camera.projectionMatrix.multiplyVector3( tempPosition );
  11936. // setup arrays for gl programs
  11937. screenPosition.copy( tempPosition )
  11938. screenPositionPixels.x = screenPosition.x * halfViewportWidth + halfViewportWidth;
  11939. screenPositionPixels.y = screenPosition.y * halfViewportHeight + halfViewportHeight;
  11940. // screen cull
  11941. if ( _lensFlare.hasVertexTexture || (
  11942. screenPositionPixels.x > 0 &&
  11943. screenPositionPixels.x < viewportWidth &&
  11944. screenPositionPixels.y > 0 &&
  11945. screenPositionPixels.y < viewportHeight ) ) {
  11946. // save current RGB to temp texture
  11947. _gl.activeTexture( _gl.TEXTURE1 );
  11948. _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
  11949. _gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 );
  11950. // render pink quad
  11951. _gl.uniform1i( uniforms.renderType, 0 );
  11952. _gl.uniform2f( uniforms.scale, scale.x, scale.y );
  11953. _gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
  11954. _gl.disable( _gl.BLEND );
  11955. _gl.enable( _gl.DEPTH_TEST );
  11956. _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
  11957. // copy result to occlusionMap
  11958. _gl.activeTexture( _gl.TEXTURE0 );
  11959. _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
  11960. _gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 );
  11961. // restore graphics
  11962. _gl.uniform1i( uniforms.renderType, 1 );
  11963. _gl.disable( _gl.DEPTH_TEST );
  11964. _gl.activeTexture( _gl.TEXTURE1 );
  11965. _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
  11966. _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
  11967. // update object positions
  11968. flare.positionScreen.copy( screenPosition )
  11969. if ( flare.customUpdateCallback ) {
  11970. flare.customUpdateCallback( flare );
  11971. } else {
  11972. flare.updateLensFlares();
  11973. }
  11974. // render flares
  11975. _gl.uniform1i( uniforms.renderType, 2 );
  11976. _gl.enable( _gl.BLEND );
  11977. for ( j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {
  11978. sprite = flare.lensFlares[ j ];
  11979. if ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {
  11980. screenPosition.x = sprite.x;
  11981. screenPosition.y = sprite.y;
  11982. screenPosition.z = sprite.z;
  11983. size = sprite.size * sprite.scale / viewportHeight;
  11984. scale.x = size * invAspect;
  11985. scale.y = size;
  11986. _gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
  11987. _gl.uniform2f( uniforms.scale, scale.x, scale.y );
  11988. _gl.uniform1f( uniforms.rotation, sprite.rotation );
  11989. _gl.uniform1f( uniforms.opacity, sprite.opacity );
  11990. _gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );
  11991. _renderer.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );
  11992. _renderer.setTexture( sprite.texture, 1 );
  11993. _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
  11994. }
  11995. }
  11996. }
  11997. }
  11998. // restore gl
  11999. _gl.enable( _gl.CULL_FACE );
  12000. _gl.enable( _gl.DEPTH_TEST );
  12001. _gl.depthMask( true );
  12002. };
  12003. function createProgram ( shader ) {
  12004. var program = _gl.createProgram();
  12005. var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
  12006. var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
  12007. _gl.shaderSource( fragmentShader, shader.fragmentShader );
  12008. _gl.shaderSource( vertexShader, shader.vertexShader );
  12009. _gl.compileShader( fragmentShader );
  12010. _gl.compileShader( vertexShader );
  12011. _gl.attachShader( program, fragmentShader );
  12012. _gl.attachShader( program, vertexShader );
  12013. _gl.linkProgram( program );
  12014. return program;
  12015. };
  12016. };/**
  12017. * @author alteredq / http://alteredqualia.com/
  12018. */
  12019. THREE.ShadowMapPlugin = function ( ) {
  12020. var _gl,
  12021. _renderer,
  12022. _depthMaterial, _depthMaterialMorph, _depthMaterialSkin,
  12023. _frustum = new THREE.Frustum(),
  12024. _projScreenMatrix = new THREE.Matrix4(),
  12025. _min = new THREE.Vector3(),
  12026. _max = new THREE.Vector3();
  12027. this.init = function ( renderer ) {
  12028. _gl = renderer.context;
  12029. _renderer = renderer;
  12030. var depthShader = THREE.ShaderLib[ "depthRGBA" ];
  12031. var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
  12032. _depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
  12033. _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } );
  12034. _depthMaterialSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, skinning: true } );
  12035. _depthMaterial._shadowPass = true;
  12036. _depthMaterialMorph._shadowPass = true;
  12037. _depthMaterialSkin._shadowPass = true;
  12038. };
  12039. this.render = function ( scene, camera ) {
  12040. if ( ! ( _renderer.shadowMapEnabled && _renderer.shadowMapAutoUpdate ) ) return;
  12041. this.update( scene, camera );
  12042. };
  12043. this.update = function ( scene, camera ) {
  12044. var i, il, j, jl, n,
  12045. shadowMap, shadowMatrix, shadowCamera,
  12046. program, buffer, material,
  12047. webglObject, object, light,
  12048. renderList,
  12049. lights = [],
  12050. k = 0,
  12051. fog = null;
  12052. // set GL state for depth map
  12053. _gl.clearColor( 1, 1, 1, 1 );
  12054. _gl.disable( _gl.BLEND );
  12055. _gl.enable( _gl.CULL_FACE );
  12056. if ( _renderer.shadowMapCullFrontFaces ) {
  12057. _gl.cullFace( _gl.FRONT );
  12058. } else {
  12059. _gl.cullFace( _gl.BACK );
  12060. }
  12061. _renderer.setDepthTest( true );
  12062. // preprocess lights
  12063. // - skip lights that are not casting shadows
  12064. // - create virtual lights for cascaded shadow maps
  12065. for ( i = 0, il = scene.__lights.length; i < il; i ++ ) {
  12066. light = scene.__lights[ i ];
  12067. if ( ! light.castShadow ) continue;
  12068. if ( ( light instanceof THREE.DirectionalLight ) && light.shadowCascade ) {
  12069. for ( n = 0; n < light.shadowCascadeCount; n ++ ) {
  12070. var virtualLight;
  12071. if ( ! light.shadowCascadeArray[ n ] ) {
  12072. virtualLight = createVirtualLight( light, n );
  12073. virtualLight.originalCamera = camera;
  12074. var gyro = new THREE.Gyroscope();
  12075. gyro.position = light.shadowCascadeOffset;
  12076. gyro.add( virtualLight );
  12077. gyro.add( virtualLight.target );
  12078. camera.add( gyro );
  12079. light.shadowCascadeArray[ n ] = virtualLight;
  12080. console.log( "Created virtualLight", virtualLight );
  12081. } else {
  12082. virtualLight = light.shadowCascadeArray[ n ];
  12083. }
  12084. updateVirtualLight( light, n );
  12085. lights[ k ] = virtualLight;
  12086. k ++;
  12087. }
  12088. } else {
  12089. lights[ k ] = light;
  12090. k ++;
  12091. }
  12092. }
  12093. // render depth map
  12094. for ( i = 0, il = lights.length; i < il; i ++ ) {
  12095. light = lights[ i ];
  12096. if ( ! light.shadowMap ) {
  12097. var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
  12098. light.shadowMap = new THREE.WebGLRenderTarget( light.shadowMapWidth, light.shadowMapHeight, pars );
  12099. light.shadowMapSize = new THREE.Vector2( light.shadowMapWidth, light.shadowMapHeight );
  12100. light.shadowMatrix = new THREE.Matrix4();
  12101. }
  12102. if ( ! light.shadowCamera ) {
  12103. if ( light instanceof THREE.SpotLight ) {
  12104. light.shadowCamera = new THREE.PerspectiveCamera( light.shadowCameraFov, light.shadowMapWidth / light.shadowMapHeight, light.shadowCameraNear, light.shadowCameraFar );
  12105. } else if ( light instanceof THREE.DirectionalLight ) {
  12106. light.shadowCamera = new THREE.OrthographicCamera( light.shadowCameraLeft, light.shadowCameraRight, light.shadowCameraTop, light.shadowCameraBottom, light.shadowCameraNear, light.shadowCameraFar );
  12107. } else {
  12108. console.error( "Unsupported light type for shadow" );
  12109. continue;
  12110. }
  12111. scene.add( light.shadowCamera );
  12112. if ( _renderer.autoUpdateScene ) scene.updateMatrixWorld();
  12113. }
  12114. if ( light.shadowCameraVisible && ! light.cameraHelper ) {
  12115. light.cameraHelper = new THREE.CameraHelper( light.shadowCamera );
  12116. light.shadowCamera.add( light.cameraHelper );
  12117. }
  12118. if ( light.isVirtual && virtualLight.originalCamera == camera ) {
  12119. updateShadowCamera( camera, light );
  12120. }
  12121. shadowMap = light.shadowMap;
  12122. shadowMatrix = light.shadowMatrix;
  12123. shadowCamera = light.shadowCamera;
  12124. shadowCamera.position.copy( light.matrixWorld.getPosition() );
  12125. shadowCamera.lookAt( light.target.matrixWorld.getPosition() );
  12126. shadowCamera.updateMatrixWorld();
  12127. shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
  12128. if ( light.cameraHelper ) light.cameraHelper.lines.visible = light.shadowCameraVisible;
  12129. if ( light.shadowCameraVisible ) light.cameraHelper.update();
  12130. // compute shadow matrix
  12131. shadowMatrix.set( 0.5, 0.0, 0.0, 0.5,
  12132. 0.0, 0.5, 0.0, 0.5,
  12133. 0.0, 0.0, 0.5, 0.5,
  12134. 0.0, 0.0, 0.0, 1.0 );
  12135. shadowMatrix.multiplySelf( shadowCamera.projectionMatrix );
  12136. shadowMatrix.multiplySelf( shadowCamera.matrixWorldInverse );
  12137. // update camera matrices and frustum
  12138. if ( ! shadowCamera._viewMatrixArray ) shadowCamera._viewMatrixArray = new Float32Array( 16 );
  12139. if ( ! shadowCamera._projectionMatrixArray ) shadowCamera._projectionMatrixArray = new Float32Array( 16 );
  12140. shadowCamera.matrixWorldInverse.flattenToArray( shadowCamera._viewMatrixArray );
  12141. shadowCamera.projectionMatrix.flattenToArray( shadowCamera._projectionMatrixArray );
  12142. _projScreenMatrix.multiply( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
  12143. _frustum.setFromMatrix( _projScreenMatrix );
  12144. // render shadow map
  12145. _renderer.setRenderTarget( shadowMap );
  12146. _renderer.clear();
  12147. // set object matrices & frustum culling
  12148. renderList = scene.__webglObjects;
  12149. for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
  12150. webglObject = renderList[ j ];
  12151. object = webglObject.object;
  12152. webglObject.render = false;
  12153. if ( object.visible && object.castShadow ) {
  12154. if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
  12155. object._modelViewMatrix.multiply( shadowCamera.matrixWorldInverse, object.matrixWorld );
  12156. webglObject.render = true;
  12157. }
  12158. }
  12159. }
  12160. // render regular objects
  12161. for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
  12162. webglObject = renderList[ j ];
  12163. if ( webglObject.render ) {
  12164. object = webglObject.object;
  12165. buffer = webglObject.buffer;
  12166. // culling is overriden globally for all objects
  12167. // while rendering depth map
  12168. //_renderer.setObjectFaces( object );
  12169. if ( object.customDepthMaterial ) {
  12170. material = object.customDepthMaterial;
  12171. } else if ( object.geometry.morphTargets.length ) {
  12172. material = _depthMaterialMorph;
  12173. } else if ( object instanceof THREE.SkinnedMesh ) {
  12174. material = _depthMaterialSkin;
  12175. } else {
  12176. material = _depthMaterial;
  12177. }
  12178. if ( buffer instanceof THREE.BufferGeometry ) {
  12179. _renderer.renderBufferDirect( shadowCamera, scene.__lights, fog, material, buffer, object );
  12180. } else {
  12181. _renderer.renderBuffer( shadowCamera, scene.__lights, fog, material, buffer, object );
  12182. }
  12183. }
  12184. }
  12185. // set matrices and render immediate objects
  12186. renderList = scene.__webglObjectsImmediate;
  12187. for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
  12188. webglObject = renderList[ j ];
  12189. object = webglObject.object;
  12190. if ( object.visible && object.castShadow ) {
  12191. object._modelViewMatrix.multiply( shadowCamera.matrixWorldInverse, object.matrixWorld );
  12192. _renderer.renderImmediateObject( shadowCamera, scene.__lights, fog, _depthMaterial, object );
  12193. }
  12194. }
  12195. }
  12196. // restore GL state
  12197. var clearColor = _renderer.getClearColor(),
  12198. clearAlpha = _renderer.getClearAlpha();
  12199. _gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
  12200. _gl.enable( _gl.BLEND );
  12201. if ( _renderer.shadowMapCullFrontFaces ) {
  12202. _gl.cullFace( _gl.BACK );
  12203. }
  12204. };
  12205. function createVirtualLight( light, cascade ) {
  12206. var virtualLight = new THREE.DirectionalLight();
  12207. virtualLight.isVirtual = true;
  12208. virtualLight.onlyShadow = true;
  12209. virtualLight.castShadow = true;
  12210. virtualLight.shadowCameraNear = light.shadowCameraNear;
  12211. virtualLight.shadowCameraFar = light.shadowCameraFar;
  12212. virtualLight.shadowCameraLeft = light.shadowCameraLeft;
  12213. virtualLight.shadowCameraRight = light.shadowCameraRight;
  12214. virtualLight.shadowCameraBottom = light.shadowCameraBottom;
  12215. virtualLight.shadowCameraTop = light.shadowCameraTop;
  12216. virtualLight.shadowCameraVisible = light.shadowCameraVisible;
  12217. virtualLight.shadowDarkness = light.shadowDarkness;
  12218. virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];
  12219. virtualLight.shadowMapWidth = light.shadowCascadeWidth[ cascade ];
  12220. virtualLight.shadowMapHeight = light.shadowCascadeHeight[ cascade ];
  12221. virtualLight.pointsWorld = [];
  12222. virtualLight.pointsFrustum = [];
  12223. var pointsWorld = virtualLight.pointsWorld,
  12224. pointsFrustum = virtualLight.pointsFrustum;
  12225. for ( var i = 0; i < 8; i ++ ) {
  12226. pointsWorld[ i ] = new THREE.Vector3();
  12227. pointsFrustum[ i ] = new THREE.Vector3();
  12228. }
  12229. var nearZ = light.shadowCascadeNearZ[ cascade ];
  12230. var farZ = light.shadowCascadeFarZ[ cascade ];
  12231. pointsFrustum[ 0 ].set( -1, -1, nearZ );
  12232. pointsFrustum[ 1 ].set( 1, -1, nearZ );
  12233. pointsFrustum[ 2 ].set( -1, 1, nearZ );
  12234. pointsFrustum[ 3 ].set( 1, 1, nearZ );
  12235. pointsFrustum[ 4 ].set( -1, -1, farZ );
  12236. pointsFrustum[ 5 ].set( 1, -1, farZ );
  12237. pointsFrustum[ 6 ].set( -1, 1, farZ );
  12238. pointsFrustum[ 7 ].set( 1, 1, farZ );
  12239. return virtualLight;
  12240. }
  12241. // Synchronize virtual light with the original light
  12242. function updateVirtualLight( light, cascade ) {
  12243. var virtualLight = light.shadowCascadeArray[ cascade ];
  12244. virtualLight.position.copy( light.position );
  12245. virtualLight.target.position.copy( light.target.position );
  12246. virtualLight.lookAt( virtualLight.target );
  12247. virtualLight.shadowCameraVisible = light.shadowCameraVisible;
  12248. virtualLight.shadowDarkness = light.shadowDarkness;
  12249. virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];
  12250. var nearZ = light.shadowCascadeNearZ[ cascade ];
  12251. var farZ = light.shadowCascadeFarZ[ cascade ];
  12252. var pointsFrustum = virtualLight.pointsFrustum;
  12253. pointsFrustum[ 0 ].z = nearZ;
  12254. pointsFrustum[ 1 ].z = nearZ;
  12255. pointsFrustum[ 2 ].z = nearZ;
  12256. pointsFrustum[ 3 ].z = nearZ;
  12257. pointsFrustum[ 4 ].z = farZ;
  12258. pointsFrustum[ 5 ].z = farZ;
  12259. pointsFrustum[ 6 ].z = farZ;
  12260. pointsFrustum[ 7 ].z = farZ;
  12261. }
  12262. // Fit shadow camera's ortho frustum to camera frustum
  12263. function updateShadowCamera( camera, light ) {
  12264. var shadowCamera = light.shadowCamera,
  12265. pointsFrustum = light.pointsFrustum,
  12266. pointsWorld = light.pointsWorld;
  12267. _min.set( Infinity, Infinity, Infinity );
  12268. _max.set( -Infinity, -Infinity, -Infinity );
  12269. for ( var i = 0; i < 8; i ++ ) {
  12270. var p = pointsWorld[ i ];
  12271. p.copy( pointsFrustum[ i ] );
  12272. THREE.ShadowMapPlugin.__projector.unprojectVector( p, camera );
  12273. shadowCamera.matrixWorldInverse.multiplyVector3( p );
  12274. if ( p.x < _min.x ) _min.x = p.x;
  12275. if ( p.x > _max.x ) _max.x = p.x;
  12276. if ( p.y < _min.y ) _min.y = p.y;
  12277. if ( p.y > _max.y ) _max.y = p.y;
  12278. if ( p.z < _min.z ) _min.z = p.z;
  12279. if ( p.z > _max.z ) _max.z = p.z;
  12280. }
  12281. shadowCamera.left = _min.x;
  12282. shadowCamera.right = _max.x;
  12283. shadowCamera.top = _max.y;
  12284. shadowCamera.bottom = _min.y;
  12285. // can't really fit near/far
  12286. //shadowCamera.near = _min.z;
  12287. //shadowCamera.far = _max.z;
  12288. shadowCamera.updateProjectionMatrix();
  12289. }
  12290. };
  12291. THREE.ShadowMapPlugin.__projector = new THREE.Projector();
  12292. /**
  12293. * @author mikael emtinger / http://gomo.se/
  12294. * @author alteredq / http://alteredqualia.com/
  12295. */
  12296. THREE.SpritePlugin = function ( ) {
  12297. var _gl, _renderer, _sprite = {};
  12298. this.init = function ( renderer ) {
  12299. _gl = renderer.context;
  12300. _renderer = renderer;
  12301. _sprite.vertices = new Float32Array( 8 + 8 );
  12302. _sprite.faces = new Uint16Array( 6 );
  12303. var i = 0;
  12304. _sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = -1; // vertex 0
  12305. _sprite.vertices[ i++ ] = 0; _sprite.vertices[ i++ ] = 0; // uv 0
  12306. _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = -1; // vertex 1
  12307. _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = 0; // uv 1
  12308. _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = 1; // vertex 2
  12309. _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = 1; // uv 2
  12310. _sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = 1; // vertex 3
  12311. _sprite.vertices[ i++ ] = 0; _sprite.vertices[ i++ ] = 1; // uv 3
  12312. i = 0;
  12313. _sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 1; _sprite.faces[ i++ ] = 2;
  12314. _sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 2; _sprite.faces[ i++ ] = 3;
  12315. _sprite.vertexBuffer = _gl.createBuffer();
  12316. _sprite.elementBuffer = _gl.createBuffer();
  12317. _gl.bindBuffer( _gl.ARRAY_BUFFER, _sprite.vertexBuffer );
  12318. _gl.bufferData( _gl.ARRAY_BUFFER, _sprite.vertices, _gl.STATIC_DRAW );
  12319. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
  12320. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _sprite.faces, _gl.STATIC_DRAW );
  12321. _sprite.program = createProgram( THREE.ShaderSprite[ "sprite" ] );
  12322. _sprite.attributes = {};
  12323. _sprite.uniforms = {};
  12324. _sprite.attributes.position = _gl.getAttribLocation ( _sprite.program, "position" );
  12325. _sprite.attributes.uv = _gl.getAttribLocation ( _sprite.program, "uv" );
  12326. _sprite.uniforms.uvOffset = _gl.getUniformLocation( _sprite.program, "uvOffset" );
  12327. _sprite.uniforms.uvScale = _gl.getUniformLocation( _sprite.program, "uvScale" );
  12328. _sprite.uniforms.rotation = _gl.getUniformLocation( _sprite.program, "rotation" );
  12329. _sprite.uniforms.scale = _gl.getUniformLocation( _sprite.program, "scale" );
  12330. _sprite.uniforms.alignment = _gl.getUniformLocation( _sprite.program, "alignment" );
  12331. _sprite.uniforms.color = _gl.getUniformLocation( _sprite.program, "color" );
  12332. _sprite.uniforms.map = _gl.getUniformLocation( _sprite.program, "map" );
  12333. _sprite.uniforms.opacity = _gl.getUniformLocation( _sprite.program, "opacity" );
  12334. _sprite.uniforms.useScreenCoordinates = _gl.getUniformLocation( _sprite.program, "useScreenCoordinates" );
  12335. _sprite.uniforms.affectedByDistance = _gl.getUniformLocation( _sprite.program, "affectedByDistance" );
  12336. _sprite.uniforms.screenPosition = _gl.getUniformLocation( _sprite.program, "screenPosition" );
  12337. _sprite.uniforms.modelViewMatrix = _gl.getUniformLocation( _sprite.program, "modelViewMatrix" );
  12338. _sprite.uniforms.projectionMatrix = _gl.getUniformLocation( _sprite.program, "projectionMatrix" );
  12339. _sprite.attributesEnabled = false;
  12340. };
  12341. this.render = function ( scene, camera, viewportWidth, viewportHeight ) {
  12342. var sprites = scene.__webglSprites,
  12343. nSprites = sprites.length;
  12344. if ( ! nSprites ) return;
  12345. var attributes = _sprite.attributes,
  12346. uniforms = _sprite.uniforms;
  12347. var invAspect = viewportHeight / viewportWidth;
  12348. var halfViewportWidth = viewportWidth * 0.5,
  12349. halfViewportHeight = viewportHeight * 0.5;
  12350. var mergeWith3D = true;
  12351. // setup gl
  12352. _gl.useProgram( _sprite.program );
  12353. if ( ! _sprite.attributesEnabled ) {
  12354. _gl.enableVertexAttribArray( attributes.position );
  12355. _gl.enableVertexAttribArray( attributes.uv );
  12356. _sprite.attributesEnabled = true;
  12357. }
  12358. _gl.disable( _gl.CULL_FACE );
  12359. _gl.enable( _gl.BLEND );
  12360. _gl.depthMask( true );
  12361. _gl.bindBuffer( _gl.ARRAY_BUFFER, _sprite.vertexBuffer );
  12362. _gl.vertexAttribPointer( attributes.position, 2, _gl.FLOAT, false, 2 * 8, 0 );
  12363. _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );
  12364. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
  12365. _gl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera._projectionMatrixArray );
  12366. _gl.activeTexture( _gl.TEXTURE0 );
  12367. _gl.uniform1i( uniforms.map, 0 );
  12368. // update positions and sort
  12369. var i, sprite, screenPosition, size, scale = [];
  12370. for( i = 0; i < nSprites; i ++ ) {
  12371. sprite = sprites[ i ];
  12372. if ( ! sprite.visible || sprite.opacity === 0 ) continue;
  12373. if( ! sprite.useScreenCoordinates ) {
  12374. sprite._modelViewMatrix.multiply( camera.matrixWorldInverse, sprite.matrixWorld );
  12375. sprite.z = - sprite._modelViewMatrix.elements[14];
  12376. } else {
  12377. sprite.z = - sprite.position.z;
  12378. }
  12379. }
  12380. sprites.sort( painterSort );
  12381. // render all sprites
  12382. for( i = 0; i < nSprites; i ++ ) {
  12383. sprite = sprites[ i ];
  12384. if ( ! sprite.visible || sprite.opacity === 0 ) continue;
  12385. if ( sprite.map && sprite.map.image && sprite.map.image.width ) {
  12386. if ( sprite.useScreenCoordinates ) {
  12387. _gl.uniform1i( uniforms.useScreenCoordinates, 1 );
  12388. _gl.uniform3f( uniforms.screenPosition, ( sprite.position.x - halfViewportWidth ) / halfViewportWidth,
  12389. ( halfViewportHeight - sprite.position.y ) / halfViewportHeight,
  12390. Math.max( 0, Math.min( 1, sprite.position.z ) ) );
  12391. } else {
  12392. _gl.uniform1i( uniforms.useScreenCoordinates, 0 );
  12393. _gl.uniform1i( uniforms.affectedByDistance, sprite.affectedByDistance ? 1 : 0 );
  12394. _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite._modelViewMatrix.elements );
  12395. }
  12396. size = sprite.map.image.width / ( sprite.scaleByViewport ? viewportHeight : 1 );
  12397. scale[ 0 ] = size * invAspect * sprite.scale.x;
  12398. scale[ 1 ] = size * sprite.scale.y;
  12399. _gl.uniform2f( uniforms.uvScale, sprite.uvScale.x, sprite.uvScale.y );
  12400. _gl.uniform2f( uniforms.uvOffset, sprite.uvOffset.x, sprite.uvOffset.y );
  12401. _gl.uniform2f( uniforms.alignment, sprite.alignment.x, sprite.alignment.y );
  12402. _gl.uniform1f( uniforms.opacity, sprite.opacity );
  12403. _gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );
  12404. _gl.uniform1f( uniforms.rotation, sprite.rotation );
  12405. _gl.uniform2fv( uniforms.scale, scale );
  12406. if ( sprite.mergeWith3D && !mergeWith3D ) {
  12407. _gl.enable( _gl.DEPTH_TEST );
  12408. mergeWith3D = true;
  12409. } else if ( ! sprite.mergeWith3D && mergeWith3D ) {
  12410. _gl.disable( _gl.DEPTH_TEST );
  12411. mergeWith3D = false;
  12412. }
  12413. _renderer.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );
  12414. _renderer.setTexture( sprite.map, 0 );
  12415. _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
  12416. }
  12417. }
  12418. // restore gl
  12419. _gl.enable( _gl.CULL_FACE );
  12420. _gl.enable( _gl.DEPTH_TEST );
  12421. _gl.depthMask( true );
  12422. };
  12423. function createProgram ( shader ) {
  12424. var program = _gl.createProgram();
  12425. var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
  12426. var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
  12427. _gl.shaderSource( fragmentShader, shader.fragmentShader );
  12428. _gl.shaderSource( vertexShader, shader.vertexShader );
  12429. _gl.compileShader( fragmentShader );
  12430. _gl.compileShader( vertexShader );
  12431. _gl.attachShader( program, fragmentShader );
  12432. _gl.attachShader( program, vertexShader );
  12433. _gl.linkProgram( program );
  12434. return program;
  12435. };
  12436. function painterSort ( a, b ) {
  12437. return b.z - a.z;
  12438. };
  12439. };/**
  12440. * @author mikael emtinger / http://gomo.se/
  12441. *
  12442. */
  12443. THREE.ShaderFlares = {
  12444. 'lensFlareVertexTexture': {
  12445. vertexShader: [
  12446. "uniform vec3 screenPosition;",
  12447. "uniform vec2 scale;",
  12448. "uniform float rotation;",
  12449. "uniform int renderType;",
  12450. "uniform sampler2D occlusionMap;",
  12451. "attribute vec2 position;",
  12452. "attribute vec2 uv;",
  12453. "varying vec2 vUV;",
  12454. "varying float vVisibility;",
  12455. "void main() {",
  12456. "vUV = uv;",
  12457. "vec2 pos = position;",
  12458. "if( renderType == 2 ) {",
  12459. "vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) ) +",
  12460. "texture2D( occlusionMap, vec2( 0.5, 0.1 ) ) +",
  12461. "texture2D( occlusionMap, vec2( 0.9, 0.1 ) ) +",
  12462. "texture2D( occlusionMap, vec2( 0.9, 0.5 ) ) +",
  12463. "texture2D( occlusionMap, vec2( 0.9, 0.9 ) ) +",
  12464. "texture2D( occlusionMap, vec2( 0.5, 0.9 ) ) +",
  12465. "texture2D( occlusionMap, vec2( 0.1, 0.9 ) ) +",
  12466. "texture2D( occlusionMap, vec2( 0.1, 0.5 ) ) +",
  12467. "texture2D( occlusionMap, vec2( 0.5, 0.5 ) );",
  12468. "vVisibility = ( visibility.r / 9.0 ) *",
  12469. "( 1.0 - visibility.g / 9.0 ) *",
  12470. "( visibility.b / 9.0 ) *",
  12471. "( 1.0 - visibility.a / 9.0 );",
  12472. "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
  12473. "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
  12474. "}",
  12475. "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
  12476. "}"
  12477. ].join( "\n" ),
  12478. fragmentShader: [
  12479. "precision mediump float;",
  12480. "uniform sampler2D map;",
  12481. "uniform float opacity;",
  12482. "uniform int renderType;",
  12483. "uniform vec3 color;",
  12484. "varying vec2 vUV;",
  12485. "varying float vVisibility;",
  12486. "void main() {",
  12487. // pink square
  12488. "if( renderType == 0 ) {",
  12489. "gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );",
  12490. // restore
  12491. "} else if( renderType == 1 ) {",
  12492. "gl_FragColor = texture2D( map, vUV );",
  12493. // flare
  12494. "} else {",
  12495. "vec4 texture = texture2D( map, vUV );",
  12496. "texture.a *= opacity * vVisibility;",
  12497. "gl_FragColor = texture;",
  12498. "gl_FragColor.rgb *= color;",
  12499. "}",
  12500. "}"
  12501. ].join( "\n" )
  12502. },
  12503. 'lensFlare': {
  12504. vertexShader: [
  12505. "uniform vec3 screenPosition;",
  12506. "uniform vec2 scale;",
  12507. "uniform float rotation;",
  12508. "uniform int renderType;",
  12509. "attribute vec2 position;",
  12510. "attribute vec2 uv;",
  12511. "varying vec2 vUV;",
  12512. "void main() {",
  12513. "vUV = uv;",
  12514. "vec2 pos = position;",
  12515. "if( renderType == 2 ) {",
  12516. "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
  12517. "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
  12518. "}",
  12519. "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
  12520. "}"
  12521. ].join( "\n" ),
  12522. fragmentShader: [
  12523. "precision mediump float;",
  12524. "uniform sampler2D map;",
  12525. "uniform sampler2D occlusionMap;",
  12526. "uniform float opacity;",
  12527. "uniform int renderType;",
  12528. "uniform vec3 color;",
  12529. "varying vec2 vUV;",
  12530. "void main() {",
  12531. // pink square
  12532. "if( renderType == 0 ) {",
  12533. "gl_FragColor = vec4( texture2D( map, vUV ).rgb, 0.0 );",
  12534. // restore
  12535. "} else if( renderType == 1 ) {",
  12536. "gl_FragColor = texture2D( map, vUV );",
  12537. // flare
  12538. "} else {",
  12539. "float visibility = texture2D( occlusionMap, vec2( 0.5, 0.1 ) ).a +",
  12540. "texture2D( occlusionMap, vec2( 0.9, 0.5 ) ).a +",
  12541. "texture2D( occlusionMap, vec2( 0.5, 0.9 ) ).a +",
  12542. "texture2D( occlusionMap, vec2( 0.1, 0.5 ) ).a;",
  12543. "visibility = ( 1.0 - visibility / 4.0 );",
  12544. "vec4 texture = texture2D( map, vUV );",
  12545. "texture.a *= opacity * visibility;",
  12546. "gl_FragColor = texture;",
  12547. "gl_FragColor.rgb *= color;",
  12548. "}",
  12549. "}"
  12550. ].join( "\n" )
  12551. }
  12552. };
  12553. /**
  12554. * @author mikael emtinger / http://gomo.se/
  12555. *
  12556. */
  12557. THREE.ShaderSprite = {
  12558. 'sprite': {
  12559. vertexShader: [
  12560. "uniform int useScreenCoordinates;",
  12561. "uniform int affectedByDistance;",
  12562. "uniform vec3 screenPosition;",
  12563. "uniform mat4 modelViewMatrix;",
  12564. "uniform mat4 projectionMatrix;",
  12565. "uniform float rotation;",
  12566. "uniform vec2 scale;",
  12567. "uniform vec2 alignment;",
  12568. "uniform vec2 uvOffset;",
  12569. "uniform vec2 uvScale;",
  12570. "attribute vec2 position;",
  12571. "attribute vec2 uv;",
  12572. "varying vec2 vUV;",
  12573. "void main() {",
  12574. "vUV = uvOffset + uv * uvScale;",
  12575. "vec2 alignedPosition = position + alignment;",
  12576. "vec2 rotatedPosition;",
  12577. "rotatedPosition.x = ( cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y ) * scale.x;",
  12578. "rotatedPosition.y = ( sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y ) * scale.y;",
  12579. "vec4 finalPosition;",
  12580. "if( useScreenCoordinates != 0 ) {",
  12581. "finalPosition = vec4( screenPosition.xy + rotatedPosition, screenPosition.z, 1.0 );",
  12582. "} else {",
  12583. "finalPosition = projectionMatrix * modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );",
  12584. "finalPosition.xy += rotatedPosition * ( affectedByDistance == 1 ? 1.0 : finalPosition.z );",
  12585. "}",
  12586. "gl_Position = finalPosition;",
  12587. "}"
  12588. ].join( "\n" ),
  12589. fragmentShader: [
  12590. "precision mediump float;",
  12591. "uniform vec3 color;",
  12592. "uniform sampler2D map;",
  12593. "uniform float opacity;",
  12594. "varying vec2 vUV;",
  12595. "void main() {",
  12596. "vec4 texture = texture2D( map, vUV );",
  12597. "gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );",
  12598. "}"
  12599. ].join( "\n" )
  12600. }
  12601. };