ThreeWebGL.js 115 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046
  1. // ThreeWebGL.js r32 - http://github.com/mrdoob/three.js
  2. /**
  3. * @author mr.doob / http://mrdoob.com/
  4. */
  5. var THREE = THREE || {};
  6. /**
  7. * @author mr.doob / http://mrdoob.com/
  8. */
  9. THREE.Color = function ( hex ) {
  10. this.autoUpdate = true;
  11. this.setHex( hex );
  12. };
  13. THREE.Color.prototype = {
  14. setRGB: function ( r, g, b ) {
  15. this.r = r;
  16. this.g = g;
  17. this.b = b;
  18. if ( this.autoUpdate ) {
  19. this.updateHex();
  20. this.updateStyleString();
  21. }
  22. },
  23. setHex: function ( hex ) {
  24. this.hex = ( ~~ hex ) & 0xffffff;
  25. if ( this.autoUpdate ) {
  26. this.updateRGBA();
  27. this.updateStyleString();
  28. }
  29. },
  30. updateHex: function () {
  31. this.hex = ~~( this.r * 255 ) << 16 ^ ~~( this.g * 255 ) << 8 ^ ~~( this.b * 255 );
  32. },
  33. updateRGBA: function () {
  34. this.r = ( this.hex >> 16 & 255 ) / 255;
  35. this.g = ( this.hex >> 8 & 255 ) / 255;
  36. this.b = ( this.hex & 255 ) / 255;
  37. },
  38. updateStyleString: function () {
  39. this.__styleString = 'rgb(' + ~~( this.r * 255 ) + ',' + ~~( this.g * 255 ) + ',' + ~~( this.b * 255 ) + ')';
  40. },
  41. clone: function () {
  42. return new THREE.Color( this.hex );
  43. },
  44. toString: function () {
  45. return 'THREE.Color ( r: ' + this.r + ', g: ' + this.g + ', b: ' + this.b + ', hex: ' + this.hex + ' )';
  46. }
  47. };
  48. /**
  49. * @author mr.doob / http://mrdoob.com/
  50. * @author philogb / http://blog.thejit.org/
  51. */
  52. THREE.Vector2 = function ( x, y ) {
  53. this.x = x || 0;
  54. this.y = y || 0;
  55. };
  56. THREE.Vector2.prototype = {
  57. set: function ( x, y ) {
  58. this.x = x;
  59. this.y = y;
  60. return this;
  61. },
  62. copy: function ( v ) {
  63. this.x = v.x;
  64. this.y = v.y;
  65. return this;
  66. },
  67. addSelf: function ( v ) {
  68. this.x += v.x;
  69. this.y += v.y;
  70. return this;
  71. },
  72. add: function ( v1, v2 ) {
  73. this.x = v1.x + v2.x;
  74. this.y = v1.y + v2.y;
  75. return this;
  76. },
  77. subSelf: function ( v ) {
  78. this.x -= v.x;
  79. this.y -= v.y;
  80. return this;
  81. },
  82. sub: function ( v1, v2 ) {
  83. this.x = v1.x - v2.x;
  84. this.y = v1.y - v2.y;
  85. return this;
  86. },
  87. multiplyScalar: function ( s ) {
  88. this.x *= s;
  89. this.y *= s;
  90. return this;
  91. },
  92. unit: function () {
  93. this.multiplyScalar( 1 / this.length() );
  94. return this;
  95. },
  96. length: function () {
  97. return Math.sqrt( this.x * this.x + this.y * this.y );
  98. },
  99. lengthSq: function () {
  100. return this.x * this.x + this.y * this.y;
  101. },
  102. negate: function() {
  103. this.x = - this.x;
  104. this.y = - this.y;
  105. return this;
  106. },
  107. clone: function () {
  108. return new THREE.Vector2( this.x, this.y );
  109. },
  110. toString: function () {
  111. return 'THREE.Vector2 (' + this.x + ', ' + this.y + ')';
  112. }
  113. };
  114. /**
  115. * @author mr.doob / http://mrdoob.com/
  116. * @author kile / http://kile.stravaganza.org/
  117. * @author philogb / http://blog.thejit.org/
  118. */
  119. THREE.Vector3 = function ( x, y, z ) {
  120. this.x = x || 0;
  121. this.y = y || 0;
  122. this.z = z || 0;
  123. };
  124. THREE.Vector3.prototype = {
  125. set: function ( x, y, z ) {
  126. this.x = x;
  127. this.y = y;
  128. this.z = z;
  129. return this;
  130. },
  131. copy: function ( v ) {
  132. this.x = v.x;
  133. this.y = v.y;
  134. this.z = v.z;
  135. return this;
  136. },
  137. add: function ( a, b ) {
  138. this.x = a.x + b.x;
  139. this.y = a.y + b.y;
  140. this.z = a.z + b.z;
  141. return this;
  142. },
  143. addSelf: function ( v ) {
  144. this.x += v.x;
  145. this.y += v.y;
  146. this.z += v.z;
  147. return this;
  148. },
  149. addScalar: function ( s ) {
  150. this.x += s;
  151. this.y += s;
  152. this.z += s;
  153. return this;
  154. },
  155. sub: function( a, b ) {
  156. this.x = a.x - b.x;
  157. this.y = a.y - b.y;
  158. this.z = a.z - b.z;
  159. return this;
  160. },
  161. subSelf: function ( v ) {
  162. this.x -= v.x;
  163. this.y -= v.y;
  164. this.z -= v.z;
  165. return this;
  166. },
  167. cross: function ( a, b ) {
  168. this.x = a.y * b.z - a.z * b.y;
  169. this.y = a.z * b.x - a.x * b.z;
  170. this.z = a.x * b.y - a.y * b.x;
  171. return this;
  172. },
  173. crossSelf: function ( v ) {
  174. var tx = this.x, ty = this.y, tz = this.z;
  175. this.x = ty * v.z - tz * v.y;
  176. this.y = tz * v.x - tx * v.z;
  177. this.z = tx * v.y - ty * v.x;
  178. return this;
  179. },
  180. multiply: function ( a, b ) {
  181. this.x = a.x * b.x;
  182. this.y = a.y * b.y;
  183. this.z = a.z * b.z;
  184. return this;
  185. },
  186. multiplySelf: function ( v ) {
  187. this.x *= v.x;
  188. this.y *= v.y;
  189. this.z *= v.z;
  190. return this;
  191. },
  192. multiplyScalar: function ( s ) {
  193. this.x *= s;
  194. this.y *= s;
  195. this.z *= s;
  196. return this;
  197. },
  198. divideSelf: function ( v ) {
  199. this.x /= v.x;
  200. this.y /= v.y;
  201. this.z /= v.z;
  202. return this;
  203. },
  204. divideScalar: function ( s ) {
  205. this.x /= s;
  206. this.y /= s;
  207. this.z /= s;
  208. return this;
  209. },
  210. dot: function ( v ) {
  211. return this.x * v.x + this.y * v.y + this.z * v.z;
  212. },
  213. distanceTo: function ( v ) {
  214. var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
  215. return Math.sqrt( dx * dx + dy * dy + dz * dz );
  216. },
  217. distanceToSquared: function ( v ) {
  218. var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
  219. return dx * dx + dy * dy + dz * dz;
  220. },
  221. length: function () {
  222. return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
  223. },
  224. lengthSq: function () {
  225. return this.x * this.x + this.y * this.y + this.z * this.z;
  226. },
  227. negate: function () {
  228. this.x = - this.x;
  229. this.y = - this.y;
  230. this.z = - this.z;
  231. return this;
  232. },
  233. normalize: function () {
  234. var length = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
  235. length > 0 ? this.multiplyScalar( 1 / length ) : this.set( 0, 0, 0 );
  236. return this;
  237. },
  238. setLength: function( len ) {
  239. return this.normalize().multiplyScalar( len );
  240. },
  241. isZero: function () {
  242. var almostZero = 0.0001;
  243. return ( Math.abs( this.x ) < almostZero ) && ( Math.abs( this.y ) < almostZero ) && ( Math.abs( this.z ) < almostZero );
  244. },
  245. clone: function () {
  246. return new THREE.Vector3( this.x, this.y, this.z );
  247. },
  248. toString: function () {
  249. return 'THREE.Vector3 ( ' + this.x + ', ' + this.y + ', ' + this.z + ' )';
  250. }
  251. };
  252. /**
  253. * @author supereggbert / http://www.paulbrunt.co.uk/
  254. * @author philogb / http://blog.thejit.org/
  255. */
  256. THREE.Vector4 = function ( x, y, z, w ) {
  257. this.x = x || 0;
  258. this.y = y || 0;
  259. this.z = z || 0;
  260. this.w = w || 1;
  261. };
  262. THREE.Vector4.prototype = {
  263. set: function ( x, y, z, w ) {
  264. this.x = x;
  265. this.y = y;
  266. this.z = z;
  267. this.w = w;
  268. return this;
  269. },
  270. copy: function ( v ) {
  271. this.x = v.x;
  272. this.y = v.y;
  273. this.z = v.z;
  274. this.w = v.w || 1.0;
  275. return this;
  276. },
  277. add: function ( v1, v2 ) {
  278. this.x = v1.x + v2.x;
  279. this.y = v1.y + v2.y;
  280. this.z = v1.z + v2.z;
  281. this.w = v1.w + v2.w;
  282. return this;
  283. },
  284. addSelf: function ( v ) {
  285. this.x += v.x;
  286. this.y += v.y;
  287. this.z += v.z;
  288. this.w += v.w;
  289. return this;
  290. },
  291. sub: function ( v1, v2 ) {
  292. this.x = v1.x - v2.x;
  293. this.y = v1.y - v2.y;
  294. this.z = v1.z - v2.z;
  295. this.w = v1.w - v2.w;
  296. return this;
  297. },
  298. subSelf: function ( v ) {
  299. this.x -= v.x;
  300. this.y -= v.y;
  301. this.z -= v.z;
  302. this.w -= v.w;
  303. return this;
  304. },
  305. multiplyScalar: function ( s ) {
  306. this.x *= s;
  307. this.y *= s;
  308. this.z *= s;
  309. this.w *= s;
  310. return this;
  311. },
  312. divideScalar: function ( s ) {
  313. this.x /= s;
  314. this.y /= s;
  315. this.z /= s;
  316. this.w /= s;
  317. return this;
  318. },
  319. lerpSelf: function ( v, alpha ) {
  320. this.x = this.x + (v.x - this.x) * alpha;
  321. this.y = this.y + (v.y - this.y) * alpha;
  322. this.z = this.z + (v.z - this.z) * alpha;
  323. this.w = this.w + (v.w - this.w) * alpha;
  324. },
  325. clone: function () {
  326. return new THREE.Vector4( this.x, this.y, this.z, this.w );
  327. },
  328. toString: function () {
  329. return 'THREE.Vector4 (' + this.x + ', ' + this.y + ', ' + this.z + ', ' + this.w + ')';
  330. }
  331. };
  332. /**
  333. * @author mr.doob / http://mrdoob.com/
  334. */
  335. THREE.Ray = function ( origin, direction ) {
  336. this.origin = origin || new THREE.Vector3();
  337. this.direction = direction || new THREE.Vector3();
  338. }
  339. THREE.Ray.prototype = {
  340. intersectScene: function ( scene ) {
  341. var i, l, object,
  342. objects = scene.objects,
  343. intersects = [];
  344. for ( i = 0, l = objects.length; i < l; i++ ) {
  345. object = objects[i];
  346. if ( object instanceof THREE.Mesh ) {
  347. intersects = intersects.concat( this.intersectObject( object ) );
  348. }
  349. }
  350. intersects.sort( function ( a, b ) { return a.distance - b.distance; } );
  351. return intersects;
  352. },
  353. intersectObject: function ( object ) {
  354. var f, fl, face, a, b, c, d, normal,
  355. dot, scalar,
  356. origin, direction,
  357. geometry = object.geometry,
  358. vertices = geometry.vertices,
  359. intersect, intersects = [],
  360. intersectPoint;
  361. for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
  362. face = geometry.faces[ f ];
  363. origin = this.origin.clone();
  364. direction = this.direction.clone();
  365. a = object.matrix.multiplyVector3( vertices[ face.a ].position.clone() );
  366. b = object.matrix.multiplyVector3( vertices[ face.b ].position.clone() );
  367. c = object.matrix.multiplyVector3( vertices[ face.c ].position.clone() );
  368. d = face instanceof THREE.Face4 ? object.matrix.multiplyVector3( vertices[ face.d ].position.clone() ) : null;
  369. normal = object.rotationMatrix.multiplyVector3( face.normal.clone() );
  370. dot = direction.dot( normal );
  371. if ( dot < 0 ) { // Math.abs( dot ) > 0.0001
  372. scalar = normal.dot( new THREE.Vector3().sub( a, origin ) ) / dot;
  373. intersectPoint = origin.addSelf( direction.multiplyScalar( scalar ) );
  374. if ( face instanceof THREE.Face3 ) {
  375. if ( pointInFace3( intersectPoint, a, b, c ) ) {
  376. intersect = {
  377. distance: this.origin.distanceTo( intersectPoint ),
  378. point: intersectPoint,
  379. face: face,
  380. object: object
  381. };
  382. intersects.push( intersect );
  383. }
  384. } else if ( face instanceof THREE.Face4 ) {
  385. if ( pointInFace3( intersectPoint, a, b, d ) || pointInFace3( intersectPoint, b, c, d ) ) {
  386. intersect = {
  387. distance: this.origin.distanceTo( intersectPoint ),
  388. point: intersectPoint,
  389. face: face,
  390. object: object
  391. };
  392. intersects.push( intersect );
  393. }
  394. }
  395. }
  396. }
  397. return intersects;
  398. // http://www.blackpawn.com/texts/pointinpoly/default.html
  399. function pointInFace3( p, a, b, c ) {
  400. var v0 = c.clone().subSelf( a ), v1 = b.clone().subSelf( a ), v2 = p.clone().subSelf( a ),
  401. dot00 = v0.dot( v0 ), dot01 = v0.dot( v1 ), dot02 = v0.dot( v2 ), dot11 = v1.dot( v1 ), dot12 = v1.dot( v2 ),
  402. invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 ),
  403. u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom,
  404. v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
  405. return ( u > 0 ) && ( v > 0 ) && ( u + v < 1 );
  406. }
  407. }
  408. };
  409. /**
  410. * @author mr.doob / http://mrdoob.com/
  411. */
  412. THREE.Rectangle = function () {
  413. var _left, _top, _right, _bottom,
  414. _width, _height, _isEmpty = true;
  415. function resize() {
  416. _width = _right - _left;
  417. _height = _bottom - _top;
  418. }
  419. this.getX = function () {
  420. return _left;
  421. };
  422. this.getY = function () {
  423. return _top;
  424. };
  425. this.getWidth = function () {
  426. return _width;
  427. };
  428. this.getHeight = function () {
  429. return _height;
  430. };
  431. this.getLeft = function() {
  432. return _left;
  433. };
  434. this.getTop = function() {
  435. return _top;
  436. };
  437. this.getRight = function() {
  438. return _right;
  439. };
  440. this.getBottom = function() {
  441. return _bottom;
  442. };
  443. this.set = function ( left, top, right, bottom ) {
  444. _isEmpty = false;
  445. _left = left; _top = top;
  446. _right = right; _bottom = bottom;
  447. resize();
  448. };
  449. this.addPoint = function ( x, y ) {
  450. if ( _isEmpty ) {
  451. _isEmpty = false;
  452. _left = x; _top = y;
  453. _right = x; _bottom = y;
  454. resize();
  455. } else {
  456. _left = _left < x ? _left : x; // Math.min( _left, x );
  457. _top = _top < y ? _top : y; // Math.min( _top, y );
  458. _right = _right > x ? _right : x; // Math.max( _right, x );
  459. _bottom = _bottom > y ? _bottom : y; // Math.max( _bottom, y );
  460. resize();
  461. }
  462. };
  463. this.add3Points = function ( x1, y1, x2, y2, x3, y3 ) {
  464. if (_isEmpty) {
  465. _isEmpty = false;
  466. _left = x1 < x2 ? ( x1 < x3 ? x1 : x3 ) : ( x2 < x3 ? x2 : x3 );
  467. _top = y1 < y2 ? ( y1 < y3 ? y1 : y3 ) : ( y2 < y3 ? y2 : y3 );
  468. _right = x1 > x2 ? ( x1 > x3 ? x1 : x3 ) : ( x2 > x3 ? x2 : x3 );
  469. _bottom = y1 > y2 ? ( y1 > y3 ? y1 : y3 ) : ( y2 > y3 ? y2 : y3 );
  470. resize();
  471. } else {
  472. _left = x1 < x2 ? ( x1 < x3 ? ( x1 < _left ? x1 : _left ) : ( x3 < _left ? x3 : _left ) ) : ( x2 < x3 ? ( x2 < _left ? x2 : _left ) : ( x3 < _left ? x3 : _left ) );
  473. _top = y1 < y2 ? ( y1 < y3 ? ( y1 < _top ? y1 : _top ) : ( y3 < _top ? y3 : _top ) ) : ( y2 < y3 ? ( y2 < _top ? y2 : _top ) : ( y3 < _top ? y3 : _top ) );
  474. _right = x1 > x2 ? ( x1 > x3 ? ( x1 > _right ? x1 : _right ) : ( x3 > _right ? x3 : _right ) ) : ( x2 > x3 ? ( x2 > _right ? x2 : _right ) : ( x3 > _right ? x3 : _right ) );
  475. _bottom = y1 > y2 ? ( y1 > y3 ? ( y1 > _bottom ? y1 : _bottom ) : ( y3 > _bottom ? y3 : _bottom ) ) : ( y2 > y3 ? ( y2 > _bottom ? y2 : _bottom ) : ( y3 > _bottom ? y3 : _bottom ) );
  476. resize();
  477. };
  478. };
  479. this.addRectangle = function ( r ) {
  480. if ( _isEmpty ) {
  481. _isEmpty = false;
  482. _left = r.getLeft(); _top = r.getTop();
  483. _right = r.getRight(); _bottom = r.getBottom();
  484. resize();
  485. } else {
  486. _left = _left < r.getLeft() ? _left : r.getLeft(); // Math.min(_left, r.getLeft() );
  487. _top = _top < r.getTop() ? _top : r.getTop(); // Math.min(_top, r.getTop() );
  488. _right = _right > r.getRight() ? _right : r.getRight(); // Math.max(_right, r.getRight() );
  489. _bottom = _bottom > r.getBottom() ? _bottom : r.getBottom(); // Math.max(_bottom, r.getBottom() );
  490. resize();
  491. }
  492. };
  493. this.inflate = function ( v ) {
  494. _left -= v; _top -= v;
  495. _right += v; _bottom += v;
  496. resize();
  497. };
  498. this.minSelf = function ( r ) {
  499. _left = _left > r.getLeft() ? _left : r.getLeft(); // Math.max( _left, r.getLeft() );
  500. _top = _top > r.getTop() ? _top : r.getTop(); // Math.max( _top, r.getTop() );
  501. _right = _right < r.getRight() ? _right : r.getRight(); // Math.min( _right, r.getRight() );
  502. _bottom = _bottom < r.getBottom() ? _bottom : r.getBottom(); // Math.min( _bottom, r.getBottom() );
  503. resize();
  504. };
  505. /*
  506. this.contains = function ( x, y ) {
  507. return x > _left && x < _right && y > _top && y < _bottom;
  508. };
  509. */
  510. this.instersects = function ( r ) {
  511. // return this.contains( r.getLeft(), r.getTop() ) || this.contains( r.getRight(), r.getTop() ) || this.contains( r.getLeft(), r.getBottom() ) || this.contains( r.getRight(), r.getBottom() );
  512. return Math.min( _right, r.getRight() ) - Math.max( _left, r.getLeft() ) >= 0 &&
  513. Math.min( _bottom, r.getBottom() ) - Math.max( _top, r.getTop() ) >= 0;
  514. };
  515. this.empty = function () {
  516. _isEmpty = true;
  517. _left = 0; _top = 0;
  518. _right = 0; _bottom = 0;
  519. resize();
  520. };
  521. this.isEmpty = function () {
  522. return _isEmpty;
  523. };
  524. this.toString = function () {
  525. return "THREE.Rectangle ( left: " + _left + ", right: " + _right + ", top: " + _top + ", bottom: " + _bottom + ", width: " + _width + ", height: " + _height + " )";
  526. };
  527. };
  528. THREE.Matrix3 = function () {
  529. this.m = [];
  530. };
  531. THREE.Matrix3.prototype = {
  532. transpose: function () {
  533. var tmp;
  534. tmp = this.m[1]; this.m[1] = this.m[3]; this.m[3] = tmp;
  535. tmp = this.m[2]; this.m[2] = this.m[6]; this.m[6] = tmp;
  536. tmp = this.m[5]; this.m[5] = this.m[7]; this.m[7] = tmp;
  537. return this;
  538. }
  539. };
  540. /**
  541. * @author mr.doob / http://mrdoob.com/
  542. * @author supereggbert / http://www.paulbrunt.co.uk/
  543. * @author philogb / http://blog.thejit.org/
  544. * @author jordi_ros / http://plattsoft.com
  545. * @author D1plo1d / http://github.com/D1plo1d
  546. */
  547. THREE.Matrix4 = function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
  548. this.n11 = n11 || 1; this.n12 = n12 || 0; this.n13 = n13 || 0; this.n14 = n14 || 0;
  549. this.n21 = n21 || 0; this.n22 = n22 || 1; this.n23 = n23 || 0; this.n24 = n24 || 0;
  550. this.n31 = n31 || 0; this.n32 = n32 || 0; this.n33 = n33 || 1; this.n34 = n34 || 0;
  551. this.n41 = n41 || 0; this.n42 = n42 || 0; this.n43 = n43 || 0; this.n44 = n44 || 1;
  552. };
  553. THREE.Matrix4.prototype = {
  554. identity: function () {
  555. this.n11 = 1; this.n12 = 0; this.n13 = 0; this.n14 = 0;
  556. this.n21 = 0; this.n22 = 1; this.n23 = 0; this.n24 = 0;
  557. this.n31 = 0; this.n32 = 0; this.n33 = 1; this.n34 = 0;
  558. this.n41 = 0; this.n42 = 0; this.n43 = 0; this.n44 = 1;
  559. return this;
  560. },
  561. set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
  562. this.n11 = n11; this.n12 = n12; this.n13 = n13; this.n14 = n14;
  563. this.n21 = n21; this.n22 = n22; this.n23 = n23; this.n24 = n24;
  564. this.n31 = n31; this.n32 = n32; this.n33 = n33; this.n34 = n34;
  565. this.n41 = n41; this.n42 = n42; this.n43 = n43; this.n44 = n44;
  566. return this;
  567. },
  568. copy: function ( m ) {
  569. this.n11 = m.n11; this.n12 = m.n12; this.n13 = m.n13; this.n14 = m.n14;
  570. this.n21 = m.n21; this.n22 = m.n22; this.n23 = m.n23; this.n24 = m.n24;
  571. this.n31 = m.n31; this.n32 = m.n32; this.n33 = m.n33; this.n34 = m.n34;
  572. this.n41 = m.n41; this.n42 = m.n42; this.n43 = m.n43; this.n44 = m.n44;
  573. return this;
  574. },
  575. lookAt: function ( eye, center, up ) {
  576. var x = new THREE.Vector3(), y = new THREE.Vector3(), z = new THREE.Vector3();
  577. z.sub( eye, center ).normalize();
  578. x.cross( up, z ).normalize();
  579. y.cross( z, x ).normalize();
  580. this.n11 = x.x; this.n12 = x.y; this.n13 = x.z; this.n14 = - x.dot( eye );
  581. this.n21 = y.x; this.n22 = y.y; this.n23 = y.z; this.n24 = - y.dot( eye );
  582. this.n31 = z.x; this.n32 = z.y; this.n33 = z.z; this.n34 = - z.dot( eye );
  583. this.n41 = 0; this.n42 = 0; this.n43 = 0; this.n44 = 1;
  584. return this;
  585. },
  586. multiplyVector3: function ( v ) {
  587. var vx = v.x, vy = v.y, vz = v.z,
  588. d = 1 / ( this.n41 * vx + this.n42 * vy + this.n43 * vz + this.n44 );
  589. v.x = ( this.n11 * vx + this.n12 * vy + this.n13 * vz + this.n14 ) * d;
  590. v.y = ( this.n21 * vx + this.n22 * vy + this.n23 * vz + this.n24 ) * d;
  591. v.z = ( this.n31 * vx + this.n32 * vy + this.n33 * vz + this.n34 ) * d;
  592. return v;
  593. },
  594. multiplyVector4: function ( v ) {
  595. var vx = v.x, vy = v.y, vz = v.z, vw = v.w;
  596. v.x = this.n11 * vx + this.n12 * vy + this.n13 * vz + this.n14 * vw;
  597. v.y = this.n21 * vx + this.n22 * vy + this.n23 * vz + this.n24 * vw;
  598. v.z = this.n31 * vx + this.n32 * vy + this.n33 * vz + this.n34 * vw;
  599. v.w = this.n41 * vx + this.n42 * vy + this.n43 * vz + this.n44 * vw;
  600. return v;
  601. },
  602. crossVector: function ( a ) {
  603. var v = new THREE.Vector4();
  604. v.x = this.n11 * a.x + this.n12 * a.y + this.n13 * a.z + this.n14 * a.w;
  605. v.y = this.n21 * a.x + this.n22 * a.y + this.n23 * a.z + this.n24 * a.w;
  606. v.z = this.n31 * a.x + this.n32 * a.y + this.n33 * a.z + this.n34 * a.w;
  607. v.w = ( a.w ) ? this.n41 * a.x + this.n42 * a.y + this.n43 * a.z + this.n44 * a.w : 1;
  608. return v;
  609. },
  610. multiply: function ( a, b ) {
  611. var a11 = a.n11, a12 = a.n12, a13 = a.n13, a14 = a.n14,
  612. a21 = a.n21, a22 = a.n22, a23 = a.n23, a24 = a.n24,
  613. a31 = a.n31, a32 = a.n32, a33 = a.n33, a34 = a.n34,
  614. a41 = a.n41, a42 = a.n42, a43 = a.n43, a44 = a.n44,
  615. b11 = b.n11, b12 = b.n12, b13 = b.n13, b14 = b.n14,
  616. b21 = b.n21, b22 = b.n22, b23 = b.n23, b24 = b.n24,
  617. b31 = b.n31, b32 = b.n32, b33 = b.n33, b34 = b.n34,
  618. b41 = b.n41, b42 = b.n42, b43 = b.n43, b44 = b.n44;
  619. this.n11 = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
  620. this.n12 = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
  621. this.n13 = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
  622. this.n14 = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
  623. this.n21 = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
  624. this.n22 = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
  625. this.n23 = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
  626. this.n24 = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
  627. this.n31 = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
  628. this.n32 = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
  629. this.n33 = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
  630. this.n34 = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
  631. this.n41 = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
  632. this.n42 = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
  633. this.n43 = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
  634. this.n44 = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
  635. return this;
  636. },
  637. multiplySelf: function ( m ) {
  638. var n11 = this.n11, n12 = this.n12, n13 = this.n13, n14 = this.n14,
  639. n21 = this.n21, n22 = this.n22, n23 = this.n23, n24 = this.n24,
  640. n31 = this.n31, n32 = this.n32, n33 = this.n33, n34 = this.n34,
  641. n41 = this.n41, n42 = this.n42, n43 = this.n43, n44 = this.n44,
  642. mn11 = m.n11, mn21 = m.n21, mn31 = m.n31, mn41 = m.n41,
  643. mn12 = m.n12, mn22 = m.n22, mn32 = m.n32, mn42 = m.n42,
  644. mn13 = m.n13, mn23 = m.n23, mn33 = m.n33, mn43 = m.n43,
  645. mn14 = m.n14, mn24 = m.n24, mn34 = m.n34, mn44 = m.n44;
  646. this.n11 = n11 * mn11 + n12 * mn21 + n13 * mn31 + n14 * mn41;
  647. this.n12 = n11 * mn12 + n12 * mn22 + n13 * mn32 + n14 * mn42;
  648. this.n13 = n11 * mn13 + n12 * mn23 + n13 * mn33 + n14 * mn43;
  649. this.n14 = n11 * mn14 + n12 * mn24 + n13 * mn34 + n14 * mn44;
  650. this.n21 = n21 * mn11 + n22 * mn21 + n23 * mn31 + n24 * mn41;
  651. this.n22 = n21 * mn12 + n22 * mn22 + n23 * mn32 + n24 * mn42;
  652. this.n23 = n21 * mn13 + n22 * mn23 + n23 * mn33 + n24 * mn43;
  653. this.n24 = n21 * mn14 + n22 * mn24 + n23 * mn34 + n24 * mn44;
  654. this.n31 = n31 * mn11 + n32 * mn21 + n33 * mn31 + n34 * mn41;
  655. this.n32 = n31 * mn12 + n32 * mn22 + n33 * mn32 + n34 * mn42;
  656. this.n33 = n31 * mn13 + n32 * mn23 + n33 * mn33 + n34 * mn43;
  657. this.n34 = n31 * mn14 + n32 * mn24 + n33 * mn34 + n34 * mn44;
  658. this.n41 = n41 * mn11 + n42 * mn21 + n43 * mn31 + n44 * mn41;
  659. this.n42 = n41 * mn12 + n42 * mn22 + n43 * mn32 + n44 * mn42;
  660. this.n43 = n41 * mn13 + n42 * mn23 + n43 * mn33 + n44 * mn43;
  661. this.n44 = n41 * mn14 + n42 * mn24 + n43 * mn34 + n44 * mn44;
  662. return this;
  663. },
  664. multiplyScalar: function ( s ) {
  665. this.n11 *= s; this.n12 *= s; this.n13 *= s; this.n14 *= s;
  666. this.n21 *= s; this.n22 *= s; this.n23 *= s; this.n24 *= s;
  667. this.n31 *= s; this.n32 *= s; this.n33 *= s; this.n34 *= s;
  668. this.n41 *= s; this.n42 *= s; this.n43 *= s; this.n44 *= s;
  669. return this;
  670. },
  671. determinant: function () {
  672. //TODO: make this more efficient
  673. //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
  674. return (
  675. this.n14 * this.n23 * this.n32 * this.n41-
  676. this.n13 * this.n24 * this.n32 * this.n41-
  677. this.n14 * this.n22 * this.n33 * this.n41+
  678. this.n12 * this.n24 * this.n33 * this.n41+
  679. this.n13 * this.n22 * this.n34 * this.n41-
  680. this.n12 * this.n23 * this.n34 * this.n41-
  681. this.n14 * this.n23 * this.n31 * this.n42+
  682. this.n13 * this.n24 * this.n31 * this.n42+
  683. this.n14 * this.n21 * this.n33 * this.n42-
  684. this.n11 * this.n24 * this.n33 * this.n42-
  685. this.n13 * this.n21 * this.n34 * this.n42+
  686. this.n11 * this.n23 * this.n34 * this.n42+
  687. this.n14 * this.n22 * this.n31 * this.n43-
  688. this.n12 * this.n24 * this.n31 * this.n43-
  689. this.n14 * this.n21 * this.n32 * this.n43+
  690. this.n11 * this.n24 * this.n32 * this.n43+
  691. this.n12 * this.n21 * this.n34 * this.n43-
  692. this.n11 * this.n22 * this.n34 * this.n43-
  693. this.n13 * this.n22 * this.n31 * this.n44+
  694. this.n12 * this.n23 * this.n31 * this.n44+
  695. this.n13 * this.n21 * this.n32 * this.n44-
  696. this.n11 * this.n23 * this.n32 * this.n44-
  697. this.n12 * this.n21 * this.n33 * this.n44+
  698. this.n11 * this.n22 * this.n33 * this.n44 );
  699. },
  700. transpose: function () {
  701. function swap( obj, p1, p2 ) {
  702. var aux = obj[ p1 ];
  703. obj[ p1 ] = obj[ p2 ];
  704. obj[ p2 ] = aux;
  705. }
  706. swap( this, 'n21', 'n12' );
  707. swap( this, 'n31', 'n13' );
  708. swap( this, 'n32', 'n23' );
  709. swap( this, 'n41', 'n14' );
  710. swap( this, 'n42', 'n24' );
  711. swap( this, 'n43', 'n34' );
  712. return this;
  713. },
  714. clone: function () {
  715. var m = new THREE.Matrix4();
  716. m.n11 = this.n11; m.n12 = this.n12; m.n13 = this.n13; m.n14 = this.n14;
  717. m.n21 = this.n21; m.n22 = this.n22; m.n23 = this.n23; m.n24 = this.n24;
  718. m.n31 = this.n31; m.n32 = this.n32; m.n33 = this.n33; m.n34 = this.n34;
  719. m.n41 = this.n41; m.n42 = this.n42; m.n43 = this.n43; m.n44 = this.n44;
  720. return m;
  721. },
  722. flatten: function() {
  723. return [ this.n11, this.n21, this.n31, this.n41,
  724. this.n12, this.n22, this.n32, this.n42,
  725. this.n13, this.n23, this.n33, this.n43,
  726. this.n14, this.n24, this.n34, this.n44 ];
  727. },
  728. toString: function() {
  729. return "| " + this.n11 + " " + this.n12 + " " + this.n13 + " " + this.n14 + " |\n" +
  730. "| " + this.n21 + " " + this.n22 + " " + this.n23 + " " + this.n24 + " |\n" +
  731. "| " + this.n31 + " " + this.n32 + " " + this.n33 + " " + this.n34 + " |\n" +
  732. "| " + this.n41 + " " + this.n42 + " " + this.n43 + " " + this.n44 + " |";
  733. }
  734. };
  735. THREE.Matrix4.translationMatrix = function ( x, y, z ) {
  736. var m = new THREE.Matrix4();
  737. m.n14 = x;
  738. m.n24 = y;
  739. m.n34 = z;
  740. return m;
  741. };
  742. THREE.Matrix4.scaleMatrix = function ( x, y, z ) {
  743. var m = new THREE.Matrix4();
  744. m.n11 = x;
  745. m.n22 = y;
  746. m.n33 = z;
  747. return m;
  748. };
  749. THREE.Matrix4.rotationXMatrix = function ( theta ) {
  750. var rot = new THREE.Matrix4();
  751. rot.n22 = rot.n33 = Math.cos( theta );
  752. rot.n32 = Math.sin( theta );
  753. rot.n23 = - rot.n32;
  754. return rot;
  755. };
  756. THREE.Matrix4.rotationYMatrix = function ( theta ) {
  757. var rot = new THREE.Matrix4();
  758. rot.n11 = rot.n33 = Math.cos( theta );
  759. rot.n13 = Math.sin( theta );
  760. rot.n31 = - rot.n13;
  761. return rot;
  762. };
  763. THREE.Matrix4.rotationZMatrix = function ( theta ) {
  764. var rot = new THREE.Matrix4();
  765. rot.n11 = rot.n22 = Math.cos( theta );
  766. rot.n21 = Math.sin( theta );
  767. rot.n12 = - rot.n21;
  768. return rot;
  769. };
  770. THREE.Matrix4.rotationAxisAngleMatrix = function ( axis, angle ) {
  771. //Based on http://www.gamedev.net/reference/articles/article1199.asp
  772. var rot = new THREE.Matrix4(),
  773. c = Math.cos( angle ),
  774. s = Math.sin( angle ),
  775. t = 1 - c,
  776. x = axis.x, y = axis.y, z = axis.z;
  777. rot.n11 = t * x * x + c;
  778. rot.n12 = t * x * y - s * z;
  779. rot.n13 = t * x * z + s * y;
  780. rot.n21 = t * x * y + s * z;
  781. rot.n22 = t * y * y + c;
  782. rot.n23 = t * y * z - s * x;
  783. rot.n31 = t * x * z - s * y;
  784. rot.n32 = t * y * z + s * x;
  785. rot.n33 = t * z * z + c;
  786. return rot;
  787. };
  788. THREE.Matrix4.makeInvert = function ( m1 ) {
  789. //TODO: make this more efficient
  790. //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
  791. var m2 = new THREE.Matrix4();
  792. m2.n11 = m1.n23*m1.n34*m1.n42 - m1.n24*m1.n33*m1.n42 + m1.n24*m1.n32*m1.n43 - m1.n22*m1.n34*m1.n43 - m1.n23*m1.n32*m1.n44 + m1.n22*m1.n33*m1.n44;
  793. m2.n12 = m1.n14*m1.n33*m1.n42 - m1.n13*m1.n34*m1.n42 - m1.n14*m1.n32*m1.n43 + m1.n12*m1.n34*m1.n43 + m1.n13*m1.n32*m1.n44 - m1.n12*m1.n33*m1.n44;
  794. m2.n13 = m1.n13*m1.n24*m1.n42 - m1.n14*m1.n23*m1.n42 + m1.n14*m1.n22*m1.n43 - m1.n12*m1.n24*m1.n43 - m1.n13*m1.n22*m1.n44 + m1.n12*m1.n23*m1.n44;
  795. m2.n14 = m1.n14*m1.n23*m1.n32 - m1.n13*m1.n24*m1.n32 - m1.n14*m1.n22*m1.n33 + m1.n12*m1.n24*m1.n33 + m1.n13*m1.n22*m1.n34 - m1.n12*m1.n23*m1.n34;
  796. m2.n21 = m1.n24*m1.n33*m1.n41 - m1.n23*m1.n34*m1.n41 - m1.n24*m1.n31*m1.n43 + m1.n21*m1.n34*m1.n43 + m1.n23*m1.n31*m1.n44 - m1.n21*m1.n33*m1.n44;
  797. m2.n22 = m1.n13*m1.n34*m1.n41 - m1.n14*m1.n33*m1.n41 + m1.n14*m1.n31*m1.n43 - m1.n11*m1.n34*m1.n43 - m1.n13*m1.n31*m1.n44 + m1.n11*m1.n33*m1.n44;
  798. m2.n23 = m1.n14*m1.n23*m1.n41 - m1.n13*m1.n24*m1.n41 - m1.n14*m1.n21*m1.n43 + m1.n11*m1.n24*m1.n43 + m1.n13*m1.n21*m1.n44 - m1.n11*m1.n23*m1.n44;
  799. m2.n24 = m1.n13*m1.n24*m1.n31 - m1.n14*m1.n23*m1.n31 + m1.n14*m1.n21*m1.n33 - m1.n11*m1.n24*m1.n33 - m1.n13*m1.n21*m1.n34 + m1.n11*m1.n23*m1.n34;
  800. m2.n31 = m1.n22*m1.n34*m1.n41 - m1.n24*m1.n32*m1.n41 + m1.n24*m1.n31*m1.n42 - m1.n21*m1.n34*m1.n42 - m1.n22*m1.n31*m1.n44 + m1.n21*m1.n32*m1.n44;
  801. m2.n32 = m1.n14*m1.n32*m1.n41 - m1.n12*m1.n34*m1.n41 - m1.n14*m1.n31*m1.n42 + m1.n11*m1.n34*m1.n42 + m1.n12*m1.n31*m1.n44 - m1.n11*m1.n32*m1.n44;
  802. m2.n33 = m1.n13*m1.n24*m1.n41 - m1.n14*m1.n22*m1.n41 + m1.n14*m1.n21*m1.n42 - m1.n11*m1.n24*m1.n42 - m1.n12*m1.n21*m1.n44 + m1.n11*m1.n22*m1.n44;
  803. m2.n34 = m1.n14*m1.n22*m1.n31 - m1.n12*m1.n24*m1.n31 - m1.n14*m1.n21*m1.n32 + m1.n11*m1.n24*m1.n32 + m1.n12*m1.n21*m1.n34 - m1.n11*m1.n22*m1.n34;
  804. m2.n41 = m1.n23*m1.n32*m1.n41 - m1.n22*m1.n33*m1.n41 - m1.n23*m1.n31*m1.n42 + m1.n21*m1.n33*m1.n42 + m1.n22*m1.n31*m1.n43 - m1.n21*m1.n32*m1.n43;
  805. m2.n42 = m1.n12*m1.n33*m1.n41 - m1.n13*m1.n32*m1.n41 + m1.n13*m1.n31*m1.n42 - m1.n11*m1.n33*m1.n42 - m1.n12*m1.n31*m1.n43 + m1.n11*m1.n32*m1.n43;
  806. m2.n43 = m1.n13*m1.n22*m1.n41 - m1.n12*m1.n23*m1.n41 - m1.n13*m1.n21*m1.n42 + m1.n11*m1.n23*m1.n42 + m1.n12*m1.n21*m1.n43 - m1.n11*m1.n22*m1.n43;
  807. m2.n44 = m1.n12*m1.n23*m1.n31 - m1.n13*m1.n22*m1.n31 + m1.n13*m1.n21*m1.n32 - m1.n11*m1.n23*m1.n32 - m1.n12*m1.n21*m1.n33 + m1.n11*m1.n22*m1.n33;
  808. m2.multiplyScalar( 1 / m1.determinant() );
  809. return m2;
  810. };
  811. THREE.Matrix4.makeInvert3x3 = function ( m1 ) {
  812. // input: THREE.Matrix4, output: THREE.Matrix3
  813. // ( based on http://code.google.com/p/webgl-mjs/ )
  814. var m = m1.flatten(),
  815. m2 = new THREE.Matrix3(),
  816. a11 = m[ 10 ] * m[ 5 ] - m[ 6 ] * m[ 9 ],
  817. a21 = - m[ 10 ] * m[ 1 ] + m[ 2 ] * m[ 9 ],
  818. a31 = m[ 6 ] * m[ 1 ] - m[ 2 ] * m[ 5 ],
  819. a12 = - m[ 10 ] * m[ 4 ] + m[ 6 ] * m[ 8 ],
  820. a22 = m[ 10 ] * m[ 0 ] - m[ 2 ] * m[ 8 ],
  821. a32 = - m[ 6 ] * m[ 0 ] + m[ 2 ] * m[ 4 ],
  822. a13 = m[ 9 ] * m[ 4 ] - m[ 5 ] * m[ 8 ],
  823. a23 = - m[ 9 ] * m[ 0 ] + m[ 1 ] * m[ 8 ],
  824. a33 = m[ 5 ] * m[ 0 ] - m[ 1 ] * m[ 4 ],
  825. det = m[ 0 ] * ( a11 ) + m[ 1 ] * ( a12 ) + m[ 2 ] * ( a13 ),
  826. idet;
  827. // no inverse
  828. if (det == 0) throw "matrix not invertible";
  829. idet = 1.0 / det;
  830. m2.m[ 0 ] = idet * a11; m2.m[ 1 ] = idet * a21; m2.m[ 2 ] = idet * a31;
  831. m2.m[ 3 ] = idet * a12; m2.m[ 4 ] = idet * a22; m2.m[ 5 ] = idet * a32;
  832. m2.m[ 6 ] = idet * a13; m2.m[ 7 ] = idet * a23; m2.m[ 8 ] = idet * a33;
  833. return m2;
  834. }
  835. THREE.Matrix4.makeFrustum = function( left, right, bottom, top, near, far ) {
  836. var m, x, y, a, b, c, d;
  837. m = new THREE.Matrix4();
  838. x = 2 * near / ( right - left );
  839. y = 2 * near / ( top - bottom );
  840. a = ( right + left ) / ( right - left );
  841. b = ( top + bottom ) / ( top - bottom );
  842. c = - ( far + near ) / ( far - near );
  843. d = - 2 * far * near / ( far - near );
  844. m.n11 = x; m.n12 = 0; m.n13 = a; m.n14 = 0;
  845. m.n21 = 0; m.n22 = y; m.n23 = b; m.n24 = 0;
  846. m.n31 = 0; m.n32 = 0; m.n33 = c; m.n34 = d;
  847. m.n41 = 0; m.n42 = 0; m.n43 = - 1; m.n44 = 0;
  848. return m;
  849. };
  850. THREE.Matrix4.makePerspective = function( fov, aspect, near, far ) {
  851. var ymax, ymin, xmin, xmax;
  852. ymax = near * Math.tan( fov * Math.PI / 360 );
  853. ymin = - ymax;
  854. xmin = ymin * aspect;
  855. xmax = ymax * aspect;
  856. return THREE.Matrix4.makeFrustum( xmin, xmax, ymin, ymax, near, far );
  857. };
  858. THREE.Matrix4.makeOrtho = function( left, right, top, bottom, near, far ) {
  859. var m, x, y, z, w, h, p;
  860. m = new THREE.Matrix4();
  861. w = right - left;
  862. h = top - bottom;
  863. p = far - near;
  864. x = ( right + left ) / w;
  865. y = ( top + bottom ) / h;
  866. z = ( far + near ) / p;
  867. m.n11 = 2 / w; m.n12 = 0; m.n13 = 0; m.n14 = -x;
  868. m.n21 = 0; m.n22 = 2 / h; m.n23 = 0; m.n24 = -y;
  869. m.n31 = 0; m.n32 = 0; m.n33 = -2 / p; m.n34 = -z;
  870. m.n41 = 0; m.n42 = 0; m.n43 = 0; m.n44 = 1;
  871. return m;
  872. };
  873. /**
  874. * @author mr.doob / http://mrdoob.com/
  875. */
  876. THREE.Vertex = function ( position, normal ) {
  877. this.position = position || new THREE.Vector3();
  878. this.positionWorld = new THREE.Vector3();
  879. this.positionScreen = new THREE.Vector4();
  880. this.normal = normal || new THREE.Vector3();
  881. this.normalWorld = new THREE.Vector3();
  882. this.normalScreen = new THREE.Vector3();
  883. this.tangent = new THREE.Vector4();
  884. this.__visible = true;
  885. };
  886. THREE.Vertex.prototype = {
  887. toString: function () {
  888. return 'THREE.Vertex ( position: ' + this.position + ', normal: ' + this.normal + ' )';
  889. }
  890. };
  891. /**
  892. * @author mr.doob / http://mrdoob.com/
  893. */
  894. THREE.Face3 = function ( a, b, c, normal, materials ) {
  895. this.a = a;
  896. this.b = b;
  897. this.c = c;
  898. this.centroid = new THREE.Vector3();
  899. this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
  900. this.vertexNormals = normal instanceof Array ? normal : [];
  901. this.materials = materials instanceof Array ? materials : [ materials ];
  902. };
  903. THREE.Face3.prototype = {
  904. toString: function () {
  905. return 'THREE.Face3 ( ' + this.a + ', ' + this.b + ', ' + this.c + ' )';
  906. }
  907. };
  908. /**
  909. * @author mr.doob / http://mrdoob.com/
  910. */
  911. THREE.Face4 = function ( a, b, c, d, normal, materials ) {
  912. this.a = a;
  913. this.b = b;
  914. this.c = c;
  915. this.d = d;
  916. this.centroid = new THREE.Vector3();
  917. this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
  918. this.vertexNormals = normal instanceof Array ? normal : [];
  919. this.materials = materials instanceof Array ? materials : [ materials ];
  920. };
  921. THREE.Face4.prototype = {
  922. toString: function () {
  923. return 'THREE.Face4 ( ' + this.a + ', ' + this.b + ', ' + this.c + ' ' + this.d + ' )';
  924. }
  925. };
  926. /**
  927. * @author mr.doob / http://mrdoob.com/
  928. */
  929. THREE.UV = function ( u, v ) {
  930. this.u = u || 0;
  931. this.v = v || 0;
  932. };
  933. THREE.UV.prototype = {
  934. copy: function ( uv ) {
  935. this.u = uv.u;
  936. this.v = uv.v;
  937. },
  938. toString: function () {
  939. return 'THREE.UV (' + this.u + ', ' + this.v + ')';
  940. }
  941. };
  942. /**
  943. * @author mr.doob / http://mrdoob.com/
  944. * @author kile / http://kile.stravaganza.org/
  945. * @author alteredq / http://alteredqualia.com/
  946. */
  947. THREE.Geometry = function () {
  948. this.vertices = [];
  949. this.faces = [];
  950. this.uvs = [];
  951. this.boundingBox = null;
  952. this.boundingSphere = null;
  953. this.geometryChunks = {};
  954. this.hasTangents = false;
  955. };
  956. THREE.Geometry.prototype = {
  957. computeCentroids: function () {
  958. var f, fl, face;
  959. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  960. face = this.faces[ f ];
  961. face.centroid.set( 0, 0, 0 );
  962. if ( face instanceof THREE.Face3 ) {
  963. face.centroid.addSelf( this.vertices[ face.a ].position );
  964. face.centroid.addSelf( this.vertices[ face.b ].position );
  965. face.centroid.addSelf( this.vertices[ face.c ].position );
  966. face.centroid.divideScalar( 3 );
  967. } else if ( face instanceof THREE.Face4 ) {
  968. face.centroid.addSelf( this.vertices[ face.a ].position );
  969. face.centroid.addSelf( this.vertices[ face.b ].position );
  970. face.centroid.addSelf( this.vertices[ face.c ].position );
  971. face.centroid.addSelf( this.vertices[ face.d ].position );
  972. face.centroid.divideScalar( 4 );
  973. }
  974. }
  975. },
  976. computeFaceNormals: function ( useVertexNormals ) {
  977. var n, nl, v, vl, vertex, f, fl, face, vA, vB, vC,
  978. cb = new THREE.Vector3(), ab = new THREE.Vector3();
  979. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  980. vertex = this.vertices[ v ];
  981. vertex.normal.set( 0, 0, 0 );
  982. }
  983. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  984. face = this.faces[ f ];
  985. if ( useVertexNormals && face.vertexNormals.length ) {
  986. cb.set( 0, 0, 0 );
  987. for ( n = 0, nl = face.normal.length; n < nl; n++ ) {
  988. cb.addSelf( face.vertexNormals[n] );
  989. }
  990. cb.divideScalar( 3 );
  991. if ( ! cb.isZero() ) {
  992. cb.normalize();
  993. }
  994. face.normal.copy( cb );
  995. } else {
  996. vA = this.vertices[ face.a ];
  997. vB = this.vertices[ face.b ];
  998. vC = this.vertices[ face.c ];
  999. cb.sub( vC.position, vB.position );
  1000. ab.sub( vA.position, vB.position );
  1001. cb.crossSelf( ab );
  1002. if ( !cb.isZero() ) {
  1003. cb.normalize();
  1004. }
  1005. face.normal.copy( cb );
  1006. }
  1007. }
  1008. },
  1009. computeVertexNormals: function () {
  1010. var v, vl, vertices = [],
  1011. f, fl, face;
  1012. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  1013. vertices[ v ] = new THREE.Vector3();
  1014. }
  1015. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  1016. face = this.faces[ f ];
  1017. if ( face instanceof THREE.Face3 ) {
  1018. vertices[ face.a ].addSelf( face.normal );
  1019. vertices[ face.b ].addSelf( face.normal );
  1020. vertices[ face.c ].addSelf( face.normal );
  1021. } else if ( face instanceof THREE.Face4 ) {
  1022. vertices[ face.a ].addSelf( face.normal );
  1023. vertices[ face.b ].addSelf( face.normal );
  1024. vertices[ face.c ].addSelf( face.normal );
  1025. vertices[ face.d ].addSelf( face.normal );
  1026. }
  1027. }
  1028. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  1029. vertices[ v ].normalize();
  1030. }
  1031. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  1032. face = this.faces[ f ];
  1033. if ( face instanceof THREE.Face3 ) {
  1034. face.vertexNormals[ 0 ] = vertices[ face.a ].clone();
  1035. face.vertexNormals[ 1 ] = vertices[ face.b ].clone();
  1036. face.vertexNormals[ 2 ] = vertices[ face.c ].clone();
  1037. } else if ( face instanceof THREE.Face4 ) {
  1038. face.vertexNormals[ 0 ] = vertices[ face.a ].clone();
  1039. face.vertexNormals[ 1 ] = vertices[ face.b ].clone();
  1040. face.vertexNormals[ 2 ] = vertices[ face.c ].clone();
  1041. face.vertexNormals[ 3 ] = vertices[ face.d ].clone();
  1042. }
  1043. }
  1044. },
  1045. computeTangents: function() {
  1046. // based on http://www.terathon.com/code/tangent.html
  1047. // tangents go to vertices
  1048. var f, fl, v, vl, face, uv, vA, vB, vC, uvA, uvB, uvC,
  1049. x1, x2, y1, y2, z1, z2,
  1050. s1, s2, t1, t2, r, t, test,
  1051. tan1 = [], tan2 = [],
  1052. sdir = new THREE.Vector3(), tdir = new THREE.Vector3(),
  1053. tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(),
  1054. n = new THREE.Vector3(), w;
  1055. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  1056. tan1[ v ] = new THREE.Vector3();
  1057. tan2[ v ] = new THREE.Vector3();
  1058. }
  1059. function handleTriangle( context, a, b, c, ua, ub, uc ) {
  1060. vA = context.vertices[ a ].position;
  1061. vB = context.vertices[ b ].position;
  1062. vC = context.vertices[ c ].position;
  1063. uvA = uv[ ua ];
  1064. uvB = uv[ ub ];
  1065. uvC = uv[ uc ];
  1066. x1 = vB.x - vA.x;
  1067. x2 = vC.x - vA.x;
  1068. y1 = vB.y - vA.y;
  1069. y2 = vC.y - vA.y;
  1070. z1 = vB.z - vA.z;
  1071. z2 = vC.z - vA.z;
  1072. s1 = uvB.u - uvA.u;
  1073. s2 = uvC.u - uvA.u;
  1074. t1 = uvB.v - uvA.v;
  1075. t2 = uvC.v - uvA.v;
  1076. r = 1.0 / ( s1 * t2 - s2 * t1 );
  1077. sdir.set( ( t2 * x1 - t1 * x2 ) * r,
  1078. ( t2 * y1 - t1 * y2 ) * r,
  1079. ( t2 * z1 - t1 * z2 ) * r );
  1080. tdir.set( ( s1 * x2 - s2 * x1 ) * r,
  1081. ( s1 * y2 - s2 * y1 ) * r,
  1082. ( s1 * z2 - s2 * z1 ) * r );
  1083. tan1[ a ].addSelf( sdir );
  1084. tan1[ b ].addSelf( sdir );
  1085. tan1[ c ].addSelf( sdir );
  1086. tan2[ a ].addSelf( tdir );
  1087. tan2[ b ].addSelf( tdir );
  1088. tan2[ c ].addSelf( tdir );
  1089. }
  1090. for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
  1091. face = this.faces[ f ];
  1092. uv = this.uvs[ f ];
  1093. if ( face instanceof THREE.Face3 ) {
  1094. handleTriangle( this, face.a, face.b, face.c, 0, 1, 2 );
  1095. this.vertices[ face.a ].normal.copy( face.vertexNormals[ 0 ] );
  1096. this.vertices[ face.b ].normal.copy( face.vertexNormals[ 1 ] );
  1097. this.vertices[ face.c ].normal.copy( face.vertexNormals[ 2 ] );
  1098. } else if ( face instanceof THREE.Face4 ) {
  1099. handleTriangle( this, face.a, face.b, face.c, 0, 1, 2 );
  1100. handleTriangle( this, face.a, face.b, face.d, 0, 1, 3 );
  1101. this.vertices[ face.a ].normal.copy( face.vertexNormals[ 0 ] );
  1102. this.vertices[ face.b ].normal.copy( face.vertexNormals[ 1 ] );
  1103. this.vertices[ face.c ].normal.copy( face.vertexNormals[ 2 ] );
  1104. this.vertices[ face.d ].normal.copy( face.vertexNormals[ 3 ] );
  1105. }
  1106. }
  1107. for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  1108. n.copy( this.vertices[ v ].normal );
  1109. t = tan1[ v ];
  1110. // Gram-Schmidt orthogonalize
  1111. tmp.copy( t );
  1112. tmp.subSelf( n.multiplyScalar( n.dot( t ) ) ).normalize();
  1113. // Calculate handedness
  1114. tmp2.cross( this.vertices[ v ].normal, t );
  1115. test = tmp2.dot( tan2[ v ] );
  1116. w = (test < 0.0) ? -1.0 : 1.0;
  1117. this.vertices[ v ].tangent.set( tmp.x, tmp.y, tmp.z, w );
  1118. }
  1119. this.hasTangents = true;
  1120. },
  1121. computeBoundingBox: function () {
  1122. var vertex;
  1123. if ( this.vertices.length > 0 ) {
  1124. this.boundingBox = { 'x': [ this.vertices[ 0 ].position.x, this.vertices[ 0 ].position.x ],
  1125. 'y': [ this.vertices[ 0 ].position.y, this.vertices[ 0 ].position.y ],
  1126. 'z': [ this.vertices[ 0 ].position.z, this.vertices[ 0 ].position.z ] };
  1127. for ( var v = 1, vl = this.vertices.length; v < vl; v ++ ) {
  1128. vertex = this.vertices[ v ];
  1129. if ( vertex.position.x < this.boundingBox.x[ 0 ] ) {
  1130. this.boundingBox.x[ 0 ] = vertex.position.x;
  1131. } else if ( vertex.position.x > this.boundingBox.x[ 1 ] ) {
  1132. this.boundingBox.x[ 1 ] = vertex.position.x;
  1133. }
  1134. if ( vertex.position.y < this.boundingBox.y[ 0 ] ) {
  1135. this.boundingBox.y[ 0 ] = vertex.position.y;
  1136. } else if ( vertex.position.y > this.boundingBox.y[ 1 ] ) {
  1137. this.boundingBox.y[ 1 ] = vertex.position.y;
  1138. }
  1139. if ( vertex.position.z < this.boundingBox.z[ 0 ] ) {
  1140. this.boundingBox.z[ 0 ] = vertex.position.z;
  1141. } else if ( vertex.position.z > this.boundingBox.z[ 1 ] ) {
  1142. this.boundingBox.z[ 1 ] = vertex.position.z;
  1143. }
  1144. }
  1145. }
  1146. },
  1147. computeBoundingSphere: function () {
  1148. var radius = this.boundingSphere === null ? 0 : this.boundingSphere.radius;
  1149. for ( var v = 0, vl = this.vertices.length; v < vl; v ++ ) {
  1150. radius = Math.max( radius, this.vertices[ v ].position.length() );
  1151. }
  1152. this.boundingSphere = { radius: radius };
  1153. },
  1154. sortFacesByMaterial: function () {
  1155. // TODO
  1156. // Should optimize by grouping faces with ColorFill / ColorStroke materials
  1157. // which could then use vertex color attributes instead of each being
  1158. // in its separate VBO
  1159. var i, l, f, fl, face, material, materials, vertices, mhash, ghash, hash_map = {};
  1160. function materialHash( material ) {
  1161. var hash_array = [];
  1162. for ( i = 0, l = material.length; i < l; i++ ) {
  1163. if ( material[ i ] == undefined ) {
  1164. hash_array.push( "undefined" );
  1165. } else {
  1166. hash_array.push( material[ i ].toString() );
  1167. }
  1168. }
  1169. return hash_array.join( '_' );
  1170. }
  1171. for ( f = 0, fl = this.faces.length; f < fl; f++ ) {
  1172. face = this.faces[ f ];
  1173. materials = face.materials;
  1174. mhash = materialHash( materials );
  1175. if ( hash_map[ mhash ] == undefined ) {
  1176. hash_map[ mhash ] = { 'hash': mhash, 'counter': 0 };
  1177. }
  1178. ghash = hash_map[ mhash ].hash + '_' + hash_map[ mhash ].counter;
  1179. if ( this.geometryChunks[ ghash ] == undefined ) {
  1180. this.geometryChunks[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0 };
  1181. }
  1182. vertices = face instanceof THREE.Face3 ? 3 : 4;
  1183. if ( this.geometryChunks[ ghash ].vertices + vertices > 65535 ) {
  1184. hash_map[ mhash ].counter += 1;
  1185. ghash = hash_map[ mhash ].hash + '_' + hash_map[ mhash ].counter;
  1186. if ( this.geometryChunks[ ghash ] == undefined ) {
  1187. this.geometryChunks[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0 };
  1188. }
  1189. }
  1190. this.geometryChunks[ ghash ].faces.push( f );
  1191. this.geometryChunks[ ghash ].vertices += vertices;
  1192. }
  1193. },
  1194. toString: function () {
  1195. return 'THREE.Geometry ( vertices: ' + this.vertices + ', faces: ' + this.faces + ', uvs: ' + this.uvs + ' )';
  1196. }
  1197. };
  1198. /**
  1199. * @author mr.doob / http://mrdoob.com/
  1200. */
  1201. THREE.Camera = function ( fov, aspect, near, far ) {
  1202. this.fov = fov;
  1203. this.aspect = aspect;
  1204. this.near = near;
  1205. this.far = far;
  1206. this.position = new THREE.Vector3();
  1207. this.target = { position: new THREE.Vector3() };
  1208. this.autoUpdateMatrix = true;
  1209. this.projectionMatrix = null;
  1210. this.matrix = new THREE.Matrix4();
  1211. this.up = new THREE.Vector3( 0, 1, 0 );
  1212. this.translateX = function ( amount ) {
  1213. var vector = this.target.position.clone().subSelf( this.position ).normalize().multiplyScalar( amount );
  1214. vector.cross( vector.clone(), this.up );
  1215. this.position.addSelf( vector );
  1216. this.target.position.addSelf( vector );
  1217. };
  1218. /* TODO
  1219. this.translateY = function ( amount ) {
  1220. };
  1221. */
  1222. this.translateZ = function ( amount ) {
  1223. var vector = this.target.position.clone().subSelf( this.position ).normalize().multiplyScalar( amount );
  1224. this.position.subSelf( vector );
  1225. this.target.position.subSelf( vector );
  1226. };
  1227. this.updateMatrix = function () {
  1228. this.matrix.lookAt( this.position, this.target.position, this.up );
  1229. };
  1230. this.updateProjectionMatrix = function () {
  1231. this.projectionMatrix = THREE.Matrix4.makePerspective( this.fov, this.aspect, this.near, this.far );
  1232. };
  1233. this.updateProjectionMatrix();
  1234. };
  1235. THREE.Camera.prototype = {
  1236. toString: function () {
  1237. return 'THREE.Camera ( ' + this.position + ', ' + this.target.position + ' )';
  1238. }
  1239. };
  1240. THREE.Light = function ( hex ) {
  1241. this.color = new THREE.Color( hex );
  1242. };
  1243. THREE.AmbientLight = function ( hex ) {
  1244. THREE.Light.call( this, hex );
  1245. };
  1246. THREE.AmbientLight.prototype = new THREE.Light();
  1247. THREE.AmbientLight.prototype.constructor = THREE.AmbientLight;
  1248. THREE.DirectionalLight = function ( hex, intensity ) {
  1249. THREE.Light.call( this, hex );
  1250. this.position = new THREE.Vector3( 0, 1, 0 );
  1251. this.intensity = intensity || 1;
  1252. };
  1253. THREE.DirectionalLight.prototype = new THREE.Light();
  1254. THREE.DirectionalLight.prototype.constructor = THREE.DirectionalLight;
  1255. THREE.PointLight = function ( hex, intensity ) {
  1256. THREE.Light.call( this, hex );
  1257. this.position = new THREE.Vector3();
  1258. this.intensity = intensity || 1;
  1259. };
  1260. THREE.DirectionalLight.prototype = new THREE.Light();
  1261. THREE.DirectionalLight.prototype.constructor = THREE.PointLight;
  1262. /**
  1263. * @author mr.doob / http://mrdoob.com/
  1264. */
  1265. THREE.Object3D = function () {
  1266. this.id = THREE.Object3DCounter.value ++;
  1267. this.position = new THREE.Vector3();
  1268. this.rotation = new THREE.Vector3();
  1269. this.scale = new THREE.Vector3( 1, 1, 1 );
  1270. this.matrix = new THREE.Matrix4();
  1271. this.translationMatrix = new THREE.Matrix4();
  1272. this.rotationMatrix = new THREE.Matrix4();
  1273. this.scaleMatrix = new THREE.Matrix4();
  1274. this.screen = new THREE.Vector3();
  1275. this.autoUpdateMatrix = true;
  1276. this.visible = true;
  1277. };
  1278. THREE.Object3D.prototype = {
  1279. updateMatrix: function () {
  1280. this.matrixPosition = THREE.Matrix4.translationMatrix( this.position.x, this.position.y, this.position.z );
  1281. this.rotationMatrix = THREE.Matrix4.rotationXMatrix( this.rotation.x );
  1282. this.rotationMatrix.multiplySelf( THREE.Matrix4.rotationYMatrix( this.rotation.y ) );
  1283. this.rotationMatrix.multiplySelf( THREE.Matrix4.rotationZMatrix( this.rotation.z ) );
  1284. this.scaleMatrix = THREE.Matrix4.scaleMatrix( this.scale.x, this.scale.y, this.scale.z );
  1285. this.matrix.copy( this.matrixPosition );
  1286. this.matrix.multiplySelf( this.rotationMatrix );
  1287. this.matrix.multiplySelf( this.scaleMatrix );
  1288. }
  1289. };
  1290. THREE.Object3DCounter = { value: 0 };
  1291. /**
  1292. * @author mr.doob / http://mrdoob.com/
  1293. */
  1294. THREE.Particle = function ( materials ) {
  1295. THREE.Object3D.call( this );
  1296. this.materials = materials instanceof Array ? materials : [ materials ];
  1297. this.autoUpdateMatrix = false;
  1298. };
  1299. THREE.Particle.prototype = new THREE.Object3D();
  1300. THREE.Particle.prototype.constructor = THREE.Particle;
  1301. /**
  1302. * @author alteredq / http://alteredqualia.com/
  1303. */
  1304. THREE.ParticleSystem = function ( geometry, materials ) {
  1305. THREE.Object3D.call( this );
  1306. this.geometry = geometry;
  1307. this.materials = materials instanceof Array ? materials : [ materials ];
  1308. this.autoUpdateMatrix = false;
  1309. };
  1310. THREE.ParticleSystem.prototype = new THREE.Object3D();
  1311. THREE.ParticleSystem.prototype.constructor = THREE.ParticleSystem;
  1312. /**
  1313. * @author mr.doob / http://mrdoob.com/
  1314. */
  1315. THREE.Line = function ( geometry, materials, type ) {
  1316. THREE.Object3D.call( this );
  1317. this.geometry = geometry;
  1318. this.materials = materials instanceof Array ? materials : [ materials ];
  1319. this.type = type !== undefined ? type : THREE.LineContinuous;
  1320. };
  1321. THREE.LineStrip = 0;
  1322. THREE.LinePieces = 1;
  1323. THREE.Line.prototype = new THREE.Object3D();
  1324. THREE.Line.prototype.constructor = THREE.Line;
  1325. /**
  1326. * @author mr.doob / http://mrdoob.com/
  1327. * @author alteredq / http://alteredqualia.com/
  1328. */
  1329. THREE.Mesh = function ( geometry, materials ) {
  1330. THREE.Object3D.call( this );
  1331. this.geometry = geometry;
  1332. this.materials = materials instanceof Array ? materials : [ materials ];
  1333. this.flipSided = false;
  1334. this.doubleSided = false;
  1335. this.overdraw = false; // TODO: Move to material?
  1336. this.geometry.boundingSphere || this.geometry.computeBoundingSphere();
  1337. };
  1338. THREE.Mesh.prototype = new THREE.Object3D();
  1339. THREE.Mesh.prototype.constructor = THREE.Mesh;
  1340. /**
  1341. * @author mr.doob / http://mrdoob.com/
  1342. */
  1343. THREE.FlatShading = 0;
  1344. THREE.SmoothShading = 1;
  1345. THREE.NormalBlending = 0;
  1346. THREE.AdditiveBlending = 1;
  1347. THREE.SubtractiveBlending = 2;
  1348. /**
  1349. * @author mr.doob / http://mrdoob.com/
  1350. *
  1351. * parameters = {
  1352. * color: <hex>,
  1353. * opacity: <float>,
  1354. * blending: THREE.NormalBlending,
  1355. * linewidth: <float>
  1356. * }
  1357. */
  1358. THREE.LineBasicMaterial = function ( parameters ) {
  1359. this.color = new THREE.Color( 0xffffff );
  1360. this.opacity = 1;
  1361. this.blending = THREE.NormalBlending;
  1362. this.linewidth = 1;
  1363. this.linecap = 'round';
  1364. this.linejoin = 'round';
  1365. if ( parameters ) {
  1366. if ( parameters.color !== undefined ) this.color.setHex( parameters.color );
  1367. if ( parameters.opacity !== undefined ) this.opacity = parameters.opacity;
  1368. if ( parameters.blending !== undefined ) this.blending = parameters.blending;
  1369. if ( parameters.linewidth !== undefined ) this.linewidth = parameters.linewidth;
  1370. if ( parameters.linecap !== undefined ) this.linecap = parameters.linecap;
  1371. if ( parameters.linejoin !== undefined ) this.linejoin = parameters.linejoin;
  1372. }
  1373. };
  1374. THREE.LineBasicMaterial.prototype = {
  1375. toString: function () {
  1376. return 'THREE.LineBasicMaterial (<br/>' +
  1377. 'color: ' + this.color + '<br/>' +
  1378. 'opacity: ' + this.opacity + '<br/>' +
  1379. 'blending: ' + this.blending + '<br/>' +
  1380. 'linewidth: ' + this.linewidth +'<br/>' +
  1381. 'linecap: ' + this.linecap +'<br/>' +
  1382. 'linejoin: ' + this.linejoin +'<br/>' +
  1383. ')';
  1384. }
  1385. }
  1386. /**
  1387. * @author mr.doob / http://mrdoob.com/
  1388. * @author alteredq / http://alteredqualia.com/
  1389. *
  1390. * parameters = {
  1391. * color: <hex>,
  1392. * map: new THREE.Texture( <Image> ),
  1393. * env_map: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
  1394. * combine: THREE.Multiply,
  1395. * reflectivity: <float>,
  1396. * refraction_ratio: <float>,
  1397. * opacity: <float>,
  1398. * shading: THREE.SmoothShading,
  1399. * blending: THREE.NormalBlending,
  1400. * wireframe: <boolean>,
  1401. * wireframe_linewidth: <float>
  1402. * }
  1403. */
  1404. THREE.MeshBasicMaterial = function ( parameters ) {
  1405. this.id = THREE.MeshBasicMaterialCounter.value ++;
  1406. this.color = new THREE.Color( 0xffffff );
  1407. this.map = null;
  1408. this.env_map = null;
  1409. this.combine = THREE.MultiplyOperation;
  1410. this.reflectivity = 1;
  1411. this.refraction_ratio = 0.98;
  1412. this.fog = true;
  1413. this.opacity = 1;
  1414. this.shading = THREE.SmoothShading;
  1415. this.blending = THREE.NormalBlending;
  1416. this.wireframe = false;
  1417. this.wireframe_linewidth = 1;
  1418. this.wireframe_linecap = 'round';
  1419. this.wireframe_linejoin = 'round';
  1420. if ( parameters ) {
  1421. if ( parameters.color !== undefined ) this.color.setHex( parameters.color );
  1422. if ( parameters.map !== undefined ) this.map = parameters.map;
  1423. if ( parameters.env_map !== undefined ) this.env_map = parameters.env_map;
  1424. if ( parameters.combine !== undefined ) this.combine = parameters.combine;
  1425. if ( parameters.reflectivity !== undefined ) this.reflectivity = parameters.reflectivity;
  1426. if ( parameters.refraction_ratio !== undefined ) this.refraction_ratio = parameters.refraction_ratio;
  1427. if ( parameters.fog !== undefined ) this.fog = parameters.fog;
  1428. if ( parameters.opacity !== undefined ) this.opacity = parameters.opacity;
  1429. if ( parameters.shading !== undefined ) this.shading = parameters.shading;
  1430. if ( parameters.blending !== undefined ) this.blending = parameters.blending;
  1431. if ( parameters.wireframe !== undefined ) this.wireframe = parameters.wireframe;
  1432. if ( parameters.wireframe_linewidth !== undefined ) this.wireframe_linewidth = parameters.wireframe_linewidth;
  1433. if ( parameters.wireframe_linecap !== undefined ) this.wireframe_linecap = parameters.wireframe_linecap;
  1434. if ( parameters.wireframe_linejoin !== undefined ) this.wireframe_linejoin = parameters.wireframe_linejoin;
  1435. }
  1436. };
  1437. THREE.MeshBasicMaterial.prototype = {
  1438. toString: function () {
  1439. return 'THREE.MeshBasicMaterial (<br/>' +
  1440. 'id: ' + this.id + '<br/>' +
  1441. 'color: ' + this.color + '<br/>' +
  1442. 'map: ' + this.map + '<br/>' +
  1443. 'env_map: ' + this.env_map + '<br/>' +
  1444. 'combine: ' + this.combine + '<br/>' +
  1445. 'reflectivity: ' + this.reflectivity + '<br/>' +
  1446. 'refraction_ratio: ' + this.refraction_ratio + '<br/>' +
  1447. 'opacity: ' + this.opacity + '<br/>' +
  1448. 'blending: ' + this.blending + '<br/>' +
  1449. 'wireframe: ' + this.wireframe + '<br/>' +
  1450. 'wireframe_linewidth: ' + this.wireframe_linewidth +'<br/>' +
  1451. 'wireframe_linecap: ' + this.wireframe_linecap +'<br/>' +
  1452. 'wireframe_linejoin: ' + this.wireframe_linejoin +'<br/>' +
  1453. ')';
  1454. }
  1455. };
  1456. THREE.MeshBasicMaterialCounter = { value: 0 };
  1457. /**
  1458. * @author mr.doob / http://mrdoob.com/
  1459. * @author alteredq / http://alteredqualia.com/
  1460. *
  1461. * parameters = {
  1462. * color: <hex>,
  1463. * map: new THREE.Texture( <Image> ),
  1464. * env_map: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
  1465. * combine: THREE.Multiply,
  1466. * reflectivity: <float>,
  1467. * refraction_ratio: <float>,
  1468. * opacity: <float>,
  1469. * shading: THREE.SmoothShading,
  1470. * blending: THREE.NormalBlending,
  1471. * wireframe: <boolean>,
  1472. * wireframe_linewidth: <float>
  1473. * }
  1474. */
  1475. THREE.MeshLambertMaterial = function ( parameters ) {
  1476. this.id = THREE.MeshLambertMaterialCounter.value ++;
  1477. this.color = new THREE.Color( 0xffffff );
  1478. this.map = null;
  1479. this.env_map = null;
  1480. this.combine = THREE.MultiplyOperation;
  1481. this.reflectivity = 1;
  1482. this.refraction_ratio = 0.98;
  1483. this.fog = true;
  1484. this.opacity = 1;
  1485. this.shading = THREE.SmoothShading;
  1486. this.blending = THREE.NormalBlending;
  1487. this.wireframe = false;
  1488. this.wireframe_linewidth = 1;
  1489. this.wireframe_linecap = 'round';
  1490. this.wireframe_linejoin = 'round';
  1491. if ( parameters ) {
  1492. if ( parameters.color !== undefined ) this.color.setHex( parameters.color );
  1493. if ( parameters.map !== undefined ) this.map = parameters.map;
  1494. if ( parameters.env_map !== undefined ) this.env_map = parameters.env_map;
  1495. if ( parameters.combine !== undefined ) this.combine = parameters.combine;
  1496. if ( parameters.reflectivity !== undefined ) this.reflectivity = parameters.reflectivity;
  1497. if ( parameters.refraction_ratio !== undefined ) this.refraction_ratio = parameters.refraction_ratio;
  1498. if ( parameters.fog !== undefined ) this.fog = parameters.fog;
  1499. if ( parameters.opacity !== undefined ) this.opacity = parameters.opacity;
  1500. if ( parameters.shading !== undefined ) this.shading = parameters.shading;
  1501. if ( parameters.blending !== undefined ) this.blending = parameters.blending;
  1502. if ( parameters.wireframe !== undefined ) this.wireframe = parameters.wireframe;
  1503. if ( parameters.wireframe_linewidth !== undefined ) this.wireframe_linewidth = parameters.wireframe_linewidth;
  1504. if ( parameters.wireframe_linecap !== undefined ) this.wireframe_linecap = parameters.wireframe_linecap;
  1505. if ( parameters.wireframe_linejoin !== undefined ) this.wireframe_linejoin = parameters.wireframe_linejoin;
  1506. }
  1507. };
  1508. THREE.MeshLambertMaterial.prototype = {
  1509. toString: function () {
  1510. return 'THREE.MeshLambertMaterial (<br/>' +
  1511. 'id: ' + this.id + '<br/>' +
  1512. 'color: ' + this.color + '<br/>' +
  1513. 'map: ' + this.map + '<br/>' +
  1514. 'env_map: ' + this.env_map + '<br/>' +
  1515. 'combine: ' + this.combine + '<br/>' +
  1516. 'reflectivity: ' + this.reflectivity + '<br/>' +
  1517. 'refraction_ratio: ' + this.refraction_ratio + '<br/>' +
  1518. 'opacity: ' + this.opacity + '<br/>' +
  1519. 'shading: ' + this.shading + '<br/>' +
  1520. 'blending: ' + this.blending + '<br/>' +
  1521. 'wireframe: ' + this.wireframe + '<br/>' +
  1522. 'wireframe_linewidth: ' + this.wireframe_linewidth +'<br/>' +
  1523. 'wireframe_linecap: ' + this.wireframe_linecap +'<br/>' +
  1524. 'wireframe_linejoin: ' + this.wireframe_linejoin +'<br/>' +
  1525. ' )';
  1526. }
  1527. };
  1528. THREE.MeshLambertMaterialCounter = { value: 0 };
  1529. /**
  1530. * @author mr.doob / http://mrdoob.com/
  1531. * @author alteredq / http://alteredqualia.com/
  1532. *
  1533. * parameters = {
  1534. * color: <hex>,
  1535. * ambient: <hex>,
  1536. * specular: <hex>,
  1537. * shininess: <float>,
  1538. * map: new THREE.Texture( <Image> ),
  1539. * specular_map: new THREE.Texture( <Image> ),
  1540. * env_map: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
  1541. * combine: THREE.Multiply,
  1542. * reflectivity: <float>,
  1543. * refraction_ratio: <float>,
  1544. * opacity: <float>,
  1545. * shading: THREE.SmoothShading,
  1546. * blending: THREE.NormalBlending,
  1547. * wireframe: <boolean>,
  1548. * wireframe_linewidth: <float>
  1549. * }
  1550. */
  1551. THREE.MeshPhongMaterial = function ( parameters ) {
  1552. this.id = THREE.MeshPhongMaterialCounter.value ++;
  1553. this.color = new THREE.Color( 0xffffff );
  1554. this.ambient = new THREE.Color( 0x050505 );
  1555. this.specular = new THREE.Color( 0x111111 );
  1556. this.shininess = 30;
  1557. this.map = null;
  1558. this.specular_map = null;
  1559. this.env_map = null;
  1560. this.combine = THREE.MultiplyOperation;
  1561. this.reflectivity = 1;
  1562. this.refraction_ratio = 0.98;
  1563. this.fog = true;
  1564. this.opacity = 1;
  1565. this.shading = THREE.SmoothShading;
  1566. this.blending = THREE.NormalBlending;
  1567. this.wireframe = false;
  1568. this.wireframe_linewidth = 1;
  1569. this.wireframe_linecap = 'round';
  1570. this.wireframe_linejoin = 'round';
  1571. if ( parameters ) {
  1572. if ( parameters.color !== undefined ) this.color = new THREE.Color( parameters.color );
  1573. if ( parameters.ambient !== undefined ) this.ambient = new THREE.Color( parameters.ambient );
  1574. if ( parameters.specular !== undefined ) this.specular = new THREE.Color( parameters.specular );
  1575. if ( parameters.shininess !== undefined ) this.shininess = parameters.shininess;
  1576. if ( parameters.map !== undefined ) this.map = parameters.map;
  1577. if ( parameters.specular_map !== undefined ) this.specular_map = parameters.specular_map;
  1578. if ( parameters.env_map !== undefined ) this.env_map = parameters.env_map;
  1579. if ( parameters.combine !== undefined ) this.combine = parameters.combine;
  1580. if ( parameters.reflectivity !== undefined ) this.reflectivity = parameters.reflectivity;
  1581. if ( parameters.refraction_ratio !== undefined ) this.refraction_ratio = parameters.refraction_ratio;
  1582. if ( parameters.fog !== undefined ) this.fog = parameters.fog;
  1583. if ( parameters.opacity !== undefined ) this.opacity = parameters.opacity;
  1584. if ( parameters.shading !== undefined ) this.shading = parameters.shading;
  1585. if ( parameters.blending !== undefined ) this.blending = parameters.blending;
  1586. if ( parameters.wireframe !== undefined ) this.wireframe = parameters.wireframe;
  1587. if ( parameters.wireframe_linewidth !== undefined ) this.wireframe_linewidth = parameters.wireframe_linewidth;
  1588. if ( parameters.wireframe_linecap !== undefined ) this.wireframe_linecap = parameters.wireframe_linecap;
  1589. if ( parameters.wireframe_linejoin !== undefined ) this.wireframe_linejoin = parameters.wireframe_linejoin;
  1590. }
  1591. };
  1592. THREE.MeshPhongMaterial.prototype = {
  1593. toString: function () {
  1594. return 'THREE.MeshPhongMaterial (<br/>' +
  1595. 'id: ' + this.id + '<br/>' +
  1596. 'color: ' + this.color + '<br/>' +
  1597. 'ambient: ' + this.ambient + '<br/>' +
  1598. 'specular: ' + this.specular + '<br/>' +
  1599. 'shininess: ' + this.shininess + '<br/>' +
  1600. 'map: ' + this.map + '<br/>' +
  1601. 'specular_map: ' + this.specular_map + '<br/>' +
  1602. 'env_map: ' + this.env_map + '<br/>' +
  1603. 'combine: ' + this.combine + '<br/>' +
  1604. 'reflectivity: ' + this.reflectivity + '<br/>' +
  1605. 'refraction_ratio: ' + this.refraction_ratio + '<br/>' +
  1606. 'opacity: ' + this.opacity + '<br/>' +
  1607. 'shading: ' + this.shading + '<br/>' +
  1608. 'wireframe: ' + this.wireframe + '<br/>' +
  1609. 'wireframe_linewidth: ' + this.wireframe_linewidth + '<br/>' +
  1610. 'wireframe_linecap: ' + this.wireframe_linecap +'<br/>' +
  1611. 'wireframe_linejoin: ' + this.wireframe_linejoin +'<br/>' +
  1612. ')';
  1613. }
  1614. };
  1615. THREE.MeshPhongMaterialCounter = { value: 0 };
  1616. /**
  1617. * @author mr.doob / http://mrdoob.com/
  1618. *
  1619. * parameters = {
  1620. * opacity: <float>,
  1621. * blending: THREE.NormalBlending
  1622. * }
  1623. */
  1624. THREE.MeshDepthMaterial = function ( parameters ) {
  1625. this.opacity = 1;
  1626. this.shading = THREE.SmoothShading;
  1627. this.blending = THREE.NormalBlending;
  1628. this.wireframe = false;
  1629. this.wireframe_linewidth = 1;
  1630. this.wireframe_linecap = 'round';
  1631. this.wireframe_linejoin = 'round';
  1632. if ( parameters ) {
  1633. if ( parameters.opacity !== undefined ) this.opacity = parameters.opacity;
  1634. if ( parameters.blending !== undefined ) this.blending = parameters.blending;
  1635. }
  1636. };
  1637. THREE.MeshDepthMaterial.prototype = {
  1638. toString: function () {
  1639. return 'THREE.MeshDepthMaterial';
  1640. }
  1641. };
  1642. /**
  1643. * @author mr.doob / http://mrdoob.com/
  1644. *
  1645. * parameters = {
  1646. * opacity: <float>,
  1647. * shading: THREE.FlatShading,
  1648. * blending: THREE.NormalBlending
  1649. * }
  1650. */
  1651. THREE.MeshNormalMaterial = function ( parameters ) {
  1652. this.opacity = 1;
  1653. this.shading = THREE.FlatShading;
  1654. this.blending = THREE.NormalBlending;
  1655. if ( parameters ) {
  1656. if ( parameters.opacity !== undefined ) this.opacity = parameters.opacity;
  1657. if ( parameters.shading !== undefined ) this.shading = parameters.shading;
  1658. if ( parameters.blending !== undefined ) this.blending = parameters.blending;
  1659. }
  1660. };
  1661. THREE.MeshNormalMaterial.prototype = {
  1662. toString: function () {
  1663. return 'THREE.MeshNormalMaterial';
  1664. }
  1665. };
  1666. /**
  1667. * @author mr.doob / http://mrdoob.com/
  1668. */
  1669. THREE.MeshFaceMaterial = function () {
  1670. };
  1671. THREE.MeshFaceMaterial.prototype = {
  1672. toString: function () {
  1673. return 'THREE.MeshFaceMaterial';
  1674. }
  1675. };
  1676. /**
  1677. * @author alteredq / http://alteredqualia.com/
  1678. *
  1679. * parameters = {
  1680. * fragment_shader: <string>,
  1681. * vertex_shader: <string>,
  1682. * uniforms: { "parameter1": { type: "f", value: 1.0 }, "parameter2": { type: "i" value2: 2 } },
  1683. * shading: THREE.SmoothShading,
  1684. * blending: THREE.NormalBlending,
  1685. * wireframe: <boolean>,
  1686. * wireframe_linewidth: <float>
  1687. * }
  1688. */
  1689. THREE.MeshShaderMaterial = function ( parameters ) {
  1690. this.id = THREE.MeshShaderMaterialCounter.value ++;
  1691. this.fragment_shader = "void main() {}";
  1692. this.vertex_shader = "void main() {}";
  1693. this.uniforms = {};
  1694. this.opacity = 1;
  1695. this.shading = THREE.SmoothShading;
  1696. this.blending = THREE.NormalBlending;
  1697. this.wireframe = false;
  1698. this.wireframe_linewidth = 1;
  1699. this.wireframe_linecap = 'round';
  1700. this.wireframe_linejoin = 'round';
  1701. if ( parameters ) {
  1702. if ( parameters.fragment_shader !== undefined ) this.fragment_shader = parameters.fragment_shader;
  1703. if ( parameters.vertex_shader !== undefined ) this.vertex_shader = parameters.vertex_shader;
  1704. if ( parameters.uniforms !== undefined ) this.uniforms = parameters.uniforms;
  1705. if ( parameters.shading !== undefined ) this.shading = parameters.shading;
  1706. if ( parameters.blending !== undefined ) this.blending = parameters.blending;
  1707. if ( parameters.wireframe !== undefined ) this.wireframe = parameters.wireframe;
  1708. if ( parameters.wireframe_linewidth !== undefined ) this.wireframe_linewidth = parameters.wireframe_linewidth;
  1709. if ( parameters.wireframe_linecap !== undefined ) this.wireframe_linecap = parameters.wireframe_linecap;
  1710. if ( parameters.wireframe_linejoin !== undefined ) this.wireframe_linejoin = parameters.wireframe_linejoin;
  1711. }
  1712. };
  1713. THREE.MeshShaderMaterial.prototype = {
  1714. toString: function () {
  1715. return 'THREE.MeshShaderMaterial (<br/>' +
  1716. 'id: ' + this.id + '<br/>' +
  1717. 'blending: ' + this.blending + '<br/>' +
  1718. 'wireframe: ' + this.wireframe + '<br/>' +
  1719. 'wireframe_linewidth: ' + this.wireframe_linewidth +'<br/>' +
  1720. 'wireframe_linecap: ' + this.wireframe_linecap +'<br/>' +
  1721. 'wireframe_linejoin: ' + this.wireframe_linejoin +'<br/>' +
  1722. ')';
  1723. }
  1724. };
  1725. THREE.MeshShaderMaterialCounter = { value: 0 };
  1726. /**
  1727. * @author mr.doob / http://mrdoob.com/
  1728. *
  1729. * parameters = {
  1730. * color: <hex>,
  1731. * map: new THREE.Texture( <Image> ),
  1732. * opacity: <float>,
  1733. * blending: THREE.NormalBlending
  1734. * }
  1735. */
  1736. THREE.ParticleBasicMaterial = function ( parameters ) {
  1737. this.color = new THREE.Color( 0xffffff );
  1738. this.map = null;
  1739. this.opacity = 1;
  1740. this.blending = THREE.NormalBlending;
  1741. this.offset = new THREE.Vector2(); // TODO: expose to parameters
  1742. if ( parameters ) {
  1743. if ( parameters.color !== undefined ) this.color.setHex( parameters.color );
  1744. if ( parameters.map !== undefined ) this.map = parameters.map;
  1745. if ( parameters.opacity !== undefined ) this.opacity = parameters.opacity;
  1746. if ( parameters.blending !== undefined ) this.blending = parameters.blending;
  1747. }
  1748. };
  1749. THREE.ParticleBasicMaterial.prototype = {
  1750. toString: function () {
  1751. return 'THREE.ParticleBasicMaterial (<br/>' +
  1752. 'color: ' + this.color + '<br/>' +
  1753. 'map: ' + this.map + '<br/>' +
  1754. 'opacity: ' + this.opacity + '<br/>' +
  1755. 'blending: ' + this.blending + '<br/>' +
  1756. ')';
  1757. }
  1758. };
  1759. /**
  1760. * @author mr.doob / http://mrdoob.com/
  1761. *
  1762. * parameters = {
  1763. * color: <hex>,
  1764. * opacity: <float>,
  1765. * blending: THREE.NormalBlending
  1766. * }
  1767. */
  1768. THREE.ParticleCircleMaterial = function ( parameters ) {
  1769. this.color = new THREE.Color( 0xffffff );
  1770. this.opacity = 1;
  1771. this.blending = THREE.NormalBlending;
  1772. if ( parameters ) {
  1773. if ( parameters.color !== undefined ) this.color.setHex( parameters.color );
  1774. if ( parameters.opacity !== undefined ) this.opacity = parameters.opacity;
  1775. if ( parameters.blending !== undefined ) this.blending = parameters.blending;
  1776. }
  1777. };
  1778. THREE.ParticleCircleMaterial.prototype = {
  1779. toString: function () {
  1780. return 'THREE.ParticleCircleMaterial (<br/>' +
  1781. 'color: ' + this.color + '<br/>' +
  1782. 'opacity: ' + this.opacity + '<br/>' +
  1783. 'blending: ' + this.blending + '<br/>' +
  1784. ')';
  1785. }
  1786. };
  1787. /**
  1788. * @author mr.doob / http://mrdoob.com/
  1789. * @author alteredq / http://alteredqualia.com/
  1790. */
  1791. THREE.Texture = function ( image, mapping, wrap_s, wrap_t, mag_filter, min_filter ) {
  1792. this.image = image;
  1793. this.mapping = mapping !== undefined ? mapping : new THREE.UVMapping();
  1794. this.wrap_s = wrap_s !== undefined ? wrap_s : THREE.ClampToEdgeWrapping;
  1795. this.wrap_t = wrap_t !== undefined ? wrap_t : THREE.ClampToEdgeWrapping;
  1796. this.mag_filter = mag_filter !== undefined ? mag_filter : THREE.LinearFilter;
  1797. this.min_filter = min_filter !== undefined ? min_filter : THREE.LinearMipMapLinearFilter;
  1798. };
  1799. THREE.Texture.prototype = {
  1800. clone: function () {
  1801. return new THREE.Texture( this.image, this.mapping, this.wrap_s, this.wrap_t, this.mag_filter, this.min_filter );
  1802. },
  1803. toString: function () {
  1804. return 'THREE.Texture (<br/>' +
  1805. 'image: ' + this.image + '<br/>' +
  1806. 'wrap_s: ' + this.wrap_s + '<br/>' +
  1807. 'wrap_t: ' + this.wrap_t + '<br/>' +
  1808. 'mag_filter: ' + this.mag_filter + '<br/>' +
  1809. 'min_filter: ' + this.min_filter + '<br/>' +
  1810. ')';
  1811. }
  1812. };
  1813. THREE.MultiplyOperation = 0;
  1814. THREE.MixOperation = 1;
  1815. THREE.RepeatWrapping = 0;
  1816. THREE.ClampToEdgeWrapping = 1;
  1817. THREE.MirroredRepeatWrapping = 2;
  1818. THREE.NearestFilter = 3;
  1819. THREE.NearestMipMapNearestFilter = 4;
  1820. THREE.NearestMipMapLinearFilter = 5;
  1821. THREE.LinearFilter = 6;
  1822. THREE.LinearMipMapNearestFilter = 7;
  1823. THREE.LinearMipMapLinearFilter = 8;
  1824. THREE.RGBFormat = 9;
  1825. THREE.UnsignedByteType = 10;
  1826. THREE.RenderTexture = function ( width, height, options ) {
  1827. this.width = width;
  1828. this.height = height;
  1829. options = options || {};
  1830. this.wrap_s = options.wrap_s !== undefined ? options.wrap_s : THREE.ClampToEdgeWrapping;
  1831. this.wrap_t = options.wrap_t !== undefined ? options.wrap_t : THREE.ClampToEdgeWrapping;
  1832. this.mag_filter = options.mag_filter !== undefined ? options.mag_filter : THREE.LinearFilter;
  1833. this.min_filter = options.min_filter !== undefined ? options.min_filter : THREE.LinearFilter;
  1834. this.format = options.format !== undefined ? options.format : THREE.RGBFormat;
  1835. this.type = options.type !== undefined ? options.type : THREE.UnsignedByteType;
  1836. };
  1837. var Uniforms = {
  1838. clone: function( uniforms_src ) {
  1839. var u, p, parameter, parameter_src, uniforms_dst = {};
  1840. for ( u in uniforms_src ) {
  1841. uniforms_dst[ u ] = {};
  1842. for ( p in uniforms_src[ u ] ) {
  1843. parameter_src = uniforms_src[ u ][ p ];
  1844. if ( parameter_src instanceof THREE.Color ||
  1845. parameter_src instanceof THREE.Vector3 ||
  1846. parameter_src instanceof THREE.Texture ) {
  1847. uniforms_dst[ u ][ p ] = parameter_src.clone();
  1848. } else {
  1849. uniforms_dst[ u ][ p ] = parameter_src;
  1850. }
  1851. }
  1852. }
  1853. return uniforms_dst;
  1854. },
  1855. merge: function( uniforms ) {
  1856. var u, p, tmp, merged = {};
  1857. for( u = 0; u < uniforms.length; u++ ) {
  1858. tmp = this.clone( uniforms[ u ] );
  1859. for ( p in tmp ) {
  1860. merged[ p ] = tmp[ p ];
  1861. }
  1862. }
  1863. return merged;
  1864. }
  1865. };
  1866. /**
  1867. * @author mr.doob / http://mrdoob.com/
  1868. */
  1869. THREE.CubeReflectionMapping = function () {
  1870. };
  1871. /**
  1872. * @author mr.doob / http://mrdoob.com/
  1873. */
  1874. THREE.CubeRefractionMapping = function () {
  1875. };
  1876. /**
  1877. * @author mr.doob / http://mrdoob.com/
  1878. */
  1879. THREE.LatitudeReflectionMapping = function () {
  1880. };
  1881. /**
  1882. * @author mr.doob / http://mrdoob.com/
  1883. */
  1884. THREE.LatitudeRefractionMapping = function () {
  1885. };
  1886. /**
  1887. * @author mr.doob / http://mrdoob.com/
  1888. */
  1889. THREE.SphericalReflectionMapping = function () {
  1890. };
  1891. /**
  1892. * @author mr.doob / http://mrdoob.com/
  1893. */
  1894. THREE.SphericalRefractionMapping = function () {
  1895. };
  1896. /**
  1897. * @author mr.doob / http://mrdoob.com/
  1898. */
  1899. THREE.UVMapping = function () {
  1900. };
  1901. /**
  1902. * @author mr.doob / http://mrdoob.com/
  1903. */
  1904. THREE.Scene = function () {
  1905. this.objects = [];
  1906. this.lights = [];
  1907. this.fog = null;
  1908. this.addObject = function ( object ) {
  1909. var i = this.objects.indexOf( object );
  1910. if ( i === -1 ) {
  1911. this.objects.push( object );
  1912. }
  1913. };
  1914. this.removeObject = function ( object ) {
  1915. var i = this.objects.indexOf( object );
  1916. if ( i !== -1 ) {
  1917. this.objects.splice( i, 1 );
  1918. }
  1919. };
  1920. this.addLight = function ( light ) {
  1921. var i = this.lights.indexOf( light );
  1922. if ( i === -1 ) {
  1923. this.lights.push( light );
  1924. }
  1925. };
  1926. this.removeLight = function ( light ) {
  1927. var i = this.lights.indexOf( light );
  1928. if ( i !== -1 ) {
  1929. this.lights.splice( i, 1 );
  1930. }
  1931. };
  1932. this.toString = function () {
  1933. return 'THREE.Scene ( ' + this.objects + ' )';
  1934. };
  1935. };
  1936. /**
  1937. * @author mr.doob / http://mrdoob.com/
  1938. * @author alteredq / http://alteredqualia.com/
  1939. */
  1940. THREE.Fog = function ( hex, near, far ) {
  1941. this.color = new THREE.Color( hex );
  1942. this.near = near || 1;
  1943. this.far = far || 1000;
  1944. };
  1945. /**
  1946. * @author mr.doob / http://mrdoob.com/
  1947. * @author alteredq / http://alteredqualia.com/
  1948. */
  1949. THREE.FogExp2 = function ( hex, density ) {
  1950. this.color = new THREE.Color( hex );
  1951. this.density = density || 0.00025;
  1952. };
  1953. /**
  1954. * @author supereggbert / http://www.paulbrunt.co.uk/
  1955. * @author mrdoob / http://mrdoob.com/
  1956. * @author alteredq / http://alteredqualia.com/
  1957. */
  1958. THREE.WebGLRenderer = function ( parameters ) {
  1959. // Currently you can use just up to 4 directional / point lights total.
  1960. // Chrome barfs on shader linking when there are more than 4 lights :(
  1961. // The problem comes from shader using too many varying vectors.
  1962. // This is not GPU limitation as the same shader works ok in Firefox
  1963. // and Chrome with "--use-gl=desktop" flag.
  1964. // Difference comes from Chrome on Windows using by default ANGLE,
  1965. // thus going DirectX9 route (while FF uses OpenGL).
  1966. // See http://code.google.com/p/chromium/issues/detail?id=63491
  1967. var _canvas = document.createElement( 'canvas' ), _gl,
  1968. _oldProgram = null,
  1969. _modelViewMatrix = new THREE.Matrix4(), _normalMatrix,
  1970. _viewMatrixArray = new Float32Array(16),
  1971. _modelViewMatrixArray = new Float32Array(16),
  1972. _projectionMatrixArray = new Float32Array(16),
  1973. _normalMatrixArray = new Float32Array(9),
  1974. _objectMatrixArray = new Float32Array(16),
  1975. // parameters defaults
  1976. antialias = true,
  1977. clearColor = new THREE.Color( 0x000000 ),
  1978. clearAlpha = 0;
  1979. if ( parameters ) {
  1980. if ( parameters.antialias !== undefined ) antialias = parameters.antialias;
  1981. if ( parameters.clearColor !== undefined ) clearColor.setHex( parameters.clearColor );
  1982. if ( parameters.clearAlpha !== undefined ) clearAlpha = parameters.clearAlpha;
  1983. }
  1984. this.domElement = _canvas;
  1985. this.autoClear = true;
  1986. initGL( antialias, clearColor, clearAlpha );
  1987. //alert( dumpObject( getGLParams() ) );
  1988. this.setSize = function ( width, height ) {
  1989. _canvas.width = width;
  1990. _canvas.height = height;
  1991. _gl.viewport( 0, 0, _canvas.width, _canvas.height );
  1992. };
  1993. this.setClearColor = function( hex, alpha ) {
  1994. var color = new THREE.Color( hex );
  1995. _gl.clearColor( color.r, color.g, color.b, alpha );
  1996. };
  1997. this.clear = function () {
  1998. _gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT );
  1999. };
  2000. this.setupLights = function ( program, lights ) {
  2001. var l, ll, light, r = 0, g = 0, b = 0,
  2002. dcolors = [], dpositions = [],
  2003. pcolors = [], ppositions = [];
  2004. for ( l = 0, ll = lights.length; l < ll; l++ ) {
  2005. light = lights[ l ];
  2006. if ( light instanceof THREE.AmbientLight ) {
  2007. r += light.color.r;
  2008. g += light.color.g;
  2009. b += light.color.b;
  2010. } else if ( light instanceof THREE.DirectionalLight ) {
  2011. dcolors.push( light.color.r * light.intensity,
  2012. light.color.g * light.intensity,
  2013. light.color.b * light.intensity );
  2014. dpositions.push( light.position.x,
  2015. light.position.y,
  2016. light.position.z );
  2017. } else if( light instanceof THREE.PointLight ) {
  2018. pcolors.push( light.color.r * light.intensity,
  2019. light.color.g * light.intensity,
  2020. light.color.b * light.intensity );
  2021. ppositions.push( light.position.x,
  2022. light.position.y,
  2023. light.position.z );
  2024. }
  2025. }
  2026. return { ambient: [ r, g, b ], directional: { colors: dcolors, positions: dpositions }, point: { colors: pcolors, positions: ppositions } };
  2027. };
  2028. this.createParticleBuffers = function( object ) {
  2029. };
  2030. this.createLineBuffers = function( object ) {
  2031. var v, vl, vertex,
  2032. vertexArray = [], lineArray = [],
  2033. vertices = object.geometry.vertices;
  2034. for ( v = 0, vl = vertices.length; v < vl; v++ ) {
  2035. vertex = vertices[ v ].position;
  2036. vertexArray.push( vertex.x, vertex.y, vertex.z );
  2037. lineArray.push( v );
  2038. }
  2039. if ( !vertexArray.length ) {
  2040. return;
  2041. }
  2042. object.__webGLVertexBuffer = _gl.createBuffer();
  2043. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLVertexBuffer );
  2044. _gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( vertexArray ), _gl.STATIC_DRAW );
  2045. object.__webGLLineBuffer = _gl.createBuffer();
  2046. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, object.__webGLLineBuffer );
  2047. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( lineArray ), _gl.STATIC_DRAW );
  2048. object.__webGLLineCount = lineArray.length;
  2049. };
  2050. this.createBuffers = function ( object, g ) {
  2051. var f, fl, fi, face, vertexNormals, faceNormal, normal, uv, v1, v2, v3, v4, t1, t2, t3, t4, m, ml, i,
  2052. faceArray = [],
  2053. lineArray = [],
  2054. vertexArray = [],
  2055. normalArray = [],
  2056. tangentArray = [],
  2057. uvArray = [],
  2058. vertexIndex = 0,
  2059. geometryChunk = object.geometry.geometryChunks[ g ],
  2060. needsSmoothNormals = bufferNeedsSmoothNormals ( geometryChunk, object );
  2061. for ( f = 0, fl = geometryChunk.faces.length; f < fl; f++ ) {
  2062. fi = geometryChunk.faces[ f ];
  2063. face = object.geometry.faces[ fi ];
  2064. vertexNormals = face.vertexNormals;
  2065. faceNormal = face.normal;
  2066. uv = object.geometry.uvs[ fi ];
  2067. if ( face instanceof THREE.Face3 ) {
  2068. v1 = object.geometry.vertices[ face.a ].position;
  2069. v2 = object.geometry.vertices[ face.b ].position;
  2070. v3 = object.geometry.vertices[ face.c ].position;
  2071. vertexArray.push( v1.x, v1.y, v1.z,
  2072. v2.x, v2.y, v2.z,
  2073. v3.x, v3.y, v3.z );
  2074. if ( object.geometry.hasTangents ) {
  2075. t1 = object.geometry.vertices[ face.a ].tangent;
  2076. t2 = object.geometry.vertices[ face.b ].tangent;
  2077. t3 = object.geometry.vertices[ face.c ].tangent;
  2078. tangentArray.push( t1.x, t1.y, t1.z, t1.w,
  2079. t2.x, t2.y, t2.z, t2.w,
  2080. t3.x, t3.y, t3.z, t3.w );
  2081. }
  2082. if ( vertexNormals.length == 3 && needsSmoothNormals ) {
  2083. for ( i = 0; i < 3; i ++ ) {
  2084. normalArray.push( vertexNormals[ i ].x, vertexNormals[ i ].y, vertexNormals[ i ].z );
  2085. }
  2086. } else {
  2087. for ( i = 0; i < 3; i ++ ) {
  2088. normalArray.push( faceNormal.x, faceNormal.y, faceNormal.z );
  2089. }
  2090. }
  2091. if ( uv ) {
  2092. for ( i = 0; i < 3; i ++ ) {
  2093. uvArray.push( uv[ i ].u, uv[ i ].v );
  2094. }
  2095. }
  2096. faceArray.push( vertexIndex, vertexIndex + 1, vertexIndex + 2 );
  2097. // TODO: don't add lines that already exist (faces sharing edge)
  2098. lineArray.push( vertexIndex, vertexIndex + 1,
  2099. vertexIndex, vertexIndex + 2,
  2100. vertexIndex + 1, vertexIndex + 2 );
  2101. vertexIndex += 3;
  2102. } else if ( face instanceof THREE.Face4 ) {
  2103. v1 = object.geometry.vertices[ face.a ].position;
  2104. v2 = object.geometry.vertices[ face.b ].position;
  2105. v3 = object.geometry.vertices[ face.c ].position;
  2106. v4 = object.geometry.vertices[ face.d ].position;
  2107. vertexArray.push( v1.x, v1.y, v1.z,
  2108. v2.x, v2.y, v2.z,
  2109. v3.x, v3.y, v3.z,
  2110. v4.x, v4.y, v4.z );
  2111. if ( object.geometry.hasTangents ) {
  2112. t1 = object.geometry.vertices[ face.a ].tangent;
  2113. t2 = object.geometry.vertices[ face.b ].tangent;
  2114. t3 = object.geometry.vertices[ face.c ].tangent;
  2115. t4 = object.geometry.vertices[ face.d ].tangent;
  2116. tangentArray.push( t1.x, t1.y, t1.z, t1.w,
  2117. t2.x, t2.y, t2.z, t2.w,
  2118. t3.x, t3.y, t3.z, t3.w,
  2119. t4.x, t4.y, t4.z, t4.w );
  2120. }
  2121. if ( vertexNormals.length == 4 && needsSmoothNormals ) {
  2122. for ( i = 0; i < 4; i ++ ) {
  2123. normalArray.push( vertexNormals[ i ].x, vertexNormals[ i ].y, vertexNormals[ i ].z );
  2124. }
  2125. } else {
  2126. for ( i = 0; i < 4; i ++ ) {
  2127. normalArray.push( faceNormal.x, faceNormal.y, faceNormal.z );
  2128. }
  2129. }
  2130. if ( uv ) {
  2131. for ( i = 0; i < 4; i ++ ) {
  2132. uvArray.push( uv[ i ].u, uv[ i ].v );
  2133. }
  2134. }
  2135. faceArray.push( vertexIndex, vertexIndex + 1, vertexIndex + 2,
  2136. vertexIndex, vertexIndex + 2, vertexIndex + 3 );
  2137. // TODO: don't add lines that already exist (faces sharing edge)
  2138. lineArray.push( vertexIndex, vertexIndex + 1,
  2139. vertexIndex, vertexIndex + 2,
  2140. vertexIndex, vertexIndex + 3,
  2141. vertexIndex + 1, vertexIndex + 2,
  2142. vertexIndex + 2, vertexIndex + 3 );
  2143. vertexIndex += 4;
  2144. }
  2145. }
  2146. if ( !vertexArray.length ) {
  2147. return;
  2148. }
  2149. geometryChunk.__webGLVertexBuffer = _gl.createBuffer();
  2150. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLVertexBuffer );
  2151. _gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( vertexArray ), _gl.STATIC_DRAW );
  2152. geometryChunk.__webGLNormalBuffer = _gl.createBuffer();
  2153. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLNormalBuffer );
  2154. _gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( normalArray ), _gl.STATIC_DRAW );
  2155. if ( object.geometry.hasTangents ) {
  2156. geometryChunk.__webGLTangentBuffer = _gl.createBuffer();
  2157. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLTangentBuffer );
  2158. _gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( tangentArray ), _gl.STATIC_DRAW );
  2159. }
  2160. if ( uvArray.length > 0 ) {
  2161. geometryChunk.__webGLUVBuffer = _gl.createBuffer();
  2162. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLUVBuffer );
  2163. _gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( uvArray ), _gl.STATIC_DRAW );
  2164. }
  2165. geometryChunk.__webGLFaceBuffer = _gl.createBuffer();
  2166. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLFaceBuffer );
  2167. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( faceArray ), _gl.STATIC_DRAW );
  2168. geometryChunk.__webGLLineBuffer = _gl.createBuffer();
  2169. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLLineBuffer );
  2170. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( lineArray ), _gl.STATIC_DRAW );
  2171. geometryChunk.__webGLFaceCount = faceArray.length;
  2172. geometryChunk.__webGLLineCount = lineArray.length;
  2173. };
  2174. function setMaterialShaders( material, shaders ) {
  2175. material.fragment_shader = shaders.fragment_shader;
  2176. material.vertex_shader = shaders.vertex_shader;
  2177. material.uniforms = Uniforms.clone( shaders.uniforms );
  2178. };
  2179. function refreshUniformsCommon( material, fog ) {
  2180. // premultiply alpha
  2181. material.uniforms.color.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
  2182. // pure color
  2183. //material.uniforms.color.value.setHex( material.color.hex );
  2184. material.uniforms.opacity.value = material.opacity;
  2185. material.uniforms.map.texture = material.map;
  2186. material.uniforms.env_map.texture = material.env_map;
  2187. material.uniforms.reflectivity.value = material.reflectivity;
  2188. material.uniforms.refraction_ratio.value = material.refraction_ratio;
  2189. material.uniforms.combine.value = material.combine;
  2190. material.uniforms.useRefract.value = material.env_map && material.env_map.mapping instanceof THREE.CubeRefractionMapping;
  2191. if ( fog ) {
  2192. material.uniforms.fogColor.value.setHex( fog.color.hex );
  2193. if ( fog instanceof THREE.Fog ) {
  2194. material.uniforms.fogNear.value = fog.near;
  2195. material.uniforms.fogFar.value = fog.far;
  2196. } else if ( fog instanceof THREE.FogExp2 ) {
  2197. material.uniforms.fogDensity.value = fog.density;
  2198. }
  2199. }
  2200. };
  2201. function refreshUniformsLine( material, fog ) {
  2202. material.uniforms.color.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity );
  2203. material.uniforms.opacity.value = material.opacity;
  2204. if ( fog ) {
  2205. material.uniforms.fogColor.value.setHex( fog.color.hex );
  2206. if ( fog instanceof THREE.Fog ) {
  2207. material.uniforms.fogNear.value = fog.near;
  2208. material.uniforms.fogFar.value = fog.far;
  2209. } else if ( fog instanceof THREE.FogExp2 ) {
  2210. material.uniforms.fogDensity.value = fog.density;
  2211. }
  2212. }
  2213. };
  2214. function refreshUniformsPhong( material ) {
  2215. //material.uniforms.ambient.value.setHex( material.ambient.hex );
  2216. //material.uniforms.specular.value.setHex( material.specular.hex );
  2217. material.uniforms.ambient.value.setRGB( material.ambient.r, material.ambient.g, material.ambient.b );
  2218. material.uniforms.specular.value.setRGB( material.specular.r, material.specular.g, material.specular.b );
  2219. material.uniforms.shininess.value = material.shininess;
  2220. };
  2221. function refreshLights( material, lights ) {
  2222. material.uniforms.enableLighting.value = lights.directional.positions.length + lights.point.positions.length;
  2223. material.uniforms.ambientLightColor.value = lights.ambient;
  2224. material.uniforms.directionalLightColor.value = lights.directional.colors;
  2225. material.uniforms.directionalLightDirection.value = lights.directional.positions;
  2226. material.uniforms.pointLightColor.value = lights.point.colors;
  2227. material.uniforms.pointLightPosition.value = lights.point.positions;
  2228. };
  2229. this.renderBuffer = function ( camera, lights, fog, material, geometryChunk ) {
  2230. var program, u, identifiers, attributes, parameters, vector_lights, maxLightCount, linewidth, primitives;
  2231. if ( !material.program ) {
  2232. if ( material instanceof THREE.MeshDepthMaterial ) {
  2233. setMaterialShaders( material, THREE.ShaderLib[ 'depth' ] );
  2234. material.uniforms.mNear.value = camera.near;
  2235. material.uniforms.mFar.value = camera.far;
  2236. } else if ( material instanceof THREE.MeshNormalMaterial ) {
  2237. setMaterialShaders( material, THREE.ShaderLib[ 'normal' ] );
  2238. } else if ( material instanceof THREE.MeshBasicMaterial ) {
  2239. setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] );
  2240. refreshUniformsCommon( material, fog );
  2241. } else if ( material instanceof THREE.MeshLambertMaterial ) {
  2242. setMaterialShaders( material, THREE.ShaderLib[ 'lambert' ] );
  2243. refreshUniformsCommon( material, fog );
  2244. } else if ( material instanceof THREE.MeshPhongMaterial ) {
  2245. setMaterialShaders( material, THREE.ShaderLib[ 'phong' ] );
  2246. refreshUniformsCommon( material, fog );
  2247. } else if ( material instanceof THREE.LineBasicMaterial ) {
  2248. setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] );
  2249. refreshUniformsLine( material, fog );
  2250. }
  2251. // heuristics to create shader parameters according to lights in the scene
  2252. // (not to blow over maxLights budget)
  2253. maxLightCount = allocateLights( lights, 4 );
  2254. parameters = { fog: fog, map: material.map, env_map: material.env_map, maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point };
  2255. material.program = buildProgram( material.fragment_shader, material.vertex_shader, parameters );
  2256. identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition' ];
  2257. for( u in material.uniforms ) {
  2258. identifiers.push(u);
  2259. }
  2260. cacheUniformLocations( material.program, identifiers );
  2261. cacheAttributeLocations( material.program, [ "position", "normal", "uv", "tangent" ] );
  2262. }
  2263. program = material.program;
  2264. if( program != _oldProgram ) {
  2265. _gl.useProgram( program );
  2266. _oldProgram = program;
  2267. }
  2268. this.loadCamera( program, camera );
  2269. this.loadMatrices( program );
  2270. if ( material instanceof THREE.MeshPhongMaterial ||
  2271. material instanceof THREE.MeshLambertMaterial ) {
  2272. vector_lights = this.setupLights( program, lights );
  2273. refreshLights( material, vector_lights );
  2274. }
  2275. if ( material instanceof THREE.MeshBasicMaterial ||
  2276. material instanceof THREE.MeshLambertMaterial ||
  2277. material instanceof THREE.MeshPhongMaterial ) {
  2278. refreshUniformsCommon( material, fog );
  2279. }
  2280. if ( material instanceof THREE.LineBasicMaterial ) {
  2281. refreshUniformsLine( material, fog );
  2282. }
  2283. if ( material instanceof THREE.MeshPhongMaterial ) {
  2284. refreshUniformsPhong( material );
  2285. }
  2286. setUniforms( program, material.uniforms );
  2287. attributes = program.attributes;
  2288. // vertices
  2289. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLVertexBuffer );
  2290. _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
  2291. _gl.enableVertexAttribArray( attributes.position );
  2292. // normals
  2293. if ( attributes.normal >= 0 ) {
  2294. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLNormalBuffer );
  2295. _gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
  2296. _gl.enableVertexAttribArray( attributes.normal );
  2297. }
  2298. // tangents
  2299. if ( attributes.tangent >= 0 ) {
  2300. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLTangentBuffer );
  2301. _gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
  2302. _gl.enableVertexAttribArray( attributes.tangent );
  2303. }
  2304. // uvs
  2305. if ( attributes.uv >= 0 ) {
  2306. if ( geometryChunk.__webGLUVBuffer ) {
  2307. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLUVBuffer );
  2308. _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
  2309. _gl.enableVertexAttribArray( attributes.uv );
  2310. } else {
  2311. _gl.disableVertexAttribArray( attributes.uv );
  2312. }
  2313. }
  2314. // render lines
  2315. if ( material.wireframe || material instanceof THREE.LineBasicMaterial ) {
  2316. linewidth = material.wireframe_linewidth !== undefined ? material.wireframe_linewidth :
  2317. material.linewidth !== undefined ? material.linewidth : 1;
  2318. primitives = material instanceof THREE.LineBasicMaterial && geometryChunk.type == THREE.LineStrip ? _gl.LINE_STRIP : _gl.LINES;
  2319. _gl.lineWidth( linewidth );
  2320. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLLineBuffer );
  2321. _gl.drawElements( primitives, geometryChunk.__webGLLineCount, _gl.UNSIGNED_SHORT, 0 );
  2322. // render triangles
  2323. } else {
  2324. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLFaceBuffer );
  2325. _gl.drawElements( _gl.TRIANGLES, geometryChunk.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
  2326. }
  2327. };
  2328. this.renderPass = function ( camera, lights, fog, object, geometryChunk, blending, transparent ) {
  2329. var i, l, m, ml, material, meshMaterial;
  2330. for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
  2331. meshMaterial = object.materials[ m ];
  2332. if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
  2333. for ( i = 0, l = geometryChunk.materials.length; i < l; i++ ) {
  2334. material = geometryChunk.materials[ i ];
  2335. if ( material && material.blending == blending && ( material.opacity < 1.0 == transparent ) ) {
  2336. this.setBlending( material.blending );
  2337. this.renderBuffer( camera, lights, fog, material, geometryChunk );
  2338. }
  2339. }
  2340. } else {
  2341. material = meshMaterial;
  2342. if ( material && material.blending == blending && ( material.opacity < 1.0 == transparent ) ) {
  2343. this.setBlending( material.blending );
  2344. this.renderBuffer( camera, lights, fog, material, geometryChunk );
  2345. }
  2346. }
  2347. }
  2348. };
  2349. this.render = function( scene, camera, renderTarget ) {
  2350. var o, ol, webGLObject, object, buffer,
  2351. lights = scene.lights,
  2352. fog = scene.fog;
  2353. this.initWebGLObjects( scene );
  2354. setRenderTarget( renderTarget );
  2355. if ( this.autoClear ) {
  2356. this.clear();
  2357. }
  2358. camera.autoUpdateMatrix && camera.updateMatrix();
  2359. _viewMatrixArray.set( camera.matrix.flatten() );
  2360. _projectionMatrixArray.set( camera.projectionMatrix.flatten() );
  2361. // opaque pass
  2362. for ( o = 0, ol = scene.__webGLObjects.length; o < ol; o++ ) {
  2363. webGLObject = scene.__webGLObjects[ o ];
  2364. object = webGLObject.object;
  2365. buffer = webGLObject.buffer;
  2366. if ( object.visible ) {
  2367. this.setupMatrices( object, camera );
  2368. this.renderPass( camera, lights, fog, object, buffer, THREE.NormalBlending, false );
  2369. }
  2370. }
  2371. // transparent pass
  2372. for ( o = 0, ol = scene.__webGLObjects.length; o < ol; o++ ) {
  2373. webGLObject = scene.__webGLObjects[ o ];
  2374. object = webGLObject.object;
  2375. buffer = webGLObject.buffer;
  2376. if ( object.visible ) {
  2377. this.setupMatrices( object, camera );
  2378. // opaque blended materials
  2379. this.renderPass( camera, lights, fog, object, buffer, THREE.AdditiveBlending, false );
  2380. this.renderPass( camera, lights, fog, object, buffer, THREE.SubtractiveBlending, false );
  2381. // transparent blended materials
  2382. this.renderPass( camera, lights, fog, object, buffer, THREE.AdditiveBlending, true );
  2383. this.renderPass( camera, lights, fog, object, buffer, THREE.SubtractiveBlending, true );
  2384. // transparent normal materials
  2385. this.renderPass( camera, lights, fog, object, buffer, THREE.NormalBlending, true );
  2386. }
  2387. }
  2388. };
  2389. this.initWebGLObjects = function( scene ) {
  2390. function add_buffer( objmap, id, buffer, object ) {
  2391. if ( objmap[ id ] == undefined ) {
  2392. scene.__webGLObjects.push( { buffer: buffer, object: object } );
  2393. objmap[ id ] = 1;
  2394. }
  2395. };
  2396. var o, ol, object, g, geometryChunk, objmap;
  2397. if ( !scene.__webGLObjects ) {
  2398. scene.__webGLObjects = [];
  2399. scene.__webGLObjectsMap = {};
  2400. }
  2401. for ( o = 0, ol = scene.objects.length; o < ol; o++ ) {
  2402. object = scene.objects[ o ];
  2403. if ( scene.__webGLObjectsMap[ object.id ] == undefined ) {
  2404. scene.__webGLObjectsMap[ object.id ] = {};
  2405. }
  2406. objmap = scene.__webGLObjectsMap[ object.id ];
  2407. if ( object instanceof THREE.Mesh ) {
  2408. // create separate VBOs per geometry chunk
  2409. for ( g in object.geometry.geometryChunks ) {
  2410. geometryChunk = object.geometry.geometryChunks[ g ];
  2411. // initialise VBO on the first access
  2412. if( ! geometryChunk.__webGLVertexBuffer ) {
  2413. this.createBuffers( object, g );
  2414. }
  2415. // create separate wrapper per each use of VBO
  2416. add_buffer( objmap, g, geometryChunk, object );
  2417. }
  2418. } else if ( object instanceof THREE.Line ) {
  2419. if( ! object.__webGLVertexBuffer ) {
  2420. this.createLineBuffers( object );
  2421. }
  2422. add_buffer( objmap, 0, object, object );
  2423. } else if ( object instanceof THREE.ParticleSystem ) {
  2424. if( ! object.__webGLVertexBuffer ) {
  2425. this.createParticleBuffers( object );
  2426. }
  2427. add_buffer( objmap, 0, object, object );
  2428. }/*else if ( object instanceof THREE.Particle ) {
  2429. }*/
  2430. }
  2431. };
  2432. this.removeObject = function ( scene, object ) {
  2433. var o, ol, zobject;
  2434. for ( o = scene.__webGLObjects.length - 1; o >= 0; o-- ) {
  2435. zobject = scene.__webGLObjects[ o ].object;
  2436. if ( object == zobject ) {
  2437. scene.__webGLObjects.splice( o, 1 );
  2438. }
  2439. }
  2440. };
  2441. this.setupMatrices = function ( object, camera ) {
  2442. object.autoUpdateMatrix && object.updateMatrix();
  2443. _modelViewMatrix.multiply( camera.matrix, object.matrix );
  2444. _modelViewMatrixArray.set( _modelViewMatrix.flatten() );
  2445. _normalMatrix = THREE.Matrix4.makeInvert3x3( _modelViewMatrix ).transpose();
  2446. _normalMatrixArray.set( _normalMatrix.m );
  2447. _objectMatrixArray.set( object.matrix.flatten() );
  2448. };
  2449. this.loadMatrices = function ( program ) {
  2450. _gl.uniformMatrix4fv( program.uniforms.viewMatrix, false, _viewMatrixArray );
  2451. _gl.uniformMatrix4fv( program.uniforms.modelViewMatrix, false, _modelViewMatrixArray );
  2452. _gl.uniformMatrix4fv( program.uniforms.projectionMatrix, false, _projectionMatrixArray );
  2453. _gl.uniformMatrix3fv( program.uniforms.normalMatrix, false, _normalMatrixArray );
  2454. _gl.uniformMatrix4fv( program.uniforms.objectMatrix, false, _objectMatrixArray );
  2455. };
  2456. this.loadCamera = function( program, camera ) {
  2457. _gl.uniform3f( program.uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
  2458. };
  2459. this.setBlending = function( blending ) {
  2460. switch ( blending ) {
  2461. case THREE.AdditiveBlending:
  2462. _gl.blendEquation( _gl.FUNC_ADD );
  2463. _gl.blendFunc( _gl.ONE, _gl.ONE );
  2464. break;
  2465. case THREE.SubtractiveBlending:
  2466. //_gl.blendEquation( _gl.FUNC_SUBTRACT );
  2467. _gl.blendFunc( _gl.DST_COLOR, _gl.ZERO );
  2468. break;
  2469. default:
  2470. _gl.blendEquation( _gl.FUNC_ADD );
  2471. _gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
  2472. break;
  2473. }
  2474. };
  2475. this.setFaceCulling = function ( cullFace, frontFace ) {
  2476. if ( cullFace ) {
  2477. if ( !frontFace || frontFace == "ccw" ) {
  2478. _gl.frontFace( _gl.CCW );
  2479. } else {
  2480. _gl.frontFace( _gl.CW );
  2481. }
  2482. if( cullFace == "back" ) {
  2483. _gl.cullFace( _gl.BACK );
  2484. } else if( cullFace == "front" ) {
  2485. _gl.cullFace( _gl.FRONT );
  2486. } else {
  2487. _gl.cullFace( _gl.FRONT_AND_BACK );
  2488. }
  2489. _gl.enable( _gl.CULL_FACE );
  2490. } else {
  2491. _gl.disable( _gl.CULL_FACE );
  2492. }
  2493. };
  2494. this.supportsVertexTextures = function() {
  2495. return maxVertexTextures() > 0;
  2496. };
  2497. function maxVertexTextures() {
  2498. return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
  2499. };
  2500. function initGL( antialias, clearColor, clearAlpha ) {
  2501. try {
  2502. _gl = _canvas.getContext( 'experimental-webgl', { antialias: antialias } );
  2503. } catch(e) { }
  2504. if (!_gl) {
  2505. alert("WebGL not supported");
  2506. throw "cannot create webgl context";
  2507. }
  2508. _gl.clearColor( 0, 0, 0, 1 );
  2509. _gl.clearDepth( 1 );
  2510. _gl.enable( _gl.DEPTH_TEST );
  2511. _gl.depthFunc( _gl.LEQUAL );
  2512. _gl.frontFace( _gl.CCW );
  2513. _gl.cullFace( _gl.BACK );
  2514. _gl.enable( _gl.CULL_FACE );
  2515. _gl.enable( _gl.BLEND );
  2516. _gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
  2517. _gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
  2518. };
  2519. function buildProgram( fragment_shader, vertex_shader, parameters ) {
  2520. var program = _gl.createProgram(),
  2521. prefix_fragment = [
  2522. "#ifdef GL_ES",
  2523. "precision highp float;",
  2524. "#endif",
  2525. "#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
  2526. "#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
  2527. parameters.fog ? "#define USE_FOG" : "",
  2528. parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
  2529. parameters.map ? "#define USE_MAP" : "",
  2530. parameters.env_map ? "#define USE_ENVMAP" : "",
  2531. "uniform mat4 viewMatrix;",
  2532. "uniform vec3 cameraPosition;",
  2533. ""
  2534. ].join("\n"),
  2535. prefix_vertex = [
  2536. maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
  2537. "#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
  2538. "#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
  2539. parameters.map ? "#define USE_MAP" : "",
  2540. parameters.env_map ? "#define USE_ENVMAP" : "",
  2541. "uniform mat4 objectMatrix;",
  2542. "uniform mat4 modelViewMatrix;",
  2543. "uniform mat4 projectionMatrix;",
  2544. "uniform mat4 viewMatrix;",
  2545. "uniform mat3 normalMatrix;",
  2546. "uniform vec3 cameraPosition;",
  2547. "attribute vec3 position;",
  2548. "attribute vec3 normal;",
  2549. "attribute vec2 uv;",
  2550. ""
  2551. ].join("\n");
  2552. _gl.attachShader( program, getShader( "fragment", prefix_fragment + fragment_shader ) );
  2553. _gl.attachShader( program, getShader( "vertex", prefix_vertex + vertex_shader ) );
  2554. _gl.linkProgram( program );
  2555. if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
  2556. alert( "Could not initialise shaders\n"+
  2557. "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
  2558. //console.log( prefix_fragment + fragment_shader );
  2559. //console.log( prefix_vertex + vertex_shader );
  2560. }
  2561. program.uniforms = {};
  2562. program.attributes = {};
  2563. return program;
  2564. };
  2565. function setUniforms( program, uniforms ) {
  2566. var u, value, type, location, texture;
  2567. for( u in uniforms ) {
  2568. location = program.uniforms[u];
  2569. if ( !location ) continue;
  2570. type = uniforms[u].type;
  2571. value = uniforms[u].value;
  2572. if( type == "i" ) {
  2573. _gl.uniform1i( location, value );
  2574. } else if( type == "f" ) {
  2575. _gl.uniform1f( location, value );
  2576. } else if( type == "fv" ) {
  2577. _gl.uniform3fv( location, value );
  2578. } else if( type == "v2" ) {
  2579. _gl.uniform2f( location, value.x, value.y );
  2580. } else if( type == "v3" ) {
  2581. _gl.uniform3f( location, value.x, value.y, value.z );
  2582. } else if( type == "c" ) {
  2583. _gl.uniform3f( location, value.r, value.g, value.b );
  2584. } else if( type == "t" ) {
  2585. _gl.uniform1i( location, value );
  2586. texture = uniforms[u].texture;
  2587. if ( !texture ) continue;
  2588. if ( texture.image instanceof Array && texture.image.length == 6 ) {
  2589. setCubeTexture( texture, value );
  2590. } else {
  2591. setTexture( texture, value );
  2592. }
  2593. }
  2594. }
  2595. };
  2596. function setCubeTexture( texture, slot ) {
  2597. if ( texture.image.length == 6 ) {
  2598. if ( !texture.image.__webGLTextureCube &&
  2599. !texture.image.__cubeMapInitialized && texture.image.loadCount == 6 ) {
  2600. texture.image.__webGLTextureCube = _gl.createTexture();
  2601. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
  2602. _gl.texParameteri( _gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
  2603. _gl.texParameteri( _gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
  2604. _gl.texParameteri( _gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_MAG_FILTER, _gl.LINEAR );
  2605. _gl.texParameteri( _gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR_MIPMAP_LINEAR );
  2606. for ( var i = 0; i < 6; ++i ) {
  2607. _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
  2608. }
  2609. _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
  2610. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
  2611. texture.image.__cubeMapInitialized = true;
  2612. }
  2613. _gl.activeTexture( _gl.TEXTURE0 + slot );
  2614. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
  2615. }
  2616. };
  2617. function setTexture( texture, slot ) {
  2618. if ( !texture.__webGLTexture && texture.image.loaded ) {
  2619. texture.__webGLTexture = _gl.createTexture();
  2620. _gl.bindTexture( _gl.TEXTURE_2D, texture.__webGLTexture );
  2621. _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
  2622. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrap_s ) );
  2623. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrap_t ) );
  2624. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.mag_filter ) );
  2625. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.min_filter ) );
  2626. _gl.generateMipmap( _gl.TEXTURE_2D );
  2627. _gl.bindTexture( _gl.TEXTURE_2D, null );
  2628. }
  2629. _gl.activeTexture( _gl.TEXTURE0 + slot );
  2630. _gl.bindTexture( _gl.TEXTURE_2D, texture.__webGLTexture );
  2631. };
  2632. function setRenderTarget( renderTexture ) {
  2633. var framebuffer;
  2634. if ( renderTexture && !renderTexture.__webGLFramebuffer ) {
  2635. renderTexture.__webGLFramebuffer = _gl.createFramebuffer();
  2636. renderTexture.__webGLRenderbuffer = _gl.createRenderbuffer();
  2637. renderTexture.__webGLTexture = _gl.createTexture();
  2638. // Setup renderbuffer
  2639. _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer );
  2640. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );
  2641. // Setup texture
  2642. _gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webGLTexture );
  2643. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, paramThreeToGL( renderTexture.wrap_s ) );
  2644. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, paramThreeToGL( renderTexture.wrap_t ) );
  2645. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( renderTexture.mag_filter ) );
  2646. _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( renderTexture.min_filter ) );
  2647. _gl.generateMipmap(_gl.TEXTURE_2D);
  2648. _gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null);
  2649. // Setup framebuffer
  2650. _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webGLFramebuffer );
  2651. _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webGLTexture, 0 );
  2652. _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer);
  2653. // Release everything
  2654. _gl.bindTexture( _gl.TEXTURE_2D, null );
  2655. _gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
  2656. _gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
  2657. }
  2658. framebuffer = renderTexture ? renderTexture.__webGLFramebuffer : null;
  2659. _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
  2660. }
  2661. function cacheUniformLocations( program, identifiers ) {
  2662. var i, l, id;
  2663. for( i = 0, l = identifiers.length; i < l; i++ ) {
  2664. id = identifiers[ i ];
  2665. program.uniforms[ id ] = _gl.getUniformLocation( program, id );
  2666. }
  2667. };
  2668. function cacheAttributeLocations( program, identifiers ) {
  2669. var i, l, id;
  2670. for( i = 0, l = identifiers.length; i < l; i++ ) {
  2671. id = identifiers[ i ];
  2672. program.attributes[ id ] = _gl.getAttribLocation( program, id );
  2673. }
  2674. };
  2675. function getShader( type, string ) {
  2676. var shader;
  2677. if ( type == "fragment" ) {
  2678. shader = _gl.createShader( _gl.FRAGMENT_SHADER );
  2679. } else if ( type == "vertex" ) {
  2680. shader = _gl.createShader( _gl.VERTEX_SHADER );
  2681. }
  2682. _gl.shaderSource( shader, string );
  2683. _gl.compileShader( shader );
  2684. if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
  2685. alert( _gl.getShaderInfoLog( shader ) );
  2686. return null;
  2687. }
  2688. return shader;
  2689. };
  2690. function paramThreeToGL( p ) {
  2691. switch ( p ) {
  2692. case THREE.RepeatWrapping: return _gl.REPEAT; break;
  2693. case THREE.ClampToEdgeWrapping: return _gl.CLAMP_TO_EDGE; break;
  2694. case THREE.MirroredRepeatWrapping: return _gl.MIRRORED_REPEAT; break;
  2695. case THREE.NearestFilter: return _gl.NEAREST; break;
  2696. case THREE.NearestMipMapNearestFilter: return _gl.NEAREST_MIPMAP_NEAREST; break;
  2697. case THREE.NearestMipMapLinearFilter: return _gl.NEAREST_MIPMAP_LINEAR; break;
  2698. case THREE.LinearFilter: return _gl.LINEAR; break;
  2699. case THREE.LinearMipMapNearestFilter: return _gl.LINEAR_MIPMAP_NEAREST; break;
  2700. case THREE.LinearMipMapLinearFilter: return _gl.LINEAR_MIPMAP_LINEAR; break;
  2701. case THREE.RGBFormat: return _gl.RGB; break;
  2702. case THREE.UnsignedByteType: return _gl.UNSIGNED_BYTE; break;
  2703. }
  2704. return 0;
  2705. };
  2706. function materialNeedsSmoothNormals( material ) {
  2707. return material && material.shading != undefined && material.shading == THREE.SmoothShading;
  2708. };
  2709. function bufferNeedsSmoothNormals( geometryChunk, object ) {
  2710. var m, ml, i, l, meshMaterial, needsSmoothNormals = false;
  2711. for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
  2712. meshMaterial = object.materials[ m ];
  2713. if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
  2714. for ( i = 0, l = geometryChunk.materials.length; i < l; i++ ) {
  2715. if ( materialNeedsSmoothNormals( geometryChunk.materials[ i ] ) ) {
  2716. needsSmoothNormals = true;
  2717. break;
  2718. }
  2719. }
  2720. } else {
  2721. if ( materialNeedsSmoothNormals( meshMaterial ) ) {
  2722. needsSmoothNormals = true;
  2723. break;
  2724. }
  2725. }
  2726. if ( needsSmoothNormals ) break;
  2727. }
  2728. return needsSmoothNormals;
  2729. };
  2730. function allocateLights( lights, maxLights ) {
  2731. var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
  2732. dirLights = pointLights = maxDirLights = maxPointLights = 0;
  2733. for ( l = 0, ll = lights.length; l < ll; l++ ) {
  2734. light = lights[ l ];
  2735. if ( light instanceof THREE.DirectionalLight ) dirLights++;
  2736. if ( light instanceof THREE.PointLight ) pointLights++;
  2737. }
  2738. if ( ( pointLights + dirLights ) <= maxLights ) {
  2739. maxDirLights = dirLights;
  2740. maxPointLights = pointLights;
  2741. } else {
  2742. maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
  2743. maxPointLights = maxLights - maxDirLights;
  2744. }
  2745. return { 'directional' : maxDirLights, 'point' : maxPointLights };
  2746. };
  2747. /* DEBUG
  2748. function getGLParams() {
  2749. var params = {
  2750. 'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
  2751. 'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
  2752. 'MAX_TEXTURE_IMAGE_UNITS': _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS ),
  2753. 'MAX_VERTEX_TEXTURE_IMAGE_UNITS': _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ),
  2754. 'MAX_COMBINED_TEXTURE_IMAGE_UNITS' : _gl.getParameter( _gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS ),
  2755. 'MAX_VERTEX_UNIFORM_VECTORS': _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS ),
  2756. 'MAX_FRAGMENT_UNIFORM_VECTORS': _gl.getParameter( _gl.MAX_FRAGMENT_UNIFORM_VECTORS )
  2757. }
  2758. return params;
  2759. };
  2760. function dumpObject( obj ) {
  2761. var p, str = "";
  2762. for ( p in obj ) {
  2763. str += p + ": " + obj[p] + "\n";
  2764. }
  2765. return str;
  2766. }
  2767. */
  2768. };
  2769. THREE.Snippets = {
  2770. fog_pars_fragment: [
  2771. "#ifdef USE_FOG",
  2772. "uniform vec3 fogColor;",
  2773. "#ifdef FOG_EXP2",
  2774. "uniform float fogDensity;",
  2775. "#else",
  2776. "uniform float fogNear;",
  2777. "uniform float fogFar;",
  2778. "#endif",
  2779. "#endif"
  2780. ].join("\n"),
  2781. fog_fragment: [
  2782. "#ifdef USE_FOG",
  2783. "float depth = gl_FragCoord.z / gl_FragCoord.w;",
  2784. "#ifdef FOG_EXP2",
  2785. "const float LOG2 = 1.442695;",
  2786. "float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );",
  2787. "fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );",
  2788. "#else",
  2789. "float fogFactor = smoothstep( fogNear, fogFar, depth );",
  2790. "#endif",
  2791. "gl_FragColor = mix( gl_FragColor, vec4( fogColor, 1.0 ), fogFactor );",
  2792. "#endif"
  2793. ].join("\n"),
  2794. envmap_pars_fragment: [
  2795. "#ifdef USE_ENVMAP",
  2796. "varying vec3 vReflect;",
  2797. "uniform float reflectivity;",
  2798. "uniform samplerCube env_map;",
  2799. "uniform int combine;",
  2800. "#endif"
  2801. ].join("\n"),
  2802. envmap_fragment: [
  2803. "#ifdef USE_ENVMAP",
  2804. "cubeColor = textureCube( env_map, vec3( -vReflect.x, vReflect.yz ) );",
  2805. "if ( combine == 1 ) {",
  2806. "gl_FragColor = mix( gl_FragColor, cubeColor, reflectivity );",
  2807. "} else {",
  2808. "gl_FragColor = gl_FragColor * cubeColor;",
  2809. "}",
  2810. "#endif"
  2811. ].join("\n"),
  2812. envmap_pars_vertex: [
  2813. "#ifdef USE_ENVMAP",
  2814. "varying vec3 vReflect;",
  2815. "uniform float refraction_ratio;",
  2816. "uniform bool useRefract;",
  2817. "#endif"
  2818. ].join("\n"),
  2819. envmap_vertex : [
  2820. "#ifdef USE_ENVMAP",
  2821. "vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
  2822. "vec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;",
  2823. "if ( useRefract ) {",
  2824. "vReflect = refract( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ), refraction_ratio );",
  2825. "} else {",
  2826. "vReflect = reflect( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ) );",
  2827. "}",
  2828. "#endif"
  2829. ].join("\n"),
  2830. map_pars_fragment: [
  2831. "#ifdef USE_MAP",
  2832. "varying vec2 vUv;",
  2833. "uniform sampler2D map;",
  2834. "#endif"
  2835. ].join("\n"),
  2836. map_pars_vertex: [
  2837. "#ifdef USE_MAP",
  2838. "varying vec2 vUv;",
  2839. "#endif"
  2840. ].join("\n"),
  2841. map_fragment: [
  2842. "#ifdef USE_MAP",
  2843. "mapColor = texture2D( map, vUv );",
  2844. "#endif"
  2845. ].join("\n"),
  2846. map_vertex: [
  2847. "#ifdef USE_MAP",
  2848. "vUv = uv;",
  2849. "#endif"
  2850. ].join("\n"),
  2851. lights_pars_vertex: [
  2852. "uniform bool enableLighting;",
  2853. "uniform vec3 ambientLightColor;",
  2854. "#if MAX_DIR_LIGHTS > 0",
  2855. "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
  2856. "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
  2857. "#endif",
  2858. "#if MAX_POINT_LIGHTS > 0",
  2859. "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
  2860. "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
  2861. "#ifdef PHONG",
  2862. "varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];",
  2863. "#endif",
  2864. "#endif"
  2865. ].join("\n"),
  2866. lights_vertex: [
  2867. "if ( !enableLighting ) {",
  2868. "vLightWeighting = vec3( 1.0 );",
  2869. "} else {",
  2870. "vLightWeighting = ambientLightColor;",
  2871. "#if MAX_DIR_LIGHTS > 0",
  2872. "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
  2873. "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
  2874. "float directionalLightWeighting = max( dot( transformedNormal, normalize( lDirection.xyz ) ), 0.0 );",
  2875. "vLightWeighting += directionalLightColor[ i ] * directionalLightWeighting;",
  2876. "}",
  2877. "#endif",
  2878. "#if MAX_POINT_LIGHTS > 0",
  2879. "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
  2880. "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
  2881. "vec3 pointLightVector = normalize( lPosition.xyz - mvPosition.xyz );",
  2882. "float pointLightWeighting = max( dot( transformedNormal, pointLightVector ), 0.0 );",
  2883. "vLightWeighting += pointLightColor[ i ] * pointLightWeighting;",
  2884. "#ifdef PHONG",
  2885. "vPointLightVector[ i ] = pointLightVector;",
  2886. "#endif",
  2887. "}",
  2888. "#endif",
  2889. "}"
  2890. ].join("\n"),
  2891. lights_pars_fragment: [
  2892. "#if MAX_DIR_LIGHTS > 0",
  2893. "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
  2894. "#endif",
  2895. "#if MAX_POINT_LIGHTS > 0",
  2896. "varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];",
  2897. "#endif",
  2898. "varying vec3 vViewPosition;",
  2899. "varying vec3 vNormal;"
  2900. ].join("\n"),
  2901. lights_fragment: [
  2902. "vec3 normal = normalize( vNormal );",
  2903. "vec3 viewPosition = normalize( vViewPosition );",
  2904. "vec4 mSpecular = vec4( specular, opacity );",
  2905. "#if MAX_POINT_LIGHTS > 0",
  2906. "vec4 pointDiffuse = vec4( 0.0 );",
  2907. "vec4 pointSpecular = vec4( 0.0 );",
  2908. "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
  2909. "vec3 pointVector = normalize( vPointLightVector[ i ] );",
  2910. "vec3 pointHalfVector = normalize( vPointLightVector[ i ] + vViewPosition );",
  2911. "float pointDotNormalHalf = dot( normal, pointHalfVector );",
  2912. "float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
  2913. "float pointSpecularWeight = 0.0;",
  2914. "if ( pointDotNormalHalf >= 0.0 )",
  2915. "pointSpecularWeight = pow( pointDotNormalHalf, shininess );",
  2916. "pointDiffuse += mColor * pointDiffuseWeight;",
  2917. "pointSpecular += mSpecular * pointSpecularWeight;",
  2918. "}",
  2919. "#endif",
  2920. "#if MAX_DIR_LIGHTS > 0",
  2921. "vec4 dirDiffuse = vec4( 0.0 );",
  2922. "vec4 dirSpecular = vec4( 0.0 );" ,
  2923. "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
  2924. "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
  2925. "vec3 dirVector = normalize( lDirection.xyz );",
  2926. "vec3 dirHalfVector = normalize( lDirection.xyz + vViewPosition );",
  2927. "float dirDotNormalHalf = dot( normal, dirHalfVector );",
  2928. "float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
  2929. "float dirSpecularWeight = 0.0;",
  2930. "if ( dirDotNormalHalf >= 0.0 )",
  2931. "dirSpecularWeight = pow( dirDotNormalHalf, shininess );",
  2932. "dirDiffuse += mColor * dirDiffuseWeight;",
  2933. "dirSpecular += mSpecular * dirSpecularWeight;",
  2934. "}",
  2935. "#endif",
  2936. "vec4 totalLight = vec4( ambient, opacity );",
  2937. "#if MAX_DIR_LIGHTS > 0",
  2938. "totalLight += dirDiffuse + dirSpecular;",
  2939. "#endif",
  2940. "#if MAX_POINT_LIGHTS > 0",
  2941. "totalLight += pointDiffuse + pointSpecular;",
  2942. "#endif"
  2943. ].join("\n")
  2944. };
  2945. THREE.UniformsLib = {
  2946. common: {
  2947. "color" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
  2948. "opacity" : { type: "f", value: 1 },
  2949. "map" : { type: "t", value: 0, texture: null },
  2950. "env_map" : { type: "t", value: 1, texture: null },
  2951. "useRefract" : { type: "i", value: 0 },
  2952. "reflectivity" : { type: "f", value: 1 },
  2953. "refraction_ratio": { type: "f", value: 0.98 },
  2954. "combine" : { type: "i", value: 0 },
  2955. "fogDensity": { type: "f", value: 0.00025 },
  2956. "fogNear" : { type: "f", value: 1 },
  2957. "fogFar" : { type: "f", value: 2000 },
  2958. "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) }
  2959. },
  2960. lights: {
  2961. "enableLighting" : { type: "i", value: 1 },
  2962. "ambientLightColor" : { type: "fv", value: [] },
  2963. "directionalLightDirection" : { type: "fv", value: [] },
  2964. "directionalLightColor" : { type: "fv", value: [] },
  2965. "pointLightPosition" : { type: "fv", value: [] },
  2966. "pointLightColor" : { type: "fv", value: [] }
  2967. }
  2968. };
  2969. THREE.ShaderLib = {
  2970. 'depth': {
  2971. uniforms: { "mNear": { type: "f", value: 1.0 },
  2972. "mFar" : { type: "f", value: 2000.0 } },
  2973. fragment_shader: [
  2974. "uniform float mNear;",
  2975. "uniform float mFar;",
  2976. "void main() {",
  2977. "float depth = gl_FragCoord.z / gl_FragCoord.w;",
  2978. "float color = 1.0 - smoothstep( mNear, mFar, depth );",
  2979. "gl_FragColor = vec4( vec3( color ), 1.0 );",
  2980. "}"
  2981. ].join("\n"),
  2982. vertex_shader: [
  2983. "void main() {",
  2984. "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
  2985. "}"
  2986. ].join("\n")
  2987. },
  2988. 'normal': {
  2989. uniforms: { },
  2990. fragment_shader: [
  2991. "varying vec3 vNormal;",
  2992. "void main() {",
  2993. "gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, 1.0 );",
  2994. "}"
  2995. ].join("\n"),
  2996. vertex_shader: [
  2997. "varying vec3 vNormal;",
  2998. "void main() {",
  2999. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  3000. "vNormal = normalize( normalMatrix * normal );",
  3001. "gl_Position = projectionMatrix * mvPosition;",
  3002. "}"
  3003. ].join("\n")
  3004. },
  3005. 'basic': {
  3006. uniforms: THREE.UniformsLib[ "common" ],
  3007. fragment_shader: [
  3008. "uniform vec3 color;",
  3009. "uniform float opacity;",
  3010. THREE.Snippets[ "map_pars_fragment" ],
  3011. THREE.Snippets[ "envmap_pars_fragment" ],
  3012. THREE.Snippets[ "fog_pars_fragment" ],
  3013. "void main() {",
  3014. "vec4 mColor = vec4( color, opacity );",
  3015. "vec4 mapColor = vec4( 1.0 );",
  3016. "vec4 cubeColor = vec4( 1.0 );",
  3017. THREE.Snippets[ "map_fragment" ],
  3018. "gl_FragColor = mColor * mapColor;",
  3019. THREE.Snippets[ "envmap_fragment" ],
  3020. THREE.Snippets[ "fog_fragment" ],
  3021. "}"
  3022. ].join("\n"),
  3023. vertex_shader: [
  3024. THREE.Snippets[ "map_pars_vertex" ],
  3025. THREE.Snippets[ "envmap_pars_vertex" ],
  3026. "void main() {",
  3027. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  3028. THREE.Snippets[ "map_vertex" ],
  3029. THREE.Snippets[ "envmap_vertex" ],
  3030. "gl_Position = projectionMatrix * mvPosition;",
  3031. "}"
  3032. ].join("\n")
  3033. },
  3034. 'lambert': {
  3035. uniforms: Uniforms.merge( [ THREE.UniformsLib[ "common" ],
  3036. THREE.UniformsLib[ "lights" ] ] ),
  3037. fragment_shader: [
  3038. "uniform vec3 color;",
  3039. "uniform float opacity;",
  3040. "varying vec3 vLightWeighting;",
  3041. THREE.Snippets[ "map_pars_fragment" ],
  3042. THREE.Snippets[ "envmap_pars_fragment" ],
  3043. THREE.Snippets[ "fog_pars_fragment" ],
  3044. "void main() {",
  3045. "vec4 mColor = vec4( color, opacity );",
  3046. "vec4 mapColor = vec4( 1.0 );",
  3047. "vec4 cubeColor = vec4( 1.0 );",
  3048. THREE.Snippets[ "map_fragment" ],
  3049. "gl_FragColor = mColor * mapColor * vec4( vLightWeighting, 1.0 );",
  3050. THREE.Snippets[ "envmap_fragment" ],
  3051. THREE.Snippets[ "fog_fragment" ],
  3052. "}"
  3053. ].join("\n"),
  3054. vertex_shader: [
  3055. "varying vec3 vLightWeighting;",
  3056. THREE.Snippets[ "map_pars_vertex" ],
  3057. THREE.Snippets[ "envmap_pars_vertex" ],
  3058. THREE.Snippets[ "lights_pars_vertex" ],
  3059. "void main() {",
  3060. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  3061. THREE.Snippets[ "map_vertex" ],
  3062. THREE.Snippets[ "envmap_vertex" ],
  3063. "vec3 transformedNormal = normalize( normalMatrix * normal );",
  3064. THREE.Snippets[ "lights_vertex" ],
  3065. "gl_Position = projectionMatrix * mvPosition;",
  3066. "}"
  3067. ].join("\n")
  3068. },
  3069. 'phong': {
  3070. uniforms: Uniforms.merge( [ THREE.UniformsLib[ "common" ],
  3071. THREE.UniformsLib[ "lights" ],
  3072. { "ambient" : { type: "c", value: new THREE.Color( 0x050505 ) },
  3073. "specular" : { type: "c", value: new THREE.Color( 0x111111 ) },
  3074. "shininess": { type: "f", value: 30 }
  3075. }
  3076. ] ),
  3077. fragment_shader: [
  3078. "uniform vec3 color;",
  3079. "uniform float opacity;",
  3080. "uniform vec3 ambient;",
  3081. "uniform vec3 specular;",
  3082. "uniform float shininess;",
  3083. "varying vec3 vLightWeighting;",
  3084. THREE.Snippets[ "map_pars_fragment" ],
  3085. THREE.Snippets[ "envmap_pars_fragment" ],
  3086. THREE.Snippets[ "fog_pars_fragment" ],
  3087. THREE.Snippets[ "lights_pars_fragment" ],
  3088. "void main() {",
  3089. "vec4 mColor = vec4( color, opacity );",
  3090. "vec4 mapColor = vec4( 1.0 );",
  3091. "vec4 cubeColor = vec4( 1.0 );",
  3092. THREE.Snippets[ "map_fragment" ],
  3093. THREE.Snippets[ "lights_fragment" ],
  3094. "gl_FragColor = mapColor * totalLight * vec4( vLightWeighting, 1.0 );",
  3095. THREE.Snippets[ "envmap_fragment" ],
  3096. THREE.Snippets[ "fog_fragment" ],
  3097. "}"
  3098. ].join("\n"),
  3099. vertex_shader: [
  3100. "#define PHONG",
  3101. "varying vec3 vLightWeighting;",
  3102. "varying vec3 vViewPosition;",
  3103. "varying vec3 vNormal;",
  3104. THREE.Snippets[ "map_pars_vertex" ],
  3105. THREE.Snippets[ "envmap_pars_vertex" ],
  3106. THREE.Snippets[ "lights_pars_vertex" ],
  3107. "void main() {",
  3108. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
  3109. THREE.Snippets[ "map_vertex" ],
  3110. THREE.Snippets[ "envmap_vertex" ],
  3111. "#ifndef USE_ENVMAP",
  3112. "vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
  3113. "#endif",
  3114. "vViewPosition = cameraPosition - mPosition.xyz;",
  3115. "vec3 transformedNormal = normalize( normalMatrix * normal );",
  3116. "vNormal = transformedNormal;",
  3117. THREE.Snippets[ "lights_vertex" ],
  3118. "gl_Position = projectionMatrix * mvPosition;",
  3119. "}"
  3120. ].join("\n")
  3121. }
  3122. };
粤ICP备19079148号